From 3c3310dd9d6ce34753524fb486939777d77a67ac Mon Sep 17 00:00:00 2001 From: wh_zcy Date: Wed, 2 Nov 2022 19:53:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=9A=E9=95=BF=E9=80=89=E4=B8=BE=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/v2/ui/protocol.go | 4 +- cmd/v2/ui/views/mail_list.go | 62 ++++++++++- modules/friend/api_cross_randlist.go | 2 +- modules/gourmet/api_getranduser.go | 2 +- modules/hero/hero_test.go | 2 +- modules/smithy/api_getranduser.go | 2 +- modules/sociaty/api_cross_discharge.go | 4 + modules/sociaty/api_cross_dismiss.go | 8 ++ modules/sociaty/api_cross_mine.go | 7 ++ modules/sociaty/model_sociaty.go | 145 ++++++++++++++++++++++--- modules/sociaty/model_sociatylog.go | 16 ++- modules/sociaty/model_sociatytask.go | 2 +- pb/sociaty_db.pb.go | 2 +- utils/random.go | 2 +- utils/utils_test.go | 4 +- 15 files changed, 235 insertions(+), 29 deletions(-) diff --git a/cmd/v2/ui/protocol.go b/cmd/v2/ui/protocol.go index a192c1921..536c11bf9 100644 --- a/cmd/v2/ui/protocol.go +++ b/cmd/v2/ui/protocol.go @@ -368,8 +368,8 @@ var ( Enabled: true, }, ff(comm.ModuleMail, "getlist"): { - NavLabel: "邮件列表", - Desc: "邮件列表", + NavLabel: "我的邮件", + Desc: "我的邮件", MainType: string(comm.ModuleMail), SubType: "getlist", Enabled: true, diff --git a/cmd/v2/ui/views/mail_list.go b/cmd/v2/ui/views/mail_list.go index 3539a94ac..3fce720f6 100644 --- a/cmd/v2/ui/views/mail_list.go +++ b/cmd/v2/ui/views/mail_list.go @@ -1,23 +1,79 @@ package formview import ( + "fmt" + "go_dreamfactory/cmd/v2/lib/common" "go_dreamfactory/cmd/v2/model" "go_dreamfactory/cmd/v2/service" + "go_dreamfactory/cmd/v2/service/observer" + "go_dreamfactory/comm" "go_dreamfactory/pb" "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/theme" + "fyne.io/fyne/v2/widget" "github.com/sirupsen/logrus" ) type MailListView struct { BaseformView + mailList func() + itemList *common.ItemList + flag bool } func (this *MailListView) CreateView(t *model.TestCase) fyne.CanvasObject { - this.form.OnSubmit = func() { - if err := service.GetPttService().SendToClient(t.MainType, t.SubType, &pb.MailGetListReq{}); err != nil { + this.itemList = common.NewItemList() + + this.itemList.ItemList = this.itemList.CreateDefaultCheckList() + + this.mailList = func() { + if err := service.GetPttService().SendToClient( + t.MainType, + t.SubType, + &pb.MailGetListReq{}); err != nil { logrus.Error(err) } } - return this.form + + defer this.mailList() + + refreshBtn := widget.NewButtonWithIcon("", theme.ViewRefreshIcon(), func() { + this.itemList.Reset() + this.mailList() + }) + buttonBar := container.NewHBox(refreshBtn) + c := container.NewBorder(buttonBar, nil, nil, nil, this.itemList.ItemList) + + return c +} + +func (this *MailListView) dataListener() { + if this.flag { + return + } + this.obs.AddListener(observer.EVENT_REQ_RSP, observer.Listener{ + OnNotify: func(d interface{}, args ...interface{}) { + data := d.(*pb.UserMessage) + if !(data.MainType == string(comm.ModuleMail) && + data.SubType == "getlist") { + return + } + rsp := &pb.MailGetListResp{} + if !comm.ProtoUnmarshal(data, rsp) { + logrus.Error("MailGetListResp unmarshal err") + return + } + + for i, v := range rsp.Mails { + item := common.Item{ + Id: v.ObjId, + Text: fmt.Sprintf("%d-%s %s", i+1, v.Title, v.Contex), + } + this.itemList.AddItem(item) + } + }, + }) + this.flag = true } diff --git a/modules/friend/api_cross_randlist.go b/modules/friend/api_cross_randlist.go index 3922a178f..a1defd252 100644 --- a/modules/friend/api_cross_randlist.go +++ b/modules/friend/api_cross_randlist.go @@ -52,7 +52,7 @@ func (this *apiComp) Randlist(session comm.IUserSession, req *pb.FriendRandlistR var randOnlineUsers []string if len(newList) > recommend { - randArr := utils.Numbers(0, len(newList), recommend) + randArr := utils.RandomNumbers(0, len(newList), recommend) for _, v := range randArr { if newList[v] != nil { randOnlineUsers = append(randOnlineUsers, newList[v].Uid) diff --git a/modules/gourmet/api_getranduser.go b/modules/gourmet/api_getranduser.go index 1708762ba..57d1eed04 100644 --- a/modules/gourmet/api_getranduser.go +++ b/modules/gourmet/api_getranduser.go @@ -51,7 +51,7 @@ func (this *apiComp) GetRandUser(session comm.IUserSession, req *pb.GourmetGetRa } // 随机在线玩家信息 if len(szUid) > int(req.People) { - randArr := utils.Numbers(0, len(szUid), int(req.People)) + randArr := utils.RandomNumbers(0, len(szUid), int(req.People)) for _, v := range randArr { if szUid[v] != "" { mapUser[szUid[v]] = struct{}{} diff --git a/modules/hero/hero_test.go b/modules/hero/hero_test.go index a1f4cfb39..4baf294a9 100644 --- a/modules/hero/hero_test.go +++ b/modules/hero/hero_test.go @@ -61,7 +61,7 @@ func (this *TestService) InitSys() { func Test_Main(t *testing.T) { - ids := utils.Numbers(0, 10, 5) + ids := utils.RandomNumbers(0, 10, 5) for _, v := range ids { fmt.Printf("%d", v) } diff --git a/modules/smithy/api_getranduser.go b/modules/smithy/api_getranduser.go index 10acf8f10..a545de272 100644 --- a/modules/smithy/api_getranduser.go +++ b/modules/smithy/api_getranduser.go @@ -51,7 +51,7 @@ func (this *apiComp) GetRandUser(session comm.IUserSession, req *pb.SmithyGetRan } // 随机在线玩家信息 if len(szUid) > int(req.People) { - randArr := utils.Numbers(0, len(szUid), int(req.People)) + randArr := utils.RandomNumbers(0, len(szUid), int(req.People)) for _, v := range randArr { if szUid[v] != "" { mapUser[szUid[v]] = struct{}{} diff --git a/modules/sociaty/api_cross_discharge.go b/modules/sociaty/api_cross_discharge.go index 681f471c7..edeb45e58 100644 --- a/modules/sociaty/api_cross_discharge.go +++ b/modules/sociaty/api_cross_discharge.go @@ -42,6 +42,10 @@ func (this *apiComp) Discharge(session comm.IUserSession, req *pb.SociatyDischar return } + // 发邮件 + receiver := this.module.modelSociaty.getMemberIds(sociaty) + this.module.modelSociaty.sendMail(receiver) + //清除玩家sociatyId update := map[string]interface{}{ "sociatyId": "", //公会ID置空 diff --git a/modules/sociaty/api_cross_dismiss.go b/modules/sociaty/api_cross_dismiss.go index 74f018232..8661e4dcc 100644 --- a/modules/sociaty/api_cross_dismiss.go +++ b/modules/sociaty/api_cross_dismiss.go @@ -28,7 +28,10 @@ func (this *apiComp) Dismiss(session comm.IUserSession, req *pb.SociatyDismissRe return } + // 邮件接收人 + var receiver []string for _, m := range sociaty.Members { + receiver = append(receiver, m.Uid) //清除成员任务 if err := this.module.modelSociatyTask.deleTask(sociaty.Id, m.Uid); err != nil { this.module.Errorf("删除玩家 uid:%s 公会 sociatyId:%s err:%v", m.Uid, sociaty.Id, err) @@ -57,6 +60,11 @@ func (this *apiComp) Dismiss(session comm.IUserSession, req *pb.SociatyDismissRe return } + //发送邮件 + if err := this.module.modelSociaty.sendMail(receiver); err != nil { + this.module.Errorf("邮件发送失败 sociatyId: %s err:%v", sociaty.Id, err) + } + rsp := &pb.SociatyDismissResp{ Uid: session.GetUserId(), SociatyId: sociaty.Id, diff --git a/modules/sociaty/api_cross_mine.go b/modules/sociaty/api_cross_mine.go index c8c8103cd..23862e5d0 100644 --- a/modules/sociaty/api_cross_mine.go +++ b/modules/sociaty/api_cross_mine.go @@ -31,7 +31,14 @@ func (this *apiComp) Mine(session comm.IUserSession, req *pb.SociatyMineReq) (co return } + // 获取会长 master := this.module.modelSociaty.getMasterInfo(sociaty) + if master != nil { + //判断当前玩家是否是会长 + if master.Uid == uid { //会长 + this.module.modelSociaty.extendJob(uid, sociaty) + } + } rsp.Sociaty = sociaty rsp.Master = master } diff --git a/modules/sociaty/model_sociaty.go b/modules/sociaty/model_sociaty.go index 6d2ed8108..c75895f5a 100644 --- a/modules/sociaty/model_sociaty.go +++ b/modules/sociaty/model_sociaty.go @@ -39,11 +39,7 @@ type ModelSociaty struct { type SociatyListen struct { event_v2.App - sociatyId string - name string - lv int32 - activity int32 - ctime int64 + sociaty *pb.DBSociaty } func (this *ModelSociaty) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { @@ -334,10 +330,23 @@ func (this *ModelSociaty) addMember(uid string, sociaty *pb.DBSociaty) error { return err } + // 发邮件 + this.sendMail(this.getMemberIds(sociaty)) + // 记录日志 this.moduleSociaty.modelSociatyLog.addLog(Log_Add, sociaty.Id, uid) return nil } +// 发邮件给公会成员 +func (this *ModelSociaty) sendMail(receiver []string) error { + if module, err := this.moduleSociaty.service.GetModule(comm.ModuleMail); err == nil { + if mail, ok := module.(comm.Imail); ok { + mail.SendNewMail(&pb.DBMailData{}, receiver...) + } + } + return nil +} + // 成员列表 func (this *ModelSociaty) members(sociaty *pb.DBSociaty) (list []*pb.SociatyMemberInfo) { for _, m := range sociaty.Members { @@ -357,6 +366,14 @@ func (this *ModelSociaty) members(sociaty *pb.DBSociaty) (list []*pb.SociatyMemb return } +// 成员IDs +func (this *ModelSociaty) getMemberIds(sociaty *pb.DBSociaty) (ids []string) { + for _, m := range sociaty.Members { + ids = append(ids, m.Uid) + } + return +} + // 同意 func (this *ModelSociaty) agree(uid string, sociaty *pb.DBSociaty) error { if this.isMember(uid, sociaty) { @@ -480,10 +497,103 @@ func (this *ModelSociaty) accuse(sociaty *pb.DBSociaty) error { //会长离线时间 now := time.Now().Unix() left := now - user.Offlinetime - if left < 7*3600 || user.Offlinetime == 0 { + if left < 72*3600 || user.Offlinetime == 0 { return errors.New("会长很称职,无需弹劾") + } else { + //更新会长的弹劾时间 + update := map[string]interface{}{ + "accuseTime": time.Now().Unix(), + } + return this.updateSociaty(sociaty.Id, update) + } +} + +// 弹劾倒计时判断 +// srcMasterId 原会长ID +func (this *ModelSociaty) extendJob(srcMasterId string, sociaty *pb.DBSociaty) error { + if sociaty.AccuseTime != 0 { + now := time.Now().Unix() + //48小时内终止弹劾 + if now-sociaty.AccuseTime < 48*3600 { + update := map[string]interface{}{ + "accuseTime": 0, + } + return this.updateSociaty(sociaty.Id, update) + } else { + //会长降为普通成员 + if err := this.settingJob(srcMasterId, pb.SociatyJob_MEMBER, sociaty); err != nil { + return err + } + //选举新会长 + if err := this.electNewMaster(srcMasterId, sociaty); err != nil { + return err + } + } + } + return nil +} + +//选举新会长 +func (this *ModelSociaty) electNewMaster(srcMasterId string, sociaty *pb.DBSociaty) error { + vpIds := []*pb.SociatyMember{} // 副会长 + aIds := []*pb.SociatyMember{} //管理员 + mIds := []*pb.SociatyMember{} //普通成员 + + for _, m := range sociaty.Members { + if m.Uid != srcMasterId { + if m.Job == pb.SociatyJob_VICEPRESIDENT { + vpIds = append(vpIds, m) + } else if m.Job == pb.SociatyJob_ADMIN { + aIds = append(aIds, m) + } else { + mIds = append(mIds, m) + } + } } + elect := func(data []*pb.SociatyMember) error { + if len(data) == 1 { + return this.settingJob(data[0].Uid, pb.SociatyJob_PRESIDENT, sociaty) + } else if len(data) > 1 { + //从数组中找到最大的贡献值,并标识数量 + maxNum := data[0] + maxCount := 0 //最大的贡献值数量 + maxIndex := 0 //最大贡献值的索引 + + for i := 1; i < len(data); i++ { + if data[i].Contribution > maxNum.Contribution { + maxNum = data[i] + maxIndex = i + } else if data[i].Contribution == maxNum.Contribution { + maxCount++ + } + } + if maxCount >= 1 { //有两个以上的最大值 + //比较时间 升序 + sort.SliceStable(data, func(i, j int) bool { + return data[i].Ctime < data[j].Ctime + }) + //取第一个值 + return this.settingJob(data[0].Uid, pb.SociatyJob_PRESIDENT, sociaty) + } else { + return this.settingJob(data[maxIndex].Uid, pb.SociatyJob_PRESIDENT, sociaty) + } + } + return nil + } + + // 以下按照职位大小依次调用 + if len(vpIds) > 0 { + return elect(vpIds) + } + + if len(aIds) > 0 { + return elect(aIds) + } + + if len(mIds) > 0 { + return elect(aIds) + } return nil } @@ -588,20 +698,23 @@ func (this *ModelSociaty) rankDataChanged(event interface{}, next func(event int } data := event.(*SociatyListen) + if data.sociaty == nil { + return + } newRank := &pb.DBSociatyRank{ - SociatyId: data.sociatyId, - Name: data.name, - Lv: data.lv, - Activity: data.activity, - Ctime: data.ctime, + SociatyId: data.sociaty.Id, + Name: data.sociaty.Name, + Lv: data.sociaty.Lv, + Activity: data.sociaty.Activity, + Ctime: data.sociaty.Ctime, } if len(list) == 0 || len(list) > 0 && len(list) < 20 { if data != nil { - this.AddList("", data.sociatyId, newRank) + this.AddList("", data.sociaty.Id, newRank) } } else { - this.AddList("", data.sociatyId, newRank) + this.AddList("", data.sociaty.Id, newRank) if err := this.GetList("", &list); err != nil { log.Errorf("sociaty list err:%v", err) return @@ -619,7 +732,7 @@ func (this *ModelSociaty) rankDataChanged(event interface{}, next func(event int } } -// 排行榜 +// 排行榜列表 func (this *ModelSociaty) rank() (rank []*pb.DBSociatyRank) { var list []*pb.DBSociaty if err := this.GetList("", &list); err != nil { @@ -678,6 +791,10 @@ func (this *ModelSociaty) changeLv(sociaty *pb.DBSociaty) error { if err = this.updateSociaty(sociaty.Id, update); err != nil { return err } + // 更新排行榜 + this.EventApp.Dispatch(comm.EventSociatyRankChanged, &SociatyListen{ + sociaty: sociaty, + }) } return nil diff --git a/modules/sociaty/model_sociatylog.go b/modules/sociaty/model_sociatylog.go index e762dfaca..084409381 100644 --- a/modules/sociaty/model_sociatylog.go +++ b/modules/sociaty/model_sociatylog.go @@ -139,7 +139,21 @@ func (this *ModelSociatyLog) addLog(tag Tag, sociatyId string, params ...string) "sociatyId": sociatyId, "list": log.List, } - return this.Change(sociatyId, update) + if err := this.Change(sociatyId, update); err != nil { + return err + } + + // 发消息到公会聊天 + if module, err := this.moduleSociaty.service.GetModule(comm.ModuleChat); err == nil { + if chat, ok := module.(comm.IChat); ok { + chat.SendUnionChat(&pb.DBChat{ + Channel: pb.ChatChannel_Union, + Ctype: pb.ChatType_Text, + UnionId: sociatyId, + Content: content, + }) + } + } } return nil } diff --git a/modules/sociaty/model_sociatytask.go b/modules/sociaty/model_sociatytask.go index 5e61ebb9f..0d96b6ec7 100644 --- a/modules/sociaty/model_sociatytask.go +++ b/modules/sociaty/model_sociatytask.go @@ -39,7 +39,7 @@ func (this *ModelSociatyTask) initSociatyTask(uid, sociatyId string) error { // 大于4条配置 if len(list) > 4 { //随机4条任务 - randInts := utils.Numbers(0, len(list)-1, 4) + randInts := utils.RandomNumbers(0, len(list)-1, 4) for _, v := range randInts { taskList = append(taskList, &pb.SociatyTask{ TaskId: list[v].Id, diff --git a/pb/sociaty_db.pb.go b/pb/sociaty_db.pb.go index cfda5257e..bb19e48fe 100644 --- a/pb/sociaty_db.pb.go +++ b/pb/sociaty_db.pb.go @@ -91,7 +91,7 @@ type DBSociaty struct { IsApplyCheck bool `protobuf:"varint,8,opt,name=isApplyCheck,proto3" json:"isApplyCheck" bson:"isApplyCheck"` //是否必须审批 ApplyLv int32 `protobuf:"varint,9,opt,name=applyLv,proto3" json:"applyLv" bson:"applyLv"` // 等级限制 Ctime int64 `protobuf:"varint,10,opt,name=ctime,proto3" json:"ctime" bson:"ctime"` //创建时间 - ApplyRecord []*ApplyRecord `protobuf:"bytes,11,rep,name=applyRecord,proto3" json:"applyRecord" bson:"applyRecord"` //收到的玩家入会申请 + ApplyRecord []*ApplyRecord `protobuf:"bytes,11,rep,name=applyRecord,proto3" json:"applyRecord" bson:"applyRecord"` //入会申请 Members []*SociatyMember `protobuf:"bytes,12,rep,name=members,proto3" json:"members"` //@go_tags(`bson:"members"`) 公会成员 Activity int32 `protobuf:"varint,13,opt,name=activity,proto3" json:"activity" bson:"activity"` //活跃度 AccuseTime int64 `protobuf:"varint,14,opt,name=accuseTime,proto3" json:"accuseTime" bson:"accuseTime"` //会长弹劾时间 diff --git a/utils/random.go b/utils/random.go index 9564f9319..d2b9f7a42 100644 --- a/utils/random.go +++ b/utils/random.go @@ -23,7 +23,7 @@ func GenValidateCode(width int) string { // 随机一组随机数 // number >= start and < end num 随机数个数 -func Numbers(start, end, num int) []int { +func RandomNumbers(start, end, num int) []int { if end-start < 0 || num > (end-start) { return nil } diff --git a/utils/utils_test.go b/utils/utils_test.go index e227c398c..1857fd9be 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -35,7 +35,7 @@ func TestRandom(t *testing.T) { func TestNumber(t *testing.T) { for i := 0; i < 100; i++ { - fmt.Println(utils.Numbers(0, 99, 10)) + fmt.Println(utils.RandomNumbers(0, 99, 10)) } } @@ -45,7 +45,7 @@ func BenchmarkNumber(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - utils.Numbers(0, 1000, 10) + utils.RandomNumbers(0, 1000, 10) } }