wk_process.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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 CompleteWorkflowNode(wfInterface model.GVA_Workflow)(err error){
  175. //
  176. //}
  177. func complete(tx *gorm.DB, wfm *model.WorkflowMove) (err error) {
  178. var returnWfm model.WorkflowMove
  179. var nodeInfo model.WorkflowNode
  180. var Edges []model.WorkflowEdge
  181. 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
  182. if txErr != nil {
  183. return txErr
  184. }
  185. txErr = tx.First(&nodeInfo, "ID = ?", wfm.WorkflowNodeID).Error
  186. if txErr != nil {
  187. return txErr
  188. }
  189. if nodeInfo.Clazz == model.START || nodeInfo.Clazz == model.USER_TASK {
  190. txErr = tx.Find(&Edges, "workflow_process_id = ? and source = ?", wfm.WorkflowProcessID, wfm.WorkflowNodeID).Error
  191. if txErr != nil {
  192. return txErr
  193. }
  194. if len(Edges) == 0 {
  195. return errors.New("不存在当前节点为起点的后续流程")
  196. }
  197. if len(Edges) == 1 {
  198. //当前节点为初始节点时候
  199. if nodeInfo.Clazz == model.START {
  200. txErr = tx.Where("id = ?", returnWfm.ID).First(&model.WorkflowMove{}).Update("is_active", false).Update("operator_id", wfm.OperatorID).Error
  201. if txErr != nil {
  202. return txErr
  203. }
  204. }
  205. //当前节点为流转节点时候
  206. if nodeInfo.Clazz == model.USER_TASK {
  207. txErr = tx.Where("id = ?", returnWfm.ID).First(&model.WorkflowMove{}).Update("action", "complete").Update("is_active", false).Update("operator_id", wfm.OperatorID).Error
  208. if txErr != nil {
  209. return txErr
  210. }
  211. }
  212. newWfm := createNewWorkflowMove(&returnWfm, Edges[0].Target)
  213. txErr = tx.Create(newWfm).Error
  214. if txErr != nil {
  215. return txErr
  216. }
  217. // 当target为自动节点时候 需要做一些事情 这里暂时先不处理 后续慢慢完善
  218. }
  219. if len(Edges) > 1 {
  220. var needUseTargetNodeID string
  221. txErr = tx.Where("id = ?", returnWfm.ID).First(&model.WorkflowMove{}).Update("action", "complete").Update("is_active", false).Update("operator_id", wfm.OperatorID).Error
  222. if txErr != nil {
  223. return txErr
  224. }
  225. for _, v := range Edges {
  226. if v.ConditionExpression == wfm.Param {
  227. needUseTargetNodeID = v.Target
  228. break
  229. }
  230. }
  231. newWfm := createNewWorkflowMove(&returnWfm, needUseTargetNodeID)
  232. txErr = tx.Create(newWfm).Error
  233. if txErr != nil {
  234. return txErr
  235. }
  236. // 当target为自动节点时候 需要做一些事情 这里暂时先不处理 后续慢慢完善
  237. }
  238. } else if nodeInfo.Clazz == model.EXCLUSIVE_GATEWAY {
  239. return errors.New("目前只支持start节点和userTask功能,其他功能正在开发中")
  240. } else if nodeInfo.Clazz == model.INCLUSIVE_GATEWAY {
  241. return errors.New("目前只支持start节点和userTask功能,其他功能正在开发中")
  242. } else if nodeInfo.Clazz == model.PARELLEL_GATEWAY {
  243. return errors.New("目前只支持start节点和userTask功能,其他功能正在开发中")
  244. } else {
  245. return errors.New("目前只支持start节点和userTask功能,其他功能正在开发中")
  246. }
  247. return nil
  248. }
  249. func createNewWorkflowMove(oldWfm *model.WorkflowMove, targetNodeID string) (newWfm *model.WorkflowMove) {
  250. return &model.WorkflowMove{
  251. BusinessID: oldWfm.BusinessID,
  252. BusinessType: oldWfm.BusinessType,
  253. PromoterID: oldWfm.PromoterID,
  254. OperatorID: 0,
  255. WorkflowNodeID: targetNodeID,
  256. WorkflowProcessID: oldWfm.WorkflowProcessID,
  257. Action: "",
  258. IsActive: true,
  259. }
  260. }
  261. func GetMyStated(userID uint) (err error, wfms []model.WorkflowMove) {
  262. 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
  263. return err, wfms
  264. }
  265. func GetMyNeed(userID uint, AuthorityID string) (err error, wfms []model.WorkflowMove) {
  266. user := "%," + strconv.Itoa(int(userID)) + ",%"
  267. auth := "%," + AuthorityID + ",%"
  268. 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
  269. return err, wfms
  270. }
  271. func GetWorkflowMoveByID(id float64) (err error, move model.WorkflowMove, moves []model.WorkflowMove, business interface{}) {
  272. var result interface{}
  273. err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
  274. var txErr error
  275. txErr = tx.Preload("Promoter").Preload("Operator").Preload("WorkflowNode").Preload("WorkflowProcess").First(&move, "id = ?", id).Error
  276. if txErr != nil {
  277. return txErr
  278. }
  279. txErr = tx.Preload("Promoter").Preload("Operator").Preload("WorkflowNode").Preload("WorkflowProcess").Find(&moves, "business_id = ? AND business_type = ?", move.BusinessID, move.BusinessType).Error
  280. if txErr != nil {
  281. return txErr
  282. }
  283. result = getTable(move.BusinessType)
  284. fmt.Println(result)
  285. txErr = tx.First(result, "id = ?", move.BusinessID).Error
  286. if txErr != nil {
  287. return txErr
  288. }
  289. return nil
  290. })
  291. return err, move, moves, result
  292. }