plat_task.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. package plat
  2. import (
  3. "bytes"
  4. "context"
  5. workflowModel "dashoo.cn/micro/app/model/workflow"
  6. workflowService "dashoo.cn/micro/app/service/workflow"
  7. "dashoo.cn/opms_libary/plugin/dingtalk/message"
  8. "dashoo.cn/opms_libary/plugin/dingtalk/workflow"
  9. "dashoo.cn/opms_libary/utils"
  10. "database/sql"
  11. "errors"
  12. "fmt"
  13. "strconv"
  14. "strings"
  15. "dashoo.cn/opms_libary/myerrors"
  16. "github.com/360EntSecGroup-Skylar/excelize"
  17. "github.com/gogf/gf/frame/g"
  18. "github.com/gogf/gf/os/gtime"
  19. "github.com/gogf/gf/util/gconv"
  20. "dashoo.cn/micro/app/dao/plat"
  21. model "dashoo.cn/micro/app/model/plat"
  22. "dashoo.cn/micro/app/service"
  23. )
  24. var PlatTaskApprovalProcessCode = "PROC-B2BE7E92-8A12-4CFF-83CD-FF23F397CCE2"
  25. type taskService struct {
  26. *service.ContextService
  27. Dao *plat.PlatTaskDao
  28. }
  29. func NewTaskService(ctx context.Context) (svc *taskService, err error) {
  30. svc = new(taskService)
  31. if svc.ContextService, err = svc.Init(ctx); err != nil {
  32. return nil, err
  33. }
  34. svc.Dao = plat.NewPlatTaskDao(svc.Tenant)
  35. return svc, nil
  36. }
  37. // GetList 任务信息列表
  38. func (s *taskService) GetList(req *model.SearchPlatTaskReq) (total int, TaskList []*model.PlatTaskEx, err error) {
  39. TaskModel := s.Dao.LeftJoin("plat_task_handle", "plat_task_handle.task_id=plat_task.id")
  40. if req.TaskId != "" {
  41. TaskModel = TaskModel.Where("plat_task.id", req.TaskId)
  42. }
  43. if req.TaskTitle != "" {
  44. TaskModel = TaskModel.Where("plat_task.task_title LIKE ?", "%"+req.TaskTitle+"%")
  45. }
  46. if req.TaskType != "" {
  47. TaskModel = TaskModel.Where("plat_task.task_type", req.TaskType)
  48. }
  49. if req.Source != "" {
  50. TaskModel = TaskModel.Where("plat_task.source", req.Source)
  51. }
  52. if req.TaskStatus != "" {
  53. TaskModel = TaskModel.Where("plat_task.task_status", req.TaskStatus)
  54. }
  55. if req.IsOverdue != "" {
  56. TaskModel = TaskModel.Where("plat_task.is_overdue", req.IsOverdue)
  57. }
  58. if req.MainUserId != "" {
  59. TaskModel = TaskModel.Where("plat_task.main_user_id", req.MainUserId)
  60. }
  61. if req.TargetId != "" {
  62. TaskModel = TaskModel.Where("plat_task.target_id", req.TargetId)
  63. }
  64. if req.TargetType != "" {
  65. TaskModel = TaskModel.Where("plat_task.target_type", req.TargetType)
  66. }
  67. if req.MySelf == "1" {
  68. TaskModel = TaskModel.Where("plat_task.created_by", s.GetCxtUserId())
  69. }
  70. if req.IsMain == "1" {
  71. TaskModel = TaskModel.Where("plat_task.main_user_id", s.GetCxtUserId())
  72. }
  73. if req.OperateType == "1" {
  74. TaskModel = TaskModel.Where(fmt.Sprintf("plat_task_handle.task_status='10' AND (plat_task_handle.main_user_id=%v OR FIND_IN_SET(%v, plat_task_handle.owner_user_id))", s.GetCxtUserId(), s.GetCxtUserId()))
  75. } else if req.OperateType == "2" {
  76. TaskModel = TaskModel.Where("plat_task.created_by", s.GetCxtUserId())
  77. } else if req.OperateType == "3" {
  78. TaskModel = TaskModel.Where(fmt.Sprintf("plat_task_handle.task_status='20' AND plat_task_handle.handle_user_id=%v", s.GetCxtUserId()))
  79. }
  80. TaskModel = TaskModel.Group("plat_task.id")
  81. total, err = TaskModel.Count()
  82. if err != nil {
  83. g.Log().Error(err)
  84. err = myerrors.DbError("获取总行数失败。")
  85. return
  86. }
  87. err = TaskModel.Page(req.GetPage()).Order("plat_task.created_time DESC").Fields("plat_task.*,plat_task_handle.step").Scan(&TaskList)
  88. return
  89. }
  90. // Export 导出数据
  91. func (s *taskService) Export(req *model.ExportReq) (content *model.ExportContent, err error) {
  92. var con model.ExportContent
  93. // 获取数据
  94. total, list, err := s.GetList(&req.SearchPlatTaskReq)
  95. if err != nil {
  96. return nil, err
  97. }
  98. //rsp.List
  99. f := excelize.NewFile()
  100. // Create a new sheet.
  101. index := f.NewSheet("Sheet1")
  102. for index, item := range req.Columns {
  103. sheetPosition := service.Div(index+1) + "1"
  104. f.SetCellValue("Sheet1", sheetPosition, item)
  105. }
  106. if total > 0 {
  107. // 构造用户和类型填充数据
  108. userMap := make(map[int]string, 0)
  109. typeMap := make(map[string]string, 0)
  110. users, err := s.Dao.DB.Model("sys_user").FindAll()
  111. if err != nil {
  112. return nil, err
  113. }
  114. types, err := s.Dao.DB.Model("sys_dict_data").Where("dict_type='TaskType'").FindAll()
  115. if err != nil {
  116. return nil, err
  117. }
  118. for _, item := range users {
  119. userMap[item["id"].Int()] = item["nick_name"].String()
  120. }
  121. for _, item := range types {
  122. typeMap[item["dict_value"].String()] = item["dict_label"].String()
  123. }
  124. // 构造excel数据
  125. for lineNum, item := range list {
  126. for index, value := range req.Columns {
  127. if value == "督办标题" {
  128. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), item.TaskTitle)
  129. }
  130. if value == "督办类型" {
  131. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), typeMap[item.TaskType])
  132. }
  133. if value == "状态" {
  134. data := ""
  135. if item.TaskStatus == "10" {
  136. data = "发起"
  137. } else if item.TaskStatus == "20" {
  138. data = "进行中"
  139. } else if item.TaskStatus == "30" {
  140. data = "流程完成"
  141. }
  142. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), data)
  143. }
  144. if value == "督办事项来源" {
  145. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), item.Source)
  146. }
  147. if value == "超期" {
  148. data := ""
  149. if gtime.Now().Format("Y-m-d H:i:s") <= item.TaskEndDate.Format("Y-m-d 23:59:59") {
  150. data = "否"
  151. } else {
  152. data = "是"
  153. }
  154. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), data)
  155. }
  156. if value == "督办说明" {
  157. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), item.TaskDesc)
  158. }
  159. if value == "关联对象" {
  160. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), item.TargetName)
  161. }
  162. if value == "负责人" {
  163. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), userMap[item.MainUserId])
  164. }
  165. if value == "协办人" {
  166. names := ""
  167. if item.OwnerUserId != "" {
  168. ids := strings.Split(item.OwnerUserId, ",")
  169. for _, id := range ids {
  170. if names == "" {
  171. names = userMap[gconv.Int(id)]
  172. } else {
  173. names += "," + userMap[gconv.Int(id)]
  174. }
  175. }
  176. }
  177. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), names)
  178. }
  179. if value == "督办人" {
  180. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), userMap[item.SupervisorUserId])
  181. }
  182. if value == "发布时间" {
  183. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), item.TaskStartDate.Format("Y-m-d"))
  184. }
  185. if value == "要求完成时间" {
  186. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), item.TaskEndDate.Format("Y-m-d"))
  187. }
  188. if value == "创建时间" {
  189. f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(lineNum+2), item.CreatedTime.Format("Y-m-d H:i:s"))
  190. }
  191. }
  192. }
  193. }
  194. f.SetActiveSheet(index)
  195. var buffer *bytes.Buffer
  196. buffer, _ = f.WriteToBuffer()
  197. con.Content = buffer.Bytes()
  198. return &con, err
  199. }
  200. // Statistics 统计
  201. func (s *taskService) Statistics(req *model.SearchPlatTaskReq) (*model.TaskNumberCount, error) {
  202. var result model.TaskNumberCount
  203. // 统计数量
  204. count, err := s.Dao.InnerJoin("plat_task_handle", "plat_task.Id=plat_task_handle.task_id").Where(fmt.Sprintf("plat_task_handle.task_status='10' AND (plat_task_handle.main_user_id=%v OR FIND_IN_SET(%v, plat_task_handle.owner_user_id))", s.GetCxtUserId(), s.GetCxtUserId())).Group("plat_task.Id").Count()
  205. if err != nil {
  206. return nil, err
  207. }
  208. result.ToDoNumber = count
  209. return &result, nil
  210. }
  211. // Create 添加信息
  212. func (s *taskService) Create(req *model.AddPlatTaskReq) (err error) {
  213. platTask := new(model.PlatTask)
  214. if err = gconv.Struct(req, platTask); err != nil {
  215. return
  216. }
  217. // 初始数据
  218. platTask.IsOverdue = "10" // 是否超期(10否20是)
  219. if platTask.TaskStartDate == nil || platTask.TaskStartDate.IsZero() {
  220. platTask.TaskStartDate = gtime.Now()
  221. }
  222. // 填充创建信息
  223. service.SetCreatedInfo(platTask, s.GetCxtUserId(), s.GetCxtUserName())
  224. // 填充更新信息
  225. //service.SetUpdatedInfo(platTask, s.GetCxtUserId(), s.GetCxtUserName())
  226. res, err := s.Dao.Insert(platTask)
  227. if err != nil {
  228. return
  229. }
  230. // 创建操作任务
  231. id, _ := res.LastInsertId()
  232. platTask.Id = int(id)
  233. err = s.startDingApproval(platTask)
  234. if err != nil {
  235. return
  236. }
  237. // 流程日志
  238. err = CreateTaskLog(s, nil, int(id), s.GetCxtUserId(), s.GetCxtUserName(), "创建督办", "创建督办成功", "")
  239. return
  240. }
  241. // AddTaskApproval 创建督办之后,需要钉钉审批才能生效
  242. func (s *taskService) AddTaskApproval(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
  243. task, err := s.Dao.Where("id = ?", flow.BizCode).FindOne()
  244. if err != nil {
  245. return fmt.Errorf("创建督办审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
  246. }
  247. if err != nil {
  248. return err
  249. }
  250. if task == nil {
  251. return fmt.Errorf("督办不存在:%s Id: %d", flow.BizCode, flow.Id)
  252. }
  253. if msg.ProcessType != "finish" && msg.ProcessType != "terminate" {
  254. return fmt.Errorf("无法识别的 ProcessType :%s", msg.ProcessType)
  255. }
  256. if msg.Result != "agree" && msg.Result != "refuse" && msg.Result != "" {
  257. return fmt.Errorf("无法识别的 Result :%s", msg.Result)
  258. }
  259. if msg.ProcessType == "terminate" {
  260. _, err = s.Dao.Update("task_status='50'", fmt.Sprintf("id='%v'", task.Id))
  261. if err != nil {
  262. return err
  263. }
  264. // 流程日志
  265. err = CreateTaskLog(s, nil, task.Id, s.GetCxtUserId(), s.GetCxtUserName(), "督办审批", "撤销", "")
  266. } else {
  267. if msg.Result == "agree" {
  268. nextHandle := createNextTaskHandel(s, task, 10)
  269. _, err = s.Dao.DB.Insert("plat_task_handle", nextHandle)
  270. if err != nil {
  271. return err
  272. }
  273. // 流程日志
  274. err = CreateTaskLog(s, nil, task.Id, s.GetCxtUserId(), s.GetCxtUserName(), "督办审批", "通过", "")
  275. } else if msg.Result == "refuse" {
  276. _, err = s.Dao.Update("task_status='40'", fmt.Sprintf("id='%v'", task.Id))
  277. if err != nil {
  278. return err
  279. }
  280. // 流程日志
  281. err = CreateTaskLog(s, nil, task.Id, s.GetCxtUserId(), s.GetCxtUserName(), "督办审批", "拒绝", "")
  282. }
  283. }
  284. return err
  285. }
  286. // ChangeStatus 修改状态
  287. func (s *taskService) ChangeStatus(req *model.ChangeStatusReq) (err error) {
  288. data := ""
  289. where := fmt.Sprintf("id='%v'", req.TaskId)
  290. nodeName := "状态修改"
  291. desc := "修改成功"
  292. // 类型合规判断
  293. if req.Type == "TaskStatus" {
  294. data = fmt.Sprintf("task_status='%v'", req.NowStatus)
  295. nodeName = "状态修改"
  296. if req.NowStatus == "20" {
  297. desc = "关闭"
  298. data += fmt.Sprintf(",task_end_date='%v'", gtime.Now().Format("Y-m-d H:i:s"))
  299. }
  300. } else if req.Type == "IsOverdue" {
  301. nodeName = "超期状态修改"
  302. if req.NowStatus == "20" {
  303. desc = "超期"
  304. }
  305. data = fmt.Sprintf("is_overdue='%v'", req.NowStatus)
  306. } else {
  307. err = myerrors.TipsError("类型不匹配,请仔细检查。")
  308. return err
  309. }
  310. // 读取现有数据
  311. task, err := s.Dao.Where(where).FindOne()
  312. if err != nil {
  313. return err
  314. }
  315. if task == nil {
  316. err = myerrors.TipsError("数据异常,无匹配数据。")
  317. return err
  318. }
  319. // 状态数据一致性判断
  320. if (req.Type == "TaskStatus" && task.TaskStatus != req.OldStatus) || (req.Type == "IsOverdue" && task.IsOverdue != req.OldStatus) {
  321. err = myerrors.TipsError("状态不匹配,进行该操作")
  322. return err
  323. }
  324. // 更新数据
  325. _, err = s.Dao.Update(data, where)
  326. if err != nil {
  327. return
  328. }
  329. // 流程日志
  330. taskId, _ := strconv.Atoi(req.TaskId)
  331. err = CreateTaskLog(s, nil, taskId, s.GetCxtUserId(), s.GetCxtUserName(), nodeName, desc, "")
  332. return
  333. }
  334. // Handle 督办任务处理
  335. //步骤号(10接收 15暂存 20提交 30审批(督办人) 40评价(监办人))
  336. func (s *taskService) Handle(req *model.HandleReq) (err error) {
  337. // 步骤号(10接收 15暂存 20提交 30审批(督办人) 40评价(监办人))
  338. // 处理结果(10接收20提交30审批通过40审批退回)
  339. logNodeName := ""
  340. logDesc := ""
  341. var taskHandle model.PlatTaskHandle
  342. if req.Step != 15 {
  343. err = s.Dao.DB.Model("plat_task_handle").Where(fmt.Sprintf("task_id='%v' AND step=%v AND task_status='10' AND (main_user_id=%v OR FIND_IN_SET(%v, owner_user_id))", req.TaskId, req.Step, s.GetCxtUserId(), s.GetCxtUserId())).Scan(&taskHandle)
  344. if err != nil {
  345. if err == sql.ErrNoRows {
  346. err = myerrors.TipsError("数据不匹配,刷新数据重试")
  347. return err
  348. }
  349. return err
  350. }
  351. }
  352. now := gtime.Now()
  353. // 数据暂存,不做任何流程修改
  354. if req.Step == 15 {
  355. // 暂存
  356. logNodeName = "暂存"
  357. logDesc = s.GetCxtUserName() + "暂存进展信息"
  358. // 更新进展数据
  359. err = s.saveProgressList(req, now)
  360. if err != nil {
  361. return err
  362. }
  363. } else {
  364. var nextHandle = new(model.PlatTaskHandle)
  365. task, err := s.Dao.Where("id", req.TaskId).FindOne()
  366. if err != nil {
  367. return err
  368. }
  369. if task == nil {
  370. err = myerrors.TipsError("数据异常,无匹配数据")
  371. return err
  372. }
  373. // 构造更新数据
  374. handleData := g.Map{
  375. "task_status": "20",
  376. "handle_user_id": s.GetCxtUserId(),
  377. "handle_date": now.Format("Y-m-d H:i:s"),
  378. "handle_status": req.HandleStatus,
  379. "handle_desc": req.HandleDesc,
  380. "updated_by": s.GetCxtUserId(),
  381. "updated_name": s.GetCxtUserName(),
  382. "updated_time": now.Format("Y-m-d H:i:s"),
  383. }
  384. taskData := g.Map{
  385. "updated_by": s.GetCxtUserId(),
  386. "updated_name": s.GetCxtUserName(),
  387. "updated_time": now.Format("Y-m-d H:i:s"),
  388. }
  389. // 督办任务接收
  390. if req.Step == 10 {
  391. // 接收任务
  392. taskData["task_status"] = "20"
  393. taskData["receive_date"] = now.Format("Y-m-d H:i:s")
  394. nextHandle = createNextTaskHandel(s, task, 20)
  395. logNodeName = "接收"
  396. logDesc = s.GetCxtUserName() + "接收督办任务"
  397. } else if req.Step == 20 {
  398. // 提交数据
  399. nextHandle = createNextTaskHandel(s, task, 30)
  400. logNodeName = "提交"
  401. logDesc = s.GetCxtUserName() + "提交督办任务"
  402. // 更新进展数据
  403. err = s.saveProgressList(req, now)
  404. if err != nil {
  405. return err
  406. }
  407. } else if req.Step == 30 {
  408. // 督办人审批
  409. taskData["approver_id"] = s.GetCxtUserId()
  410. taskData["appro_date"] = now.Format("Y-m-d H:i:s")
  411. taskData["appro_status"] = req.HandleStatus
  412. taskData["appro_desc"] = req.HandleDesc
  413. logNodeName = "审批"
  414. if req.HandleStatus == "30" {
  415. logDesc = s.GetCxtUserName() + "审批通过"
  416. nextHandle = createNextTaskHandel(s, task, 40)
  417. } else if req.HandleStatus == "40" {
  418. logDesc = s.GetCxtUserName() + "审批退回"
  419. nextHandle = createNextTaskHandel(s, task, 20)
  420. }
  421. } else if req.Step == 40 {
  422. // 监办人评价
  423. taskData["evaluator_id"] = s.GetCxtUserId()
  424. taskData["evaluate_date"] = now.Format("Y-m-d H:i:s")
  425. taskData["evaluate_status"] = req.HandleStatus
  426. taskData["evaluate_desc"] = req.HandleDesc
  427. logNodeName = "评价"
  428. if req.HandleStatus == "30" {
  429. // 监办人评价,审批通过,任务结束
  430. logDesc = s.GetCxtUserName() + "审批通过"
  431. nextHandle = nil
  432. taskData["actual_close_date"] = now.Format("Y-m-d H:i:s")
  433. taskData["task_status"] = "30"
  434. } else if req.HandleStatus == "40" {
  435. logDesc = s.GetCxtUserName() + "审批退回"
  436. nextHandle = createNextTaskHandel(s, task, 20)
  437. }
  438. } else {
  439. err = myerrors.TipsError("未知步骤,无法操作")
  440. return err
  441. }
  442. // 更新数据
  443. // 更新督办任务数据
  444. _, err = s.Dao.Update(taskData, fmt.Sprintf("id='%v'", req.TaskId))
  445. if err != nil {
  446. return err
  447. }
  448. // 更新任务数据
  449. _, err = s.Dao.DB.Update("plat_task_handle", handleData, fmt.Sprintf("ID='%v'", taskHandle.ID))
  450. if err != nil {
  451. return err
  452. }
  453. // 创建下一条任务
  454. if nextHandle != nil {
  455. _, err = s.Dao.DB.Save("plat_task_handle", nextHandle)
  456. if err != nil {
  457. return err
  458. }
  459. }
  460. }
  461. // 流程日志
  462. err = CreateTaskLog(s, nil, req.TaskId, s.GetCxtUserId(), s.GetCxtUserName(), logNodeName, logDesc, "")
  463. if err != nil {
  464. return err
  465. }
  466. return nil
  467. }
  468. // CreateTaskLog 任务日志创建方法
  469. func CreateTaskLog(s1 *taskService, s2 *taskProgressService, taskId, userId int, userName, nodeName, desc, remark string) (err error) {
  470. var log model.PlatTaskLog
  471. startTime := gtime.Now()
  472. endTime := startTime
  473. // 默认为当前时间,然后随已有日志情况进行更新
  474. if s1 != nil {
  475. logs, err := s1.Dao.DB.Model(plat.PlatTaskLog.Table).Where(fmt.Sprintf("task_id='%v'", taskId)).Order("created_time DESC").FindAll()
  476. if err != nil && err != sql.ErrNoRows {
  477. return err
  478. }
  479. if len(logs) > 0 {
  480. startTime = logs[0]["end_time"].GTime()
  481. }
  482. } else {
  483. logs, err := s2.Dao.DB.Model(plat.PlatTaskLog.Table).Where(fmt.Sprintf("task_id='%v'", taskId)).Order("created_time DESC").FindAll()
  484. if err != nil && err != sql.ErrNoRows {
  485. return err
  486. }
  487. if len(logs) > 0 {
  488. startTime = logs[0]["end_time"].GTime()
  489. }
  490. }
  491. // 填入日志相关数据
  492. log.TaskId = taskId
  493. log.NodeName = nodeName
  494. log.Desc = desc
  495. log.StartTime = startTime
  496. log.EndTime = endTime
  497. log.Remark = remark
  498. log.CreatedTime = endTime
  499. log.CreatedName = userName
  500. log.CreatedBy = userId
  501. if s1 != nil {
  502. _, err = s1.Dao.DB.Save(plat.PlatTaskLog.Table, log)
  503. } else {
  504. _, err = s2.Dao.DB.Save(plat.PlatTaskLog.Table, log)
  505. }
  506. return err
  507. }
  508. // 创建个人的督办任务(其中,暂存不会生成个人任务,不会改变任何东西,只会新增一条日志)
  509. func createNextTaskHandel(s *taskService, task *model.PlatTask, step int) *model.PlatTaskHandle {
  510. // 步骤号(10接收 15暂存 20提交 30审批(督办人) 40评价(监办人))
  511. var personTask model.PlatTaskHandle
  512. personTask.TaskId = task.Id
  513. personTask.TaskStatus = "10"
  514. personTask.Step = step
  515. // 督办任务为发起时
  516. if step == 10 {
  517. personTask.MainUserId = task.MainUserId
  518. personTask.OwnerUserId = task.OwnerUserId
  519. } else if step == 20 {
  520. // 创建提交任务
  521. personTask.MainUserId = task.MainUserId
  522. personTask.OwnerUserId = task.OwnerUserId
  523. } else if step == 30 {
  524. // 提交给督办人审批
  525. personTask.MainUserId = task.SupervisorUserId
  526. } else if step == 40 {
  527. // 提交给监办人评价
  528. personTask.MainUserId = task.WatchUserId
  529. }
  530. // 填充创建信息
  531. service.SetCreatedInfo(&personTask, s.GetCxtUserId(), s.GetCxtUserName())
  532. return &personTask
  533. }
  534. func (s *taskService) startDingApproval(task *model.PlatTask) error {
  535. dictMap := make(map[string]string, 0)
  536. userMap := make(map[int]string, 0)
  537. teamNames := ""
  538. dicts, err := s.Dao.DB.Model("sys_dict_data").Where("dict_type = 'plat_task_source'").FindAll()
  539. if err != nil && err != sql.ErrNoRows {
  540. return err
  541. }
  542. if len(dicts) == 0 {
  543. return errors.New("督办来源数据缺失,请前往配置")
  544. }
  545. for _, dict := range dicts {
  546. dictMap[dict["dict_value"].String()] = dict["dict_label"].String()
  547. }
  548. users, err := s.Dao.DB.Model("sys_user").FindAll()
  549. if err != nil && err != sql.ErrNoRows {
  550. return err
  551. }
  552. if len(users) == 0 {
  553. return errors.New("用户数据数据缺失,请前往配置")
  554. }
  555. for _, user := range users {
  556. userMap[user["id"].Int()] = user["nick_name"].String()
  557. }
  558. if task.OwnerUserId != "" {
  559. ids := strings.Split(task.OwnerUserId, ",")
  560. for _, id := range ids {
  561. if teamNames == "" {
  562. teamNames = userMap[gconv.Int(id)]
  563. } else {
  564. teamNames += "," + userMap[gconv.Int(id)]
  565. }
  566. }
  567. }
  568. workflowSrv, err := workflowService.NewFlowService(s.Ctx)
  569. if err != nil {
  570. return err
  571. }
  572. _, err = workflowSrv.StartProcessInstance(gconv.String(task.Id), "40", "", &workflow.StartProcessInstanceRequest{
  573. ProcessCode: &PlatTaskApprovalProcessCode,
  574. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  575. {
  576. Id: utils.String("TextField-K2AD4O5B"),
  577. Name: utils.String("督办标题"),
  578. Value: utils.String(task.TaskTitle),
  579. },
  580. {
  581. Id: utils.String("DDDateField_C7LJMHNU6N40"),
  582. Name: utils.String("发布时间"),
  583. Value: utils.String(task.CreatedTime.Format("Y-m-d")),
  584. },
  585. {
  586. Id: utils.String("DDSelectField_OF3POKFZ43K"),
  587. Name: utils.String("督办来源"),
  588. Value: utils.String(dictMap[task.Source]),
  589. },
  590. {
  591. Id: utils.String("TextField_VPO2N6I4N5S0"),
  592. Name: utils.String("督办内容"),
  593. Value: utils.String(task.TaskDesc),
  594. },
  595. {
  596. Id: utils.String("DDAttachment_18RP41VRTITC0"),
  597. Name: utils.String("附件"),
  598. Value: utils.String(""),
  599. },
  600. {
  601. Id: utils.String("DDPhotoField_11WXOUDIZ85C0"),
  602. Name: utils.String("图片"),
  603. Value: utils.String(""),
  604. },
  605. {
  606. Id: utils.String("TextField_1ER7VNEEGU0W0"),
  607. Name: utils.String("督办人"),
  608. Value: utils.String(userMap[task.SupervisorUserId]),
  609. },
  610. {
  611. Id: utils.String("TextField_OKAEW6GD2FK0"),
  612. Name: utils.String("监办人"),
  613. Value: utils.String(userMap[task.WatchUserId]),
  614. },
  615. {
  616. Id: utils.String("TextField_G97RO96HMXK0"),
  617. Name: utils.String("被督办人"),
  618. Value: utils.String(userMap[task.MainUserId]),
  619. },
  620. {
  621. Id: utils.String("TextField_1FKS6CUW7REO0"),
  622. Name: utils.String("共同完成人"),
  623. Value: utils.String(teamNames),
  624. },
  625. {
  626. Id: utils.String("DDDateField_T9YBZCDTB680"),
  627. Name: utils.String("要求完成时间"),
  628. Value: utils.String(task.TaskEndDate.Format("Y-m-d")),
  629. },
  630. {
  631. Id: utils.String("TextField_LMV0Q71JD5C0"),
  632. Name: utils.String("备注"),
  633. Value: utils.String(task.Remark),
  634. },
  635. },
  636. })
  637. if err != nil {
  638. return err
  639. }
  640. return err
  641. }
  642. // 处理暂存、提交任务进展
  643. func (s *taskService) saveProgressList(req *model.HandleReq, now *gtime.Time) (err error) {
  644. ids := ""
  645. deleteWhere := fmt.Sprintf("task_id='%v'", req.TaskId)
  646. for index, progress := range req.ProgressList {
  647. if progress.Id != 0 {
  648. if ids == "" {
  649. ids = fmt.Sprintf("%v", progress.Id)
  650. } else {
  651. ids += fmt.Sprintf(",%v", progress.Id)
  652. }
  653. }
  654. req.ProgressList[index].TaskId = req.TaskId
  655. // 填充创建信息
  656. if progress.CreatedBy == 0 {
  657. service.SetCreatedInfo(req.ProgressList[index], s.GetCxtUserId(), s.GetCxtUserName())
  658. }
  659. // 填充更新信息
  660. service.SetUpdatedInfo(req.ProgressList[index], s.GetCxtUserId(), s.GetCxtUserName())
  661. }
  662. if ids != "" {
  663. deleteWhere += fmt.Sprintf(" AND ID NOT IN (%v)", ids)
  664. }
  665. // 保存督办进展
  666. // 1 标记删除旧的进展数据
  667. _, err = s.Dao.DB.Update("plat_task_progress", fmt.Sprintf("deleted_time='%v'", now.Format("Y-m-d H:i:s")), deleteWhere)
  668. if err != nil {
  669. return err
  670. }
  671. // 2 保存新的数据
  672. _, err = s.Dao.DB.Save("plat_task_progress", req.ProgressList)
  673. if err != nil {
  674. return err
  675. }
  676. return nil
  677. }