Browse Source

新增模型装置分组后台功能

liling 1 year ago
parent
commit
71dab18e22

+ 31 - 1
service/models/bo/check_sys_model.go

@@ -118,6 +118,10 @@ func (c *SysCheckModelMgr) Save() (err error) {
 			lm.Model.ModelId = int(newid)
 			lm.SetUserInfo(c.GetUserInfo())
 			lm.Save()
+			//保存装置分组
+			bgm := new(SysCheckModelIedtypeGroupMgr)
+			bgm.Model = T_data_model_iedtype_group{ModelId: int(newid)}
+			bgm.Save(c.Model.RelationJson)
 			if c.Model.RelationJson != "" {
 				m2 := new(SysCheckModelIedRelationMgr)
 				m2.SetUserInfo(c.GetUserInfo())
@@ -199,9 +203,25 @@ func (c *SysCheckModelMgr) Save() (err error) {
 			if modelJson["nodes"] != nil {
 				nodes := modelJson["nodes"].([]interface{})
 				iedtypes := []string{}
+				groupIedTypes := map[string]int{}
 				for _, ritem := range nodes {
-					properties := ritem.(map[string]interface{})["properties"].(map[string]interface{})
+					ritem2 := ritem.(map[string]interface{})
+					nodetype := tools.IsEmpty(ritem2["type"])
+					if nodetype == "group" {
+						//装置分组
+						childrens := ritem2["children"]
+						if childrens != nil {
+							for _, ci := range childrens.([]string) {
+								groupIedTypes[ci] = 1
+							}
+						}
+					}
+					properties := ritem2["properties"].(map[string]interface{})
 					tmp := tools.IsEmpty(properties["ied_type"])
+					if groupIedTypes[tmp] == 1 {
+						//过滤属于分组中的装置类型
+						continue
+					}
 					if arrayex.IndexOf(iedtypes, tmp) > 0 {
 						//装置类型重复了
 						return errors.New("装置类型" + tmp + "不能重复引用")
@@ -231,6 +251,9 @@ func (c *SysCheckModelMgr) Save() (err error) {
 						m1 := new(SysCheckModelIedFuncMgr)
 						m1.Model = T_data_model_func_def{ModelId: c.Model.Id, IedType: item}
 						m1.Delete()
+						bgm := new(SysCheckModelIedtypeGroupMgr)
+						bgm.Model = T_data_model_iedtype_group{ModelId: c.Model.Id}
+						bgm.Delete(item)
 					}
 				}
 			}
@@ -290,6 +313,9 @@ func (c *SysCheckModelMgr) Delete() (err error) {
 		m3 := new(SysCheckModelIedFuncMgr)
 		m3.Model = T_data_model_func_def{ModelId: c.Model.Id}
 		m3.Delete()
+		bgm := new(SysCheckModelIedtypeGroupMgr)
+		bgm.Model = T_data_model_iedtype_group{ModelId: c.Model.Id}
+		bgm.Delete()
 		dblog.Description = fmt.Sprintf("删除%s%s成功", sysCheckModelDesc, c.Model.ModelName)
 		dblog.Success2()
 	}
@@ -336,6 +362,10 @@ func (c *SysCheckModelMgr) Copy(modelid int) (error, int) {
 			dblog.Fail2()
 			return err, 0
 		}
+		//复制装置类型分组数据
+		bgm := new(SysCheckModelIedtypeGroupMgr)
+		bgm.Model = T_data_model_iedtype_group{ModelId: modelid}
+		bgm.Copy(int(newid))
 		//复制功能及端子信息
 		m3 := new(SysCheckModelIedFuncMgr)
 		m3.SetUserInfo(c.GetUserInfo())

+ 9 - 1
service/models/bo/check_sysmodel_ied_func.go

@@ -260,11 +260,19 @@ func (c *SysCheckModelIedFuncMgr) Imp(param map[string]interface{}) (bool, error
 	fcdaMap := map[string]int{}
 	fcdaMgr := new(SysCheckModelIedFuncFcdaMgr)
 	fcdaMgr.Model.ModelId = modelId
+	//获取装置分组信息
+	bgm := new(SysCheckModelIedtypeGroupMgr)
+	bgm.Model = T_data_model_iedtype_group{ModelId: modelId}
+	groupList := bgm.List()
 	for _, row := range datalist {
-		ied_type := tools.IsEmpty(row[2])
+		ied_type := strings.ToUpper(tools.IsEmpty(row[2]))
 		if ied_type == "" {
 			return false, errors.New(fmt.Sprintf("第%d行:装置类型编码不能为空", i))
 		}
+		//判断装置类型是否是合并分组类型,如PLC由PL+CL合并
+		if groupList != nil && groupList[ied_type] != "" {
+			ied_type = groupList[ied_type]
+		}
 		if !strings.Contains(modelInfoIedTypes, ","+ied_type+",") {
 			//模型中未发现该装置类型
 			continue

+ 2 - 2
service/models/bo/check_sysmodel_ied_func_fcda.go

@@ -192,12 +192,12 @@ func (c *SysCheckModelIedFuncFcdaMgr) GetList(funcids ...[]string) ([]orm.Params
 	outsql := ""
 	desc := ""
 	if c.Model.Inorout == "接收" {
-		outsql = ",(select from_fcda_id from t_data_model_fcda_ref where model_id=? and to_fcda_id=t.id) from_fcda_id"
+		outsql = ",(select from_fcda_id from t_data_model_fcda_ref where model_id=? and to_fcda_id=t.id and from_func_id=t1.id) from_fcda_id"
 		sqlParamters = append(sqlParamters, c.Model.ModelId)
 		desc = " from_fcda_id," //已有关联关系的端子排在前面
 	}
 	if c.Model.Inorout == "输出" {
-		outsql = ",(select to_fcda_id from t_data_model_fcda_ref where model_id=? and from_fcda_id=t.id) to_fcda_id"
+		outsql = ",(select to_fcda_id from t_data_model_fcda_ref where model_id=? and from_fcda_id=t.id and to_func_id=t1.id) 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=? "

+ 117 - 0
service/models/bo/check_sysmodel_iedtype_group.go

@@ -0,0 +1,117 @@
+package bo
+
+import (
+	"encoding/json"
+	"scd_check_tools/logger"
+	"scd_check_tools/tools"
+
+	"github.com/astaxie/beego/orm"
+)
+
+type T_data_model_iedtype_group struct {
+	Id           int `orm:"pk"`
+	ModelId      int // '模型ID' ,
+	IedType      string
+	ChildrenType string
+}
+
+//内置检测模型-装置分组管理
+type SysCheckModelIedtypeGroupMgr struct {
+	Model T_data_model_iedtype_group
+	DeviceBaseModel
+}
+
+func init() {
+	orm.RegisterModel(new(T_data_model_iedtype_group))
+}
+
+func (c *SysCheckModelIedtypeGroupMgr) Delete(iedtype ...string) {
+	db := orm.NewOrm()
+	if c.Model.Id > 0 {
+		db.Delete(&c.Model)
+		return
+	}
+	if c.Model.ModelId > 0 {
+		if len(iedtype) > 0 {
+			db.Raw("delete from t_data_model_iedtype_group where model_id=? and (ied_type=? or children_type=?)", c.Model.ModelId, iedtype[0], iedtype[0]).Exec()
+			return
+		}
+		if c.Model.IedType != "" {
+			db.Raw("delete from t_data_model_iedtype_group where model_id=? and ied_type=?", c.Model.ModelId, c.Model.IedType).Exec()
+			return
+		}
+		db.Raw("delete from t_data_model_iedtype_group where model_id=?", c.Model.ModelId).Exec()
+	}
+}
+
+func (c *SysCheckModelIedtypeGroupMgr) Copy(new_modelid int) {
+	db := orm.NewOrm()
+	db.Raw("insert into t_data_model_iedtype_group(model_id,ied_type,children_type)select ?,ied_type,children_type from t_data_model_iedtype_group where model_id=?", new_modelid, c.Model.Id).Exec()
+}
+
+func (c *SysCheckModelIedtypeGroupMgr) Save(jsonstr string) {
+	if jsonstr == "" {
+		return
+	}
+	modelJson := map[string]interface{}{}
+	err := json.Unmarshal([]byte(jsonstr), &modelJson)
+	if err != nil {
+		return
+	}
+	if modelJson["nodes"] != nil {
+		db := orm.NewOrm()
+		nodes := modelJson["nodes"].([]interface{})
+		groupIedTypes := map[string]string{}
+		for _, ritem := range nodes {
+			ritem2 := ritem.(map[string]interface{})
+			nodetype := tools.IsEmpty(ritem2["type"])
+			if nodetype != "group" {
+				continue
+			}
+			childrens := ritem2["children"]
+			if childrens == nil {
+				continue
+			}
+			properties := ritem2["properties"].(map[string]interface{})
+			gtype := tools.IsEmpty(properties["ied_type"])
+			if gtype == "" {
+				continue
+			}
+			for _, ci := range childrens.([]string) {
+				groupIedTypes[ci] = gtype
+			}
+		}
+		for _, ritem := range nodes {
+			ritem2 := ritem.(map[string]interface{})
+			nodetype := tools.IsEmpty(ritem2["type"])
+			if nodetype == "group" {
+				continue
+			}
+			properties := ritem.(map[string]interface{})["properties"].(map[string]interface{})
+			iedtype := tools.IsEmpty(properties["ied_type"])
+			if iedtype == "" || groupIedTypes[iedtype] == "" {
+				continue
+			}
+			db.Raw("insert into t_data_model_iedtype_group(model_id,ied_type,children_type)values(?,?,?)", c.Model.ModelId, groupIedTypes[iedtype], iedtype).Exec()
+		}
+	}
+}
+
+func (c *SysCheckModelIedtypeGroupMgr) List() map[string]string {
+	if c.Model.ModelId == 0 {
+		return nil
+	}
+	result := map[string]string{}
+	db := orm.NewOrm()
+	rowset := []orm.Params{}
+	_, err := db.Raw("select ied_type,children_type from t_data_model_iedtype_group where model_id=?", c.Model.ModelId).Values(&rowset)
+	if err != nil {
+		logger.Logger.Error(err)
+		return nil
+	} else {
+		for _, row := range rowset {
+			result[tools.IsEmpty(row["children_type"])] = tools.IsEmpty(row["ied_type"])
+		}
+	}
+	return result
+}

+ 165 - 65
service/models/bo/checktools_area.go

@@ -634,10 +634,25 @@ func (c *CheckAreaMgr) CheckIedFcda() error {
 			iedlst := filterAreaIeds(ied_type, vol, s1)
 			for _, ied := range iedlst {
 				iedname := tools.IsEmpty(ied["ied_name"])
+				iedObj := scdNodeMgr.GetIed(scdXmlObj, fmt.Sprintf("%d", c.ScdId), iedname)
+				iedObjDesc := ""
+				if iedObj != nil {
+					iedObjDesc = iedObj.Desc
+				} else {
+					logger.Logger.Error(fmt.Sprintf("信号接收装置%s未找到!", iedname))
+				}
 				extreflist := getIedExtRefs(iedname)
 				for outiedname, refrow := range outiedlist {
-					iedObj := scdNodeMgr.GetIed(scdXmlObj, fmt.Sprintf("%d", c.ScdId), iedname)
 					outIedObj := scdNodeMgr.GetIed(scdXmlObj, fmt.Sprintf("%d", c.ScdId), outiedname)
+					outIedObjDesc := ""
+					if outIedObj == nil {
+						logger.Logger.Error(fmt.Sprintf("信号输出装置%s未找到!", outiedname))
+					} else {
+						outIedObjDesc = outIedObj.Desc
+					}
+					if iedObj == nil && outIedObj == nil {
+						continue
+					}
 					outiedFcdaList := getIedFcdas(outiedname) //输入装置的信号输出端子
 					//检查是否有错误和缺失的端子
 					hasYaoXinFunc := false //是否具备遥信功能
@@ -666,17 +681,12 @@ func (c *CheckAreaMgr) CheckIedFcda() error {
 							}
 						}
 						if !funcExist {
-							iedObj := scdNodeMgr.GetIed(scdXmlObj, fmt.Sprintf("%d", c.ScdId), iedname)
-							outIedObj := scdNodeMgr.GetIed(scdXmlObj, fmt.Sprintf("%d", c.ScdId), outiedname)
-							parse_result := ""
-							if !funcExist {
-								parse_result = fmt.Sprintf("间隔%s的装置%s缺失端子%s", area_name, iedname, extref_name)
-							}
+							parse_result := fmt.Sprintf("间隔%s的装置%s缺失端子%s", area_name, iedname, extref_name)
 							re := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result,
 								"ied_name":      iedname,
-								"ied_desc":      iedObj.Desc,
+								"ied_desc":      iedObjDesc,
 								"out_ied_name":  outiedname,
-								"out_ied_desc":  outIedObj.Desc,
+								"out_ied_desc":  outIedObjDesc,
 								"fcda_desc":     extref_name,
 								"fcda_addr":     "",
 								"out_fcda_desc": fcda_name,
@@ -941,27 +951,32 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 		volMap["low"] = volRows[len(volRows)-1]["vol"].(string) //低压电压等级
 	}
 
-	var getIedByDesc = func(iedinfo map[string]orm.Params, desc string) (string, string) {
+	var getIedByDesc = func(iedinfo map[string]orm.Params, iedtpye string, desc string) ([]string, []string) {
 		scdParseMgr := new(ScdParse)
 		scdXmlObj, _ := scdParseMgr.GetScdXmlObjectBySCDID(tools.IsEmpty(c.ScdId))
+		r1 := []string{}
+		r2 := []string{}
 		for vn, row := range iedinfo {
-			v := tools.IsEmpty(row["ied_desc"])
-			if v == "" {
-				if scdXmlObj == nil {
-					return "", ""
+			if strings.HasPrefix(vn, iedtpye) {
+				v := tools.IsEmpty(row["ied_desc"])
+				if v == "" {
+					if scdXmlObj == nil {
+						continue
+					}
+					scdNode := new(ScdNode)
+					ied := scdNode.GetIed(scdXmlObj, "", vn)
+					if ied == nil {
+						continue
+					}
+					v = ied.Desc
 				}
-				scdNode := new(ScdNode)
-				ied := scdNode.GetIed(scdXmlObj, "", vn)
-				if ied == nil {
-					return "", ""
+				if strings.Contains(v, desc) {
+					r1 = append(r1, v)
+					r2 = append(r2, vn)
 				}
-				v = ied.Desc
-			}
-			if strings.Contains(v, desc) {
-				return v, vn
 			}
 		}
-		return "", ""
+		return r1, r2
 	}
 	//判断是否将各电压等级的保护装置合并还是分开的间隔
 	//如果存在高中低压的保护装置,则说明是分开的主变间隔
@@ -1001,16 +1016,28 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 		insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "P", "T"))
 		//判断间隔是否需要包含差动装置
 		if strings.Contains(iedtypes, "PT#C") {
-			ieddesc, iedname := getIedByDesc(ieds, "差动")
-			if strings.Contains(ieddesc, "差动") {
-				insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, iedname, "P", "TC"))
+			_, iedname := getIedByDesc(ieds, "PT", "差动")
+			if len(iedname) > 0 {
+				for _, in := range iedname {
+					tmpIednameParts := scdParseMgr.ParseIedName(in)
+					if tmpIednameParts[6] == iednameParts[6] && tmpIednameParts[7] == iednameParts[7] {
+						insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, in, "P", "TC"))
+						break
+					}
+				}
 			}
 		}
 		//判断间隔是否需要包含本体保护装置
 		if strings.Contains(iedtypes, "PT#0") {
-			ieddesc, iedname := getIedByDesc(ieds, "本体")
-			if strings.Contains(ieddesc, "本体") {
-				insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, iedname, "P", "T0"))
+			_, iedname := getIedByDesc(ieds, "PT", "本体")
+			if len(iedname) > 0 {
+				for _, in := range iedname {
+					tmpIednameParts := scdParseMgr.ParseIedName(in)
+					if tmpIednameParts[6] == iednameParts[6] && tmpIednameParts[7] == iednameParts[7] {
+						insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, in, "P", "T0"))
+						break
+					}
+				}
 			}
 		}
 		//合智一体IMT/MIT,分高中低压
@@ -1020,8 +1047,7 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 		for _, r := range h {
 			inAreaIedName = tools.IsEmpty(r["ied_name"])
 			tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName)
-			lastChar := tmpIednameParts[7]
-			if lastChar == iednameParts[7] {
+			if tmpIednameParts[6] == iednameParts[6] && tmpIednameParts[7] == iednameParts[7] {
 				insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "IM", "T"))
 			}
 		}
@@ -1031,8 +1057,7 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 		for _, r := range h {
 			inAreaIedName = tools.IsEmpty(r["ied_name"])
 			tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName)
-			lastChar := tmpIednameParts[7]
-			if lastChar == iednameParts[7] {
+			if tmpIednameParts[6] == iednameParts[6] && tmpIednameParts[7] == iednameParts[7] {
 				insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "MI", "T"))
 			}
 		}
@@ -1043,8 +1068,7 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 				//高压侧,AB套必须与PT装置相同
 				inAreaIedName = tools.IsEmpty(r["ied_name"])
 				tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName)
-				lastChar := tmpIednameParts[7]
-				if lastChar == iednameParts[7] {
+				if tmpIednameParts[6] == iednameParts[6] && tmpIednameParts[7] == iednameParts[7] {
 					insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "I", "E"))
 				}
 			}
@@ -1053,7 +1077,7 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 				inAreaIedName = tools.IsEmpty(r["ied_name"])
 				tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName)
 				lastChar := tmpIednameParts[7]
-				if lastChar == "" || lastChar == iednameParts[7] {
+				if tmpIednameParts[6] == iednameParts[6] && (lastChar == "" || tmpIednameParts[7] == iednameParts[7]) {
 					insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "I", "E"))
 				}
 			}
@@ -1065,11 +1089,23 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 		for _, r := range h {
 			inAreaIedName = tools.IsEmpty(r["ied_name"])
 			tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName)
-			lastChar := tmpIednameParts[7]
-			if lastChar == iednameParts[7] {
+			if tmpIednameParts[6] == iednameParts[6] && tmpIednameParts[7] == iednameParts[7] {
 				insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "M", "T"))
 			}
 		}
+		//是否包含本体合并单元
+		if strings.Contains(iedtypes, "MT#0") {
+			_, iedname := getIedByDesc(ieds, "MT", "本体")
+			if len(iedname) > 0 {
+				for _, in := range iedname {
+					tmpIednameParts := scdParseMgr.ParseIedName(in)
+					if tmpIednameParts[6] == iednameParts[6] && tmpIednameParts[7] == iednameParts[7] {
+						insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, in, "M", "T"))
+						break
+					}
+				}
+			}
+		}
 		//测控装置CT分高中低压侧,且可能是多套合并单元MT共用,既不分AB套
 		h, m, l = c.getIedListByVol("CT", ieds, volMap)
 		h = append(h, m...)
@@ -1080,10 +1116,23 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 			lastChar := tmpIednameParts[7]
 			tmpVol := tmpIednameParts[3] + tmpIednameParts[4]
 			//高中低压电压等级相同的
-			if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && (lastChar == "" || lastChar == iednameParts[7]) {
+			if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && tmpIednameParts[6] == iednameParts[6] && (lastChar == "" || lastChar == iednameParts[7]) {
 				insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "C", "T"))
 			}
 		}
+		//是否包含本体测控装置
+		if strings.Contains(iedtypes, "CT#0") {
+			_, iedname := getIedByDesc(ieds, "CT", "本体")
+			if len(iedname) > 0 {
+				for _, in := range iedname {
+					tmpIednameParts := scdParseMgr.ParseIedName(in)
+					if tmpIednameParts[6] == iednameParts[6] && tmpIednameParts[7] == iednameParts[7] {
+						insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, in, "C", "T"))
+						break
+					}
+				}
+			}
+		}
 		//智能终端(IB:开关\IT:分支\IF:分段)分高中低压侧
 		h, m, l = c.getIedListByVol("IB", ieds, volMap)
 		h = append(h, m...)
@@ -1094,10 +1143,25 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 			lastChar := tmpIednameParts[7]
 			tmpVol := tmpIednameParts[3] + tmpIednameParts[4]
 			//高中低压电压等级相同的
-			if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && (lastChar == "" || lastChar == iednameParts[7]) {
+			if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && tmpIednameParts[6] == iednameParts[6] && (lastChar == "" || lastChar == iednameParts[7]) {
 				insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "I", "B"))
 			}
 		}
+		//是否包含本体测控装置
+		if strings.Contains(iedtypes, "IT#0") {
+			for n, row := range ieds {
+				if strings.HasPrefix(n, "IT") || strings.HasPrefix(n, "IB") || strings.HasPrefix(n, "IF") {
+					ieddesc := tools.IsEmpty(row["ied_desc"])
+					if strings.Contains(ieddesc, "本体") {
+						tmpIednameParts := scdParseMgr.ParseIedName(n)
+						if tmpIednameParts[6] == iednameParts[6] && tmpIednameParts[7] == iednameParts[7] {
+							insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, n, "I", "T"))
+							break
+						}
+					}
+				}
+			}
+		}
 		h, m, l = c.getIedListByVol("IT", ieds, volMap)
 		h = append(h, m...)
 		h = append(h, l...)
@@ -1107,7 +1171,7 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 			lastChar := tmpIednameParts[7]
 			tmpVol := tmpIednameParts[3] + tmpIednameParts[4]
 			//高中低压电压等级相同的
-			if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && (lastChar == "" || lastChar == iednameParts[7]) {
+			if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && tmpIednameParts[6] == iednameParts[6] && (lastChar == "" || lastChar == iednameParts[7]) {
 				insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "I", "T"))
 			}
 		}
@@ -1120,7 +1184,7 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 			lastChar := tmpIednameParts[7]
 			tmpVol := tmpIednameParts[3] + tmpIednameParts[4]
 			//高中低压电压等级相同的
-			if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && (lastChar == "" || lastChar == iednameParts[7]) {
+			if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && tmpIednameParts[6] == iednameParts[6] && (lastChar == "" || lastChar == iednameParts[7]) {
 				insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "I", "F"))
 			}
 		}
@@ -1131,7 +1195,7 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 			inAreaIedName = tools.IsEmpty(r["ied_name"])
 			tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName)
 			lastChar := tmpIednameParts[7]
-			if lastChar == iednameParts[7] {
+			if tmpIednameParts[6] == iednameParts[6] && lastChar == iednameParts[7] {
 				insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "P", "M"))
 				//MM装置
 				mmIedName := c.getMMName(tmpIednameParts, ieds, iednameParts[7])
@@ -1144,7 +1208,7 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 			inAreaIedName = tools.IsEmpty(r["ied_name"])
 			tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName)
 			lastChar := tmpIednameParts[7]
-			if lastChar == "" || lastChar == iednameParts[7] {
+			if tmpIednameParts[6] == iednameParts[6] && (lastChar == "" || lastChar == iednameParts[7]) {
 				insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "P", "M"))
 				//MM装置
 				mmIedName := c.getMMName(tmpIednameParts, ieds, iednameParts[7])
@@ -1164,10 +1228,10 @@ func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Para
 //vol:电压等级
 func (c *CheckAreaMgr) pL(modelid int, vol, iedtypes string, ieds map[string]orm.Params) {
 	scdParseMgr := new(ScdParse)
-	//scdNodeMgr := new(ScdNode)
+	scdNodeMgr := new(ScdNode)
 	db := orm.NewOrm()
 
-	//scdXmlObject, _ := scdParseMgr.GetScdXmlObjectBySCDID(tools.IsEmpty(c.ScdId))
+	scdXmlObj, _ := scdParseMgr.GetScdXmlObjectBySCDID(tools.IsEmpty(c.ScdId))
 	for _, row := range ieds {
 		if tools.IsEmpty(row["vol"]) != vol || tools.IsEmpty(row["ied_type"]) != "P" || tools.IsEmpty(row["p_type"]) != "L" {
 			continue
@@ -1176,6 +1240,7 @@ func (c *CheckAreaMgr) pL(modelid int, vol, iedtypes string, ieds map[string]orm
 		mmIedName := ""
 		pl_iedname := tools.IsEmpty(row["ied_name"])
 		iednameParts := scdParseMgr.ParseIedName(pl_iedname)
+
 		//添加间隔数据
 		dbdata := T_data_check_area{
 			ModelId:  modelid,
@@ -1200,34 +1265,60 @@ func (c *CheckAreaMgr) pL(modelid int, vol, iedtypes string, ieds map[string]orm
 				pmIedName = inAreaIedName
 				if mmIedName == "" {
 					insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, ty[0:1], ty[1:2]))
-					pmIedNameParts := scdParseMgr.ParseIedName(pmIedName)
+					//pmIedNameParts := scdParseMgr.ParseIedName(pmIedName)
 					//使用PM装置的名称去定义MM的名称
 					ty = "MM"
-					inAreaIedName = c.getMMName(pmIedNameParts, ieds, iednameParts[7])
+					inAreaIedName = c.getMMName(iednameParts, ieds, iednameParts[7])
 					mmIedName = inAreaIedName
 				}
 			} else if ty == "MM" {
 				if pmIedName != "" && mmIedName == "" {
-					pmIedNameParts := scdParseMgr.ParseIedName(pmIedName)
+					//pmIedNameParts := scdParseMgr.ParseIedName(pmIedName)
 					//使用PM装置的名称去定义MM的名称
-					inAreaIedName = c.getMMName(pmIedNameParts, ieds, iednameParts[7])
+					inAreaIedName = c.getMMName(iednameParts, ieds, iednameParts[7])
 					mmIedName = inAreaIedName
 				} else {
 					continue
 				}
+			} else if ty == "PLC" || ty == "PCL" {
+				//判断是否是保测一体的
+				if strings.Contains(iedtypes, "PLC") || strings.Contains(iedtypes, "PCL") {
+					no := []string{"PLC", "PCL", "PL"}
+					for _, n := range no {
+						plcIedName := n + iednameParts[3] + iednameParts[4] + iednameParts[5] + iednameParts[6] + iednameParts[7]
+						if scdNodeMgr.GetIed(scdXmlObj, "", plcIedName) != nil {
+							inAreaIedName = plcIedName
+							break
+						}
+					}
+				}
 			} else {
 				inAreaIedName = ty + iednameParts[3] + iednameParts[4] + iednameParts[5] + iednameParts[6] + iednameParts[7]
+				if ty == "IML" {
+					//查找IML装置是否存在,不存在就查找MIL开头装置做中合智一体装置
+					no := []string{"IML", "MIL"}
+					for _, n := range no {
+						milIedName := n + iednameParts[3] + iednameParts[4] + iednameParts[5] + iednameParts[6] + iednameParts[7]
+						if scdNodeMgr.GetIed(scdXmlObj, "", milIedName) != nil {
+							inAreaIedName = milIedName
+						}
+					}
+				}
 			}
 			if strings.Index("ABCDE", iednameParts[7]) > -1 {
 				//最后一位是字母则说明是AB套
 				switch ty {
 				case "CL":
-					//测控装置,先判断是否分了AB套,没有标识(ied名称的最后一位是否是字母)则说明是多套共用装置
-					clIedname := inAreaIedName + iednameParts[7]
-					iedObj := ieds[inAreaIedName]
-					if iedObj != nil {
-						//当前测控装置也分了AB套
-						inAreaIedName = clIedname
+					if strings.Contains(iedtypes, "PLC") || strings.Contains(iedtypes, "PCL") {
+						//不处理CL装置
+					} else {
+						//测控装置,先判断是否分了AB套,没有标识(ied名称的最后一位是否是字母)则说明是多套共用装置
+						clIedname := inAreaIedName + iednameParts[7]
+						iedObj := ieds[inAreaIedName]
+						if iedObj != nil {
+							//当前测控装置也分了AB套
+							inAreaIedName = clIedname
+						}
 					}
 					break
 				default:
@@ -1243,8 +1334,8 @@ func (c *CheckAreaMgr) pL(modelid int, vol, iedtypes string, ieds map[string]orm
 		}
 		//如果mm装置还未确定
 		if mmIedName == "" {
-			pmIedNameParts := scdParseMgr.ParseIedName(pmIedName)
-			inAreaIedName := c.getMMName(pmIedNameParts, ieds, iednameParts[7])
+			//pmIedNameParts := scdParseMgr.ParseIedName(pmIedName)
+			inAreaIedName := c.getMMName(iednameParts, ieds, iednameParts[7])
 			_, err = db.Raw(ins1 + fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "M", "M")).Exec()
 			if err != nil {
 				logger.Logger.Error(err)
@@ -1638,17 +1729,26 @@ func (c *CheckAreaMgr) cT(scdXmlObj *node_attr.SCL, scdNodeMgr *ScdNode, scdNode
 
 //根据参考ied name找出应该关联PM装置
 func (c *CheckAreaMgr) getPMName(iednameParts []string, ieds map[string]orm.Params) string {
-	tmpIedName := "PM" + iednameParts[3] + iednameParts[4] + iednameParts[5] + "1" + iednameParts[7]
-	iedObj := ieds[tmpIedName]
-	if iedObj != nil {
-	} else {
-		tmpIedName = "PM" + iednameParts[3] + iednameParts[4] + iednameParts[5] + "2" + iednameParts[7]
-		iedObj = ieds[tmpIedName]
+	//如果只有一个PM装置,则直接返回该 装置
+	pmLst := []string{}
+	for n, _ := range ieds {
+		if strings.HasPrefix(n, "PM") {
+			pmLst = append(pmLst, n)
+		}
+	}
+	if len(pmLst) == 1 {
+		return pmLst[0]
+	}
+	//暴力匹配
+	no := []string{"A", "B", "C", "D", "1", "2", "3", "4"}
+	for _, i := range no {
+		tmpIedName := "PM" + iednameParts[3] + iednameParts[4] + iednameParts[5] + i + iednameParts[7]
+		iedObj := ieds[tmpIedName]
 		if iedObj != nil {
 			return tmpIedName
 		}
 	}
-	return tmpIedName
+	return ""
 }
 
 //根据参考ied name找出应该关联MM装置

+ 3 - 0
service/models/bo/task_model.go

@@ -73,6 +73,9 @@ func (c *TaskModelMgr) Save(modelids []string) (err error) {
 			if err != nil {
 				break
 			}
+			if newid == 0 {
+				continue
+			}
 			c.Model.ModelId = newid
 			_, err = db.Insert(&c.Model)
 			if err != nil {