flow.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. package bo
  2. import (
  3. "scd_check_tools/global"
  4. "scd_check_tools/logger"
  5. "scd_check_tools/models/enum"
  6. "scd_check_tools/tools"
  7. "bufio"
  8. "crypto/md5"
  9. "encoding/hex"
  10. "encoding/json"
  11. "io"
  12. "errors"
  13. "fmt"
  14. "log"
  15. "os"
  16. "strconv"
  17. "strings"
  18. "github.com/astaxie/beego/orm"
  19. )
  20. type Flow struct {
  21. DeviceBaseModel
  22. }
  23. type t_sys_flow struct {
  24. Id int64 `orm:pk;auto` // 主键
  25. CREATEDY int `gorm:"CREATED_BY"` // 创建人
  26. CREATEDIME string `gorm:"CREATED_TIME"` // 创建时间
  27. UPDATEDY int `gorm:"UPDATED_BY"` // 更新人
  28. UPDATEDIME string `gorm:"UPDATED_TIME"` // 更新时间
  29. FlowName string // 流程名称
  30. FlowType string // 流程类型
  31. Act string //
  32. IsUsed string `gorm:"isUsed"` // 启用状态
  33. }
  34. func init() {
  35. orm.RegisterModel(new(t_sys_flow))
  36. }
  37. //查询指定变电站及流程类型的节点配置信息
  38. func (c *Flow) FlowConfigList(stationid int64, flowtype, userfilter string) ([]orm.Params, error) {
  39. db := orm.NewOrm()
  40. sql := `SELECT f.flow_name,f.flow_type,n.flow_id,n.id node_id,n.node_name,n.node_code,n.node_type FROM
  41. t_sys_flow f
  42. INNER JOIN t_sys_flow_node n ON f.id = n.flow_id
  43. AND f.flow_type = ?
  44. ORDER BY n.node_position asc`
  45. rowset := []orm.Params{}
  46. _, err := db.Raw(sql, flowtype).Values(&rowset)
  47. dblog := new(SystemLog)
  48. dblog.SetUserInfo(c.GetUserInfo())
  49. dblog.Audittype = enum.AuditType_admin_scd_checkconfig
  50. dblog.Logtype = enum.LogType_Query
  51. dblog.Eventtype = enum.OptEventType_Bus
  52. dblog.Eventlevel = enum.OptEventLevel_Low
  53. dblog.Description = fmt.Sprintf("SQL:%s,参数:%+v", sql, flowtype)
  54. if err != nil {
  55. logger.Logger.Error(err, dblog.Description)
  56. dblog.Fail2()
  57. return nil, err
  58. } else {
  59. dblog.Success2()
  60. }
  61. userIsAdmin := false
  62. if userfilter == "1" {
  63. ura := new(UserAreaRelationObject)
  64. ura.SetUserInfo(c.GetUserInfo())
  65. tmpResult := ura.MakeAreaFilerWhere("")
  66. if tmpResult == "" {
  67. userIsAdmin = true
  68. }
  69. }
  70. for _, row := range rowset {
  71. //获取每个节点已关联的人员列表
  72. nodeid := tools.IsEmpty(row["node_id"])
  73. sql := `select n1.id node_inst_id, n1.staff_id,u.NAME staff_name from t_sys_flow_node_staff_ref n1
  74. LEFT JOIN t_data_user u ON n1.staff_id = u.id where n1.station_id = ? and node_id=? `
  75. tmpParams := []interface{}{}
  76. tmpParams = append(tmpParams, stationid)
  77. tmpParams = append(tmpParams, nodeid)
  78. if userfilter == "1" && !userIsAdmin {
  79. uid := c.GetUserId()
  80. if uid != "" {
  81. //需要根据当前人员进行节点过滤
  82. sql = `select n1.id node_inst_id, n1.staff_id,u.NAME staff_name from t_sys_flow_node_staff_ref n1
  83. LEFT JOIN t_data_user u ON n1.staff_id = u.id where n1.station_id = ? and node_id=? and n1.staff_id=?`
  84. tmpParams = append(tmpParams, uid)
  85. }
  86. }
  87. staffList := []orm.Params{}
  88. _, err = db.Raw(sql, tmpParams).Values(&staffList)
  89. if err != nil {
  90. log.Println(err)
  91. continue
  92. }
  93. row["staffs"] = staffList
  94. }
  95. return rowset, nil
  96. }
  97. //保存指定流程节点关联的人员
  98. func (c *Flow) SaveNodeUserRelation(stationid, nodeid, instid, userids string) error {
  99. dblog := new(SystemLog)
  100. dblog.SetUserInfo(c.GetUserInfo())
  101. dblog.Audittype = enum.AuditType_admin_scd_checkconfig
  102. dblog.Logtype = enum.LogType_Insert
  103. dblog.Eventtype = enum.OptEventType_Bus
  104. dblog.Eventlevel = enum.OptEventLevel_Hight
  105. uids := strings.Split(userids, ",")
  106. db := orm.NewOrm()
  107. for _, uid := range uids {
  108. if instid != "" {
  109. sql := "update t_sys_flow_node_staff_ref set staff_id=? where id=?"
  110. dblog.Description = fmt.Sprintf("SQL:%s,参数:%s,%s", sql, uid, instid)
  111. dblog.Logtype = enum.LogType_Update
  112. _, err := db.Raw(sql, uid, instid).Exec()
  113. if err != nil {
  114. logger.Logger.Error(err, dblog.Description)
  115. dblog.Fail2()
  116. return err
  117. }
  118. } else {
  119. sql := "insert into t_sys_flow_node_staff_ref select null, ? station_id,flow_id,id node_id,? staff_id,? CREATED_BY,now() from t_sys_flow_node where id=?"
  120. dblog.Description = fmt.Sprintf("SQL:%s,参数:%s,%s,%s,%s", sql, stationid, uid, c.GetUserId(), nodeid)
  121. dblog.Logtype = enum.LogType_Update
  122. _, err := db.Raw(sql, stationid, uid, c.GetUserId(), nodeid).Exec()
  123. if err != nil {
  124. logger.Logger.Error(err, dblog.Description)
  125. dblog.Fail2()
  126. return err
  127. }
  128. }
  129. }
  130. dblog.Success2()
  131. return nil
  132. }
  133. func (c *Flow) DeletNodeUser(node_inst_id, user_id string) error {
  134. dblog := new(SystemLog)
  135. dblog.SetUserInfo(c.GetUserInfo())
  136. dblog.Audittype = enum.AuditType_admin_scd_checkconfig
  137. dblog.Logtype = enum.LogType_Delete
  138. dblog.Eventtype = enum.OptEventType_Bus
  139. dblog.Eventlevel = enum.OptEventLevel_Hight
  140. db := orm.NewOrm()
  141. sql := "delete from t_sys_flow_node_staff_ref where id=?"
  142. dblog.Description = fmt.Sprintf("SQL:%s,参数:%s", sql, node_inst_id)
  143. _, err := db.Raw(sql, node_inst_id).Exec()
  144. if err != nil {
  145. logger.Logger.Error(err, dblog.Description)
  146. dblog.Fail2()
  147. return err
  148. }
  149. dblog.Success2()
  150. return nil
  151. }
  152. //锁定/解锁指定scd
  153. func (c *Flow) IsDispose(flowrunid string, reason string) error {
  154. dblog := new(SystemLog)
  155. dblog.SetUserInfo(c.GetUserInfo())
  156. dblog.Audittype = enum.AuditType_scd_parse
  157. dblog.Logtype = enum.LogType_unlock
  158. dblog.Eventtype = enum.OptEventType_Bus
  159. dblog.Eventlevel = enum.OptEventLevel_Hight
  160. db := orm.NewOrm()
  161. sql := "update t_sys_flow_run set deal_state=1,is_dispose=1,dispose_staff=?,dispose_reason=?,dispose_dt=? where id=?"
  162. sqlParameter := []interface{}{c.GetUserName(), reason, tools.NowTime(), flowrunid}
  163. dblog.Description = fmt.Sprintf("SQL:%s,参数:%+v", sql, sqlParameter)
  164. _, err := db.Raw(sql, sqlParameter).Exec()
  165. if err != nil {
  166. logger.Logger.Error(err, dblog.Description)
  167. dblog.Fail2()
  168. return err
  169. }
  170. dblog.Success2()
  171. flowrunidInt, _ := strconv.Atoi(flowrunid)
  172. flowruninfo, _ := c.GetFlowRunInfo(flowrunidInt)
  173. startUserID, _ := strconv.Atoi(tools.IsEmpty(flowruninfo["CREATED_BY"]))
  174. stationidint, _ := strconv.Atoi(tools.IsEmpty(flowruninfo["station_id"]))
  175. global.CheckingInInfo.Delete(fmt.Sprintf("%dscdin", stationidint))
  176. checkinLockKey := fmt.Sprintf("%d%s", stationidint, "scdin")
  177. global.CheckingInInfo.Delete(checkinLockKey)
  178. go SendNotice(c.GetUserInfo(), stationidint, NoticeType_Notice, "SCD签入(出)被终止", "你的SCD签入(出)审批被终止", int32(startUserID))
  179. return err
  180. }
  181. //获取指定站的已流转完成的签入签出记录
  182. func (c *Flow) GetFinishedRecordList(param map[string]interface{}) ([]orm.Params, error) {
  183. dblog := new(SystemLog)
  184. dblog.SetUserInfo(c.GetUserInfo())
  185. dblog.Audittype = enum.AuditType_check_inout
  186. dblog.Logtype = enum.LogType_Query
  187. dblog.Eventtype = enum.OptEventType_Bus
  188. dblog.Eventlevel = enum.OptEventLevel_Low
  189. stationid := tools.IsEmpty(param["stationid"])
  190. pageno, _ := strconv.Atoi(tools.IsEmpty(param["pageno"]))
  191. pagesize, _ := strconv.Atoi(tools.IsEmpty(param["pagesize"]))
  192. lastid, _ := strconv.Atoi(tools.IsEmpty(param["lastid"]))
  193. db := orm.NewOrm()
  194. sql := "select t.*,s.area_name statin_name,f.flow_type,f.flow_name,u.name created_name from t_sys_flow_run t inner join t_data_area s on t.station_id=s.id inner join t_sys_flow f on t.flow_id=f.id left join t_data_user u on t.CREATED_BY=u.id where t.deal_state=1 "
  195. sqlParams := []interface{}{}
  196. if stationid != "" {
  197. sql = sql + " and t.station_id=?"
  198. sqlParams = append(sqlParams, stationid)
  199. } else {
  200. uaObj := new(UserAreaRelationObject)
  201. uaObj.SetUserInfo(c.GetUserInfo())
  202. areaFilerWhere := uaObj.MakeAreaFilerIds("t.station_id", "and")
  203. sql = sql + areaFilerWhere
  204. }
  205. if lastid > 0 {
  206. sql = sql + " and t.id>? order by t.id desc"
  207. sqlParams = append(sqlParams, lastid)
  208. } else {
  209. sql = sql + fmt.Sprintf(" order by t.id desc limit %d,%d", (pageno-1)*pagesize, pagesize)
  210. }
  211. rowset := []orm.Params{}
  212. _, err := db.Raw(sql, sqlParams).Values(&rowset)
  213. dblog.Description = fmt.Sprintf("SQL:%s,参数:%+v", sql, sqlParams)
  214. if err != nil {
  215. logger.Logger.Error(err, dblog.Description)
  216. dblog.Fail2()
  217. return nil, err
  218. }
  219. dblog.Success2()
  220. return rowset, nil
  221. }
  222. //获取指定站的签入签出记录
  223. func (c *Flow) GetInoutRecordList(param map[string]interface{}) ([]orm.Params, int, error) {
  224. dblog := new(SystemLog)
  225. dblog.SetUserInfo(c.GetUserInfo())
  226. dblog.Audittype = enum.AuditType_check_inout
  227. dblog.Logtype = enum.LogType_Query
  228. dblog.Eventtype = enum.OptEventType_Bus
  229. dblog.Eventlevel = enum.OptEventLevel_Low
  230. stationid := tools.IsEmpty(param["stationid"])
  231. pageno := param["pageno"].(int)
  232. pagesize := param["pagesize"].(int)
  233. db := orm.NewOrm()
  234. uid := c.GetUserId()
  235. sql := `select t.*,t1.flow_type,t1.flow_name,u.name staff_name,
  236. case when t.CREATED_BY=` + uid + ` then 1 else 0 end iscreator,
  237. s1.checkout_lock,s1.version,s1.id scd_id ,s1.is_parse
  238. from t_sys_flow_run t,t_sys_flow t1,t_data_user u ,t_scd_scl s1
  239. where t.flow_id=t1.id and t.CREATED_BY=u.id and s1.station_id=? and s1.scd_name=t.scd_name and s1.path=concat('.',t.scd_path) and t.station_id=?`
  240. totalSql := "select count(1) cnt from t_sys_flow_run t where t.station_id=?"
  241. //只获取我发起的或该我处理的记录
  242. //where := " and (t.CREATED_BY=? or EXISTS(select 1 from t_sys_flow_run_detail d,t_sys_flow_node_staff_ref d1 where t.id=d.flow_run_id and d.node_id=d1.node_id and d1.station_id=? and d1.staff_id=?))"
  243. where := ""
  244. queryParam := []interface{}{}
  245. queryParam = append(queryParam, stationid)
  246. queryParam = append(queryParam, stationid)
  247. //queryParam = append(queryParam, uid)
  248. //queryParam = append(queryParam, stationid)
  249. //queryParam = append(queryParam, uid)
  250. if v1, ok := param["name"]; ok {
  251. v := tools.IsEmpty(v1)
  252. if v != "" {
  253. where = where + " and t.scd_name like concat('%',?,'%')"
  254. queryParam = append(queryParam, v)
  255. }
  256. }
  257. if v, ok := param["flowtype"]; ok {
  258. v1 := tools.IsEmpty(v)
  259. if v1 != "" {
  260. where = where + " and t.flow_id=(select id from t_sys_flow where flow_type=?)"
  261. queryParam = append(queryParam, v1)
  262. }
  263. }
  264. if v, ok := param["flowstate"]; ok {
  265. v1 := tools.IsEmpty(v)
  266. if v1 != "" {
  267. where = where + " and t.deal_state=?"
  268. queryParam = append(queryParam, v1)
  269. }
  270. }
  271. if v, ok := param["dt1"]; ok {
  272. v1 := tools.IsEmpty(v)
  273. if v1 != "" {
  274. where = where + " and t.CREATED_TIME>=?"
  275. queryParam = append(queryParam, v1+" 00:00:00")
  276. }
  277. }
  278. if v, ok := param["dt2"]; ok {
  279. v1 := tools.IsEmpty(v)
  280. if v1 != "" {
  281. where = where + " and t.CREATED_TIME<=?"
  282. queryParam = append(queryParam, v1+" 23:59:59")
  283. }
  284. }
  285. limit := fmt.Sprintf(" order by t.id desc limit %d,%d", (pageno-1)*pagesize, pagesize)
  286. rowset := []orm.Params{}
  287. _, err := db.Raw(sql+where+limit, queryParam).Values(&rowset)
  288. dblog.Description = fmt.Sprintf("SQL:%s,参数:%+v", sql+where+limit, queryParam)
  289. if err != nil {
  290. logger.Logger.Error(err, dblog.Description)
  291. dblog.Fail2()
  292. return nil, 0, err
  293. }
  294. dblog.Success2()
  295. if len(rowset) == 0 {
  296. return rowset, 0, nil
  297. }
  298. totalRowset := []orm.Params{}
  299. //查询总数是少一个参数
  300. queryParam = queryParam[1:]
  301. _, err = db.Raw(totalSql+where, queryParam).Values(&totalRowset)
  302. if err != nil {
  303. log.Println(err)
  304. return nil, 0, err
  305. }
  306. //获取每个流程的当前节点信息
  307. for _, row := range rowset {
  308. flow_run_id := tools.IsEmpty(row["id"])
  309. sql = "select t.*,t1.node_name,t1.node_code,u.name staff_name,(select 1 from t_sys_flow_node_staff_ref where station_id=? and staff_id=? and node_id=t.node_id) may from t_sys_flow_run_detail t inner join t_sys_flow_node t1 on t.node_id=t1.id left join t_data_user u on t.deal_staff_id=u.id where t.flow_run_id=? order by t.id desc limit 0,1"
  310. dealSet := []orm.Params{}
  311. _, err = db.Raw(sql, stationid, uid, flow_run_id).Values(&dealSet)
  312. if len(dealSet) > 0 {
  313. row["node_info"] = dealSet[0]
  314. } else {
  315. row["node_info"] = ""
  316. }
  317. }
  318. totalNum, _ := strconv.Atoi(tools.IsEmpty(totalRowset[0]["cnt"]))
  319. return rowset, totalNum, nil
  320. }
  321. //获取指定节点的下一节点信息。只获取配置了处理人员的节点
  322. func (c *Flow) GetNextNode(stationid string, nodeid int, nodecode string) (orm.Params, error) {
  323. db := orm.NewOrm()
  324. rowset := []orm.Params{}
  325. if nodeid == 0 {
  326. sql := "select id from t_sys_flow_node where node_code=? "
  327. _, err := db.Raw(sql, nodecode).Values(&rowset)
  328. if err != nil {
  329. log.Println(err)
  330. return nil, err
  331. }
  332. if len(rowset) == 0 {
  333. return nil, errors.New("无效的节点CODE")
  334. }
  335. nodeid, _ = strconv.Atoi(tools.IsEmpty(rowset[0]["id"]))
  336. }
  337. sql := "select flow_id, node_position from t_sys_flow_node where id=?"
  338. db.Raw(sql, nodeid).Values(&rowset)
  339. if len(rowset) == 0 {
  340. return nil, errors.New("无效的节点ID")
  341. }
  342. flow_id := tools.IsEmpty(rowset[0]["flow_id"])
  343. node_position := tools.IsEmpty(rowset[0]["node_position"])
  344. sql = "select * from t_sys_flow_node t where flow_id=? and node_position>? and EXISTS(select 1 from t_sys_flow_node_staff_ref s where s.station_id=? and t.id=s.node_id) order by node_position asc limit 0,1"
  345. db.Raw(sql, flow_id, node_position, stationid).Values(&rowset)
  346. if len(rowset) == 0 {
  347. return nil, nil
  348. }
  349. return rowset[0], nil
  350. }
  351. func (c *Flow) SaveNodeDealInfo(flow_type, flow_run_id, stationid, nodeCode, content string, opt int) error {
  352. nextNodeInfo, e := c.GetNextNode(stationid, 0, nodeCode)
  353. if e != nil {
  354. return e
  355. }
  356. sdcMgr := new(ScdMgr)
  357. sdcMgr.SetUserInfo(c.GetUserInfo())
  358. db := orm.NewOrm()
  359. uid := c.GetUserId()
  360. checkinLockKey := fmt.Sprintf("%s%s", stationid, "scdin")
  361. if flow_run_id == "" {
  362. //解析scd文件名称
  363. contentobj := map[string]interface{}{}
  364. json.Unmarshal([]byte(content), &contentobj)
  365. scdName := tools.IsEmpty(contentobj["scd_name"])
  366. scdPath := tools.IsEmpty(contentobj["scd_file"])
  367. if flow_type == "scdin" && (scdPath == "" || scdName == "") {
  368. return errors.New("请先上传SCD文件!")
  369. }
  370. if strings.HasSuffix(scdPath, ".zip") {
  371. //根据当前变电站及scd_name获取scd文件的scd_path
  372. attrowset := []orm.Params{}
  373. sql := "select save_path from t_sys_attachment where station_id=? and file_name=?"
  374. db.Raw(sql, stationid, scdName).Values(&attrowset)
  375. if len(attrowset) == 0 {
  376. return errors.New("无效的SCD文件:" + scdName)
  377. }
  378. scdPath = tools.IsEmpty(attrowset[0]["save_path"])
  379. }
  380. if flow_type == "scdout" {
  381. //判断当前站是否有锁定的scd,有同不能进行签出
  382. locklist, err := sdcMgr.GetCheckoutLockScd(stationid)
  383. if err != nil {
  384. return err
  385. }
  386. if len(locklist) > 0 {
  387. return errors.New("SCD文件已经签出但还未签入,不能重复签出操作!")
  388. }
  389. } else {
  390. //同一站内不能同时签入
  391. if v, h := global.CheckingInInfo.Load(checkinLockKey); h {
  392. return errors.New(fmt.Sprintf("不允许的签入操作!当前%s正在签入SCD,不允许同时签入", v))
  393. }
  394. //签入时,先进行系统负载判断
  395. if h, msg := sdcMgr.CheckParseMaxLimit(); h {
  396. return errors.New("系统繁忙:" + msg + ",请稍候(约5分钟)再试")
  397. }
  398. //锁定该站的签入操作
  399. logger.Logger.Debug(fmt.Sprintf("======用户的%s签入锁定:%s", c.GetUserName(), checkinLockKey))
  400. global.CheckingInInfo.Store(checkinLockKey, c.GetUserName())
  401. }
  402. //新流程实例
  403. if flow_type == "scdout" {
  404. //签出时,根据scdid获取名称和path
  405. scd_id := tools.IsEmpty(contentobj["scd_list"])
  406. if scd_id == "" {
  407. return errors.New("无效的scd文件ID")
  408. }
  409. scdInfo, e := sdcMgr.One(scd_id)
  410. if e != nil {
  411. return e
  412. }
  413. //锁定该scd文件
  414. sdcMgr.SetLock(stationid, scd_id, 1)
  415. scdName = tools.IsEmpty(scdInfo["scd_name"])
  416. scdPath = tools.IsEmpty(scdInfo["path"])
  417. if scdPath[0:1] == "." {
  418. scdPath = scdPath[1:]
  419. }
  420. }
  421. db.Begin()
  422. sqlInst := "insert into t_sys_flow_run select null,? station_id,t.id flow_id,? scd_path,? scd_name,0 deal_state, now() start_date,null finish_date,0,'','','',? CREATED_BY,now() CREATED_TIME from t_sys_flow t where t.flow_type=? and t.isUsed=1 limit 0,1 "
  423. sqlJob := "insert into t_base_job_content(job_type,job_content,CREATED_BY)values(?,?,?)"
  424. sqlNode := "insert into t_sys_flow_run_detail select null,? flow_run_id,t.id node_id,? work_book_id,? deal_state,? deal_result,? deal_staff_id,'' deal_comment,now() start_date,null finish_date ,? CREATED_BY,now() CREATED_TIME from t_sys_flow_node t where t.node_code=?"
  425. //先执行sqlJob,并获取到jobid
  426. sqlresult, err := db.Raw(sqlJob, "", content, uid).Exec()
  427. if err != nil {
  428. logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlJob, []interface{}{"", content, uid}))
  429. db.Rollback()
  430. global.CheckingInInfo.Delete(checkinLockKey)
  431. return err
  432. }
  433. jobid, _ := sqlresult.LastInsertId()
  434. //执行sqlInst,并获取实例ID
  435. sqlresult, err = db.Raw(sqlInst, stationid, scdPath, scdName, uid, flow_type).Exec()
  436. if err != nil {
  437. logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlInst, []interface{}{stationid, scdPath, scdName, uid, flow_type}))
  438. db.Rollback()
  439. global.CheckingInInfo.Delete(checkinLockKey)
  440. return err
  441. }
  442. flowRunID, _ := sqlresult.LastInsertId()
  443. //执行sqlNode,添加编制节点
  444. _, err = db.Raw(sqlNode, flowRunID, jobid, 1, 1, uid, uid, nodeCode).Exec()
  445. if err != nil {
  446. logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlNode, []interface{}{flowRunID, jobid, 1, 1, uid, uid, nodeCode}))
  447. db.Rollback()
  448. global.CheckingInInfo.Delete(checkinLockKey)
  449. return err
  450. }
  451. //执行sqlNode,添加下一下处理节点
  452. if nextNodeInfo != nil {
  453. nextNodecode := tools.IsEmpty(nextNodeInfo["node_code"])
  454. _, err = db.Raw(sqlNode, flowRunID, 0, 0, 0, 0, uid, nextNodecode).Exec()
  455. if err != nil {
  456. logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlNode, []interface{}{flowRunID, 0, 0, 0, 0, uid, nextNodecode}))
  457. db.Rollback()
  458. global.CheckingInInfo.Delete(checkinLockKey)
  459. return err
  460. }
  461. } else {
  462. //流程结束
  463. sqlInstUp := "update t_sys_flow_run set deal_state=?,finish_date=now() where id=?"
  464. _, err = db.Raw(sqlInstUp, 1, flowRunID).Exec()
  465. if err != nil {
  466. logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlInstUp, []interface{}{1, flowRunID}))
  467. db.Rollback()
  468. return err
  469. }
  470. if flow_type == "scdout" {
  471. //解除该站的签入锁定
  472. global.CheckingInInfo.Delete(checkinLockKey)
  473. }
  474. }
  475. db.Commit()
  476. //如果是文件签入时,做以下处理
  477. if flow_type == "scdin" {
  478. //开始做后台文件解析
  479. scd1 := GetScdParseInstance()
  480. scd1.SetUserInfo(c.GetUserInfo())
  481. scd1.IsCheckinScd = 1
  482. lstScdInfo, _ := sdcMgr.GetLastScd(stationid)
  483. lastscdid := int64(0)
  484. if lstScdInfo != nil {
  485. lastscdid, _ = strconv.ParseInt(tools.IsEmpty(lstScdInfo["id"]), 10, 64)
  486. }
  487. if nextNodeInfo != nil {
  488. //开始解析文件,并设置为不可用状态
  489. //go scd1.Parse(stationid, scdPath, scdName, 0, lastscdid)
  490. go scd1.XmlParse(stationid, scdPath, scdName, 0, lastscdid)
  491. } else {
  492. //开始解析文件,并设置为可用状态
  493. //go scd1.Parse(stationid, scdPath, scdName, 1, lastscdid)
  494. go scd1.XmlParse(stationid, scdPath, scdName, 1, lastscdid)
  495. }
  496. //发送通知提醒
  497. if nextNodeInfo != nil {
  498. nextNodeId, _ := strconv.Atoi(tools.IsEmpty(nextNodeInfo["id"]))
  499. stationidint, _ := strconv.Atoi(stationid)
  500. go SendFlowNotice(c.GetUserInfo(), stationidint, int32(nextNodeId))
  501. }
  502. } else if flow_type == "scdout" {
  503. //文件签出时,生成内部唯一crc标识并写入文件
  504. h := md5.New()
  505. h.Write([]byte(tools.NowTime() + stationid + scdName))
  506. cipherStr := h.Sum(nil)
  507. crccode := hex.EncodeToString(cipherStr) // 输出加密结果
  508. scdFilePath := strings.ReplaceAll(scdPath, "\\", string(os.PathSeparator))
  509. if scdFilePath[0:1] != "." {
  510. scdFilePath = "." + scdFilePath
  511. }
  512. var tmpFileSCD = fmt.Sprintf("%s.tmp", scdFilePath)
  513. tmpFileHander, _ := os.OpenFile(tmpFileSCD, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0644)
  514. defer tmpFileHander.Close()
  515. xmlhander, err2 := os.Open(scdFilePath)
  516. if err2 != nil {
  517. logger.Logger.Error(err2)
  518. return err2
  519. }
  520. defer xmlhander.Close()
  521. xmlread := bufio.NewReader(xmlhander)
  522. tmpWrite := bufio.NewWriter(tmpFileHander)
  523. buf := make([]byte, 1)
  524. isSCLNodeCount := 0
  525. for {
  526. n, err := xmlread.Read(buf)
  527. if err != nil {
  528. if err == io.EOF {
  529. break
  530. }
  531. logger.Logger.Error(err)
  532. break
  533. }
  534. if n == 0 {
  535. break
  536. }
  537. tmpWrite.Write(buf[0:n])
  538. if isSCLNodeCount < 2 {
  539. if string(buf) == ">" {
  540. //节点结束符表示又读取了一个节点
  541. isSCLNodeCount++
  542. }
  543. }
  544. if isSCLNodeCount == 2 {
  545. isSCLNodeCount = 99999
  546. //当读取到SCL节点后,追加crc到新文件中,后续按每次1M内容读取并写入
  547. tmpWrite.Write([]byte(`<Private when="` + tools.NowTime() + `" type="` + global.SCD_CheckoutCrcKey + `">` + crccode + `</Private>`))
  548. buf = make([]byte, 1024)
  549. }
  550. }
  551. tmpWrite.Flush()
  552. tmpFileHander.Close()
  553. xmlhander.Close()
  554. ferr := os.Rename(tmpFileSCD, strings.ReplaceAll(tmpFileSCD, ".tmp", ""))
  555. if ferr != nil {
  556. logger.Logger.Error(ferr)
  557. }
  558. //更新该scd的签出crc标识
  559. sqlUpSCL := "update t_scd_scl set out_rt_crc=? where station_id=? and path=?"
  560. _, err = db.Raw(sqlUpSCL, crccode, stationid, "."+scdPath).Exec()
  561. if err != nil {
  562. logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlUpSCL, []interface{}{1, flowRunID}))
  563. return err
  564. }
  565. }
  566. } else {
  567. //判断是否是更新还是新节点提交
  568. rowset := []orm.Params{}
  569. sql := "select t.id,t.node_type,t1.id detail_id from t_sys_flow_node t left join t_sys_flow_run_detail t1 on t.id=t1.node_id where t.node_code=? and t1.flow_run_id=?"
  570. _, err := db.Raw(sql, nodeCode, flow_run_id).Values(&rowset)
  571. if err != nil {
  572. logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sql, []interface{}{nodeCode, flow_run_id}))
  573. return err
  574. }
  575. if len(rowset) == 0 {
  576. //无效的流程ID
  577. return errors.New("无效的流程ID")
  578. } else {
  579. //nodeid := tools.IsEmpty(rowset[0]["id"])
  580. node_type := tools.IsEmpty(rowset[0]["node_type"])
  581. //新提交节点流转数据
  582. //当前流程被驳回或者结束时,根据flow_run_id更新流程信息
  583. db.Begin()
  584. sqlInstUp := "update t_sys_flow_run set deal_state=?,finish_date=? where id=?"
  585. sqlJob := "insert into t_base_job_content(job_type,job_content,CREATED_BY)values(?,?,?)"
  586. sqlNodeUp := "update t_sys_flow_run_detail set work_book_id=?,deal_state=?,deal_result=?,deal_staff_id=?,deal_comment=?,finish_date=now() where flow_run_id=? and node_id=(select id from t_sys_flow_node where node_code=?)"
  587. sqlNode := "insert into t_sys_flow_run_detail select null,? flow_run_id,t.id node_id,? work_book_id,? deal_state,? deal_result,? deal_staff_id,'' deal_comment,now() start_date,null finish_date ,? CREATED_BY,now() CREATED_TIME from t_sys_flow_node t where t.node_code=?"
  588. if opt == 1 {
  589. if node_type == "end" || nextNodeInfo == nil {
  590. //没有后续节点时,或者节点类型为end时,结束流程
  591. _, err = db.Raw(sqlInstUp, 1, tools.NowTime(), flow_run_id).Exec()
  592. } else {
  593. //更新流程状态。主要处理上一步是驳回时把状态更改为2的情况
  594. _, err = db.Raw(sqlInstUp, 0, nil, flow_run_id).Exec()
  595. }
  596. } else if opt == 0 {
  597. //被驳回时
  598. _, err = db.Raw(sqlInstUp, 2, nil, flow_run_id).Exec()
  599. }
  600. if err != nil {
  601. db.Rollback()
  602. log.Println(err)
  603. log.Println(sqlInstUp)
  604. return err
  605. }
  606. //
  607. if opt == 1 {
  608. //通过执行sqlJob,并获取到jobid
  609. sqlresult, err := db.Raw(sqlJob, "", content, uid).Exec()
  610. if err != nil {
  611. log.Println(err)
  612. db.Rollback()
  613. return err
  614. }
  615. jobid, _ := sqlresult.LastInsertId()
  616. //执行sqlNodeUp更新当前节点信息
  617. sqlresult, err = db.Raw(sqlNodeUp, jobid, 1, 1, uid, "", flow_run_id, nodeCode).Exec()
  618. if err != nil {
  619. log.Println(err)
  620. db.Rollback()
  621. return err
  622. }
  623. //执行sqlNode,添加下一下处理节点
  624. if nextNodeInfo != nil {
  625. nextNodecode := tools.IsEmpty(nextNodeInfo["node_code"])
  626. _, err = db.Raw(sqlNode, flow_run_id, 0, 0, 0, 0, uid, nextNodecode).Exec()
  627. if err != nil {
  628. log.Println(err)
  629. db.Rollback()
  630. return err
  631. }
  632. //发送通知提醒
  633. nextNodeId, _ := strconv.Atoi(tools.IsEmpty(nextNodeInfo["id"]))
  634. stationidint, _ := strconv.Atoi(stationid)
  635. go SendFlowNotice(c.GetUserInfo(), stationidint, int32(nextNodeId))
  636. } else {
  637. //流程结束
  638. //db.Raw("select scd_name,scd_path from t_sys_flow_run where id=?", flow_run_id).Values(&rowset)
  639. flow_run_id_int, _ := strconv.Atoi(flow_run_id)
  640. flowruninfo, _ := c.GetFlowRunInfo(flow_run_id_int)
  641. startUserID, _ := strconv.Atoi(tools.IsEmpty(flowruninfo["CREATED_BY"]))
  642. stationidint, _ := strconv.Atoi(stationid)
  643. //如果是文件签入时,做以下处理
  644. if flow_type == "scdin" {
  645. //解除当前站下的所有scd锁定状态
  646. sdcMgr.SetLock(stationid, "", 0)
  647. sdcMgr.SetStateByNamePath(tools.IsEmpty(flowruninfo["scd_name"]), tools.IsEmpty(flowruninfo["scd_path"]), 1)
  648. sdcMgr.UpdateScdVersion(0, stationid, tools.IsEmpty(flowruninfo["scd_name"]), tools.IsEmpty(flowruninfo["scd_path"]))
  649. go SendNotice(c.GetUserInfo(), stationidint, NoticeType_Notice, "SCD签入审批完成", "你的SCD签入已完成所有审批", int32(startUserID))
  650. } else {
  651. go SendNotice(c.GetUserInfo(), stationidint, NoticeType_Notice, "SCD签出审批完成", "你的SCD签出已完成所有审批", int32(startUserID))
  652. }
  653. logger.Logger.Debug(fmt.Sprintf("======用户的%s签入锁定解除:%s", c.GetUserName(), checkinLockKey))
  654. global.CheckingInInfo.Delete(checkinLockKey)
  655. }
  656. } else {
  657. //驳回执行sqlNode,驳回时,节点没有关联的内容需要保存
  658. _, err = db.Raw(sqlNodeUp, 0, 1, 0, uid, "驳回", flow_run_id, nodeCode).Exec()
  659. if err != nil {
  660. log.Println(err)
  661. db.Rollback()
  662. return err
  663. }
  664. //执行sqlNode,添加下一处理节点(开始节点)
  665. //获取流程的开始节点
  666. tmpSql := "select node_code,t1.CREATED_BY startUserid from t_sys_flow_node t,t_sys_flow_run t1 where t.flow_id=t1.flow_id and t1.id=? and t.node_position=0"
  667. _, err = db.Raw(tmpSql, flow_run_id).Values(&rowset)
  668. if err != nil {
  669. log.Println(err)
  670. db.Rollback()
  671. return err
  672. }
  673. firstNodecode := tools.IsEmpty(rowset[0]["node_code"])
  674. _, err = db.Raw(sqlNode, flow_run_id, 0, 0, 0, 0, uid, firstNodecode).Exec()
  675. if err != nil {
  676. log.Println(err)
  677. db.Rollback()
  678. return err
  679. }
  680. startUserid, _ := strconv.Atoi(tools.IsEmpty(rowset[0]["startUserid"]))
  681. stationidint, _ := strconv.Atoi(stationid)
  682. go SendNotice(c.GetUserInfo(), stationidint, NoticeType_Notice, "SCD签入(出)被驳回", "你的SCD签入(出)审批被驳回", int32(startUserid))
  683. }
  684. db.Commit()
  685. }
  686. }
  687. return nil
  688. }
  689. //scd签入解析失败处理
  690. func (c *Flow) CheckInFail(stationid string) {
  691. checkinLockKey := fmt.Sprintf("%s%s", stationid, "scdin") //签入锁定状态key
  692. //解除该站的签入锁定
  693. global.CheckingInInfo.Delete(checkinLockKey)
  694. //清除流程数据
  695. db := orm.NewOrm()
  696. db.Raw("delete from t_sys_flow_run_detail t where t.flow_run_id=(select id from t_sys_flow_run where station_id=? and deal_state=0)", stationid).Exec()
  697. db.Raw("delete from t_sys_flow_run where station_id=? and deal_state=0", stationid).Exec()
  698. }
  699. func (c *Flow) GetNodeDealInfo(flow_type, flow_run_id, stationid, nodeCode string) (orm.Params, error) {
  700. db := orm.NewOrm()
  701. rowset := []orm.Params{}
  702. sql := "select t.*,c.job_content,r.scd_name,r.scd_path from t_sys_flow_run_detail t inner join t_sys_flow_node n on t.node_id=n.id inner join t_sys_flow_run r on t.flow_run_id=r.id left join t_base_job_content c on t.work_book_id=c.id where t.flow_run_id=? and n.node_code=? "
  703. _, err := db.Raw(sql, flow_run_id, nodeCode).Values(&rowset)
  704. if err != nil {
  705. log.Println(err)
  706. return nil, err
  707. }
  708. if len(rowset) == 0 {
  709. return nil, errors.New("无效的节点CODE")
  710. }
  711. return rowset[0], nil
  712. }
  713. func (c *Flow) GetFlowRunInfo(flow_run_id int) (orm.Params, error) {
  714. db := orm.NewOrm()
  715. rowset := []orm.Params{}
  716. sql := "select t.* from t_sys_flow_run t where t.id=? "
  717. _, err := db.Raw(sql, flow_run_id).Values(&rowset)
  718. if err != nil {
  719. log.Println(err)
  720. return nil, err
  721. }
  722. if len(rowset) == 0 {
  723. return nil, errors.New("无效的流程ID")
  724. }
  725. return rowset[0], nil
  726. }
  727. //获取最后一次有效签出的工作内容信息
  728. func (c *Flow) GetLastCheckoutWorkbook(stationid string) (string, error) {
  729. db := orm.NewOrm()
  730. rowset := []orm.Params{}
  731. sql := "select c.job_content from t_sys_flow_run_detail t inner join t_sys_flow_node n on t.node_id=n.id inner join t_sys_flow_run r on t.flow_run_id=r.id left join t_base_job_content c on t.work_book_id=c.id where t.flow_run_id=(select max(id) id from t_sys_flow_run where station_id=? and is_dispose=0 and deal_state=1) and n.node_code='checkoutstart' "
  732. _, err := db.Raw(sql, stationid).Values(&rowset)
  733. if err != nil {
  734. log.Println(err)
  735. return "", err
  736. }
  737. if len(rowset) == 0 {
  738. return "", errors.New("没有签出的记录")
  739. }
  740. content := tools.IsEmpty(rowset[0]["job_content"])
  741. return content, nil
  742. }
  743. //获取指定scd文件签入时的工作内容信息
  744. func (c *Flow) GetCheckinWorkbook(stationid, scd_id, scdname, scdpath string) (orm.Params, error) {
  745. db := orm.NewOrm()
  746. rowset := []orm.Params{}
  747. para := []interface{}{}
  748. sql := ``
  749. if scd_id != "" {
  750. sql = `select s.id scd_id ,s.version,t.scd_name, t.id flow_id,t.start_date,t1.finish_date,u.name username,c.job_content,
  751. (select id from t_scd_diff_compare where source_id=s.id) compid
  752. from t_sys_flow_run t ,t_sys_flow_run_detail t1, t_base_job_content c ,t_scd_scl s,t_data_user u
  753. where t.id=t1.flow_run_id and t.scd_name=s.scd_name and concat('.',t.scd_path)=s.path and t.CREATED_BY=u.id
  754. and t.station_id=? and s.id=? and t1.work_book_id=c.id
  755. and t.flow_id=(select id from t_sys_flow where flow_type='scdin') order by t1.id desc limit 1`
  756. para = append(para, stationid)
  757. para = append(para, scd_id)
  758. } else {
  759. sql = `select s.id scd_id ,s.version,t.scd_name, t.id flow_id,t.start_date,t1.finish_date,u.name username,c.job_content,
  760. (select id from t_scd_diff_compare where source_id=s.id) compid
  761. from t_sys_flow_run t ,t_sys_flow_run_detail t1, t_base_job_content c ,t_scd_scl s,t_data_user u
  762. where t.id=t1.flow_run_id and t.scd_name=s.scd_name and concat('.',t.scd_path)=s.path and t.CREATED_BY=u.id
  763. and t.station_id=? and t.scd_name=? and t.scd_path=? and t1.work_book_id=c.id
  764. and t.flow_id=(select id from t_sys_flow where flow_type='scdin') order by t1.id desc limit 1`
  765. para = append(para, stationid)
  766. para = append(para, scdname)
  767. para = append(para, scdpath)
  768. }
  769. _, err := db.Raw(sql, para).Values(&rowset)
  770. if err != nil {
  771. log.Println(err)
  772. return nil, err
  773. }
  774. if len(rowset) == 0 {
  775. return nil, errors.New("没有签出的记录")
  776. }
  777. return rowset[0], nil
  778. }