6
0

announcement.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. package announcement
  2. import (
  3. "context"
  4. "database/sql"
  5. "fmt"
  6. "lims_adapter/dao/announcement"
  7. "lims_adapter/model/announcement"
  8. "strconv"
  9. "strings"
  10. "dashoo.cn/micro_libary/micro_srv"
  11. "dashoo.cn/micro_libary/myerrors"
  12. "dashoo.cn/micro_libary/request"
  13. "github.com/gogf/gf/database/gdb"
  14. "github.com/gogf/gf/frame/g"
  15. "github.com/gogf/gf/os/gtime"
  16. "github.com/gogf/gf/util/gvalid"
  17. )
  18. type AnnouncementService struct {
  19. Tenant string
  20. userInfo request.UserInfo
  21. DB gdb.DB
  22. Dao *dao.AnnouncementDao
  23. FileDao *dao.AnnouncementFileDao
  24. ReadRecordDao *dao.AnnouncementReadRecordDao
  25. }
  26. func NewAnnouncementService(ctx context.Context) (*AnnouncementService, error) {
  27. tenant, err := micro_srv.GetTenant(ctx)
  28. if err != nil {
  29. return nil, fmt.Errorf("获取组合码异常:%s", err.Error())
  30. }
  31. // 获取用户信息
  32. userInfo, err := micro_srv.GetUserInfo(ctx)
  33. if err != nil {
  34. return nil, fmt.Errorf("获取用户信息异常:%s", err.Error())
  35. }
  36. return &AnnouncementService{
  37. Tenant: tenant,
  38. userInfo: userInfo,
  39. DB: g.DB(tenant),
  40. Dao: dao.NewAnnouncementDao(tenant),
  41. FileDao: dao.NewAnnouncementFileDao(tenant),
  42. ReadRecordDao: dao.NewAnnouncementReadRecordDao(tenant),
  43. }, nil
  44. }
  45. func (s AnnouncementService) Get(ctx context.Context, req *model.IdReq) (*model.AnnouncementGetResp, error) {
  46. ent, err := s.Dao.Where("Id = ?", req.Id).One()
  47. if err != nil {
  48. return nil, err
  49. }
  50. if ent == nil {
  51. return nil, myerrors.NewMsgError(nil, "反馈不存在")
  52. }
  53. f, err := s.FileDao.Where("MessageId = ?", req.Id).All()
  54. if err != nil {
  55. return nil, err
  56. }
  57. file := []model.FileInfo{}
  58. for _, i := range f {
  59. filesize, _ := strconv.Atoi(i.FileSize)
  60. file = append(file, model.FileInfo{
  61. Id: i.Id,
  62. FileExtend: i.FileExtend,
  63. FileName: i.FileName,
  64. FileSize: filesize,
  65. FileUrl: i.FileUrl,
  66. })
  67. }
  68. names := []string{}
  69. if ent.ReceiverDevice != "" {
  70. names, err = ColumnString(s.DB.Table("instrument").Where("Terminal in (?)", strings.Split(ent.ReceiverDevice, ",")), "Name")
  71. if err != nil {
  72. return nil, err
  73. }
  74. }
  75. return &model.AnnouncementGetResp{
  76. Announcement: *ent,
  77. ReceiverDeviceName: strings.Join(names, ", "),
  78. File: file,
  79. }, nil
  80. }
  81. func (s AnnouncementService) List(ctx context.Context, req *model.AnnouncementListReq) (int, []*model.Announcement, error) {
  82. dao := &s.Dao.AnnouncementDao
  83. if req.Title != "" {
  84. dao = dao.Where("Title LIKE ?", fmt.Sprintf("%%%s%%", req.Title))
  85. }
  86. if req.Sender != "" {
  87. dao = dao.Where("Sender LIKE ?", fmt.Sprintf("%%%s%%", req.Sender))
  88. }
  89. if req.Status != 0 {
  90. dao = dao.Where("Status = ?", req.Status)
  91. }
  92. if req.PublishTimeStart != nil {
  93. dao = dao.Where("PublishTime > ?", req.PublishTimeStart)
  94. }
  95. if req.PublishTimeEnd != nil {
  96. dao = dao.Where("PublishTime < ?", req.PublishTimeEnd)
  97. }
  98. total, err := dao.Count()
  99. if err != nil {
  100. return 0, nil, err
  101. }
  102. if req.Current == 0 {
  103. req.Current = 1
  104. }
  105. if req.Size == 0 {
  106. req.Size = 10
  107. }
  108. dao = dao.Page(req.Current, req.Size)
  109. dao = dao.Order("IsTop desc,CreatedAt desc")
  110. ent, err := dao.All()
  111. return total, ent, err
  112. }
  113. func (s AnnouncementService) Announcement(ctx context.Context, req *model.AnnouncementAnnouncementReq) (int, []*model.AnnouncementWithNew, error) {
  114. dept := organization{}
  115. err := s.DB.Table("base_organize").
  116. Where("Enabled = ?", 1).
  117. Where("Id = ?", s.userInfo.DeptId).
  118. Struct(&dept)
  119. if err != nil {
  120. return 0, nil, fmt.Errorf("查询用户部门错误 %s", err)
  121. }
  122. ret := []*model.AnnouncementWithNew{}
  123. err = s.DB.Table("announcement a").
  124. LeftJoin(fmt.Sprintf("(select `Id`,`MessageId`,`UserId` from announcement_read_record where `UserId`=%d) b", s.userInfo.Id), "a.Id=b.MessageId").
  125. Where("a.Status = 2").
  126. Where("a.DeptId in (?)", strings.Split(dept.Paths, "/")).
  127. Fields("a.*, b.Id is null as IsNew").Structs(&ret)
  128. return 0, ret, err
  129. }
  130. func (s AnnouncementService) Receipt(ctx context.Context, req *model.IdReq) error {
  131. validErr := gvalid.CheckStruct(ctx, req, nil)
  132. if validErr != nil {
  133. return myerrors.NewMsgError(nil, validErr.Current().Error())
  134. }
  135. ent, err := s.Dao.Where("id = ?", req.Id).One()
  136. if err != nil {
  137. return err
  138. }
  139. if ent == nil {
  140. return myerrors.NewMsgError(nil, fmt.Sprintf("公告不存在: %d", req.Id))
  141. }
  142. count, err := s.ReadRecordDao.Where("MessageId = ?", req.Id).Where("UserId = ?", s.userInfo.Id).Count()
  143. if err != nil {
  144. return err
  145. }
  146. if count == 0 {
  147. _, err := s.ReadRecordDao.Insert(model.AnnouncementReadRecord{
  148. MessageId: req.Id,
  149. UserId: int(s.userInfo.Id),
  150. CreatedBy: s.userInfo.RealName,
  151. CreatedAt: gtime.Now(),
  152. UpdatedBy: s.userInfo.RealName,
  153. UpdatedAt: gtime.Now(),
  154. CreatedById: int(s.userInfo.Id),
  155. UpdatedById: int(s.userInfo.Id),
  156. })
  157. if err != nil {
  158. return err
  159. }
  160. }
  161. return nil
  162. }
  163. func (s AnnouncementService) BindFile(tx *gdb.TX, msgId int, fileinfo []model.FileInfo, fileDelete []int) error {
  164. if len(fileDelete) != 0 {
  165. _, err := tx.Delete("announcement_file", "id in (?)", fileDelete)
  166. if err != nil {
  167. return err
  168. }
  169. }
  170. file := []model.AnnouncementFile{}
  171. for _, i := range fileinfo {
  172. file = append(file, model.AnnouncementFile{
  173. MessageId: msgId,
  174. FileName: i.FileName,
  175. FileUrl: i.FileUrl,
  176. FileId: "",
  177. FileSize: strconv.Itoa(i.FileSize),
  178. FileExtend: i.FileExtend,
  179. CreatedBy: s.userInfo.RealName,
  180. CreatedAt: gtime.Now(),
  181. UpdatedBy: s.userInfo.RealName,
  182. UpdatedAt: gtime.Now(),
  183. })
  184. }
  185. if len(file) != 0 {
  186. _, err := tx.Insert("announcement_file", file)
  187. if err != nil {
  188. return err
  189. }
  190. }
  191. return nil
  192. }
  193. type organize struct {
  194. Id int
  195. FullName string
  196. }
  197. func (s AnnouncementService) Add(ctx context.Context, req *model.AnnouncementAddReq) (int, error) {
  198. validErr := gvalid.CheckStruct(ctx, req, nil)
  199. if validErr != nil {
  200. return 0, myerrors.NewMsgError(nil, validErr.Current().Error())
  201. }
  202. if req.DeptId == 0 && len(req.ReceiverDevice) == 0 {
  203. return 0, myerrors.NewMsgError(nil, fmt.Sprintf("请输入通知对象"))
  204. }
  205. dept := &organize{}
  206. err := s.DB.Table("base_organize").Where("Id = ?", req.DeptId).Struct(dept)
  207. if err == sql.ErrNoRows {
  208. return 0, myerrors.NewMsgError(err, fmt.Sprintf("所选部门不存在"))
  209. }
  210. if err != nil {
  211. return 0, err
  212. }
  213. var msgId int
  214. txerr := s.Dao.DB.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
  215. publishTime := gtime.Now()
  216. if req.Status == 1 {
  217. publishTime = nil
  218. }
  219. istop := 0
  220. if req.IsTop {
  221. istop = 1
  222. }
  223. id, err := tx.InsertAndGetId("announcement", model.Announcement{
  224. Title: req.Title,
  225. Content: req.Content,
  226. Sender: s.userInfo.RealName,
  227. SenderId: int(s.userInfo.Id),
  228. Status: req.Status,
  229. DeptId: req.DeptId,
  230. DeptName: dept.FullName,
  231. PublishTime: publishTime,
  232. CreatedBy: s.userInfo.RealName,
  233. CreatedAt: gtime.Now(),
  234. UpdatedBy: s.userInfo.RealName,
  235. UpdatedAt: gtime.Now(),
  236. CreatedById: int(s.userInfo.Id),
  237. UpdatedById: int(s.userInfo.Id),
  238. ReceiverDevice: req.ReceiverDevice,
  239. Link: req.Link,
  240. IsTop: istop,
  241. })
  242. if err != nil {
  243. return err
  244. }
  245. err = s.BindFile(tx, int(id), req.File, nil)
  246. if err != nil {
  247. return err
  248. }
  249. msgId = int(id)
  250. return nil
  251. })
  252. return msgId, txerr
  253. }
  254. func (s AnnouncementService) Update(ctx context.Context, req *model.AnnouncementUpdateReq) error {
  255. validErr := gvalid.CheckStruct(ctx, req, nil)
  256. if validErr != nil {
  257. return myerrors.NewMsgError(nil, validErr.Current().Error())
  258. }
  259. ent, err := s.Dao.Where("id = ?", req.Id).One()
  260. if err != nil {
  261. return err
  262. }
  263. if ent == nil {
  264. return myerrors.NewMsgError(nil, fmt.Sprintf("公告不存在: %d", req.Id))
  265. }
  266. dept := &organize{}
  267. if req.DeptId != 0 {
  268. err := s.DB.Table("base_organize").Where("Id = ?", req.DeptId).Struct(dept)
  269. if err == sql.ErrNoRows {
  270. return myerrors.NewMsgError(err, fmt.Sprintf("所选部门不存在"))
  271. }
  272. if err != nil {
  273. return err
  274. }
  275. }
  276. toupdate := map[string]interface{}{}
  277. if req.Title != "" {
  278. toupdate["Title"] = req.Title
  279. }
  280. if req.Content != "" {
  281. toupdate["Content"] = req.Content
  282. }
  283. if req.IsTop != nil {
  284. toupdate["IsTop"] = *req.IsTop
  285. }
  286. if req.Link != "" {
  287. toupdate["Link"] = req.Link
  288. }
  289. if req.DeptId != 0 {
  290. toupdate["DeptId"] = req.DeptId
  291. toupdate["DeptName"] = dept.FullName
  292. }
  293. if req.ReceiverDevice != nil {
  294. toupdate["ReceiverDevice"] = req.ReceiverDevice
  295. }
  296. txerr := s.Dao.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
  297. if len(toupdate) != 0 {
  298. toupdate["UpdatedAt"] = gtime.Now()
  299. toupdate["UpdatedBy"] = s.userInfo.RealName
  300. toupdate["UpdatedById"] = int(s.userInfo.Id)
  301. _, err := tx.Update("announcement", toupdate, "Id = ?", req.Id)
  302. if err != nil {
  303. return err
  304. }
  305. }
  306. err = s.BindFile(tx, req.Id, req.File, req.FileDelete)
  307. if err != nil {
  308. return err
  309. }
  310. return nil
  311. })
  312. return txerr
  313. }
  314. func (s AnnouncementService) Publish(ctx context.Context, req *model.IdReq) error {
  315. validErr := gvalid.CheckStruct(ctx, req, nil)
  316. if validErr != nil {
  317. return myerrors.NewMsgError(nil, validErr.Current().Error())
  318. }
  319. ent, err := s.Dao.Where("id = ?", req.Id).One()
  320. if err != nil {
  321. return err
  322. }
  323. if ent == nil {
  324. return myerrors.NewMsgError(nil, fmt.Sprintf("公告不存在: %d", req.Id))
  325. }
  326. if ent.Status != 1 {
  327. return myerrors.NewMsgError(nil, fmt.Sprintf("当前公告不可发布"))
  328. }
  329. _, err = s.Dao.Data(map[string]interface{}{
  330. "Sender": s.userInfo.RealName,
  331. "SenderId": int(s.userInfo.Id),
  332. "Status": 2,
  333. "PublishTime": gtime.Now(),
  334. }).Where("Id = ?", req.Id).Update()
  335. return err
  336. }
  337. func (s AnnouncementService) Delete(ctx context.Context, id []int) error {
  338. if len(id) == 0 {
  339. return nil
  340. }
  341. _, err := s.Dao.Where("Id IN (?)", id).Delete()
  342. if err != nil {
  343. return err
  344. }
  345. _, err = s.FileDao.Where("MessageId IN (?)", id).Delete()
  346. if err != nil {
  347. return err
  348. }
  349. _, err = s.ReadRecordDao.Where("MessageId IN (?)", id).Delete()
  350. return err
  351. }
  352. func ColumnString(m *gdb.Model, name string) ([]string, error) {
  353. v, err := m.Fields(name).Array()
  354. if err != nil {
  355. return nil, err
  356. }
  357. res := []string{}
  358. for _, i := range v {
  359. res = append(res, i.String())
  360. }
  361. return res, nil
  362. }
  363. type organization struct {
  364. Id int `orm:"Id,primary" json:"id"` //
  365. ParentId int `orm:"ParentId" json:"parentId"` // 上级组织id
  366. FullName string `orm:"FullName" json:"fullName"` // 名称
  367. Paths string `orm:"Paths" json:"paths"` // 路径索引
  368. }
  369. type DeptNode struct {
  370. Id int
  371. Name string
  372. SubDept []*DeptNode
  373. }
  374. func (n DeptNode) String() string {
  375. Subdept := "{"
  376. for _, i := range n.SubDept {
  377. Subdept = Subdept + i.String() + ","
  378. }
  379. Subdept = Subdept + "}"
  380. return fmt.Sprintf("DeptNode{id=%d, name=%s, SubDept=%s}", n.Id, n.Name, Subdept)
  381. }
  382. func DeptTree(tenant string, id int) (*DeptNode, error) {
  383. deptlist := []organization{}
  384. err := g.DB(tenant).Table("base_organize").
  385. Where("Enabled = ?", 1).Structs(&deptlist)
  386. if err == sql.ErrNoRows {
  387. err = nil
  388. }
  389. if err != nil {
  390. return nil, err
  391. }
  392. deptMap := map[int]*DeptNode{}
  393. for _, d := range deptlist {
  394. deptMap[d.Id] = &DeptNode{
  395. Id: d.Id,
  396. Name: d.FullName,
  397. }
  398. }
  399. for _, d := range deptlist {
  400. if d.ParentId == 0 {
  401. continue
  402. }
  403. deptMap[d.ParentId].SubDept = append(deptMap[d.ParentId].SubDept, deptMap[d.Id])
  404. }
  405. for _, d := range deptMap {
  406. if d.Id == id {
  407. return d, nil
  408. }
  409. }
  410. return nil, nil
  411. }
  412. func RangeDeptTree(node *DeptNode) []*DeptNode {
  413. if node == nil {
  414. return nil
  415. }
  416. allnode := []*DeptNode{}
  417. nodes := []*DeptNode{node}
  418. for len(nodes) != 0 {
  419. newnode := []*DeptNode{}
  420. for _, n := range nodes {
  421. allnode = append(allnode, n)
  422. newnode = append(newnode, n.SubDept...)
  423. }
  424. nodes = newnode
  425. }
  426. return allnode
  427. }