Merge branches 'meixiongfeng' and 'dev' of http://git.legu.cc/liwei_3d/go_dreamfactory into meixiongfeng
This commit is contained in:
commit
fe868ea764
@ -114,6 +114,7 @@ func (this *appTerm) LazyInit(obs observer.Observer) error {
|
||||
|
||||
//excute
|
||||
excuteBtn := &widget.Button{Text: "执行", Icon: theme.ConfirmIcon()}
|
||||
excuteBtn.TypedKey(&fyne.KeyEvent{Name: fyne.KeyEnter})
|
||||
excuteBtn.OnTapped = func() {
|
||||
output.Text = ""
|
||||
excuteBtn.Disable()
|
||||
@ -136,7 +137,7 @@ func (this *appTerm) LazyInit(obs observer.Observer) error {
|
||||
split := container.NewVSplit(container.NewGridWithColumns(2,
|
||||
cmdLast,
|
||||
container.NewBorder(configForm, btns, widget.NewSeparator(), nil)), output)
|
||||
split.Offset = 0.3
|
||||
split.Offset = 0.25
|
||||
content.Objects = append(content.Objects, split)
|
||||
|
||||
this.tabItem.Content = content
|
||||
|
@ -115,6 +115,11 @@ func (this *MCompModel) GetListObj(uid string, id string, data interface{}) (err
|
||||
return this.DBModel.GetListObj(uid, id, data)
|
||||
}
|
||||
|
||||
//批量读取列表中多个数据
|
||||
func (this *MCompModel) GetListObjs(uid string, ids []string, data interface{}) (err error) {
|
||||
return this.DBModel.GetListObjs(uid, ids, data)
|
||||
}
|
||||
|
||||
//删除用户数据
|
||||
func (this *MCompModel) Del(uid string, opt ...db.DBOption) (err error) {
|
||||
return this.DBModel.Del(uid, opt...)
|
||||
|
35
modules/equipment/api_lock.go
Normal file
35
modules/equipment/api_lock.go
Normal file
@ -0,0 +1,35 @@
|
||||
package equipment
|
||||
|
||||
import (
|
||||
"go_dreamfactory/comm"
|
||||
"go_dreamfactory/pb"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
//参数校验
|
||||
func (this *apiComp) LockCheck(session comm.IUserSession, req *pb.EquipmentLockReq) (code pb.ErrorCode) {
|
||||
if req.EquipmentId == "" {
|
||||
code = pb.ErrorCode_ReqParameterError
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
///获取用户装备列表
|
||||
func (this *apiComp) Lock(session comm.IUserSession, req *pb.EquipmentLockReq) (code pb.ErrorCode, data proto.Message) {
|
||||
var (
|
||||
err error
|
||||
equipment *pb.DB_Equipment
|
||||
)
|
||||
if code = this.LockCheck(session, req); code != pb.ErrorCode_Success {
|
||||
return
|
||||
}
|
||||
if equipment, err = this.module.modelEquipment.QueryUserEquipmentsById(session.GetUserId(), req.EquipmentId); err != nil {
|
||||
this.module.Errorf("Equip_Check err:%v", err)
|
||||
code = pb.ErrorCode_EquipmentOnFoundEquipment
|
||||
return
|
||||
}
|
||||
equipment.Lock = req.IsLock
|
||||
session.SendMsg(string(this.module.GetType()), "getlist", &pb.EquipmentLockResp{IsSucc: true, EquipmentId: req.EquipmentId, IsLock: req.IsLock})
|
||||
return
|
||||
}
|
62
modules/equipment/api_sellI.go
Normal file
62
modules/equipment/api_sellI.go
Normal file
@ -0,0 +1,62 @@
|
||||
package equipment
|
||||
|
||||
import (
|
||||
"go_dreamfactory/comm"
|
||||
"go_dreamfactory/pb"
|
||||
cfg "go_dreamfactory/sys/configure/structs"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
//参数校验
|
||||
func (this *apiComp) SellCheck(session comm.IUserSession, req *pb.EquipmentSellReq) (code pb.ErrorCode) {
|
||||
if req.EquipIds == nil || len(req.EquipIds) == 0 {
|
||||
code = pb.ErrorCode_ReqParameterError
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//出售
|
||||
func (this *apiComp) Sell(session comm.IUserSession, req *pb.EquipmentSellReq) (code pb.ErrorCode, data proto.Message) {
|
||||
var (
|
||||
err error
|
||||
equipments []*pb.DB_Equipment
|
||||
confs []*cfg.GameEquipData
|
||||
sale []*cfg.Gameatn
|
||||
)
|
||||
if code = this.SellCheck(session, req); code != pb.ErrorCode_Success {
|
||||
return
|
||||
}
|
||||
if equipments, err = this.module.modelEquipment.QueryUserEquipmentsByIds(session.GetUserId(), req.EquipIds); err != nil {
|
||||
code = pb.ErrorCode_ReqParameterError
|
||||
return
|
||||
}
|
||||
confs = make([]*cfg.GameEquipData, len(equipments))
|
||||
for i, v := range equipments {
|
||||
if v.HeroId != "" || v.Lock {
|
||||
code = pb.ErrorCode_EquipmentNoCanSell
|
||||
this.module.Errorf("NoCanSell %v", v)
|
||||
return
|
||||
}
|
||||
if confs[i], err = this.module.configure.GetEquipmentConfigureById(v.CId); err != nil {
|
||||
this.module.Errorln(err)
|
||||
code = pb.ErrorCode_EquipmentOnFoundEquipment
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
sale = make([]*cfg.Gameatn, 0)
|
||||
for _, v := range confs {
|
||||
for _, s := range v.Sale {
|
||||
sale = append(sale, s)
|
||||
}
|
||||
}
|
||||
if code = this.module.DispenseRes(session, sale, true); code != pb.ErrorCode_Success {
|
||||
return
|
||||
}
|
||||
if code = this.module.DelEquipments(session, req.EquipIds, true); code != pb.ErrorCode_Success {
|
||||
return
|
||||
}
|
||||
session.SendMsg(string(this.module.GetType()), "sell", &pb.ItemsUseItemResp{Issucc: true})
|
||||
return
|
||||
}
|
@ -70,6 +70,30 @@ func (this *configureComp) GetEquipmentConfigureById(equipmentId string) (config
|
||||
return
|
||||
}
|
||||
|
||||
//获取装备配置数据
|
||||
func (this *configureComp) GetEquipmentConfigureByIds(equipmentId []string) (configure []*cfg.GameEquipData, err error) {
|
||||
var (
|
||||
t interface{}
|
||||
c *cfg.GameEquipData
|
||||
ok bool
|
||||
)
|
||||
if t, err = this.GetConfigure(game_equip); err != nil {
|
||||
this.module.Errorf("err:%v", err)
|
||||
return
|
||||
} else {
|
||||
|
||||
configure = make([]*cfg.GameEquipData, len(equipmentId))
|
||||
|
||||
for i, v := range equipmentId {
|
||||
if c, ok = t.(*cfg.GameEquip).GetDataMap()[v]; ok {
|
||||
configure[i] = c
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//获取装备属性表
|
||||
func (this *configureComp) GetEquipmentAttrlibraryConfigure() (configure *cfg.GameEquipAttrlibrary, err error) {
|
||||
var (
|
||||
|
@ -40,6 +40,13 @@ func (this *modelEquipmentComp) QueryUserEquipmentsById(uId, id string) (equipme
|
||||
return
|
||||
}
|
||||
|
||||
//查询用户装备数据
|
||||
func (this *modelEquipmentComp) QueryUserEquipmentsByIds(uId string, ids []string) (equipments []*pb.DB_Equipment, err error) {
|
||||
equipments = []*pb.DB_Equipment{}
|
||||
err = this.GetListObjs(uId, ids, &equipments)
|
||||
return
|
||||
}
|
||||
|
||||
///查询用户的武器背包
|
||||
func (this *modelEquipmentComp) QueryUserEquipments(uId string) (equipments []*pb.DB_Equipment, err error) {
|
||||
equipments = make([]*pb.DB_Equipment, 0)
|
||||
@ -123,6 +130,23 @@ func (this *modelEquipmentComp) AddEquipments(uId string, cIds map[string]uint32
|
||||
return
|
||||
}
|
||||
|
||||
//删除装备
|
||||
func (this *modelEquipmentComp) DelEquipments(uId string, eIds []string) (change []*pb.DB_Equipment, err error) {
|
||||
change = make([]*pb.DB_Equipment, 0)
|
||||
if err = this.DelListlds(uId, eIds...); err != nil {
|
||||
this.module.Errorln(err)
|
||||
return
|
||||
}
|
||||
for _, v := range eIds {
|
||||
change = append(change, &pb.DB_Equipment{
|
||||
Id: v,
|
||||
UId: uId,
|
||||
OverlayNum: 0,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//更新武器挂载信息
|
||||
func (this *modelEquipmentComp) UpdateByHeroId(uid string, equipments ...*pb.DB_Equipment) (err error) {
|
||||
for _, v := range equipments {
|
||||
|
@ -104,11 +104,26 @@ func (this *Equipment) AddNewEquipments(source *comm.ModuleCallSource, session c
|
||||
return
|
||||
}
|
||||
|
||||
//删除武器
|
||||
func (this *Equipment) DelEquipments(session comm.IUserSession, equipIds []string, bPush bool) (code pb.ErrorCode) {
|
||||
var (
|
||||
err error
|
||||
change []*pb.DB_Equipment
|
||||
)
|
||||
if change, err = this.modelEquipment.DelEquipments(session.GetUserId(), equipIds); err != nil {
|
||||
this.Errorf("err%v", err)
|
||||
code = pb.ErrorCode_SystemError
|
||||
return
|
||||
}
|
||||
if len(change) > 0 && bPush {
|
||||
this.equipmentsChangePush(session, change)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//Evens--------------------------------------------------------------------------------------------------------------------------------
|
||||
//推送道具变化消息
|
||||
func (this *Equipment) equipmentsChangePush(session comm.IUserSession, items []*pb.DB_Equipment) (err error) {
|
||||
|
||||
session.SendMsg(string(this.GetType()), "change", &pb.EquipmentChangePush{Equipments: items})
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ func (this *modelMartialhall) queryUserMartialhall(uid string) (result *pb.DBMar
|
||||
Id: primitive.NewObjectID().Hex(),
|
||||
Uid: uid,
|
||||
Lv: 1,
|
||||
Pillar1: &pb.DBPillar{Index: 1},
|
||||
Pillar1: &pb.DBPillar{Index: 1, Isunlock: true},
|
||||
Pillar2: &pb.DBPillar{Index: 2},
|
||||
Pillar3: &pb.DBPillar{Index: 3},
|
||||
Pillar4: &pb.DBPillar{Index: 4},
|
||||
|
@ -52,8 +52,10 @@ func (this *ModuleTask) Start() (err error) {
|
||||
}
|
||||
|
||||
//初始化日常、周常、成就
|
||||
func (this *ModuleTask) InitTask(uid string, taskTag comm.TaskTag) {
|
||||
this.modelTask.initTask(uid, taskTag)
|
||||
func (this *ModuleTask) InitTaskAll(uid string) {
|
||||
this.modelTask.initTask(uid, comm.TASK_DAILY)
|
||||
this.modelTask.initTask(uid, comm.TASK_WEEKLY)
|
||||
this.modelTask.initTask(uid, comm.TASK_ACHIEVE)
|
||||
this.modelTaskActive.initActiveReward(uid)
|
||||
}
|
||||
|
||||
@ -96,7 +98,7 @@ func (this *ModuleTask) ResetTask(uid string, taskTag comm.TaskTag) {
|
||||
this.resetActive(uid, taskTag)
|
||||
this.modelTask.clearTask(uid, taskTag)
|
||||
this.modelTaskActive.clearTask(uid, taskTag)
|
||||
this.InitTask(uid, taskTag)
|
||||
this.InitTaskAll(uid)
|
||||
}
|
||||
|
||||
//任务处理
|
||||
|
@ -116,6 +116,7 @@ type DB_Equipment struct {
|
||||
AdverbEntry []*EquipmentAttributeEntry `protobuf:"bytes,9,rep,name=adverbEntry,proto3" json:"adverbEntry" bson:"adverbEntry"` //装备副词条
|
||||
OverlayNum uint32 `protobuf:"varint,10,opt,name=overlayNum,proto3" json:"overlayNum" bson:"overlayNum"` //叠加数量
|
||||
IsInitialState bool `protobuf:"varint,11,opt,name=isInitialState,proto3" json:"isInitialState" bson:"isInitialState"` //是否初始状态
|
||||
Lock bool `protobuf:"varint,12,opt,name=lock,proto3" json:"lock" bson:"lock"` //是否锁
|
||||
}
|
||||
|
||||
func (x *DB_Equipment) Reset() {
|
||||
@ -220,6 +221,13 @@ func (x *DB_Equipment) GetIsInitialState() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *DB_Equipment) GetLock() bool {
|
||||
if x != nil {
|
||||
return x.Lock
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_equipment_equipment_db_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_equipment_equipment_db_proto_rawDesc = []byte{
|
||||
@ -233,7 +241,7 @@ var file_equipment_equipment_db_proto_rawDesc = []byte{
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x41, 0x74, 0x74, 0x72,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x4c, 0x76, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x02, 0x4c, 0x76, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc8, 0x02, 0x0a, 0x0c, 0x44,
|
||||
0x01, 0x28, 0x05, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xdc, 0x02, 0x0a, 0x0c, 0x44,
|
||||
0x42, 0x5f, 0x45, 0x71, 0x75, 0x69, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x63,
|
||||
0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x49, 0x64, 0x12, 0x10, 0x0a,
|
||||
@ -254,8 +262,9 @@ var file_equipment_equipment_db_proto_rawDesc = []byte{
|
||||
0x0d, 0x52, 0x0a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x4e, 0x75, 0x6d, 0x12, 0x26, 0x0a,
|
||||
0x0e, 0x69, 0x73, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18,
|
||||
0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x73, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c,
|
||||
0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x0c, 0x20,
|
||||
0x01, 0x28, 0x08, 0x52, 0x04, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70,
|
||||
0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -307,14 +307,15 @@ func (x *EquipmentUpgradeReq) GetEquipmentId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
//装备升级 回应
|
||||
//装备升级 回应 由于装备可以叠加 升级后会创建一个新的装备出来
|
||||
//所以可能影响两个装备
|
||||
type EquipmentUpgradeResp struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
IsSucc bool `protobuf:"varint,1,opt,name=IsSucc,proto3" json:"IsSucc"`
|
||||
Equipment []*DB_Equipment `protobuf:"bytes,2,rep,name=Equipment,proto3" json:"Equipment"` //由于装备可以叠加 升级后会创建一个新的装备出来 所以可能影响两个装备
|
||||
Equipment []*DB_Equipment `protobuf:"bytes,2,rep,name=Equipment,proto3" json:"Equipment"`
|
||||
}
|
||||
|
||||
func (x *EquipmentUpgradeResp) Reset() {
|
||||
@ -363,6 +364,222 @@ func (x *EquipmentUpgradeResp) GetEquipment() []*DB_Equipment {
|
||||
return nil
|
||||
}
|
||||
|
||||
//出售道具请求sailitem
|
||||
type EquipmentLockReq struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
EquipmentId string `protobuf:"bytes,1,opt,name=EquipmentId,proto3" json:"EquipmentId"` //装备的唯一id
|
||||
IsLock bool `protobuf:"varint,2,opt,name=IsLock,proto3" json:"IsLock"` //是否锁
|
||||
}
|
||||
|
||||
func (x *EquipmentLockReq) Reset() {
|
||||
*x = EquipmentLockReq{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_equipment_equipment_msg_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EquipmentLockReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EquipmentLockReq) ProtoMessage() {}
|
||||
|
||||
func (x *EquipmentLockReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_equipment_equipment_msg_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EquipmentLockReq.ProtoReflect.Descriptor instead.
|
||||
func (*EquipmentLockReq) Descriptor() ([]byte, []int) {
|
||||
return file_equipment_equipment_msg_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *EquipmentLockReq) GetEquipmentId() string {
|
||||
if x != nil {
|
||||
return x.EquipmentId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EquipmentLockReq) GetIsLock() bool {
|
||||
if x != nil {
|
||||
return x.IsLock
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//出售道具请求 回应
|
||||
type EquipmentLockResp struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
IsSucc bool `protobuf:"varint,1,opt,name=IsSucc,proto3" json:"IsSucc"`
|
||||
EquipmentId string `protobuf:"bytes,2,opt,name=EquipmentId,proto3" json:"EquipmentId"`
|
||||
IsLock bool `protobuf:"varint,3,opt,name=IsLock,proto3" json:"IsLock"`
|
||||
}
|
||||
|
||||
func (x *EquipmentLockResp) Reset() {
|
||||
*x = EquipmentLockResp{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_equipment_equipment_msg_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EquipmentLockResp) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EquipmentLockResp) ProtoMessage() {}
|
||||
|
||||
func (x *EquipmentLockResp) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_equipment_equipment_msg_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EquipmentLockResp.ProtoReflect.Descriptor instead.
|
||||
func (*EquipmentLockResp) Descriptor() ([]byte, []int) {
|
||||
return file_equipment_equipment_msg_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *EquipmentLockResp) GetIsSucc() bool {
|
||||
if x != nil {
|
||||
return x.IsSucc
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *EquipmentLockResp) GetEquipmentId() string {
|
||||
if x != nil {
|
||||
return x.EquipmentId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EquipmentLockResp) GetIsLock() bool {
|
||||
if x != nil {
|
||||
return x.IsLock
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//出售道具请求sailitem
|
||||
type EquipmentSellReq struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
EquipIds []string `protobuf:"bytes,1,rep,name=EquipIds,proto3" json:"EquipIds"`
|
||||
}
|
||||
|
||||
func (x *EquipmentSellReq) Reset() {
|
||||
*x = EquipmentSellReq{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_equipment_equipment_msg_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EquipmentSellReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EquipmentSellReq) ProtoMessage() {}
|
||||
|
||||
func (x *EquipmentSellReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_equipment_equipment_msg_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EquipmentSellReq.ProtoReflect.Descriptor instead.
|
||||
func (*EquipmentSellReq) Descriptor() ([]byte, []int) {
|
||||
return file_equipment_equipment_msg_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *EquipmentSellReq) GetEquipIds() []string {
|
||||
if x != nil {
|
||||
return x.EquipIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//出售道具请求 回应
|
||||
type EquipmentSellResp struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
IsSucc bool `protobuf:"varint,1,opt,name=IsSucc,proto3" json:"IsSucc"`
|
||||
}
|
||||
|
||||
func (x *EquipmentSellResp) Reset() {
|
||||
*x = EquipmentSellResp{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_equipment_equipment_msg_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EquipmentSellResp) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EquipmentSellResp) ProtoMessage() {}
|
||||
|
||||
func (x *EquipmentSellResp) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_equipment_equipment_msg_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EquipmentSellResp.ProtoReflect.Descriptor instead.
|
||||
func (*EquipmentSellResp) Descriptor() ([]byte, []int) {
|
||||
return file_equipment_equipment_msg_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
func (x *EquipmentSellResp) GetIsSucc() bool {
|
||||
if x != nil {
|
||||
return x.IsSucc
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_equipment_equipment_msg_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_equipment_equipment_msg_proto_rawDesc = []byte{
|
||||
@ -399,8 +616,25 @@ var file_equipment_equipment_msg_proto_rawDesc = []byte{
|
||||
0x49, 0x73, 0x53, 0x75, 0x63, 0x63, 0x12, 0x2b, 0x0a, 0x09, 0x45, 0x71, 0x75, 0x69, 0x70, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x44, 0x42, 0x5f, 0x45,
|
||||
0x71, 0x75, 0x69, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x45, 0x71, 0x75, 0x69, 0x70, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
0x65, 0x6e, 0x74, 0x22, 0x4c, 0x0a, 0x10, 0x45, 0x71, 0x75, 0x69, 0x70, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x12, 0x20, 0x0a, 0x0b, 0x45, 0x71, 0x75, 0x69, 0x70,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x45, 0x71,
|
||||
0x75, 0x69, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x49, 0x73, 0x4c,
|
||||
0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x49, 0x73, 0x4c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x65, 0x0a, 0x11, 0x45, 0x71, 0x75, 0x69, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x6f,
|
||||
0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x49, 0x73, 0x53, 0x75, 0x63, 0x63,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x49, 0x73, 0x53, 0x75, 0x63, 0x63, 0x12, 0x20,
|
||||
0x0a, 0x0b, 0x45, 0x71, 0x75, 0x69, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0b, 0x45, 0x71, 0x75, 0x69, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x49, 0x73, 0x4c, 0x6f, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x06, 0x49, 0x73, 0x4c, 0x6f, 0x63, 0x6b, 0x22, 0x2e, 0x0a, 0x10, 0x45, 0x71, 0x75, 0x69,
|
||||
0x70, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x45, 0x71, 0x75, 0x69, 0x70, 0x49, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08,
|
||||
0x45, 0x71, 0x75, 0x69, 0x70, 0x49, 0x64, 0x73, 0x22, 0x2b, 0x0a, 0x11, 0x45, 0x71, 0x75, 0x69,
|
||||
0x70, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x49, 0x73, 0x53, 0x75, 0x63, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x49,
|
||||
0x73, 0x53, 0x75, 0x63, 0x63, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -415,7 +649,7 @@ func file_equipment_equipment_msg_proto_rawDescGZIP() []byte {
|
||||
return file_equipment_equipment_msg_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_equipment_equipment_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_equipment_equipment_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
|
||||
var file_equipment_equipment_msg_proto_goTypes = []interface{}{
|
||||
(*EquipmentGetListReq)(nil), // 0: EquipmentGetListReq
|
||||
(*EquipmentGetListResp)(nil), // 1: EquipmentGetListResp
|
||||
@ -424,13 +658,17 @@ var file_equipment_equipment_msg_proto_goTypes = []interface{}{
|
||||
(*EquipmentEquipResp)(nil), // 4: EquipmentEquipResp
|
||||
(*EquipmentUpgradeReq)(nil), // 5: EquipmentUpgradeReq
|
||||
(*EquipmentUpgradeResp)(nil), // 6: EquipmentUpgradeResp
|
||||
(*DB_Equipment)(nil), // 7: DB_Equipment
|
||||
(*EquipmentLockReq)(nil), // 7: EquipmentLockReq
|
||||
(*EquipmentLockResp)(nil), // 8: EquipmentLockResp
|
||||
(*EquipmentSellReq)(nil), // 9: EquipmentSellReq
|
||||
(*EquipmentSellResp)(nil), // 10: EquipmentSellResp
|
||||
(*DB_Equipment)(nil), // 11: DB_Equipment
|
||||
}
|
||||
var file_equipment_equipment_msg_proto_depIdxs = []int32{
|
||||
7, // 0: EquipmentGetListResp.Equipments:type_name -> DB_Equipment
|
||||
7, // 1: EquipmentChangePush.Equipments:type_name -> DB_Equipment
|
||||
7, // 2: EquipmentEquipResp.Equipments:type_name -> DB_Equipment
|
||||
7, // 3: EquipmentUpgradeResp.Equipment:type_name -> DB_Equipment
|
||||
11, // 0: EquipmentGetListResp.Equipments:type_name -> DB_Equipment
|
||||
11, // 1: EquipmentChangePush.Equipments:type_name -> DB_Equipment
|
||||
11, // 2: EquipmentEquipResp.Equipments:type_name -> DB_Equipment
|
||||
11, // 3: EquipmentUpgradeResp.Equipment:type_name -> DB_Equipment
|
||||
4, // [4:4] is the sub-list for method output_type
|
||||
4, // [4:4] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
@ -529,6 +767,54 @@ func file_equipment_equipment_msg_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_equipment_equipment_msg_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EquipmentLockReq); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_equipment_equipment_msg_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EquipmentLockResp); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_equipment_equipment_msg_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EquipmentSellReq); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_equipment_equipment_msg_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EquipmentSellResp); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@ -536,7 +822,7 @@ func file_equipment_equipment_msg_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_equipment_equipment_msg_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 7,
|
||||
NumMessages: 11,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
113
sys/db/dbconn.go
113
sys/db/dbconn.go
@ -8,6 +8,7 @@ import (
|
||||
"go_dreamfactory/lego/sys/log"
|
||||
"go_dreamfactory/lego/sys/mgo"
|
||||
lgredis "go_dreamfactory/lego/sys/redis"
|
||||
"go_dreamfactory/lego/sys/redis/pipe"
|
||||
"go_dreamfactory/lego/utils/codec"
|
||||
"go_dreamfactory/lego/utils/codec/codecore"
|
||||
"go_dreamfactory/lego/utils/codec/json"
|
||||
@ -631,6 +632,118 @@ func (this *DBModel) GetListObj(uid string, id string, data interface{}) (err er
|
||||
return
|
||||
}
|
||||
|
||||
//读取列表数据中单个数据
|
||||
func (this *DBModel) GetListObjs(uid string, ids []string, data interface{}) (err error) {
|
||||
var (
|
||||
dtype reflect2.Type
|
||||
dkind reflect.Kind
|
||||
sType reflect2.Type
|
||||
sliceType *reflect2.UnsafeSliceType
|
||||
sliceelemType reflect2.Type
|
||||
decoder codecore.IDecoderMapJson
|
||||
encoder codecore.IEncoderMapJson
|
||||
dptr unsafe.Pointer
|
||||
elemPtr unsafe.Pointer
|
||||
n int
|
||||
ok bool
|
||||
keys map[string]string = make(map[string]string)
|
||||
tempdata map[string]string
|
||||
onfound []string = make([]string, 0, len(ids))
|
||||
pipe *pipe.RedisPipe = this.Redis.RedisPipe(context.TODO())
|
||||
result []*redis.StringStringMapCmd = make([]*redis.StringStringMapCmd, len(ids))
|
||||
c *mongo.Cursor
|
||||
)
|
||||
dptr = reflect2.PtrOf(data)
|
||||
dtype = reflect2.TypeOf(data)
|
||||
dkind = dtype.Kind()
|
||||
if dkind != reflect.Ptr {
|
||||
err = fmt.Errorf("MCompModel: GetList(non-pointer %T)", data)
|
||||
return
|
||||
}
|
||||
sType = dtype.(*reflect2.UnsafePtrType).Elem()
|
||||
if sType.Kind() != reflect.Slice {
|
||||
err = fmt.Errorf("MCompModel: GetList(data no slice %T)", data)
|
||||
return
|
||||
}
|
||||
sliceType = sType.(*reflect2.UnsafeSliceType)
|
||||
sliceelemType = sliceType.Elem()
|
||||
if sliceelemType.Kind() != reflect.Ptr {
|
||||
err = fmt.Errorf("MCompModel: GetList(sliceelemType non-pointer %T)", data)
|
||||
return
|
||||
}
|
||||
if decoder, ok = codec.DecoderOf(sliceelemType, defconf).(codecore.IDecoderMapJson); !ok {
|
||||
err = fmt.Errorf("MCompModel: GetList(data not support MarshalMapJson %T)", data)
|
||||
return
|
||||
}
|
||||
sliceelemType = sliceelemType.(*reflect2.UnsafePtrType).Elem()
|
||||
for i, v := range ids {
|
||||
result[i] = pipe.HGetAllToMapString(this.ukeylist(uid, v))
|
||||
}
|
||||
if _, err = pipe.Exec(); err == nil {
|
||||
for i, v := range result {
|
||||
if tempdata, err = v.Result(); err == nil {
|
||||
sliceType.UnsafeGrow(dptr, n+1)
|
||||
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
|
||||
if *((*unsafe.Pointer)(elemPtr)) == nil {
|
||||
newPtr := sliceelemType.UnsafeNew()
|
||||
if err = decoder.DecodeForMapJson(newPtr, json.GetReader([]byte{}), tempdata); err != nil {
|
||||
log.Errorf("err:%v", err)
|
||||
return
|
||||
}
|
||||
*((*unsafe.Pointer)(elemPtr)) = newPtr
|
||||
} else {
|
||||
decoder.DecodeForMapJson(*((*unsafe.Pointer)(elemPtr)), json.GetReader([]byte{}), tempdata)
|
||||
}
|
||||
n++
|
||||
} else {
|
||||
onfound = append(onfound, ids[i])
|
||||
}
|
||||
}
|
||||
} else {
|
||||
onfound = ids
|
||||
}
|
||||
|
||||
if err == lgredis.RedisNil {
|
||||
if c, err = this.DB.Find(core.SqlTable(this.TableName), bson.M{"uid": uid}); err != nil {
|
||||
return err
|
||||
} else {
|
||||
pipe := this.Redis.RedisPipe(context.TODO())
|
||||
for c.Next(context.Background()) {
|
||||
_id := c.Current.Lookup("_id").StringValue()
|
||||
sliceType.UnsafeGrow(dptr, n+1)
|
||||
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
|
||||
if *((*unsafe.Pointer)(elemPtr)) == nil {
|
||||
newPtr := sliceelemType.UnsafeNew()
|
||||
*((*unsafe.Pointer)(elemPtr)) = newPtr
|
||||
}
|
||||
elem := sliceType.GetIndex(data, n)
|
||||
if err = c.Decode(elem); err != nil {
|
||||
return
|
||||
}
|
||||
if tempdata, err = encoder.EncodeToMapJson(*((*unsafe.Pointer)(elemPtr)), json.GetWriter()); err != nil {
|
||||
return
|
||||
}
|
||||
key := this.ukeylist(uid, _id)
|
||||
pipe.HMSetForMap(key, tempdata)
|
||||
keys[_id] = key
|
||||
n++
|
||||
}
|
||||
if len(keys) > 0 {
|
||||
pipe.HMSetForMap(this.ukey(uid), keys)
|
||||
_, err = pipe.Exec()
|
||||
}
|
||||
}
|
||||
}
|
||||
if this.Expired > 0 {
|
||||
childs := make(map[string]struct{}, len(keys))
|
||||
for _, v := range keys {
|
||||
childs[v] = struct{}{}
|
||||
}
|
||||
UpDateModelExpired(this.ukey(uid), childs, this.Expired)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//删除用户数据
|
||||
func (this *DBModel) Del(uid string, opt ...DBOption) (err error) {
|
||||
err = this.Redis.Delete(this.ukey(uid))
|
||||
|
119
sys/wordfilter/core.go
Normal file
119
sys/wordfilter/core.go
Normal file
@ -0,0 +1,119 @@
|
||||
package wordfilter
|
||||
|
||||
import "io"
|
||||
|
||||
/*
|
||||
系统:单词守卫
|
||||
描述:DFA 算法实践敏感词过滤 敏感词 过滤 验证 替换
|
||||
*/
|
||||
|
||||
type (
|
||||
ISys interface {
|
||||
//加载文件
|
||||
LoadWordDict(path string) error
|
||||
//加载网络数据
|
||||
LoadNetWordDict(url string) error
|
||||
///加载
|
||||
Load(rd io.Reader) error
|
||||
///添加敏感词
|
||||
AddWord(words ...string)
|
||||
///删除敏感词
|
||||
DelWord(words ...string)
|
||||
///过滤敏感词
|
||||
Filter(text string) string
|
||||
///和谐敏感词
|
||||
Replace(text string, repl rune) string
|
||||
///检测敏感词
|
||||
FindIn(text string) (bool, string)
|
||||
///找到所有匹配词
|
||||
FindAll(text string) []string
|
||||
///检测字符串是否合法
|
||||
Validate(text string) (bool, string)
|
||||
///去除空格等噪音
|
||||
RemoveNoise(text string) string
|
||||
///更新去噪模式
|
||||
UpdateNoisePattern(pattern string)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
defsys ISys
|
||||
)
|
||||
|
||||
func OnInit(config map[string]interface{}, opt ...Option) (err error) {
|
||||
var option *Options
|
||||
if option, err = newOptions(config, opt...); err != nil {
|
||||
return
|
||||
}
|
||||
defsys, err = newSys(option)
|
||||
return
|
||||
}
|
||||
|
||||
func NewSys(opt ...Option) (sys ISys, err error) {
|
||||
var option *Options
|
||||
if option, err = newOptionsByOption(opt...); err != nil {
|
||||
return
|
||||
}
|
||||
sys, err = newSys(option)
|
||||
return
|
||||
}
|
||||
|
||||
//加载文件
|
||||
func LoadWordDict(path string) error {
|
||||
return defsys.LoadWordDict(path)
|
||||
}
|
||||
|
||||
//加载网络数据
|
||||
func LoadNetWordDict(url string) error {
|
||||
return defsys.LoadNetWordDict(url)
|
||||
}
|
||||
|
||||
///加载
|
||||
func Load(rd io.Reader) error {
|
||||
return defsys.Load(rd)
|
||||
}
|
||||
|
||||
///添加敏感词
|
||||
func AddWord(words ...string) {
|
||||
defsys.AddWord(words...)
|
||||
}
|
||||
|
||||
///删除敏感词
|
||||
func DelWord(words ...string) {
|
||||
defsys.DelWord(words...)
|
||||
}
|
||||
|
||||
///过滤敏感词
|
||||
func Filter(text string) string {
|
||||
return defsys.Filter(text)
|
||||
}
|
||||
|
||||
///和谐敏感词
|
||||
func Replace(text string, repl rune) string {
|
||||
return defsys.Replace(text, repl)
|
||||
}
|
||||
|
||||
///检测敏感词
|
||||
func FindIn(text string) (bool, string) {
|
||||
return defsys.FindIn(text)
|
||||
}
|
||||
|
||||
///找到所有匹配词
|
||||
func FindAll(text string) []string {
|
||||
return defsys.FindAll(text)
|
||||
}
|
||||
|
||||
///检测字符串是否合法
|
||||
func Validate(text string) (bool, string) {
|
||||
return defsys.Validate(text)
|
||||
}
|
||||
|
||||
///去除空格等噪音
|
||||
func RemoveNoise(text string) string {
|
||||
return defsys.RemoveNoise(text)
|
||||
}
|
||||
|
||||
///更新去噪模式
|
||||
func UpdateNoisePattern(pattern string) {
|
||||
defsys.UpdateNoisePattern(pattern)
|
||||
}
|
53
sys/wordfilter/options.go
Normal file
53
sys/wordfilter/options.go
Normal file
@ -0,0 +1,53 @@
|
||||
package wordfilter
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"go_dreamfactory/lego/sys/log"
|
||||
"go_dreamfactory/lego/utils/mapstructure"
|
||||
)
|
||||
|
||||
type Option func(*Options)
|
||||
type Options struct {
|
||||
Debug bool //日志是否开启
|
||||
Log log.Ilogf
|
||||
}
|
||||
|
||||
func SetDebug(v bool) Option {
|
||||
return func(o *Options) {
|
||||
o.Debug = v
|
||||
}
|
||||
}
|
||||
|
||||
func SetLog(v log.Ilogf) Option {
|
||||
return func(o *Options) {
|
||||
o.Log = v
|
||||
}
|
||||
}
|
||||
|
||||
func newOptions(config map[string]interface{}, opts ...Option) (options *Options, err error) {
|
||||
options = &Options{}
|
||||
if config != nil {
|
||||
mapstructure.Decode(config, &options)
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(options)
|
||||
}
|
||||
|
||||
if options.Log = log.NewTurnlog(options.Debug, log.Clone("sys.Blockcache", 2)); options.Log == nil {
|
||||
err = errors.New("log is nil")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func newOptionsByOption(opts ...Option) (options *Options, err error) {
|
||||
options = &Options{}
|
||||
for _, o := range opts {
|
||||
o(options)
|
||||
}
|
||||
if options.Log = log.NewTurnlog(options.Debug, log.Clone("sys.Blockcache", 2)); options.Log == nil {
|
||||
err = errors.New("log is nil")
|
||||
}
|
||||
return
|
||||
}
|
113
sys/wordfilter/sys.go
Normal file
113
sys/wordfilter/sys.go
Normal file
@ -0,0 +1,113 @@
|
||||
package wordfilter
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
func newSys(options *Options) (sys *Sys, err error) {
|
||||
sys = &Sys{
|
||||
options: options,
|
||||
trie: NewTrie(),
|
||||
noise: regexp.MustCompile(`[\|\s&%$@*]+`),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type Sys struct {
|
||||
options *Options
|
||||
trie *Trie
|
||||
noise *regexp.Regexp
|
||||
}
|
||||
|
||||
// UpdateNoisePattern 更新去噪模式
|
||||
func (Sys *Sys) UpdateNoisePattern(pattern string) {
|
||||
Sys.noise = regexp.MustCompile(pattern)
|
||||
}
|
||||
|
||||
// LoadWordDict 加载敏感词字典
|
||||
func (Sys *Sys) LoadWordDict(path string) error {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return Sys.Load(f)
|
||||
}
|
||||
|
||||
// LoadNetWordDict 加载网络敏感词字典
|
||||
func (Sys *Sys) LoadNetWordDict(url string) error {
|
||||
c := http.Client{
|
||||
Timeout: 5 * time.Second,
|
||||
}
|
||||
rsp, err := c.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rsp.Body.Close()
|
||||
|
||||
return Sys.Load(rsp.Body)
|
||||
}
|
||||
|
||||
// Load common method to add words
|
||||
func (Sys *Sys) Load(rd io.Reader) error {
|
||||
buf := bufio.NewReader(rd)
|
||||
for {
|
||||
line, _, err := buf.ReadLine()
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
Sys.trie.Add(string(line))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddWord 添加敏感词
|
||||
func (Sys *Sys) AddWord(words ...string) {
|
||||
Sys.trie.Add(words...)
|
||||
}
|
||||
|
||||
// DelWord 删除敏感词
|
||||
func (Sys *Sys) DelWord(words ...string) {
|
||||
Sys.trie.Del(words...)
|
||||
}
|
||||
|
||||
// Sys 过滤敏感词
|
||||
func (Sys *Sys) Filter(text string) string {
|
||||
return Sys.trie.Filter(text)
|
||||
}
|
||||
|
||||
// Replace 和谐敏感词
|
||||
func (Sys *Sys) Replace(text string, repl rune) string {
|
||||
return Sys.trie.Replace(text, repl)
|
||||
}
|
||||
|
||||
// FindIn 检测敏感词
|
||||
func (Sys *Sys) FindIn(text string) (bool, string) {
|
||||
text = Sys.RemoveNoise(text)
|
||||
return Sys.trie.FindIn(text)
|
||||
}
|
||||
|
||||
// FindAll 找到所有匹配词
|
||||
func (Sys *Sys) FindAll(text string) []string {
|
||||
return Sys.trie.FindAll(text)
|
||||
}
|
||||
|
||||
// Validate 检测字符串是否合法
|
||||
func (Sys *Sys) Validate(text string) (bool, string) {
|
||||
text = Sys.RemoveNoise(text)
|
||||
return Sys.trie.Validate(text)
|
||||
}
|
||||
|
||||
// RemoveNoise 去除空格等噪音
|
||||
func (Sys *Sys) RemoveNoise(text string) string {
|
||||
return Sys.noise.ReplaceAllString(text, "")
|
||||
}
|
272
sys/wordfilter/trie.go
Normal file
272
sys/wordfilter/trie.go
Normal file
@ -0,0 +1,272 @@
|
||||
package wordfilter
|
||||
|
||||
// Node Trie树上的一个节点.
|
||||
type Node struct {
|
||||
isRootNode bool
|
||||
isPathEnd bool
|
||||
Character rune
|
||||
Children map[rune]*Node
|
||||
}
|
||||
|
||||
// Trie 短语组成的Trie树.
|
||||
type Trie struct {
|
||||
Root *Node
|
||||
}
|
||||
|
||||
// NewTrie 新建一棵Trie
|
||||
func NewTrie() *Trie {
|
||||
return &Trie{
|
||||
Root: NewRootNode(0),
|
||||
}
|
||||
}
|
||||
|
||||
// Add 添加若干个词
|
||||
func (tree *Trie) Add(words ...string) {
|
||||
for _, word := range words {
|
||||
tree.add(word)
|
||||
}
|
||||
}
|
||||
|
||||
func (tree *Trie) add(word string) {
|
||||
var current = tree.Root
|
||||
var runes = []rune(word)
|
||||
for position := 0; position < len(runes); position++ {
|
||||
r := runes[position]
|
||||
if next, ok := current.Children[r]; ok {
|
||||
current = next
|
||||
} else {
|
||||
newNode := NewNode(r)
|
||||
current.Children[r] = newNode
|
||||
current = newNode
|
||||
}
|
||||
if position == len(runes)-1 {
|
||||
current.isPathEnd = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (tree *Trie) Del(words ...string) {
|
||||
for _, word := range words {
|
||||
tree.del(word)
|
||||
}
|
||||
}
|
||||
|
||||
func (tree *Trie) del(word string) {
|
||||
var current = tree.Root
|
||||
var runes = []rune(word)
|
||||
for position := 0; position < len(runes); position++ {
|
||||
r := runes[position]
|
||||
if next, ok := current.Children[r]; !ok {
|
||||
return
|
||||
} else {
|
||||
current = next
|
||||
}
|
||||
|
||||
if position == len(runes)-1 {
|
||||
current.SoftDel()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace 词语替换
|
||||
func (tree *Trie) Replace(text string, character rune) string {
|
||||
var (
|
||||
parent = tree.Root
|
||||
current *Node
|
||||
runes = []rune(text)
|
||||
length = len(runes)
|
||||
left = 0
|
||||
found bool
|
||||
)
|
||||
|
||||
for position := 0; position < len(runes); position++ {
|
||||
current, found = parent.Children[runes[position]]
|
||||
|
||||
if !found || (!current.IsPathEnd() && position == length-1) {
|
||||
parent = tree.Root
|
||||
position = left
|
||||
left++
|
||||
continue
|
||||
}
|
||||
|
||||
// println(string(current.Character), current.IsPathEnd(), left)
|
||||
if current.IsPathEnd() && left <= position {
|
||||
for i := left; i <= position; i++ {
|
||||
runes[i] = character
|
||||
}
|
||||
}
|
||||
|
||||
parent = current
|
||||
}
|
||||
|
||||
return string(runes)
|
||||
}
|
||||
|
||||
// Filter 直接过滤掉字符串中的敏感词
|
||||
func (tree *Trie) Filter(text string) string {
|
||||
var (
|
||||
parent = tree.Root
|
||||
current *Node
|
||||
left = 0
|
||||
found bool
|
||||
runes = []rune(text)
|
||||
length = len(runes)
|
||||
resultRunes = make([]rune, 0, length)
|
||||
)
|
||||
|
||||
for position := 0; position < length; position++ {
|
||||
current, found = parent.Children[runes[position]]
|
||||
|
||||
if !found || (!current.IsPathEnd() && position == length-1) {
|
||||
resultRunes = append(resultRunes, runes[left])
|
||||
parent = tree.Root
|
||||
position = left
|
||||
left++
|
||||
continue
|
||||
}
|
||||
|
||||
if current.IsPathEnd() {
|
||||
left = position + 1
|
||||
parent = tree.Root
|
||||
} else {
|
||||
parent = current
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resultRunes = append(resultRunes, runes[left:]...)
|
||||
return string(resultRunes)
|
||||
}
|
||||
|
||||
// Validate 验证字符串是否合法,如不合法则返回false和检测到
|
||||
// 的第一个敏感词
|
||||
func (tree *Trie) Validate(text string) (bool, string) {
|
||||
const (
|
||||
Empty = ""
|
||||
)
|
||||
var (
|
||||
parent = tree.Root
|
||||
current *Node
|
||||
runes = []rune(text)
|
||||
length = len(runes)
|
||||
left = 0
|
||||
found bool
|
||||
)
|
||||
|
||||
for position := 0; position < len(runes); position++ {
|
||||
current, found = parent.Children[runes[position]]
|
||||
|
||||
if !found || (!current.IsPathEnd() && position == length-1) {
|
||||
parent = tree.Root
|
||||
position = left
|
||||
left++
|
||||
continue
|
||||
}
|
||||
|
||||
if current.IsPathEnd() && left <= position {
|
||||
return false, string(runes[left : position+1])
|
||||
}
|
||||
|
||||
parent = current
|
||||
}
|
||||
|
||||
return true, Empty
|
||||
}
|
||||
|
||||
// FindIn 判断text中是否含有词库中的词
|
||||
func (tree *Trie) FindIn(text string) (bool, string) {
|
||||
validated, first := tree.Validate(text)
|
||||
return !validated, first
|
||||
}
|
||||
|
||||
// FindAll 找有所有包含在词库中的词
|
||||
func (tree *Trie) FindAll(text string) []string {
|
||||
var matches []string
|
||||
var (
|
||||
parent = tree.Root
|
||||
current *Node
|
||||
runes = []rune(text)
|
||||
length = len(runes)
|
||||
left = 0
|
||||
found bool
|
||||
)
|
||||
|
||||
for position := 0; position < length; position++ {
|
||||
current, found = parent.Children[runes[position]]
|
||||
|
||||
if !found {
|
||||
parent = tree.Root
|
||||
position = left
|
||||
left++
|
||||
continue
|
||||
}
|
||||
|
||||
if current.IsPathEnd() && left <= position {
|
||||
matches = append(matches, string(runes[left:position+1]))
|
||||
}
|
||||
|
||||
if position == length-1 {
|
||||
parent = tree.Root
|
||||
position = left
|
||||
left++
|
||||
continue
|
||||
}
|
||||
|
||||
parent = current
|
||||
}
|
||||
|
||||
var i = 0
|
||||
if count := len(matches); count > 0 {
|
||||
set := make(map[string]struct{})
|
||||
for i < count {
|
||||
_, ok := set[matches[i]]
|
||||
if !ok {
|
||||
set[matches[i]] = struct{}{}
|
||||
i++
|
||||
continue
|
||||
}
|
||||
count--
|
||||
copy(matches[i:], matches[i+1:])
|
||||
}
|
||||
return matches[:count]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewNode 新建子节点
|
||||
func NewNode(character rune) *Node {
|
||||
return &Node{
|
||||
Character: character,
|
||||
Children: make(map[rune]*Node, 0),
|
||||
}
|
||||
}
|
||||
|
||||
// NewRootNode 新建根节点
|
||||
func NewRootNode(character rune) *Node {
|
||||
return &Node{
|
||||
isRootNode: true,
|
||||
Character: character,
|
||||
Children: make(map[rune]*Node, 0),
|
||||
}
|
||||
}
|
||||
|
||||
// IsLeafNode 判断是否叶子节点
|
||||
func (node *Node) IsLeafNode() bool {
|
||||
return len(node.Children) == 0
|
||||
}
|
||||
|
||||
// IsRootNode 判断是否为根节点
|
||||
func (node *Node) IsRootNode() bool {
|
||||
return node.isRootNode
|
||||
}
|
||||
|
||||
// IsPathEnd 判断是否为某个路径的结束
|
||||
func (node *Node) IsPathEnd() bool {
|
||||
return node.isPathEnd
|
||||
}
|
||||
|
||||
// SoftDel 置软删除状态
|
||||
func (node *Node) SoftDel() {
|
||||
node.isPathEnd = false
|
||||
}
|
Loading…
Reference in New Issue
Block a user