package bo import ( "scd_check_tools/global" "scd_check_tools/logger" "scd_check_tools/models/enum" "scd_check_tools/tools" "bufio" "crypto/md5" "encoding/hex" "encoding/json" "io" "errors" "fmt" "log" "os" "strconv" "strings" "github.com/astaxie/beego/orm" ) type Flow struct { DeviceBaseModel } type t_sys_flow struct { Id int64 `orm:pk;auto` // 主键 CREATEDY int `gorm:"CREATED_BY"` // 创建人 CREATEDIME string `gorm:"CREATED_TIME"` // 创建时间 UPDATEDY int `gorm:"UPDATED_BY"` // 更新人 UPDATEDIME string `gorm:"UPDATED_TIME"` // 更新时间 FlowName string // 流程名称 FlowType string // 流程类型 Act string // IsUsed string `gorm:"isUsed"` // 启用状态 } func init() { orm.RegisterModel(new(t_sys_flow)) } //查询指定变电站及流程类型的节点配置信息 func (c *Flow) FlowConfigList(stationid int64, flowtype, userfilter string) ([]orm.Params, error) { db := orm.NewOrm() 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 t_sys_flow f INNER JOIN t_sys_flow_node n ON f.id = n.flow_id AND f.flow_type = ? ORDER BY n.node_position asc` rowset := []orm.Params{} _, err := db.Raw(sql, flowtype).Values(&rowset) dblog := new(SystemLog) dblog.SetUserInfo(c.GetUserInfo()) dblog.Audittype = enum.AuditType_admin_scd_checkconfig dblog.Logtype = enum.LogType_Query dblog.Eventtype = enum.OptEventType_Bus dblog.Eventlevel = enum.OptEventLevel_Low dblog.Description = fmt.Sprintf("SQL:%s,参数:%+v", sql, flowtype) if err != nil { logger.Logger.Error(err, dblog.Description) dblog.Fail2() return nil, err } else { dblog.Success2() } userIsAdmin := false if userfilter == "1" { ura := new(UserAreaRelationObject) ura.SetUserInfo(c.GetUserInfo()) tmpResult := ura.MakeAreaFilerWhere("") if tmpResult == "" { userIsAdmin = true } } for _, row := range rowset { //获取每个节点已关联的人员列表 nodeid := tools.IsEmpty(row["node_id"]) sql := `select n1.id node_inst_id, n1.staff_id,u.NAME staff_name from t_sys_flow_node_staff_ref n1 LEFT JOIN t_data_user u ON n1.staff_id = u.id where n1.station_id = ? and node_id=? ` tmpParams := []interface{}{} tmpParams = append(tmpParams, stationid) tmpParams = append(tmpParams, nodeid) if userfilter == "1" && !userIsAdmin { uid := c.GetUserId() if uid != "" { //需要根据当前人员进行节点过滤 sql = `select n1.id node_inst_id, n1.staff_id,u.NAME staff_name from t_sys_flow_node_staff_ref n1 LEFT JOIN t_data_user u ON n1.staff_id = u.id where n1.station_id = ? and node_id=? and n1.staff_id=?` tmpParams = append(tmpParams, uid) } } staffList := []orm.Params{} _, err = db.Raw(sql, tmpParams).Values(&staffList) if err != nil { log.Println(err) continue } row["staffs"] = staffList } return rowset, nil } //保存指定流程节点关联的人员 func (c *Flow) SaveNodeUserRelation(stationid, nodeid, instid, userids string) error { dblog := new(SystemLog) dblog.SetUserInfo(c.GetUserInfo()) dblog.Audittype = enum.AuditType_admin_scd_checkconfig dblog.Logtype = enum.LogType_Insert dblog.Eventtype = enum.OptEventType_Bus dblog.Eventlevel = enum.OptEventLevel_Hight uids := strings.Split(userids, ",") db := orm.NewOrm() for _, uid := range uids { if instid != "" { sql := "update t_sys_flow_node_staff_ref set staff_id=? where id=?" dblog.Description = fmt.Sprintf("SQL:%s,参数:%s,%s", sql, uid, instid) dblog.Logtype = enum.LogType_Update _, err := db.Raw(sql, uid, instid).Exec() if err != nil { logger.Logger.Error(err, dblog.Description) dblog.Fail2() return err } } else { 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=?" dblog.Description = fmt.Sprintf("SQL:%s,参数:%s,%s,%s,%s", sql, stationid, uid, c.GetUserId(), nodeid) dblog.Logtype = enum.LogType_Update _, err := db.Raw(sql, stationid, uid, c.GetUserId(), nodeid).Exec() if err != nil { logger.Logger.Error(err, dblog.Description) dblog.Fail2() return err } } } dblog.Success2() return nil } func (c *Flow) DeletNodeUser(node_inst_id, user_id string) error { dblog := new(SystemLog) dblog.SetUserInfo(c.GetUserInfo()) dblog.Audittype = enum.AuditType_admin_scd_checkconfig dblog.Logtype = enum.LogType_Delete dblog.Eventtype = enum.OptEventType_Bus dblog.Eventlevel = enum.OptEventLevel_Hight db := orm.NewOrm() sql := "delete from t_sys_flow_node_staff_ref where id=?" dblog.Description = fmt.Sprintf("SQL:%s,参数:%s", sql, node_inst_id) _, err := db.Raw(sql, node_inst_id).Exec() if err != nil { logger.Logger.Error(err, dblog.Description) dblog.Fail2() return err } dblog.Success2() return nil } //锁定/解锁指定scd func (c *Flow) IsDispose(flowrunid string, reason string) error { dblog := new(SystemLog) dblog.SetUserInfo(c.GetUserInfo()) dblog.Audittype = enum.AuditType_scd_parse dblog.Logtype = enum.LogType_unlock dblog.Eventtype = enum.OptEventType_Bus dblog.Eventlevel = enum.OptEventLevel_Hight db := orm.NewOrm() sql := "update t_sys_flow_run set deal_state=1,is_dispose=1,dispose_staff=?,dispose_reason=?,dispose_dt=? where id=?" sqlParameter := []interface{}{c.GetUserName(), reason, tools.NowTime(), flowrunid} dblog.Description = fmt.Sprintf("SQL:%s,参数:%+v", sql, sqlParameter) _, err := db.Raw(sql, sqlParameter).Exec() if err != nil { logger.Logger.Error(err, dblog.Description) dblog.Fail2() return err } dblog.Success2() flowrunidInt, _ := strconv.Atoi(flowrunid) flowruninfo, _ := c.GetFlowRunInfo(flowrunidInt) startUserID, _ := strconv.Atoi(tools.IsEmpty(flowruninfo["CREATED_BY"])) stationidint, _ := strconv.Atoi(tools.IsEmpty(flowruninfo["station_id"])) global.CheckingInInfo.Delete(fmt.Sprintf("%dscdin", stationidint)) checkinLockKey := fmt.Sprintf("%d%s", stationidint, "scdin") global.CheckingInInfo.Delete(checkinLockKey) go SendNotice(c.GetUserInfo(), stationidint, NoticeType_Notice, "SCD签入(出)被终止", "你的SCD签入(出)审批被终止", int32(startUserID)) return err } //获取指定站的已流转完成的签入签出记录 func (c *Flow) GetFinishedRecordList(param map[string]interface{}) ([]orm.Params, error) { dblog := new(SystemLog) dblog.SetUserInfo(c.GetUserInfo()) dblog.Audittype = enum.AuditType_check_inout dblog.Logtype = enum.LogType_Query dblog.Eventtype = enum.OptEventType_Bus dblog.Eventlevel = enum.OptEventLevel_Low stationid := tools.IsEmpty(param["stationid"]) pageno, _ := strconv.Atoi(tools.IsEmpty(param["pageno"])) pagesize, _ := strconv.Atoi(tools.IsEmpty(param["pagesize"])) lastid, _ := strconv.Atoi(tools.IsEmpty(param["lastid"])) db := orm.NewOrm() 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 " sqlParams := []interface{}{} if stationid != "" { sql = sql + " and t.station_id=?" sqlParams = append(sqlParams, stationid) } else { uaObj := new(UserAreaRelationObject) uaObj.SetUserInfo(c.GetUserInfo()) areaFilerWhere := uaObj.MakeAreaFilerIds("t.station_id", "and") sql = sql + areaFilerWhere } if lastid > 0 { sql = sql + " and t.id>? order by t.id desc" sqlParams = append(sqlParams, lastid) } else { sql = sql + fmt.Sprintf(" order by t.id desc limit %d,%d", (pageno-1)*pagesize, pagesize) } rowset := []orm.Params{} _, err := db.Raw(sql, sqlParams).Values(&rowset) dblog.Description = fmt.Sprintf("SQL:%s,参数:%+v", sql, sqlParams) if err != nil { logger.Logger.Error(err, dblog.Description) dblog.Fail2() return nil, err } dblog.Success2() return rowset, nil } //获取指定站的签入签出记录 func (c *Flow) GetInoutRecordList(param map[string]interface{}) ([]orm.Params, int, error) { dblog := new(SystemLog) dblog.SetUserInfo(c.GetUserInfo()) dblog.Audittype = enum.AuditType_check_inout dblog.Logtype = enum.LogType_Query dblog.Eventtype = enum.OptEventType_Bus dblog.Eventlevel = enum.OptEventLevel_Low stationid := tools.IsEmpty(param["stationid"]) pageno := param["pageno"].(int) pagesize := param["pagesize"].(int) db := orm.NewOrm() uid := c.GetUserId() sql := `select t.*,t1.flow_type,t1.flow_name,u.name staff_name, case when t.CREATED_BY=` + uid + ` then 1 else 0 end iscreator, s1.checkout_lock,s1.version,s1.id scd_id ,s1.is_parse from t_sys_flow_run t,t_sys_flow t1,t_data_user u ,t_scd_scl s1 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=?` totalSql := "select count(1) cnt from t_sys_flow_run t where t.station_id=?" //只获取我发起的或该我处理的记录 //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=?))" where := "" queryParam := []interface{}{} queryParam = append(queryParam, stationid) queryParam = append(queryParam, stationid) //queryParam = append(queryParam, uid) //queryParam = append(queryParam, stationid) //queryParam = append(queryParam, uid) if v1, ok := param["name"]; ok { v := tools.IsEmpty(v1) if v != "" { where = where + " and t.scd_name like concat('%',?,'%')" queryParam = append(queryParam, v) } } if v, ok := param["flowtype"]; ok { v1 := tools.IsEmpty(v) if v1 != "" { where = where + " and t.flow_id=(select id from t_sys_flow where flow_type=?)" queryParam = append(queryParam, v1) } } if v, ok := param["flowstate"]; ok { v1 := tools.IsEmpty(v) if v1 != "" { where = where + " and t.deal_state=?" queryParam = append(queryParam, v1) } } if v, ok := param["dt1"]; ok { v1 := tools.IsEmpty(v) if v1 != "" { where = where + " and t.CREATED_TIME>=?" queryParam = append(queryParam, v1+" 00:00:00") } } if v, ok := param["dt2"]; ok { v1 := tools.IsEmpty(v) if v1 != "" { where = where + " and t.CREATED_TIME<=?" queryParam = append(queryParam, v1+" 23:59:59") } } limit := fmt.Sprintf(" order by t.id desc limit %d,%d", (pageno-1)*pagesize, pagesize) rowset := []orm.Params{} _, err := db.Raw(sql+where+limit, queryParam).Values(&rowset) dblog.Description = fmt.Sprintf("SQL:%s,参数:%+v", sql+where+limit, queryParam) if err != nil { logger.Logger.Error(err, dblog.Description) dblog.Fail2() return nil, 0, err } dblog.Success2() if len(rowset) == 0 { return rowset, 0, nil } totalRowset := []orm.Params{} //查询总数是少一个参数 queryParam = queryParam[1:] _, err = db.Raw(totalSql+where, queryParam).Values(&totalRowset) if err != nil { log.Println(err) return nil, 0, err } //获取每个流程的当前节点信息 for _, row := range rowset { flow_run_id := tools.IsEmpty(row["id"]) 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" dealSet := []orm.Params{} _, err = db.Raw(sql, stationid, uid, flow_run_id).Values(&dealSet) if len(dealSet) > 0 { row["node_info"] = dealSet[0] } else { row["node_info"] = "" } } totalNum, _ := strconv.Atoi(tools.IsEmpty(totalRowset[0]["cnt"])) return rowset, totalNum, nil } //获取指定节点的下一节点信息。只获取配置了处理人员的节点 func (c *Flow) GetNextNode(stationid string, nodeid int, nodecode string) (orm.Params, error) { db := orm.NewOrm() rowset := []orm.Params{} if nodeid == 0 { sql := "select id from t_sys_flow_node where node_code=? " _, err := db.Raw(sql, nodecode).Values(&rowset) if err != nil { log.Println(err) return nil, err } if len(rowset) == 0 { return nil, errors.New("无效的节点CODE") } nodeid, _ = strconv.Atoi(tools.IsEmpty(rowset[0]["id"])) } sql := "select flow_id, node_position from t_sys_flow_node where id=?" db.Raw(sql, nodeid).Values(&rowset) if len(rowset) == 0 { return nil, errors.New("无效的节点ID") } flow_id := tools.IsEmpty(rowset[0]["flow_id"]) node_position := tools.IsEmpty(rowset[0]["node_position"]) 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" db.Raw(sql, flow_id, node_position, stationid).Values(&rowset) if len(rowset) == 0 { return nil, nil } return rowset[0], nil } func (c *Flow) SaveNodeDealInfo(flow_type, flow_run_id, stationid, nodeCode, content string, opt int) error { nextNodeInfo, e := c.GetNextNode(stationid, 0, nodeCode) if e != nil { return e } sdcMgr := new(ScdMgr) sdcMgr.SetUserInfo(c.GetUserInfo()) db := orm.NewOrm() uid := c.GetUserId() checkinLockKey := fmt.Sprintf("%s%s", stationid, "scdin") if flow_run_id == "" { //解析scd文件名称 contentobj := map[string]interface{}{} json.Unmarshal([]byte(content), &contentobj) scdName := tools.IsEmpty(contentobj["scd_name"]) scdPath := tools.IsEmpty(contentobj["scd_file"]) if flow_type == "scdin" && (scdPath == "" || scdName == "") { return errors.New("请先上传SCD文件!") } if strings.HasSuffix(scdPath, ".zip") { //根据当前变电站及scd_name获取scd文件的scd_path attrowset := []orm.Params{} sql := "select save_path from t_sys_attachment where station_id=? and file_name=?" db.Raw(sql, stationid, scdName).Values(&attrowset) if len(attrowset) == 0 { return errors.New("无效的SCD文件:" + scdName) } scdPath = tools.IsEmpty(attrowset[0]["save_path"]) } if flow_type == "scdout" { //判断当前站是否有锁定的scd,有同不能进行签出 locklist, err := sdcMgr.GetCheckoutLockScd(stationid) if err != nil { return err } if len(locklist) > 0 { return errors.New("SCD文件已经签出但还未签入,不能重复签出操作!") } } else { //同一站内不能同时签入 if v, h := global.CheckingInInfo.Load(checkinLockKey); h { return errors.New(fmt.Sprintf("不允许的签入操作!当前%s正在签入SCD,不允许同时签入", v)) } //签入时,先进行系统负载判断 if h, msg := sdcMgr.CheckParseMaxLimit(); h { return errors.New("系统繁忙:" + msg + ",请稍候(约5分钟)再试") } //锁定该站的签入操作 logger.Logger.Debug(fmt.Sprintf("======用户的%s签入锁定:%s", c.GetUserName(), checkinLockKey)) global.CheckingInInfo.Store(checkinLockKey, c.GetUserName()) } //新流程实例 if flow_type == "scdout" { //签出时,根据scdid获取名称和path scd_id := tools.IsEmpty(contentobj["scd_list"]) if scd_id == "" { return errors.New("无效的scd文件ID") } scdInfo, e := sdcMgr.One(scd_id) if e != nil { return e } //锁定该scd文件 sdcMgr.SetLock(stationid, scd_id, 1) scdName = tools.IsEmpty(scdInfo["scd_name"]) scdPath = tools.IsEmpty(scdInfo["path"]) if scdPath[0:1] == "." { scdPath = scdPath[1:] } } db.Begin() 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 " sqlJob := "insert into t_base_job_content(job_type,job_content,CREATED_BY)values(?,?,?)" 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=?" //先执行sqlJob,并获取到jobid sqlresult, err := db.Raw(sqlJob, "", content, uid).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlJob, []interface{}{"", content, uid})) db.Rollback() global.CheckingInInfo.Delete(checkinLockKey) return err } jobid, _ := sqlresult.LastInsertId() //执行sqlInst,并获取实例ID sqlresult, err = db.Raw(sqlInst, stationid, scdPath, scdName, uid, flow_type).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlInst, []interface{}{stationid, scdPath, scdName, uid, flow_type})) db.Rollback() global.CheckingInInfo.Delete(checkinLockKey) return err } flowRunID, _ := sqlresult.LastInsertId() //执行sqlNode,添加编制节点 _, err = db.Raw(sqlNode, flowRunID, jobid, 1, 1, uid, uid, nodeCode).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlNode, []interface{}{flowRunID, jobid, 1, 1, uid, uid, nodeCode})) db.Rollback() global.CheckingInInfo.Delete(checkinLockKey) return err } //执行sqlNode,添加下一下处理节点 if nextNodeInfo != nil { nextNodecode := tools.IsEmpty(nextNodeInfo["node_code"]) _, err = db.Raw(sqlNode, flowRunID, 0, 0, 0, 0, uid, nextNodecode).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlNode, []interface{}{flowRunID, 0, 0, 0, 0, uid, nextNodecode})) db.Rollback() global.CheckingInInfo.Delete(checkinLockKey) return err } } else { //流程结束 sqlInstUp := "update t_sys_flow_run set deal_state=?,finish_date=now() where id=?" _, err = db.Raw(sqlInstUp, 1, flowRunID).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlInstUp, []interface{}{1, flowRunID})) db.Rollback() return err } if flow_type == "scdout" { //解除该站的签入锁定 global.CheckingInInfo.Delete(checkinLockKey) } } db.Commit() //如果是文件签入时,做以下处理 if flow_type == "scdin" { //开始做后台文件解析 scd1 := GetScdParseInstance() scd1.SetUserInfo(c.GetUserInfo()) scd1.IsCheckinScd = 1 lstScdInfo, _ := sdcMgr.GetLastScd(stationid) lastscdid := int64(0) if lstScdInfo != nil { lastscdid, _ = strconv.ParseInt(tools.IsEmpty(lstScdInfo["id"]), 10, 64) } if nextNodeInfo != nil { //开始解析文件,并设置为不可用状态 //go scd1.Parse(stationid, scdPath, scdName, 0, lastscdid) go scd1.XmlParse(stationid, scdPath, scdName, 0, lastscdid) } else { //开始解析文件,并设置为可用状态 //go scd1.Parse(stationid, scdPath, scdName, 1, lastscdid) go scd1.XmlParse(stationid, scdPath, scdName, 1, lastscdid) } //发送通知提醒 if nextNodeInfo != nil { nextNodeId, _ := strconv.Atoi(tools.IsEmpty(nextNodeInfo["id"])) stationidint, _ := strconv.Atoi(stationid) go SendFlowNotice(c.GetUserInfo(), stationidint, int32(nextNodeId)) } } else if flow_type == "scdout" { //文件签出时,生成内部唯一crc标识并写入文件 h := md5.New() h.Write([]byte(tools.NowTime() + stationid + scdName)) cipherStr := h.Sum(nil) crccode := hex.EncodeToString(cipherStr) // 输出加密结果 scdFilePath := strings.ReplaceAll(scdPath, "\\", string(os.PathSeparator)) if scdFilePath[0:1] != "." { scdFilePath = "." + scdFilePath } var tmpFileSCD = fmt.Sprintf("%s.tmp", scdFilePath) tmpFileHander, _ := os.OpenFile(tmpFileSCD, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0644) defer tmpFileHander.Close() xmlhander, err2 := os.Open(scdFilePath) if err2 != nil { logger.Logger.Error(err2) return err2 } defer xmlhander.Close() xmlread := bufio.NewReader(xmlhander) tmpWrite := bufio.NewWriter(tmpFileHander) buf := make([]byte, 1) isSCLNodeCount := 0 for { n, err := xmlread.Read(buf) if err != nil { if err == io.EOF { break } logger.Logger.Error(err) break } if n == 0 { break } tmpWrite.Write(buf[0:n]) if isSCLNodeCount < 2 { if string(buf) == ">" { //节点结束符表示又读取了一个节点 isSCLNodeCount++ } } if isSCLNodeCount == 2 { isSCLNodeCount = 99999 //当读取到SCL节点后,追加crc到新文件中,后续按每次1M内容读取并写入 tmpWrite.Write([]byte(`` + crccode + ``)) buf = make([]byte, 1024) } } tmpWrite.Flush() tmpFileHander.Close() xmlhander.Close() ferr := os.Rename(tmpFileSCD, strings.ReplaceAll(tmpFileSCD, ".tmp", "")) if ferr != nil { logger.Logger.Error(ferr) } //更新该scd的签出crc标识 sqlUpSCL := "update t_scd_scl set out_rt_crc=? where station_id=? and path=?" _, err = db.Raw(sqlUpSCL, crccode, stationid, "."+scdPath).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlUpSCL, []interface{}{1, flowRunID})) return err } } } else { //判断是否是更新还是新节点提交 rowset := []orm.Params{} 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=?" _, err := db.Raw(sql, nodeCode, flow_run_id).Values(&rowset) if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sql, []interface{}{nodeCode, flow_run_id})) return err } if len(rowset) == 0 { //无效的流程ID return errors.New("无效的流程ID") } else { //nodeid := tools.IsEmpty(rowset[0]["id"]) node_type := tools.IsEmpty(rowset[0]["node_type"]) //新提交节点流转数据 //当前流程被驳回或者结束时,根据flow_run_id更新流程信息 db.Begin() sqlInstUp := "update t_sys_flow_run set deal_state=?,finish_date=? where id=?" sqlJob := "insert into t_base_job_content(job_type,job_content,CREATED_BY)values(?,?,?)" 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=?)" 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=?" if opt == 1 { if node_type == "end" || nextNodeInfo == nil { //没有后续节点时,或者节点类型为end时,结束流程 _, err = db.Raw(sqlInstUp, 1, tools.NowTime(), flow_run_id).Exec() } else { //更新流程状态。主要处理上一步是驳回时把状态更改为2的情况 _, err = db.Raw(sqlInstUp, 0, nil, flow_run_id).Exec() } } else if opt == 0 { //被驳回时 _, err = db.Raw(sqlInstUp, 2, nil, flow_run_id).Exec() } if err != nil { db.Rollback() log.Println(err) log.Println(sqlInstUp) return err } // if opt == 1 { //通过执行sqlJob,并获取到jobid sqlresult, err := db.Raw(sqlJob, "", content, uid).Exec() if err != nil { log.Println(err) db.Rollback() return err } jobid, _ := sqlresult.LastInsertId() //执行sqlNodeUp更新当前节点信息 sqlresult, err = db.Raw(sqlNodeUp, jobid, 1, 1, uid, "", flow_run_id, nodeCode).Exec() if err != nil { log.Println(err) db.Rollback() return err } //执行sqlNode,添加下一下处理节点 if nextNodeInfo != nil { nextNodecode := tools.IsEmpty(nextNodeInfo["node_code"]) _, err = db.Raw(sqlNode, flow_run_id, 0, 0, 0, 0, uid, nextNodecode).Exec() if err != nil { log.Println(err) db.Rollback() return err } //发送通知提醒 nextNodeId, _ := strconv.Atoi(tools.IsEmpty(nextNodeInfo["id"])) stationidint, _ := strconv.Atoi(stationid) go SendFlowNotice(c.GetUserInfo(), stationidint, int32(nextNodeId)) } else { //流程结束 //db.Raw("select scd_name,scd_path from t_sys_flow_run where id=?", flow_run_id).Values(&rowset) flow_run_id_int, _ := strconv.Atoi(flow_run_id) flowruninfo, _ := c.GetFlowRunInfo(flow_run_id_int) startUserID, _ := strconv.Atoi(tools.IsEmpty(flowruninfo["CREATED_BY"])) stationidint, _ := strconv.Atoi(stationid) //如果是文件签入时,做以下处理 if flow_type == "scdin" { //解除当前站下的所有scd锁定状态 sdcMgr.SetLock(stationid, "", 0) sdcMgr.SetStateByNamePath(tools.IsEmpty(flowruninfo["scd_name"]), tools.IsEmpty(flowruninfo["scd_path"]), 1) sdcMgr.UpdateScdVersion(0, stationid, tools.IsEmpty(flowruninfo["scd_name"]), tools.IsEmpty(flowruninfo["scd_path"])) go SendNotice(c.GetUserInfo(), stationidint, NoticeType_Notice, "SCD签入审批完成", "你的SCD签入已完成所有审批", int32(startUserID)) } else { go SendNotice(c.GetUserInfo(), stationidint, NoticeType_Notice, "SCD签出审批完成", "你的SCD签出已完成所有审批", int32(startUserID)) } logger.Logger.Debug(fmt.Sprintf("======用户的%s签入锁定解除:%s", c.GetUserName(), checkinLockKey)) global.CheckingInInfo.Delete(checkinLockKey) } } else { //驳回执行sqlNode,驳回时,节点没有关联的内容需要保存 _, err = db.Raw(sqlNodeUp, 0, 1, 0, uid, "驳回", flow_run_id, nodeCode).Exec() if err != nil { log.Println(err) db.Rollback() return err } //执行sqlNode,添加下一处理节点(开始节点) //获取流程的开始节点 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" _, err = db.Raw(tmpSql, flow_run_id).Values(&rowset) if err != nil { log.Println(err) db.Rollback() return err } firstNodecode := tools.IsEmpty(rowset[0]["node_code"]) _, err = db.Raw(sqlNode, flow_run_id, 0, 0, 0, 0, uid, firstNodecode).Exec() if err != nil { log.Println(err) db.Rollback() return err } startUserid, _ := strconv.Atoi(tools.IsEmpty(rowset[0]["startUserid"])) stationidint, _ := strconv.Atoi(stationid) go SendNotice(c.GetUserInfo(), stationidint, NoticeType_Notice, "SCD签入(出)被驳回", "你的SCD签入(出)审批被驳回", int32(startUserid)) } db.Commit() } } return nil } //scd签入解析失败处理 func (c *Flow) CheckInFail(stationid string) { checkinLockKey := fmt.Sprintf("%s%s", stationid, "scdin") //签入锁定状态key //解除该站的签入锁定 global.CheckingInInfo.Delete(checkinLockKey) //清除流程数据 db := orm.NewOrm() 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() db.Raw("delete from t_sys_flow_run where station_id=? and deal_state=0", stationid).Exec() } func (c *Flow) GetNodeDealInfo(flow_type, flow_run_id, stationid, nodeCode string) (orm.Params, error) { db := orm.NewOrm() rowset := []orm.Params{} 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=? " _, err := db.Raw(sql, flow_run_id, nodeCode).Values(&rowset) if err != nil { log.Println(err) return nil, err } if len(rowset) == 0 { return nil, errors.New("无效的节点CODE") } return rowset[0], nil } func (c *Flow) GetFlowRunInfo(flow_run_id int) (orm.Params, error) { db := orm.NewOrm() rowset := []orm.Params{} sql := "select t.* from t_sys_flow_run t where t.id=? " _, err := db.Raw(sql, flow_run_id).Values(&rowset) if err != nil { log.Println(err) return nil, err } if len(rowset) == 0 { return nil, errors.New("无效的流程ID") } return rowset[0], nil } //获取最后一次有效签出的工作内容信息 func (c *Flow) GetLastCheckoutWorkbook(stationid string) (string, error) { db := orm.NewOrm() rowset := []orm.Params{} 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' " _, err := db.Raw(sql, stationid).Values(&rowset) if err != nil { log.Println(err) return "", err } if len(rowset) == 0 { return "", errors.New("没有签出的记录") } content := tools.IsEmpty(rowset[0]["job_content"]) return content, nil } //获取指定scd文件签入时的工作内容信息 func (c *Flow) GetCheckinWorkbook(stationid, scd_id, scdname, scdpath string) (orm.Params, error) { db := orm.NewOrm() rowset := []orm.Params{} para := []interface{}{} sql := `` if scd_id != "" { 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, (select id from t_scd_diff_compare where source_id=s.id) compid 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 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 and t.station_id=? and s.id=? and t1.work_book_id=c.id and t.flow_id=(select id from t_sys_flow where flow_type='scdin') order by t1.id desc limit 1` para = append(para, stationid) para = append(para, scd_id) } else { 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, (select id from t_scd_diff_compare where source_id=s.id) compid 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 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 and t.station_id=? and t.scd_name=? and t.scd_path=? and t1.work_book_id=c.id and t.flow_id=(select id from t_sys_flow where flow_type='scdin') order by t1.id desc limit 1` para = append(para, stationid) para = append(para, scdname) para = append(para, scdpath) } _, err := db.Raw(sql, para).Values(&rowset) if err != nil { log.Println(err) return nil, err } if len(rowset) == 0 { return nil, errors.New("没有签出的记录") } return rowset[0], nil }