package bo import ( "errors" "fmt" "scd_check_tools/logger" "scd_check_tools/models/enum" "scd_check_tools/tools" "strconv" "strings" "github.com/astaxie/beego/orm" ) //系统内置模型-装置功能点端子管理 type T_data_model_func_fcda struct { Id int `orm:"pk"` ModelId int // '模型ID' , FuncId int // '功能ID', FcdaName string // 端子设计名称 FcdaMatchExp string // 端子匹配表达式 Svorgoose string Inorout string ReceiveIedType string Cr int // '创建人' , Ct string `orm:"-"` // '创建时间' , Ur int // '更新人' , Ut string `orm:"-"` // '更新时间' } //内置检测模型-装置功能点端子管理 type SysCheckModelIedFuncFcdaMgr struct { Model T_data_model_func_fcda DeviceBaseModel } var sysCheckModel_iedFuncFcdaDesc = "内置检测模型-装置功能点端子管理" func init() { orm.RegisterModel(new(T_data_model_func_fcda)) } //保存检测模型装置功能信息 func (c *SysCheckModelIedFuncFcdaMgr) Save() (id int, err error) { dblog := new(SystemLog) dblog.SetUserInfo(c.GetUserInfo()) dblog.Audittype = enum.AuditType_check_model dblog.Logtype = enum.LogType_Insert dblog.Eventtype = enum.OptEventType_Bus dblog.Eventlevel = enum.OptEventLevel_Hight db := orm.NewOrm() /* hasName, _, err := c.Exist() if err != nil { return 0, err } if hasName { return 0, errors.New("端子名称[" + c.Model.FcdaName + "]已存在") } */ newid := int64(0) if c.Model.Id > 0 { //编辑 _, err = db.Update(&c.Model) } else { //新增 newid, err = db.Insert(&c.Model) c.Model.Id = int(newid) } if err != nil { logger.Logger.Error(err) dblog.Description = fmt.Sprintf("保存%s信息失败:%s,操作数据:%+v", sysCheckModel_iedFuncFcdaDesc, err.Error(), c.Model) dblog.Fail2() return 0, err } else { dblog.Description = fmt.Sprintf("保存%s信息成功,操作数据:%+v", sysCheckModel_iedFuncFcdaDesc, c.Model) dblog.Success2() } return c.Model.Id, nil } func (c *SysCheckModelIedFuncFcdaMgr) Exist() (bool, int, error) { db := orm.NewOrm() if c.Model.FcdaName == "" { return false, 0, errors.New("端子设计名称不能为空") } rowset := []orm.Params{} _, err := db.Raw("select id from t_data_model_func_fcda where model_id=? and func_id=? and fcda_name=?", c.Model.ModelId, c.Model.FuncId, c.Model.FcdaName).Values(&rowset) if len(rowset) > 0 { findId := tools.IsEmpty(rowset[0]["id"]) findIdint, _ := strconv.Atoi(findId) if tools.IsEmpty(c.Model.Id) != findId { //端子名称重复 return true, c.Model.Id, nil } else { return false, findIdint, nil } } return false, 0, err } func (c *SysCheckModelIedFuncFcdaMgr) Copy(oldFuncId, newModelId, newFuncId int) error { db := orm.NewOrm() rowset := []orm.Params{} db.Raw("select * from t_data_model_func_fcda where model_id=? and func_id=?", c.Model.ModelId, oldFuncId).Values(&rowset) for _, row := range rowset { oldFcdaId, _ := strconv.Atoi(tools.IsEmpty(row["id"])) //复制端子数据 newFcda := T_data_model_func_fcda{ ModelId: newModelId, FuncId: newFuncId, FcdaName: tools.IsEmpty(row["fcda_name"]), FcdaMatchExp: tools.IsEmpty(row["fcda_match_exp"]), Svorgoose: tools.IsEmpty(row["svorgoose"]), Inorout: tools.IsEmpty(row["inorout"]), } newid, err := db.Insert(&newFcda) if err != nil { logger.Logger.Error(err) return err } db.Raw("update t_data_model_fcda_ref set from_func_id=?,from_fcda_id=? where model_id=? and from_func_id=? and from_fcda_id=?", newFuncId, newid, newModelId, oldFuncId, oldFcdaId).Exec() db.Raw("update t_data_model_fcda_ref set to_func_id=?,to_fcda_id=? where model_id=? and to_func_id=? and to_fcda_id=?", newFuncId, newid, newModelId, oldFuncId, oldFcdaId).Exec() } return nil } //自动建立端子关系 func (c *SysCheckModelIedFuncFcdaMgr) AutoRelation(modelid int, relationrow []T_data_model_func_def) { if len(relationrow) == 0 { return } fcdaMap := map[string]T_data_model_func_def{} for _, row := range relationrow { key := fmt.Sprintf("%s%s", row.IedType, row.FcdaName) if row.FuncName == "额定延时" { if strings.Index(row.FcdaName, "额定") > -1 || strings.Index(row.FcdaName, "延迟") > -1 || strings.Index(row.FcdaName, "延时") > -1 { key = fmt.Sprintf("%s%s", row.IedType, "额定延时") } } fcdaMap[key] = row } //获取装置分组信息 bgm := new(SysCheckModelIedtypeGroupMgr) bgm.Model = T_data_model_iedtype_group{ModelId: modelid} groupList := bgm.List() var getRealIedCode = func(ied_type string, groupList map[string]string) string { /* if groupList != nil && groupList[ied_type] != "" { ied_type = groupList[ied_type] } */ return ied_type } fr := new(SysCheckModelFcdaRalationMgr) fr.Model = T_data_model_fcda_ref{ModelId: modelid} noMatchList := map[string][]interface{}{} //未完全匹配的列表 for i, row := range relationrow { if row.ReceiveIedType != "" && strings.Index(row.Inorout, "输出") > -1 { tmplst := strings.Split(row.ReceiveIedType, ",") for _, item := range tmplst { key := fmt.Sprintf("%s%s", item, row.FcdaName) if row.FuncName == "额定延时" { if strings.Index(row.FcdaName, "额定") > -1 || strings.Index(row.FcdaName, "延迟") > -1 || strings.Index(row.FcdaName, "延时") > -1 { key = fmt.Sprintf("%s%s", item, "额定延时") } } if r, h := fcdaMap[key]; h { fr.Model.FromFcdaId = row.FuncFcdaId fr.Model.ToFcdaId = r.FuncFcdaId fr.Model.FromFuncId = row.Id fr.Model.ToFuncId = r.Id fr.Model.FromIedCode = getRealIedCode(row.IedType, groupList) fr.Model.ToIedCode = getRealIedCode(r.IedType, groupList) fr.Model.Goosesv = row.Svorgoose fr.Save() } else { //未完全匹配到端子时,查找其接收端的对侧装置为当前装置的端子 k := getRealIedCode(row.IedType, groupList) + "," + getRealIedCode(item, groupList) if _, h := noMatchList[k]; !h { tmp := map[string]interface{}{"no": i, "fromrow": row} noMatchList[k] = []interface{}{tmp} } else { noMatchList[k] = append(noMatchList[k], map[string]interface{}{"no": i, "fromrow": row}) } } } } } //未完全匹配到端子时,查找其接收端的对侧装置为当前装置的端子 for iedtype, obj := range noMatchList { ks := strings.Split(iedtype, ",") subNo := 0 //相差的行数 fromrow := T_data_model_func_def{} for i, row := range relationrow { outIedType := getRealIedCode(row.IedType, groupList) receiveIedType := getRealIedCode(row.ReceiveIedType, groupList) if outIedType == ks[1] && strings.Index(receiveIedType, ks[0]) > -1 { tmp := obj[0].(map[string]interface{}) no, _ := tmp["no"].(int) subNo = no - i //相差的行数 break } } logger.Logger.Debug(fmt.Sprintf("未建立关系的装置:%s,间隔行数:%d", iedtype, subNo)) for _, item := range obj { item2 := item.(map[string]interface{}) rowno := item2["no"].(int) - subNo if rowno < 0 || rowno > len(relationrow)-1 { logger.Logger.Debug(fmt.Sprintf("建立关系异常数据:%+v", item)) return } fromrow = item2["fromrow"].(T_data_model_func_def) r := relationrow[rowno] fr.Model.FromFcdaId = fromrow.FuncFcdaId fr.Model.ToFcdaId = r.FuncFcdaId fr.Model.FromFuncId = fromrow.Id fr.Model.ToFuncId = r.Id fr.Model.FromIedCode = getRealIedCode(fromrow.IedType, groupList) fr.Model.ToIedCode = getRealIedCode(r.IedType, groupList) fr.Model.Goosesv = fromrow.Svorgoose fr.Save() } } } //根据model中指定的id删除 func (c *SysCheckModelIedFuncFcdaMgr) Delete() (err error) { dblog := new(SystemLog) dblog.SetUserInfo(c.GetUserInfo()) dblog.Audittype = enum.AuditType_check_model dblog.Logtype = enum.LogType_Delete dblog.Eventtype = enum.OptEventType_Bus dblog.Eventlevel = enum.OptEventLevel_Hight db := orm.NewOrm() one := T_data_model_func_fcda{Id: c.Model.Id} if c.Model.Id > 0 { db.Read(&one) _, err = db.Raw("delete from t_data_model_func_fcda where id=?", c.Model.Id).Exec() } else if c.Model.FuncId > 0 { _, err = db.Raw("delete from t_data_model_func_fcda where model_id=? and func_id=?", c.Model.ModelId, c.Model.FuncId).Exec() } else { _, err = db.Raw("delete from t_data_model_func_fcda where model_id=? ", c.Model.ModelId).Exec() } if err != nil { logger.Logger.Error(err) dblog.Description = fmt.Sprintf("删除%s(%d)失败:%s", sysCheckModel_iedFuncFcdaDesc, c.Model.ModelId, err.Error()) dblog.Fail2() } else { fcdaMgr := new(SysCheckModelFcdaRalationMgr) fcdaMgr.Model = T_data_model_fcda_ref{ModelId: c.Model.ModelId} if c.Model.Id > 0 { fcdaMgr.Model.FromFcdaId = c.Model.Id } else if c.Model.FuncId > 0 { fcdaMgr.Model.FromFuncId = c.Model.FuncId } fcdaMgr.Delete() dblog.Description = fmt.Sprintf("删除%s(%d)成功", sysCheckModel_iedFuncFcdaDesc, c.Model.ModelId) dblog.Success2() if c.Model.Id > 0 { //判断端子是否全部删除 if one.FuncId > 0 { c.Model.ModelId = one.ModelId c.Model.FuncId = one.FuncId r, _ := c.GetList("") if len(r) == 0 { //删除功能定义数据 funcMgr := new(SysCheckModelIedFuncMgr) funcMgr.Model.Id = one.FuncId funcMgr.Delete(true) } } } else if c.Model.FuncId > 0 { funcMgr := new(SysCheckModelIedFuncMgr) funcMgr.Model.Id = c.Model.FuncId funcMgr.Delete(true) } else { funcMgr := new(SysCheckModelIedFuncMgr) funcMgr.Model.ModelId = c.Model.ModelId funcMgr.Delete(true) } } return err } func (c *SysCheckModelIedFuncFcdaMgr) One(id int) (T_data_model_func_fcda, error) { tmp := T_data_model_func_fcda{Id: id} db := orm.NewOrm() err := db.Read(&tmp) return tmp, err } //获取指定模型及装置功能下的端子信息列表 //funcids:指定的功能编码列表。可不传 func (c *SysCheckModelIedFuncFcdaMgr) GetList(refIedtype string, funcids ...[]string) ([]orm.Params, error) { o := orm.NewOrm() sqlParamters := []interface{}{c.Model.ModelId} outsql := "" desc := "" //获取装置分组信息 bgm := new(SysCheckModelIedtypeGroupMgr) bgm.Model = T_data_model_iedtype_group{ModelId: c.Model.ModelId} groupList := bgm.List() tmpAry := []string{} if len(groupList) > 0 { for k, v := range groupList { if v == refIedtype { tmpAry = append(tmpAry, k) } } if len(tmpAry) > 0 { tmpAry = append(tmpAry, refIedtype) //包含分组编码本身 refIedtype = strings.Join(tmpAry, "','") } } if c.Model.Inorout == "接收" { outsql = ",(select GROUP_CONCAT(from_fcda_id) from_fcda_id from t_data_model_fcda_ref where model_id=? and to_fcda_id=t.id and to_func_id=t1.id and from_ied_code in ('" + refIedtype + "')) from_fcda_id" sqlParamters = append(sqlParamters, c.Model.ModelId) desc = " from_fcda_id," //已有关联关系的端子排在前面 } if c.Model.Inorout == "输出" { outsql = ",(select GROUP_CONCAT(to_fcda_id) to_fcda_id from t_data_model_fcda_ref where model_id=? and from_fcda_id=t.id and from_func_id=t1.id and to_ied_code in ('" + refIedtype + "')) to_fcda_id" sqlParamters = append(sqlParamters, c.Model.ModelId) } sql := "select t.*,t1.func_name" + outsql + " from t_data_model_func_fcda t,t_data_model_func_def t1 where t1.id=t.func_id and t.model_id=? " if c.Model.FuncId > 0 { sql = sql + " and t.func_id=?" sqlParamters = append(sqlParamters, c.Model.FuncId) } if len(funcids) > 0 { sql = sql + " and t.func_id in(" + strings.Join(funcids[0], ",") + ")" } if c.Model.Svorgoose != "" { sql = sql + " and t.svorgoose=?" sqlParamters = append(sqlParamters, c.Model.Svorgoose) } if c.Model.Inorout != "" { sql = sql + " and t.inorout like ?" sqlParamters = append(sqlParamters, "%"+c.Model.Inorout+"%") } sql = sql + " order by " + desc + " t.id" if c.Model.Inorout == "输出" { sql = "select a.id,a.model_id,a.func_id,a.fcda_name,a.fcda_match_exp,a.svorgoose,a.inorout,ifnull(a.to_fcda_id,0) to_fcda_id,ifnull(ff1.fcda_name,'') to_fcda_name,ifnull(fd1.ied_type,'') to_ied_type from (" + sql + ") a left join t_data_model_func_fcda ff1 on a.to_fcda_id=ff1.id LEFT JOIN (select f1.id,case when f2.ied_type is null then f1.ied_type else f2.ied_type end ied_type from t_data_model_func_def f1 LEFT JOIN t_data_model_iedtype_group f2 on f1.ied_type=f2.children_type and f2.model_id=f1.model_id WHERE f1.model_id=?) fd1 on ff1.func_id=fd1.id" sqlParamters = append(sqlParamters, c.Model.ModelId) } else if c.Model.Inorout == "接收" { sql = "select a.id,a.model_id,a.func_id,a.fcda_name,a.fcda_match_exp,a.svorgoose,a.inorout,ifnull(a.from_fcda_id,0) from_fcda_id,ifnull(ff1.fcda_name,'') from_fcda_name,ifnull(fd1.ied_type,'') from_ied_type from (" + sql + ") a left join t_data_model_func_fcda ff1 on a.from_fcda_id=ff1.id LEFT JOIN (select f1.id,case when f2.ied_type is null then f1.ied_type else f2.ied_type end ied_type from t_data_model_func_def f1 LEFT JOIN t_data_model_iedtype_group f2 on f1.ied_type=f2.children_type and f2.model_id=f1.model_id WHERE f1.model_id=?) fd1 on ff1.func_id=fd1.id" sqlParamters = append(sqlParamters, c.Model.ModelId) } rowset := []orm.Params{} _, err := o.Raw(sql, sqlParamters).Values(&rowset) if err != nil { logger.Logger.Error(err) } return rowset, err }