wk_process.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. package service
  2. import (
  3. "errors"
  4. "gin-vue-admin/global"
  5. "gin-vue-admin/model"
  6. "gin-vue-admin/model/request"
  7. "gorm.io/gorm"
  8. "strconv"
  9. )
  10. //@author: [piexlmax](https://github.com/piexlmax)
  11. //@function: CreateWorkflowProcess
  12. //@description: 创建工作流相关信息
  13. //@param: workflowProcess model.WorkflowProcess
  14. //@return: err error
  15. func CreateWorkflowProcess(workflowProcess model.WorkflowProcess) (err error) {
  16. err = global.GVA_DB.Create(&workflowProcess).Error
  17. return err
  18. }
  19. //@author: [piexlmax](https://github.com/piexlmax)
  20. //@function: DeleteWorkflowProcess
  21. //@description: 删除工作流相关信息
  22. //@param: workflowProcess model.WorkflowProcess
  23. //@return: err error
  24. func DeleteWorkflowProcess(workflowProcess model.WorkflowProcess) (err error) {
  25. err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
  26. var txErr error
  27. txErr = tx.Delete(workflowProcess).Error
  28. if txErr != nil {
  29. return txErr
  30. }
  31. var edges []model.WorkflowEdge
  32. txErr = tx.Delete(model.WorkflowNode{}, "workflow_process_id = ?", workflowProcess.ID).Error
  33. if txErr != nil {
  34. return txErr
  35. }
  36. txErr = tx.Find(&edges, "workflow_process_id = ?", workflowProcess.ID).Error
  37. if txErr != nil {
  38. return txErr
  39. }
  40. txErr = tx.Select("StartPoint", "EndPoint").Delete(&edges).Error
  41. if txErr != nil {
  42. return txErr
  43. }
  44. return nil
  45. })
  46. return err
  47. }
  48. //@author: [piexlmax](https://github.com/piexlmax)
  49. //@function: CreateWorkflowProcess
  50. //@description: 批量删除工作流信息(暂未启用)
  51. //@param: ids request.IdsReq
  52. //@return: err error
  53. func DeleteWorkflowProcessByIds(ids request.IdsReq) (err error) {
  54. err = global.GVA_DB.Delete(&[]model.WorkflowProcess{}, "id in ?", ids.Ids).Error
  55. return err
  56. }
  57. //@author: [piexlmax](https://github.com/piexlmax)
  58. //@function: UpdateWorkflowProcess
  59. //@description: 更新工作流相关信息
  60. //@param: workflowProcess *model.WorkflowProcess
  61. //@return: err error
  62. func UpdateWorkflowProcess(workflowProcess *model.WorkflowProcess) (err error) {
  63. return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
  64. var txErr error
  65. var edges []model.WorkflowEdge
  66. var edgesIds []string
  67. txErr = tx.Unscoped().Delete(workflowProcess).Error
  68. if txErr != nil {
  69. return txErr
  70. }
  71. txErr = tx.Unscoped().Delete(model.WorkflowNode{}, "workflow_process_id = ?", workflowProcess.ID).Error
  72. if txErr != nil {
  73. return txErr
  74. }
  75. txErr = tx.Unscoped().Find(&edges, "workflow_process_id = ?", workflowProcess.ID).Error
  76. if txErr != nil {
  77. return txErr
  78. }
  79. txErr = tx.Unscoped().Delete(&edges).Error
  80. if txErr != nil {
  81. return txErr
  82. }
  83. for _, v := range edges {
  84. edgesIds = append(edgesIds, v.ID)
  85. }
  86. txErr = tx.Unscoped().Delete(model.WorkflowStartPoint{}, "workflow_edge_id in ?", edgesIds).Error
  87. if txErr != nil {
  88. return txErr
  89. }
  90. txErr = tx.Unscoped().Delete(model.WorkflowEndPoint{}, "workflow_edge_id in ?", edgesIds).Error
  91. if txErr != nil {
  92. return txErr
  93. }
  94. txErr = tx.Create(&workflowProcess).Error
  95. if txErr != nil {
  96. return txErr
  97. }
  98. return nil
  99. })
  100. }
  101. //@author: [piexlmax](https://github.com/piexlmax)
  102. //@function: GetWorkflowProcess
  103. //@description: 获取工作流相关信息
  104. //@param: id string
  105. //@return: err error,workflowProcess model.WorkflowProcess
  106. func GetWorkflowProcess(id string) (err error, workflowProcess model.WorkflowProcess) {
  107. err = global.GVA_DB.Preload("Nodes").Preload("Edges").Where("id = ?", id).First(&workflowProcess).Error
  108. return
  109. }
  110. //@author: [piexlmax](https://github.com/piexlmax)
  111. //@function: GetWorkflowCreateStep
  112. //@description: 获取工作流步骤信息
  113. //@param: id string
  114. //@return: err error, workflowNodes []model.WorkflowNode
  115. func FindWorkflowStep(id string) (err error, workflowNode model.WorkflowProcess) {
  116. err = global.GVA_DB.Preload("Nodes", "clazz = ?", model.START).Where("id = ?", id).First(&workflowNode).Error
  117. return
  118. }
  119. //@author: [piexlmax](https://github.com/piexlmax)
  120. //@function: GetWorkflowProcessInfoList
  121. //@description: 获取工作流列表
  122. //@param: info request.WorkflowProcessSearch
  123. //@return: err error, list interface{}, total int64
  124. func GetWorkflowProcessInfoList(info request.WorkflowProcessSearch) (err error, list interface{}, total int64) {
  125. limit := info.PageSize
  126. offset := info.PageSize * (info.Page - 1)
  127. // 创建db
  128. db := global.GVA_DB.Model(&model.WorkflowProcess{})
  129. var workflowProcesss []model.WorkflowProcess
  130. // 如果有条件搜索 下方会自动创建搜索语句
  131. if info.Name != "" {
  132. db = db.Where("`name` LIKE ?", "%"+info.Name+"%")
  133. }
  134. if info.Label != "" {
  135. db = db.Where("`label` LIKE ?", "%"+info.Label+"%")
  136. }
  137. err = db.Count(&total).Error
  138. err = db.Limit(limit).Offset(offset).Find(&workflowProcesss).Error
  139. return err, workflowProcesss, total
  140. }
  141. //@author: [piexlmax](https://github.com/piexlmax)
  142. //@function: StartWorkflow
  143. //@description: 开启一个工作流
  144. //@param: wfInterface model.GVA_Workflow
  145. //@return: err error
  146. func StartWorkflow(wfInterface model.GVA_Workflow) (err error) {
  147. err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
  148. var txErr error
  149. txErr = tx.Table(wfInterface.GetTableName()).Create(wfInterface).Error
  150. if txErr != nil {
  151. return txErr
  152. }
  153. wfm := wfInterface.CreateWorkflowMove()
  154. txErr = tx.Create(wfm).Error
  155. if txErr != nil {
  156. return txErr
  157. }
  158. txErr = complete(tx, wfm)
  159. if txErr != nil {
  160. return txErr
  161. }
  162. return nil
  163. })
  164. return err
  165. }
  166. //func CompleteWorkflowNode(wfInterface model.GVA_Workflow)(err error){
  167. //
  168. //}
  169. func complete(tx *gorm.DB, wfm *model.WorkflowMove) (err error) {
  170. var returnWfm model.WorkflowMove
  171. var nodeInfo model.WorkflowNode
  172. var Edges []model.WorkflowEdge
  173. txErr := tx.First(&returnWfm, "business_type = ? and business_id = ? and workflow_process_id = ? and workflow_node_id = ? and is_active = ?", wfm.BusinessType, wfm.BusinessID, wfm.WorkflowProcessID, wfm.WorkflowNodeID, true).Error
  174. if txErr != nil {
  175. return txErr
  176. }
  177. txErr = tx.First(&nodeInfo, "ID = ?", wfm.WorkflowNodeID).Error
  178. if txErr != nil {
  179. return txErr
  180. }
  181. if nodeInfo.Clazz == model.START || nodeInfo.Clazz == model.USER_TASK {
  182. txErr = tx.Find(&Edges, "workflow_process_id = ? and source = ?", wfm.WorkflowProcessID, wfm.WorkflowNodeID).Error
  183. if txErr != nil {
  184. return txErr
  185. }
  186. if len(Edges) == 0 {
  187. return errors.New("不存在当前节点为起点的后续流程")
  188. }
  189. if len(Edges) == 1 {
  190. //当前节点为初始节点时候
  191. if nodeInfo.Clazz == model.START {
  192. txErr = tx.Where("id = ?", returnWfm.ID).First(&model.WorkflowMove{}).Update("is_active", false).Error
  193. if txErr != nil {
  194. return txErr
  195. }
  196. }
  197. //当前节点为流转节点时候
  198. if nodeInfo.Clazz == model.USER_TASK {
  199. txErr = tx.Where("id = ?", returnWfm.ID).First(&model.WorkflowMove{}).Update("action", "complete").Update("is_active", false).Error
  200. if txErr != nil {
  201. return txErr
  202. }
  203. }
  204. newWfm := createNewWorkflowMove(&returnWfm, Edges[0].Target)
  205. txErr = tx.Create(newWfm).Error
  206. if txErr != nil {
  207. return txErr
  208. }
  209. // 当target为自动节点时候 需要做一些事情 这里暂时先不处理 后续慢慢完善
  210. }
  211. if len(Edges) > 1 {
  212. var needUseTargetNodeID string
  213. txErr = tx.Where("id = ?", returnWfm.ID).Update("is_active", false).Error
  214. if txErr != nil {
  215. return txErr
  216. }
  217. for _, v := range Edges {
  218. if v.ConditionExpression == wfm.Param {
  219. needUseTargetNodeID = v.Target
  220. break
  221. }
  222. }
  223. newWfm := createNewWorkflowMove(&returnWfm, needUseTargetNodeID)
  224. txErr = tx.Create(newWfm).Error
  225. if txErr != nil {
  226. return txErr
  227. }
  228. // 当target为自动节点时候 需要做一些事情 这里暂时先不处理 后续慢慢完善
  229. }
  230. } else {
  231. return errors.New("目前只支持start节点和userTask功能,其他功能正在开发中")
  232. }
  233. return nil
  234. }
  235. func createNewWorkflowMove(oldWfm *model.WorkflowMove, targetNodeID string) (newWfm *model.WorkflowMove) {
  236. return &model.WorkflowMove{
  237. BusinessID: oldWfm.BusinessID,
  238. BusinessType: oldWfm.BusinessType,
  239. PromoterID: oldWfm.PromoterID,
  240. WorkflowNodeID: targetNodeID,
  241. WorkflowProcessID: oldWfm.WorkflowProcessID,
  242. Action: "",
  243. IsActive: true,
  244. }
  245. }
  246. func GetMyStated(userID uint) (err error, wfms []model.WorkflowMove) {
  247. err = global.GVA_DB.Find(&wfms, "promoter_id = ? and is_active", userID, true).Error
  248. return err, wfms
  249. }
  250. func GetMyNeed(userID uint, AuthorityID string) (err error, wfms []model.WorkflowMove) {
  251. user := "%," + strconv.Itoa(int(userID)) + ",%"
  252. auth := "%," + AuthorityID + ",%"
  253. err = global.GVA_DB.Joins("INNER JOIN workflow_nodes as node ON workflow_moves.workflow_node_id = node.id").Where("(node.assign_type = ? AND node.assign_value LIKE ? ) OR (node.assign_type = ? AND node.assign_value LIKE ? )", "user", user, "authority", auth).Find(&wfms).Error
  254. return err, wfms
  255. }