wk_process.go 11 KB

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