package announcement import ( "context" "database/sql" "fmt" "lims_adapter/dao/announcement" "lims_adapter/model/announcement" "strconv" "strings" "dashoo.cn/micro_libary/micro_srv" "dashoo.cn/micro_libary/myerrors" "dashoo.cn/micro_libary/request" "github.com/gogf/gf/database/gdb" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/os/gtime" "github.com/gogf/gf/util/gvalid" ) type AnnouncementService struct { Tenant string userInfo request.UserInfo DB gdb.DB Dao *dao.AnnouncementDao FileDao *dao.AnnouncementFileDao ReadRecordDao *dao.AnnouncementReadRecordDao } func NewAnnouncementService(ctx context.Context) (*AnnouncementService, error) { tenant, err := micro_srv.GetTenant(ctx) if err != nil { return nil, fmt.Errorf("获取组合码异常:%s", err.Error()) } // 获取用户信息 userInfo, err := micro_srv.GetUserInfo(ctx) if err != nil { return nil, fmt.Errorf("获取用户信息异常:%s", err.Error()) } return &AnnouncementService{ Tenant: tenant, userInfo: userInfo, DB: g.DB(tenant), Dao: dao.NewAnnouncementDao(tenant), FileDao: dao.NewAnnouncementFileDao(tenant), ReadRecordDao: dao.NewAnnouncementReadRecordDao(tenant), }, nil } func (s AnnouncementService) Get(ctx context.Context, req *model.IdReq) (*model.AnnouncementGetResp, error) { ent, err := s.Dao.Where("Id = ?", req.Id).One() if err != nil { return nil, err } if ent == nil { return nil, myerrors.NewMsgError(nil, "反馈不存在") } f, err := s.FileDao.Where("MessageId = ?", req.Id).All() if err != nil { return nil, err } file := []model.FileInfo{} for _, i := range f { filesize, _ := strconv.Atoi(i.FileSize) file = append(file, model.FileInfo{ Id: i.Id, FileExtend: i.FileExtend, FileName: i.FileName, FileSize: filesize, FileUrl: i.FileUrl, }) } names := []string{} if ent.ReceiverDevice != "" { names, err = ColumnString(s.DB.Table("instrument").Where("Terminal in (?)", strings.Split(ent.ReceiverDevice, ",")), "Name") if err != nil { return nil, err } } return &model.AnnouncementGetResp{ Announcement: *ent, ReceiverDeviceName: strings.Join(names, ", "), File: file, }, nil } func (s AnnouncementService) List(ctx context.Context, req *model.AnnouncementListReq) (int, []*model.Announcement, error) { dao := &s.Dao.AnnouncementDao if req.Title != "" { dao = dao.Where("Title LIKE ?", fmt.Sprintf("%%%s%%", req.Title)) } if req.Sender != "" { dao = dao.Where("Sender LIKE ?", fmt.Sprintf("%%%s%%", req.Sender)) } if req.Status != 0 { dao = dao.Where("Status = ?", req.Status) } if req.PublishTimeStart != nil { dao = dao.Where("PublishTime > ?", req.PublishTimeStart) } if req.PublishTimeEnd != nil { dao = dao.Where("PublishTime < ?", req.PublishTimeEnd) } total, err := dao.Count() if err != nil { return 0, nil, err } if req.Current == 0 { req.Current = 1 } if req.Size == 0 { req.Size = 10 } dao = dao.Page(req.Current, req.Size) dao = dao.Order("IsTop desc,CreatedAt desc") ent, err := dao.All() return total, ent, err } func (s AnnouncementService) Announcement(ctx context.Context, req *model.AnnouncementAnnouncementReq) (int, []*model.AnnouncementWithNew, error) { dept := organization{} err := s.DB.Table("base_organize"). Where("Enabled = ?", 1). Where("Id = ?", s.userInfo.DeptId). Struct(&dept) if err != nil { return 0, nil, fmt.Errorf("查询用户部门错误 %s", err) } ret := []*model.AnnouncementWithNew{} err = s.DB.Table("announcement a"). LeftJoin(fmt.Sprintf("(select `Id`,`MessageId`,`UserId` from announcement_read_record where `UserId`=%d) b", s.userInfo.Id), "a.Id=b.MessageId"). Where("a.Status = 2"). Where("a.DeptId in (?)", strings.Split(dept.Paths, "/")). Fields("a.*, b.Id is null as IsNew").Structs(&ret) return 0, ret, err } func (s AnnouncementService) Receipt(ctx context.Context, req *model.IdReq) error { validErr := gvalid.CheckStruct(ctx, req, nil) if validErr != nil { return myerrors.NewMsgError(nil, validErr.Current().Error()) } ent, err := s.Dao.Where("id = ?", req.Id).One() if err != nil { return err } if ent == nil { return myerrors.NewMsgError(nil, fmt.Sprintf("公告不存在: %d", req.Id)) } count, err := s.ReadRecordDao.Where("MessageId = ?", req.Id).Where("UserId = ?", s.userInfo.Id).Count() if err != nil { return err } if count == 0 { _, err := s.ReadRecordDao.Insert(model.AnnouncementReadRecord{ MessageId: req.Id, UserId: int(s.userInfo.Id), CreatedBy: s.userInfo.RealName, CreatedAt: gtime.Now(), UpdatedBy: s.userInfo.RealName, UpdatedAt: gtime.Now(), CreatedById: int(s.userInfo.Id), UpdatedById: int(s.userInfo.Id), }) if err != nil { return err } } return nil } func (s AnnouncementService) BindFile(tx *gdb.TX, msgId int, fileinfo []model.FileInfo, fileDelete []int) error { if len(fileDelete) != 0 { _, err := tx.Delete("announcement_file", "id in (?)", fileDelete) if err != nil { return err } } file := []model.AnnouncementFile{} for _, i := range fileinfo { file = append(file, model.AnnouncementFile{ MessageId: msgId, FileName: i.FileName, FileUrl: i.FileUrl, FileId: "", FileSize: strconv.Itoa(i.FileSize), FileExtend: i.FileExtend, CreatedBy: s.userInfo.RealName, CreatedAt: gtime.Now(), UpdatedBy: s.userInfo.RealName, UpdatedAt: gtime.Now(), }) } if len(file) != 0 { _, err := tx.Insert("announcement_file", file) if err != nil { return err } } return nil } type organize struct { Id int FullName string } func (s AnnouncementService) Add(ctx context.Context, req *model.AnnouncementAddReq) (int, error) { validErr := gvalid.CheckStruct(ctx, req, nil) if validErr != nil { return 0, myerrors.NewMsgError(nil, validErr.Current().Error()) } if req.DeptId == 0 && len(req.ReceiverDevice) == 0 { return 0, myerrors.NewMsgError(nil, fmt.Sprintf("请输入通知对象")) } dept := &organize{} err := s.DB.Table("base_organize").Where("Id = ?", req.DeptId).Struct(dept) if err == sql.ErrNoRows { return 0, myerrors.NewMsgError(err, fmt.Sprintf("所选部门不存在")) } if err != nil { return 0, err } var msgId int txerr := s.Dao.DB.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { publishTime := gtime.Now() if req.Status == 1 { publishTime = nil } istop := 0 if req.IsTop { istop = 1 } id, err := tx.InsertAndGetId("announcement", model.Announcement{ Title: req.Title, Content: req.Content, Sender: s.userInfo.RealName, SenderId: int(s.userInfo.Id), Status: req.Status, DeptId: req.DeptId, DeptName: dept.FullName, PublishTime: publishTime, CreatedBy: s.userInfo.RealName, CreatedAt: gtime.Now(), UpdatedBy: s.userInfo.RealName, UpdatedAt: gtime.Now(), CreatedById: int(s.userInfo.Id), UpdatedById: int(s.userInfo.Id), ReceiverDevice: req.ReceiverDevice, Link: req.Link, IsTop: istop, }) if err != nil { return err } err = s.BindFile(tx, int(id), req.File, nil) if err != nil { return err } msgId = int(id) return nil }) return msgId, txerr } func (s AnnouncementService) Update(ctx context.Context, req *model.AnnouncementUpdateReq) error { validErr := gvalid.CheckStruct(ctx, req, nil) if validErr != nil { return myerrors.NewMsgError(nil, validErr.Current().Error()) } ent, err := s.Dao.Where("id = ?", req.Id).One() if err != nil { return err } if ent == nil { return myerrors.NewMsgError(nil, fmt.Sprintf("公告不存在: %d", req.Id)) } dept := &organize{} if req.DeptId != 0 { err := s.DB.Table("base_organize").Where("Id = ?", req.DeptId).Struct(dept) if err == sql.ErrNoRows { return myerrors.NewMsgError(err, fmt.Sprintf("所选部门不存在")) } if err != nil { return err } } toupdate := map[string]interface{}{} if req.Title != "" { toupdate["Title"] = req.Title } if req.Content != "" { toupdate["Content"] = req.Content } if req.IsTop != nil { toupdate["IsTop"] = *req.IsTop } if req.Link != "" { toupdate["Link"] = req.Link } if req.DeptId != 0 { toupdate["DeptId"] = req.DeptId toupdate["DeptName"] = dept.FullName } if req.ReceiverDevice != nil { toupdate["ReceiverDevice"] = req.ReceiverDevice } txerr := s.Dao.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { if len(toupdate) != 0 { toupdate["UpdatedAt"] = gtime.Now() toupdate["UpdatedBy"] = s.userInfo.RealName toupdate["UpdatedById"] = int(s.userInfo.Id) _, err := tx.Update("announcement", toupdate, "Id = ?", req.Id) if err != nil { return err } } err = s.BindFile(tx, req.Id, req.File, req.FileDelete) if err != nil { return err } return nil }) return txerr } func (s AnnouncementService) Publish(ctx context.Context, req *model.IdReq) error { validErr := gvalid.CheckStruct(ctx, req, nil) if validErr != nil { return myerrors.NewMsgError(nil, validErr.Current().Error()) } ent, err := s.Dao.Where("id = ?", req.Id).One() if err != nil { return err } if ent == nil { return myerrors.NewMsgError(nil, fmt.Sprintf("公告不存在: %d", req.Id)) } if ent.Status != 1 { return myerrors.NewMsgError(nil, fmt.Sprintf("当前公告不可发布")) } _, err = s.Dao.Data(map[string]interface{}{ "Sender": s.userInfo.RealName, "SenderId": int(s.userInfo.Id), "Status": 2, "PublishTime": gtime.Now(), }).Where("Id = ?", req.Id).Update() return err } func (s AnnouncementService) Delete(ctx context.Context, id []int) error { if len(id) == 0 { return nil } _, err := s.Dao.Where("Id IN (?)", id).Delete() if err != nil { return err } _, err = s.FileDao.Where("MessageId IN (?)", id).Delete() if err != nil { return err } _, err = s.ReadRecordDao.Where("MessageId IN (?)", id).Delete() return err } func ColumnString(m *gdb.Model, name string) ([]string, error) { v, err := m.Fields(name).Array() if err != nil { return nil, err } res := []string{} for _, i := range v { res = append(res, i.String()) } return res, nil } type organization struct { Id int `orm:"Id,primary" json:"id"` // ParentId int `orm:"ParentId" json:"parentId"` // 上级组织id FullName string `orm:"FullName" json:"fullName"` // 名称 Paths string `orm:"Paths" json:"paths"` // 路径索引 } type DeptNode struct { Id int Name string SubDept []*DeptNode } func (n DeptNode) String() string { Subdept := "{" for _, i := range n.SubDept { Subdept = Subdept + i.String() + "," } Subdept = Subdept + "}" return fmt.Sprintf("DeptNode{id=%d, name=%s, SubDept=%s}", n.Id, n.Name, Subdept) } func DeptTree(tenant string, id int) (*DeptNode, error) { deptlist := []organization{} err := g.DB(tenant).Table("base_organize"). Where("Enabled = ?", 1).Structs(&deptlist) if err == sql.ErrNoRows { err = nil } if err != nil { return nil, err } deptMap := map[int]*DeptNode{} for _, d := range deptlist { deptMap[d.Id] = &DeptNode{ Id: d.Id, Name: d.FullName, } } for _, d := range deptlist { if d.ParentId == 0 { continue } deptMap[d.ParentId].SubDept = append(deptMap[d.ParentId].SubDept, deptMap[d.Id]) } for _, d := range deptMap { if d.Id == id { return d, nil } } return nil, nil } func RangeDeptTree(node *DeptNode) []*DeptNode { if node == nil { return nil } allnode := []*DeptNode{} nodes := []*DeptNode{node} for len(nodes) != 0 { newnode := []*DeptNode{} for _, n := range nodes { allnode = append(allnode, n) newnode = append(newnode, n.SubDept...) } nodes = newnode } return allnode }