Переглянути джерело

实现功能和端子检查

liling 1 рік тому
батько
коміт
781d14d586

+ 304 - 0
service/controllers/busAdminController.go

@@ -12,6 +12,9 @@ package controllers
 
 import (
 	"scd_check_tools/models/bo"
+	"scd_check_tools/tools"
+	"strconv"
+	"strings"
 )
 
 //业务管理服务
@@ -554,3 +557,304 @@ func (c *BusAdminController) SaveCheckAreaIedByAreaID() {
 	c.Data["json"] = c.ResultOK("", 0)
 	c.ServeJSON()
 }
+
+// @Summary 获取指定模型和装置类型的功能列表
+//	@Description  获取指定模型和装置类型的功能列表
+// 	@Tags         业务管理服务
+// 	@Accept       x-www-form-urlencoded
+// 	@Produce      json
+//	@Param 	model_id 	formData   int  	true 	"模型ID"
+//	@Param 	ied_type 	formData   string  	true 	"装置类型"
+// 	@Success     200    {object} ResultOK 成功
+// 	@Failure 	 500 	{object} ResultError  失败
+// @router /admin/model/function/list [get]
+func (c *BusAdminController) GetFuncListByIedType() {
+	modelid, _ := c.GetInt("model_id")
+	if modelid == 0 {
+		c.Data["json"] = c.ResultError("模型ID不能为空!")
+		c.ServeJSON()
+		return
+	}
+	ied_type := c.GetString("ied_type")
+	if ied_type == "" {
+		c.Data["json"] = c.ResultError("装置类型不能为空!")
+		c.ServeJSON()
+		return
+	}
+	obj := new(bo.SysCheckModelIedFuncMgr)
+	obj.SetUserInfo(c.GetCurrentUserInfo())
+	lst, err := obj.GetList(modelid, ied_type)
+	if err != nil {
+		c.Data["json"] = c.ResultError(err.Error())
+		c.ServeJSON()
+		return
+	}
+	c.Data["json"] = c.ResultOK(lst, 0)
+	c.ServeJSON()
+}
+
+// @Summary 获取指定模型和装置类型的端子列表
+//	@Description  获取指定模型和装置类型的端子列表
+// 	@Tags         业务管理服务
+// 	@Accept       x-www-form-urlencoded
+// 	@Produce      json
+//	@Param 	model_id 	formData   int  	true 	"模型ID"
+//	@Param 	ied_type 	formData   string  	true 	"装置类型"
+// 	@Success     200    {object} ResultOK 成功
+// 	@Failure 	 500 	{object} ResultError  失败
+// @router /admin/model/function/fcda/list [get]
+func (c *BusAdminController) GetFuncFcdaList() {
+	modelid, _ := c.GetInt("model_id")
+	if modelid == 0 {
+		c.Data["json"] = c.ResultError("模型ID不能为空!")
+		c.ServeJSON()
+		return
+	}
+	ied_type := c.GetString("ied_type")
+	if ied_type == "" {
+		c.Data["json"] = c.ResultError("装置类型不能为空!")
+		c.ServeJSON()
+		return
+	}
+	obj := new(bo.SysCheckModelIedFuncMgr)
+	obj.SetUserInfo(c.GetCurrentUserInfo())
+	lst, err := obj.GetList(modelid, ied_type)
+	if err != nil {
+		c.Data["json"] = c.ResultError(err.Error())
+		c.ServeJSON()
+		return
+	}
+	fcdaList := []interface{}{}
+	fcdaMgr := new(bo.SysCheckModelIedFuncFcdaMgr)
+	fcdaMgr.Model = bo.T_data_model_func_fcda{}
+	fcdaMgr.Model.ModelId = modelid
+	for _, row := range lst {
+		fcdaMgr.Model.FuncId, _ = strconv.Atoi(tools.IsEmpty(row["id"]))
+		tmpLst, err := fcdaMgr.GetList()
+		if err != nil {
+			c.Data["json"] = c.ResultError(err.Error())
+			c.ServeJSON()
+			return
+		}
+		for _, r := range tmpLst {
+			fcdaList = append(fcdaList, r)
+		}
+	}
+	c.Data["json"] = c.ResultOK(fcdaList, 0)
+	c.ServeJSON()
+}
+
+// @Summary 保存模型装置功能及端子信息
+//	@Description  保存装置功能及端子信息
+// 	@Tags         业务管理服务
+// 	@Accept       x-www-form-urlencoded
+// 	@Produce      json
+//	@Param 	model_id 	formData   int  	true 	"模型ID"
+//	@Param 	ied_type 	formData   string  	true 	"装置类型代码"
+//	@Param 	func_id 	formData   int  	false 	"功能ID。编辑时必传。"
+//	@Param 	func_name 	formData   string  	true 	"功能名称。必传。"
+//	@Param 	fcda_id 	formData   int  	false 	"端子ID。编辑时必传。"
+//	@Param 	fcda_name 	formData   string  	true 	"功能名称。必传。"
+//	@Param 	fcda_match_exp 	formData   string  	true 	"端子匹配表达式。必传。"
+// 	@Success     200    {object} ResultOK 成功
+// 	@Failure 	 500 	{object} ResultError  失败
+// @router /admin/model/function/fcda/save [post]
+func (c *BusAdminController) SaveFuncFcda() {
+	modelid, _ := c.GetInt("model_id")
+	if modelid == 0 {
+		c.Data["json"] = c.ResultError("模型ID不能为空!")
+		c.ServeJSON()
+		return
+	}
+	ied_type := c.GetString("ied_type")
+	func_name := c.GetString("func_name")
+	fcda_name := c.GetString("fcda_name")
+	fcda_match_exp := c.GetString("fcda_match_exp")
+	func_id, _ := c.GetInt("func_id")
+	fcda_id, _ := c.GetInt("fcda_id")
+	if func_name == "" {
+		c.Data["json"] = c.ResultError("功能名称不能为空!")
+		c.ServeJSON()
+		return
+	}
+	if fcda_name == "" {
+		c.Data["json"] = c.ResultError("端子设计名称不能为空!")
+		c.ServeJSON()
+		return
+	}
+	if fcda_match_exp == "" {
+		c.Data["json"] = c.ResultError("端子匹配关键词不能为空!")
+		c.ServeJSON()
+		return
+	}
+	mod := bo.T_data_model_func_def{}
+	mod.Id = func_id
+	mod.ModelId = modelid
+	mod.IedType = ied_type
+	mod.FuncFcdaId = fcda_id
+	mod.FuncName = func_name
+	mod.FcdaName = fcda_name
+	mod.FcdaMatchExp = fcda_match_exp
+	mgr := new(bo.SysCheckModelIedFuncMgr)
+	mgr.SetUserInfo(c.GetCurrentUserInfo())
+	err := mgr.Save()
+	if err != nil {
+		c.Data["json"] = c.ResultError(err.Error())
+		c.ServeJSON()
+		return
+	}
+	c.Data["json"] = c.ResultOK("", 0)
+	c.ServeJSON()
+}
+
+// @Summary 删除装置端子
+//	@Description  删除装置端子
+// 	@Tags         业务管理服务
+// 	@Accept       x-www-form-urlencoded
+// 	@Produce      json
+//	@Param 	model_id 	formData   int  	true 	"模型ID"
+//	@Param 	fcda_id 	formData   int  	true 	"端子ID"
+// 	@Success     200    {object} ResultOK 成功
+// 	@Failure 	 500 	{object} ResultError  失败
+// @router /admin/model/function/fcda/del [post]
+func (c *BusAdminController) DelFuncFcda() {
+	modelid, _ := c.GetInt("model_id")
+	if modelid == 0 {
+		c.Data["json"] = c.ResultError("模型ID不能为空!")
+		c.ServeJSON()
+		return
+	}
+	fcda_id, _ := c.GetInt("fcda_id")
+	if fcda_id == 0 {
+		c.Data["json"] = c.ResultError("端子ID不能为空!")
+		c.ServeJSON()
+		return
+	}
+
+	fcdaMgr := new(bo.SysCheckModelIedFuncFcdaMgr)
+	fcdaMgr.SetUserInfo(c.GetCurrentUserInfo())
+	fcdaMgr.Model = bo.T_data_model_func_fcda{}
+	fcdaMgr.Model.ModelId = modelid
+	fcdaMgr.Model.Id = fcda_id
+	err := fcdaMgr.Delete()
+	if err != nil {
+		c.Data["json"] = c.ResultError(err.Error())
+		c.ServeJSON()
+		return
+	}
+	c.Data["json"] = c.ResultOK("", 0)
+	c.ServeJSON()
+}
+
+// @Summary 获取模型装置端子已关联的接收端子
+//	@Description  获取模型装置端子已关联的接收端子
+// 	@Tags         业务管理服务
+// 	@Accept       x-www-form-urlencoded
+// 	@Produce      json
+//	@Param 	model_id 	formData   int  	true 	"模型ID"
+//	@Param 	from_fcda_id 	formData   int  	true 	"输出装置端子ID"
+// 	@Success     200    {object} ResultOK 成功
+// 	@Failure 	 500 	{object} ResultError  失败
+// @router /admin/model/function/fcda-ref/list [get]
+func (c *BusAdminController) GetFuncFcdaRef() {
+	modelid, _ := c.GetInt("model_id")
+	if modelid == 0 {
+		c.Data["json"] = c.ResultError("模型ID不能为空!")
+		c.ServeJSON()
+		return
+	}
+	fcda_id, _ := c.GetInt("from_fcda_id")
+	if fcda_id == 0 {
+		c.Data["json"] = c.ResultError("输出装置端子ID不能为空!")
+		c.ServeJSON()
+		return
+	}
+	fcdaMgr := new(bo.SysCheckModelFcdaRalationMgr)
+	fcdaMgr.SetUserInfo(c.GetCurrentUserInfo())
+	fcdaMgr.Model = bo.T_data_model_fcda_ref{}
+	fcdaMgr.Model.ModelId = modelid
+	fcdaMgr.Model.FromFcdaId = fcda_id
+	lst, err := fcdaMgr.GetList()
+	if err != nil {
+		c.Data["json"] = c.ResultError(err.Error())
+		c.ServeJSON()
+		return
+	}
+	c.Data["json"] = c.ResultOK(lst, len(lst))
+	c.ServeJSON()
+}
+
+// @Summary 保存模型装置端子间关联关系
+//	@Description  保存模型装置端子间关联关系
+// 	@Tags         业务管理服务
+// 	@Accept       x-www-form-urlencoded
+// 	@Produce      json
+//	@Param 	model_id 	formData   int  	true 	"模型ID"
+//	@Param 	from_ied_type 	formData   string  	true 	"输出装置类型"
+//	@Param 	to_ied_type 	formData   string  	true 	"输入装置类型"
+//	@Param 	from_fcda_id 	formData   int  	true 	"输出装置端子ID"
+//	@Param 	to_fcda_ids		formData   string  	true 	"输入装置端子ID列表。多个ID间使用逗号分隔"
+//	@Param 	goosesv 		formData   string  	true 	"信号类型。值范围:GOOSE|SV"
+// 	@Success     200    {object} ResultOK 成功
+// 	@Failure 	 500 	{object} ResultError  失败
+// @router /admin/model/function/fcda-ref/save [post]
+func (c *BusAdminController) SaveFuncFcdaRef() {
+	modelid, _ := c.GetInt("model_id")
+	if modelid == 0 {
+		c.Data["json"] = c.ResultError("模型ID不能为空!")
+		c.ServeJSON()
+		return
+	}
+	fcda_id, _ := c.GetInt("from_fcda_id")
+	if fcda_id == 0 {
+		c.Data["json"] = c.ResultError("输出装置端子ID不能为空!")
+		c.ServeJSON()
+		return
+	}
+	fcdaMgr := new(bo.SysCheckModelFcdaRalationMgr)
+	fcdaMgr.SetUserInfo(c.GetCurrentUserInfo())
+	fcdaMgr.Model = bo.T_data_model_fcda_ref{}
+	fcdaMgr.Model.ModelId = modelid
+	fcdaMgr.Model.FromFcdaId = fcda_id
+	fcdaMgr.Model.FromIedCode = c.GetString("from_ied_type")
+	fcdaMgr.Model.ToIedCode = c.GetString("to_ied_type")
+	fcdaMgr.Model.Goosesv = strings.ToUpper(c.GetString("goosesv"))
+	if fcdaMgr.Model.FromIedCode == "" || fcdaMgr.Model.ToIedCode == "" {
+		c.Data["json"] = c.ResultError("输入和输出装置类型不能为空!")
+		c.ServeJSON()
+		return
+	}
+	if fcdaMgr.Model.Goosesv == "" {
+		c.Data["json"] = c.ResultError("信号类型不能为空!")
+		c.ServeJSON()
+		return
+	}
+	if fcdaMgr.Model.Goosesv != "GOOSE" && fcdaMgr.Model.Goosesv != "SV" {
+		c.Data["json"] = c.ResultError("信号类型不正确。只能为GOOSE或SV")
+		c.ServeJSON()
+		return
+	}
+	obj := new(bo.SysCheckModelIedFuncFcdaMgr)
+	fcdainf, er := obj.One(fcdaMgr.Model.FromFcdaId)
+	if er != nil {
+		c.Data["json"] = c.ResultError(er.Error())
+		c.ServeJSON()
+		return
+	}
+	fcdaMgr.Model.FromFuncId = fcdainf.FuncId
+	fcdainf, er = obj.One(fcdaMgr.Model.ToFcdaId)
+	if er != nil {
+		c.Data["json"] = c.ResultError(er.Error())
+		c.ServeJSON()
+		return
+	}
+	fcdaMgr.Model.ToFuncId = fcdainf.FuncId
+	err := fcdaMgr.Save()
+	if err != nil {
+		c.Data["json"] = c.ResultError(err.Error())
+		c.ServeJSON()
+		return
+	}
+	c.Data["json"] = c.ResultOK("", 0)
+	c.ServeJSON()
+}

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

@@ -104,8 +104,8 @@ func (c *SysCheckModelFcdaRalationMgr) Delete() (err error) {
 
 func (c *SysCheckModelFcdaRalationMgr) GetList() ([]orm.Params, error) {
 	o := orm.NewOrm()
-	sqlParamters := []interface{}{c.Model.ModelId, c.Model.FromFuncId}
-	sql := "select t.* from t_data_model_func_fcda t where t.model_id=? and t.from_func_id=?"
+	sqlParamters := []interface{}{c.Model.ModelId, c.Model.FromFcdaId}
+	sql := "select t.* from t_data_model_func_fcda t where t.model_id=? and t.from_fcda_id=?"
 	rowset := []orm.Params{}
 	_, err := o.Raw(sql, sqlParamters).Values(&rowset)
 	if err != nil {

+ 3 - 13
service/models/bo/check_sysmodel_ied_func.go

@@ -8,8 +8,6 @@ import (
 	"scd_check_tools/tools"
 	"strconv"
 
-	"sync"
-
 	"github.com/astaxie/beego/orm"
 )
 
@@ -36,8 +34,6 @@ type SysCheckModelIedFuncMgr struct {
 
 var sysCheckModel_iedFuncDesc = "内置检测模型-装置功能管理"
 
-var SysModelFuncList = sync.Map{}
-
 func init() {
 	orm.RegisterModel(new(T_data_model_func_def))
 }
@@ -147,26 +143,20 @@ func (c *SysCheckModelIedFuncMgr) Delete() (err error) {
 		} else {
 			fcdaMgr.Delete()
 		}
-		SysModelRelationList.Delete(c.Model.ModelId)
 		dblog.Description = fmt.Sprintf("删除%s(%d)成功", sysCheckModel_iedFuncDesc, c.Model.ModelId)
 		dblog.Success2()
 	}
 	return err
 }
 
-func (c *SysCheckModelIedFuncMgr) GetListByModelid(modelid int) ([]orm.Params, error) {
-	if v, h := SysModelFuncList.Load(modelid); h {
-		return v.([]orm.Params), nil
-	}
+func (c *SysCheckModelIedFuncMgr) GetList(modelid int, iedType string) ([]orm.Params, error) {
 	o := orm.NewOrm()
-	sqlParamters := []interface{}{modelid}
-	sql := "select t.* from t_data_model_func_def t where t.model_id=?"
+	sqlParamters := []interface{}{modelid, iedType}
+	sql := "select t.* from t_data_model_func_def t where t.model_id=? and ied_type=?"
 	rowset := []orm.Params{}
 	_, err := o.Raw(sql, sqlParamters).Values(&rowset)
 	if err != nil {
 		logger.Logger.Error(err)
-	} else {
-		SysModelFuncList.Store(modelid, rowset)
 	}
 	return rowset, err
 }

+ 24 - 1
service/models/bo/check_sysmodel_ied_func_fcda.go

@@ -95,7 +95,9 @@ func (c *SysCheckModelIedFuncFcdaMgr) Delete() (err error) {
 	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()
@@ -117,14 +119,35 @@ func (c *SysCheckModelIedFuncFcdaMgr) Delete() (err error) {
 		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()
+				}
+			}
+		}
 	}
 	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
+}
+
 func (c *SysCheckModelIedFuncFcdaMgr) GetList() ([]orm.Params, error) {
 	o := orm.NewOrm()
 	sqlParamters := []interface{}{c.Model.ModelId, c.Model.FuncId}
-	sql := "select t.* from t_data_model_func_fcda t where t.model_id=? and t.func_id=?"
+	sql := "select t.*,t1.func_name from t_data_model_func_fcda t,t_data_model_func_def t1 where t1.id=t.func_id and t.model_id=? and t.func_id=?"
 	rowset := []orm.Params{}
 	_, err := o.Raw(sql, sqlParamters).Values(&rowset)
 	if err != nil {

+ 2 - 1
service/models/bo/check_sysmodel_ied_relation.go

@@ -93,6 +93,7 @@ func (c *SysCheckModelIedRelationMgr) Save(nodes map[string]interface{}) (err er
 				return err
 			}
 		}
+		SysModelRelationList.Delete(c.Model.ModelId)
 		dblog.Description = fmt.Sprintf("保存%s信息成功,操作数据:%+v", sysCheckModel_iedRelationDesc, c.Model)
 		dblog.Success2()
 	}
@@ -148,7 +149,7 @@ func (c *SysCheckModelIedRelationMgr) Copy(fromModelId int) (error, int) {
 }
 
 //获取指定电压等级下的所有模型
-func (c *SysCheckModelIedRelationMgr) GetModelsByModelid(modelid int) ([]orm.Params, error) {
+func (c *SysCheckModelIedRelationMgr) GetListByModelid(modelid int) ([]orm.Params, error) {
 	if v, h := SysModelRelationList.Load(modelid); h {
 		return v.([]orm.Params), nil
 	}

+ 232 - 11
service/models/bo/checktools_area.go

@@ -3,6 +3,7 @@ package bo
 import (
 	"errors"
 	"fmt"
+	"regexp"
 	"scd_check_tools/logger"
 	"scd_check_tools/models/enum"
 	"scd_check_tools/models/node_attr"
@@ -308,15 +309,21 @@ func (c *CheckAreaMgr) Reset() error {
 	return nil
 }
 
-//检测间隔装置关系正确性
-func (c *CheckAreaMgr) CheckAreaIedRelation() error {
-	// 获取当前scd中需要检查的间隔
+var areaCheckInfo = sync.Map{}
+
+//获取解析模型需要的基础数据信息
+func (c *CheckAreaMgr) getAreaCheckInfo() (*node_attr.SCL, []orm.Params, string, error) {
+	key := fmt.Sprintf("%d-checkinfo", c.ScdId)
+	if v, h := areaCheckInfo.Load(key); h {
+		v1 := v.([]interface{})
+		return v1[0].(*node_attr.SCL), v1[1].([]orm.Params), v1[2].(string), nil
+	}
 	arealist := []orm.Params{}
 	db := orm.NewOrm()
 	_, err := db.Raw("select id,area_name,area_type,model_id from t_data_check_area where scd_id=?", c.ScdId).Values(&arealist)
 	if err != nil {
 		logger.Logger.Error(err)
-		return err
+		return nil, nil, "", err
 	}
 	scdNodeRule := new(ScdNodeRule)
 	area_ruleid := ""
@@ -325,27 +332,47 @@ func (c *CheckAreaMgr) CheckAreaIedRelation() error {
 		area_ruleid = tools.IsEmpty(area_ruleList[0]["id"])
 	}
 	if area_ruleid == "" {
-		return errors.New(fmt.Sprintf("未定义间隔装置的检查规则“间隔装置与检查模型不符”"))
+		return nil, nil, "", errors.New(fmt.Sprintf("未定义间隔装置的检查规则“间隔装置与检查模型不符”"))
 	}
 	scdParseMgr := new(ScdParse)
 	scdXmlObj, serr := scdParseMgr.GetScdXmlObjectBySCDID(tools.IsEmpty(c.ScdId))
 	if serr != nil {
-		return serr
+		return nil, nil, "", serr
+	}
+	if scdXmlObj == nil {
+		return nil, nil, "", errors.New("无效的SCD")
+	}
+	areaCheckInfo.Store(key, []interface{}{scdXmlObj, arealist, area_ruleid})
+	return scdXmlObj, arealist, area_ruleid, nil
+}
+
+//检测间隔装置关系正确性
+func (c *CheckAreaMgr) CheckAreaIedRelation() error {
+	// 获取当前scd中需要检查的间隔
+	scdXmlObj, arealist, area_ruleid, err := c.getAreaCheckInfo()
+	db := orm.NewOrm()
+	if err != nil {
+		logger.Logger.Error(err)
+		return err
+	}
+	if area_ruleid == "" {
+		return errors.New(fmt.Sprintf("未定义间隔装置的检查规则“间隔装置与检查模型不符”"))
 	}
 	if scdXmlObj == nil {
 		return errors.New("无效的SCD")
 	}
+	scdNodeRule := new(ScdNodeRule)
 	scdNode := new(ScdNode)
 	model_refs := map[string][]orm.Params{} //模型定义的装置关系定义
 	area_ieds := map[string][]orm.Params{}  //间隔下的装置列表
+	iedRelationMgr := new(SysCheckModelIedRelationMgr)
 	for _, row := range arealist {
 		//获取间隔标准装置及关系
-		modelid := tools.IsEmpty(row["model_id"])
+		modelid, _ := strconv.Atoi(tools.IsEmpty(row["model_id"]))
 		//area_name := tools.IsEmpty(row["area_name"])
 		//area_type := tools.IsEmpty(row["area_type"]) //间隔模型类型
 		area_id := tools.IsEmpty(row["id"])
-		s := []orm.Params{}
-		_, err = db.Raw("select from_ied_code,to_ied_code,in_type from t_data_model_relation_def where model_id=?", modelid).Values(&s)
+		s, err := iedRelationMgr.GetListByModelid(modelid)
 		if err != nil {
 			logger.Logger.Error(err)
 			return err
@@ -353,7 +380,7 @@ func (c *CheckAreaMgr) CheckAreaIedRelation() error {
 		if len(s) == 0 {
 			return errors.New(fmt.Sprintf("模型%d还未配置装置关系", modelid))
 		}
-		model_refs[modelid] = s
+		model_refs[fmt.Sprintf("%d", modelid)] = s
 		/*
 			hasIeds := map[string]bool{}
 			for _, row1 := range s {
@@ -441,9 +468,202 @@ func (c *CheckAreaMgr) CheckAreaIedRelation() error {
 	return nil
 }
 
+//检测装置功能分析
+func (c *CheckAreaMgr) CheckIedFunc() error {
+
+	return nil
+}
+
+//检测装置端子分析
+func (c *CheckAreaMgr) CheckIedFcda() error {
+	scdXmlObj, arealist, area_ruleid, err := c.getAreaCheckInfo()
+	if err != nil {
+		logger.Logger.Error(err)
+		return err
+	}
+	if area_ruleid == "" {
+		return errors.New(fmt.Sprintf("未定义间隔装置的检查规则“间隔装置与检查模型不符”"))
+	}
+	if scdXmlObj == nil {
+		return errors.New("无效的SCD")
+	}
+	db := orm.NewOrm()
+	//获取当前站的各电压等级
+	volRows := []orm.Params{}
+	_, err = db.Raw("select t.vol, CAST(REPLACE(UPPER(g.name),'KV','') as SIGNED) volname from t_area_ied_relation t,global_const_code g  where g.code=CONCAT('v_level_',t.vol) and g.parentcode='voltage_level' and  t.vol!=999 and t.scd_id=? GROUP BY t.vol ORDER BY volname desc", c.ScdId).Values(&volRows)
+	if err != nil {
+		logger.Logger.Error(err)
+		return err
+	}
+	if len(volRows) == 0 {
+		logger.Logger.Error(errors.New("该scd未发现任何电压等级的装置"))
+		return errors.New("该scd未发现任何电压等级的装置")
+	}
+	volMap := map[string]string{}
+	volMap["hight"] = tools.IsEmpty(volRows[0]["vol"]) //高压电压
+	if len(volRows) == 2 {
+		volMap["middle"] = ""
+		volMap["low"] = volRows[1]["vol"].(string) //低压电压等级
+	} else {
+		volMap["middle"] = volRows[1]["vol"].(string)           //中压电压等级
+		volMap["low"] = volRows[len(volRows)-1]["vol"].(string) //低压电压等级
+	}
+	scdNodeRule := new(ScdNodeRule)
+	scdNodeMgr := new(ScdNode)
+	iedRelationMgr := new(SysCheckModelIedRelationMgr)
+	for _, row := range arealist {
+		//获取间隔标准装置及关系
+		modelid, _ := strconv.Atoi(tools.IsEmpty(row["model_id"]))
+		area_name := tools.IsEmpty(row["area_name"])
+		//area_type := tools.IsEmpty(row["area_type"]) //间隔模型类型
+		area_id := tools.IsEmpty(row["id"])
+		s, err := iedRelationMgr.GetListByModelid(modelid)
+		if err != nil {
+			logger.Logger.Error(err)
+			return err
+		}
+		if len(s) == 0 {
+			return errors.New(fmt.Sprintf("模型%d还未配置装置关系", modelid))
+		}
+		//获取该间隔下该类型的装置
+		s1 := []orm.Params{}
+		_, err = db.Raw("select ied_name from t_data_check_area_ied where area_id=?", area_id).Values(&s1)
+		//循环处理关联关系
+		dealIedType := map[string]int{} //已处理过的装置类型
+		for _, row2 := range s {
+			ied_type := tools.IsEmpty(row2["ied_type"])
+			if dealIedType[ied_type] > 0 {
+				continue
+			}
+			//获取装置类型配置的端子列表
+			fcdaMgr := new(SysCheckModelIedFuncFcdaMgr)
+			funcMgr := new(SysCheckModelIedFuncMgr)
+			funcMgr.Model = T_data_model_func_def{ModelId: modelid}
+			funclist, _ := funcMgr.GetList(modelid, ied_type)
+			if funclist == nil || len(funclist) == 0 {
+				continue
+			}
+			tmp := strings.Split(ied_type, "#")
+			ied_type = tmp[0]
+			vol := ""
+			if len(tmp) == 2 {
+				vol = tmp[1] //电压级别
+			}
+			iedlst := []orm.Params{}
+			if vol == "" {
+				for _, r := range s1 {
+					if strings.HasPrefix(tools.IsEmpty(r["ied_name"]), ied_type) {
+						iedlst = append(iedlst, r)
+					}
+				}
+			} else {
+				tmpLst := map[string]orm.Params{}
+				for _, r := range s1 {
+					iedname := tools.IsEmpty(r["ied_name"])
+					if strings.HasPrefix(iedname, ied_type) {
+						tmpLst[iedname] = r
+					}
+				}
+				h, m, l := c.getIedListByVol(ied_type, tmpLst, volMap)
+				if vol == "H" {
+					iedlst = h
+				}
+				if vol == "M" {
+					iedlst = m
+				}
+				if vol == "L" {
+					iedlst = l
+				}
+			}
+			for _, ied := range iedlst {
+				iedname := tools.IsEmpty(ied["ied_name"])
+				iedObj := scdNodeMgr.GetIed(scdXmlObj, tools.IsEmpty(c.ScdId), iedname)
+				if iedObj == nil {
+					continue
+				}
+				fcdaObjList := []*node_attr.NFCDA{}
+				for _, t1 := range iedObj.AccessPoint {
+					if t1.Server == nil || len(t1.Server.LDevice) == 0 {
+						continue
+					}
+					for _, ld := range t1.Server.LDevice {
+						if ld.LN0 != nil {
+							for _, t2 := range ld.LN0.DataSet {
+								for _, t3 := range t2.FCDA {
+									fcdaObjList = append(fcdaObjList, t3)
+								}
+							}
+						}
+					}
+				}
+				for _, row3 := range funclist {
+					funcExist := false //设计的功能是否存在
+					funcid, _ := strconv.Atoi(tools.IsEmpty(row3["id"]))
+					fcdaMgr.Model = T_data_model_func_fcda{ModelId: modelid, FuncId: funcid}
+					fcdalist, _ := fcdaMgr.GetList()
+					if fcdalist != nil && len(fcdalist) > 0 {
+						//判断端子是否存在
+						for _, row4 := range fcdalist {
+							fcda_name_match := tools.IsEmpty(row4["fcda_match_exp"])
+							fcda_name := tools.IsEmpty(row4["fcda_name"])
+							if fcda_name_match == "" {
+								fcda_name_match = fcda_name
+							}
+							fcdaExist := false
+							//获取端子FCDA描述
+							if len(fcdaObjList) > 0 {
+								for _, t4 := range fcdaObjList {
+									re, _ := scdNodeRule.IedFcdaExist(iedname, t4.LdInst, t4.LnClass, t4.LnInst, t4.Prefix, t4.DoName, t4.DaName)
+									if re == nil {
+										continue
+									}
+									doi := re.(*node_attr.NDOI)
+									desc := doi.Desc
+									if fcda_name_match == desc {
+										//完全匹配
+										fcdaExist = true
+										break
+									}
+									//正则匹配
+									//fcda_name_match = strings.ReplaceAll(fcda_name_match)
+									rexp := regexp.MustCompile(fcda_name_match)
+									if rexp.FindString(desc) != "" {
+										fcdaExist = true
+										break
+									}
+								}
+							}
+							if fcdaExist {
+								funcExist = true
+							} else {
+								parse_result := fmt.Sprintf("间隔%s的装置%s缺失虚端子%s", area_name, iedname, fcda_name)
+								r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
+								//检查未通过
+								scdNodeRule.AppendPaseResult(r)
+							}
+						}
+					}
+					if !funcExist {
+						parse_result := fmt.Sprintf("间隔%s的装置%s缺失功能%s", area_name, iedname, tools.IsEmpty(row3["func_name"]))
+						r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
+						//检查未通过
+						scdNodeRule.AppendPaseResult(r)
+					}
+				}
+			}
+			dealIedType[ied_type] = 1
+		}
+	}
+	scdNodeRule.CheckFinish()
+	scdNodeRule.Flush()
+	return nil
+}
+
 //解析模型间隔
 func (c *CheckAreaMgr) ParseModelArea() {
 	c.Init(c.ScdId)
+	key := fmt.Sprintf("%d-checkinfo", c.ScdId)
+	areaCheckInfo.Delete(key)
 	// 取得当前scd所有ied及名称解析结果
 	dbo := orm.NewOrm()
 	sql := "select t.*,t1.name area_name from t_area_ied_relation t,t_substation_area t1 where t.area_id=t1.id and t.scd_id=? order by t.p_type"
@@ -1082,7 +1302,8 @@ func (c *CheckAreaMgr) cT(scdXmlObj *node_attr.SCL, scdNodeMgr *ScdNode, scdNode
 	dealFromIed := map[string]int{}
 	for _, row := range ied_refs {
 		fromiedtype := tools.IsEmpty(row["from_ied_code"])
-		toiedtype := tools.IsEmpty(row["to_ied_code"])
+		fromiedtype = strings.Split(fromiedtype, "#")[0]                      //去除后面的电压级别标识
+		toiedtype := strings.Split(tools.IsEmpty(row["to_ied_code"]), "#")[0] //去除后面的电压级别标识
 		reftype := tools.IsEmpty(row["in_type"])
 		tmpFromAreaIeds := []orm.Params{}
 		tmpToAreaIeds := []orm.Params{}

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

@@ -1003,6 +1003,9 @@ func (c *ScdMgr) CrcCheck(scdid string) (bool, error) {
 			logger.Logger.Error(serr)
 			return
 		}
+		if scdXmlObj == nil {
+			return
+		}
 		lnodetypes := c.GetLNodeType(scdXmlObj)
 		dotypes := c.GetDOType(scdXmlObj)
 		dirChar := string(os.PathSeparator)

+ 3 - 3
service/models/bo/scd_node_rule.go

@@ -1664,7 +1664,7 @@ func (c *ScdNodeRule) CheckFunc_ied(dATypeMap map[string]*node_attr.NDAType) {
 								continue
 							}
 							//成员有效性
-							has1, _ := c.iedFcdaExist(iedObj.Name, fcdaitem.LdInst, fcdaitem.LnClass, fcdaitem.LnInst, fcdaitem.Prefix, fcdaitem.DoName, fcdaitem.DaName)
+							has1, _ := c.IedFcdaExist(iedObj.Name, fcdaitem.LdInst, fcdaitem.LnClass, fcdaitem.LnInst, fcdaitem.Prefix, fcdaitem.DoName, fcdaitem.DaName)
 							if has1 == nil {
 								parse_result := fmt.Sprintf("IED(%s)中访问点(%s:%s)下的LD(%s)数据集(%s)FCDA成员(%s)不存在", iedObj.Name, ap.Name, ap.Desc, ld.Inst, datset.Name, key)
 								r := map[string]interface{}{"scdid": c.ScdID, "lineno": fcdaitem.Lineno, "ruleid": c.getRuleIdByName("数据集成员有效性校验"), "nodeid": iedObj.NodeId, "parse_result": parse_result}
@@ -1698,7 +1698,7 @@ func (c *ScdNodeRule) CheckFunc_ied(dATypeMap map[string]*node_attr.NDAType) {
 								r := map[string]interface{}{"scdid": c.ScdID, "lineno": extref.Lineno, "ruleid": c.getRuleIdByName("连线两端数据不匹配"), "nodeid": iedObj.NodeId, "parse_result": parse_result}
 								c.AppendPaseResult(r, iedObj)
 							}
-							has1, cdc1 := c.iedFcdaExist(extref.IedName, extref.LdInst, extref.LnClass, extref.LnInst, extref.Prefix, extref.DoName, extref.DaName)
+							has1, cdc1 := c.IedFcdaExist(extref.IedName, extref.LdInst, extref.LnClass, extref.LnInst, extref.Prefix, extref.DoName, extref.DaName)
 							if has1 == nil {
 								extrefstr := fmt.Sprintf("IED=%s,addr=%s/%s%s%s.%s", extref.IedName, extref.LdInst, extref.Prefix, extref.LnClass, extref.LnInst, extref.DoName)
 								if extref.DaName != "" {
@@ -2313,7 +2313,7 @@ func (c *ScdNodeRule) CheckFunc_datatypetemplates(para orm.Params) (a3 map[strin
 //存在性检查
 //cdc检查
 //
-func (c *ScdNodeRule) iedFcdaExist(iedname, ldinst, lnclass, lninst, prefix, doname, daname string) (obj interface{}, cdc string) {
+func (c *ScdNodeRule) IedFcdaExist(iedname, ldinst, lnclass, lninst, prefix, doname, daname string) (obj interface{}, cdc string) {
 	if c.scdXmlObject == nil {
 		return nil, ""
 	}

+ 21 - 0
service/models/bo/task.go

@@ -134,10 +134,31 @@ func (c *TaskMgr) start(task T_data_task) error {
 			err = checkAreaMgr.CheckAreaIedRelation()
 			if err != nil {
 				c.SetStep(tools.IsEmpty(task.ScdId), enum.TaskStep_SCD_model_parse.Code(), 3, err.Error())
+				c.SetStep(tools.IsEmpty(task.ScdId), enum.TaskStep_SCD_func_parse.Code(), 3, "终止")
+				c.SetStep(tools.IsEmpty(task.ScdId), enum.TaskStep_SCD_fcda_parse.Code(), 3, "终止")
 			} else {
 				c.SetStep(tools.IsEmpty(task.ScdId), enum.TaskStep_SCD_model_parse.Code(), 2)
+				//功能分析
+				err = checkAreaMgr.CheckAreaIedRelation()
+				c.SetStep(tools.IsEmpty(task.ScdId), enum.TaskStep_SCD_func_parse.Code(), 1)
+				if err != nil {
+					c.SetStep(tools.IsEmpty(task.ScdId), enum.TaskStep_SCD_func_parse.Code(), 3, err.Error())
+					c.SetStep(tools.IsEmpty(task.ScdId), enum.TaskStep_SCD_fcda_parse.Code(), 3, "终止")
+				} else {
+					c.SetStep(tools.IsEmpty(task.ScdId), enum.TaskStep_SCD_func_parse.Code(), 2)
+					//端子分析
+					c.SetStep(tools.IsEmpty(task.ScdId), enum.TaskStep_SCD_fcda_parse.Code(), 1)
+					err = checkAreaMgr.CheckIedFcda()
+					if err != nil {
+						c.SetStep(tools.IsEmpty(task.ScdId), enum.TaskStep_SCD_fcda_parse.Code(), 3, err.Error())
+					} else {
+						c.SetStep(tools.IsEmpty(task.ScdId), enum.TaskStep_SCD_fcda_parse.Code(), 2)
+					}
+				}
 			}
 		}
+		//检测结束
+		c.SetActive(2)
 	}()
 	return err
 }

+ 4 - 1
service/models/enum/enum_task_step.go

@@ -16,6 +16,7 @@ const (
 	TaskStep_SCD_cid_extract
 	TaskStep_SCD_icd_extract
 	TaskStep_SCD_model_parse
+	TaskStep_SCD_func_parse
 	TaskStep_SCD_fcda_parse
 )
 
@@ -38,9 +39,11 @@ func (t TaskStep) Code() string {
 	case TaskStep_SCD_model_parse:
 		return "scd_model_parse"
 	case TaskStep_SCD_fcda_parse:
-		return "scd_fcda_parse"
+		return "scd_ied_fcda_parse"
 	case TaskStep_SCD_crc_extract:
 		return "scd_crc_extract"
+	case TaskStep_SCD_func_parse:
+		return "scd_ied_func_parse"
 	default:
 		return ""
 	}

+ 45 - 0
service/routers/commentsRouter_____________ME_GoProject_src_scd_check_tools_controllers.go

@@ -612,6 +612,51 @@ func init() {
 
     beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
         beego.ControllerComments{
+            Method: "SaveFuncFcdaRef",
+            Router: "/admin/model/function/fcda-ref/save",
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
+        beego.ControllerComments{
+            Method: "DelFuncFcda",
+            Router: "/admin/model/function/fcda/del",
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
+        beego.ControllerComments{
+            Method: "GetFuncFcdaList",
+            Router: "/admin/model/function/fcda/list",
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
+        beego.ControllerComments{
+            Method: "SaveFuncFcda",
+            Router: "/admin/model/function/fcda/save",
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
+        beego.ControllerComments{
+            Method: "GetFuncListByIedType",
+            Router: "/admin/model/function/list",
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
+        beego.ControllerComments{
             Method: "ResetCheckAreaByID",
             Router: "/admin/parse/check_area",
             AllowHTTPMethods: []string{"post"},

+ 54 - 0
service/routers/commentsRouter_controllers.go

@@ -612,6 +612,60 @@ func init() {
 
     beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
         beego.ControllerComments{
+            Method: "GetFuncFcdaRef",
+            Router: "/admin/model/function/fcda-ref/list",
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
+        beego.ControllerComments{
+            Method: "SaveFuncFcdaRef",
+            Router: "/admin/model/function/fcda-ref/save",
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
+        beego.ControllerComments{
+            Method: "DelFuncFcda",
+            Router: "/admin/model/function/fcda/del",
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
+        beego.ControllerComments{
+            Method: "GetFuncFcdaList",
+            Router: "/admin/model/function/fcda/list",
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
+        beego.ControllerComments{
+            Method: "SaveFuncFcda",
+            Router: "/admin/model/function/fcda/save",
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
+        beego.ControllerComments{
+            Method: "GetFuncListByIedType",
+            Router: "/admin/model/function/list",
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"] = append(beego.GlobalControllerRouter["scd_check_tools/controllers:BusAdminController"],
+        beego.ControllerComments{
             Method: "ResetCheckAreaByID",
             Router: "/admin/parse/check_area",
             AllowHTTPMethods: []string{"post"},

+ 288 - 0
service/static/swagger/swagger.json

@@ -365,6 +365,294 @@
                 }
             }
         },
+        "/admin/model/function/fcda-ref/list": {
+            "get": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "获取模型装置端子已关联的接收端子",
+                "description": "获取模型装置端子已关联的接收端子",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "from_fcda_id",
+                        "description": "输出装置端子ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
+        "/admin/model/function/fcda-ref/save": {
+            "post": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "保存模型装置端子间关联关系",
+                "description": "保存模型装置端子间关联关系",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "from_ied_type",
+                        "description": "输出装置类型",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "to_ied_type",
+                        "description": "输入装置类型",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "from_fcda_id",
+                        "description": "输出装置端子ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "to_fcda_ids",
+                        "description": "输入装置端子ID列表。多个ID间使用逗号分隔",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "goosesv",
+                        "description": "信号类型。值范围:GOOSE|SV",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
+        "/admin/model/function/fcda/del": {
+            "post": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "删除装置端子",
+                "description": "删除装置端子",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "fcda_id",
+                        "description": "端子ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
+        "/admin/model/function/fcda/list": {
+            "get": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "获取指定模型和装置类型的端子列表",
+                "description": "获取指定模型和装置类型的端子列表",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "ied_type",
+                        "description": "装置类型",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
+        "/admin/model/function/fcda/save": {
+            "post": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "保存模型装置功能及端子信息",
+                "description": "保存装置功能及端子信息",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "ied_type",
+                        "description": "装置类型代码",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "func_id",
+                        "description": "功能ID。编辑时必传。",
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "func_name",
+                        "description": "功能名称。必传。",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "fcda_id",
+                        "description": "端子ID。编辑时必传。",
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "fcda_name",
+                        "description": "功能名称。必传。",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "fcda_match_exp",
+                        "description": "端子匹配表达式。必传。",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
+        "/admin/model/function/list": {
+            "get": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "获取指定模型和装置类型的功能列表",
+                "description": "获取指定模型和装置类型的功能列表",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "ied_type",
+                        "description": "装置类型",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
         "/admin/parse/check_area": {
             "post": {
                 "tags": [

+ 198 - 0
service/static/swagger/swagger.yml

@@ -251,6 +251,204 @@ paths:
             $ref: '#/definitions/ResultOK'
         "500":
           description: '{object} ResultError  失败'
+  /admin/model/function/fcda-ref/list:
+    get:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 获取模型装置端子已关联的接收端子
+      description: 获取模型装置端子已关联的接收端子
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: from_fcda_id
+        description: 输出装置端子ID
+        required: true
+        type: integer
+        format: int64
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
+  /admin/model/function/fcda-ref/save:
+    post:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 保存模型装置端子间关联关系
+      description: 保存模型装置端子间关联关系
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: from_ied_type
+        description: 输出装置类型
+        required: true
+        type: string
+      - in: formData
+        name: to_ied_type
+        description: 输入装置类型
+        required: true
+        type: string
+      - in: formData
+        name: from_fcda_id
+        description: 输出装置端子ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: to_fcda_ids
+        description: 输入装置端子ID列表。多个ID间使用逗号分隔
+        required: true
+        type: string
+      - in: formData
+        name: goosesv
+        description: 信号类型。值范围:GOOSE|SV
+        required: true
+        type: string
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
+  /admin/model/function/fcda/del:
+    post:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 删除装置端子
+      description: 删除装置端子
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: fcda_id
+        description: 端子ID
+        required: true
+        type: integer
+        format: int64
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
+  /admin/model/function/fcda/list:
+    get:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 获取指定模型和装置类型的端子列表
+      description: 获取指定模型和装置类型的端子列表
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: ied_type
+        description: 装置类型
+        required: true
+        type: string
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
+  /admin/model/function/fcda/save:
+    post:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 保存模型装置功能及端子信息
+      description: 保存装置功能及端子信息
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: ied_type
+        description: 装置类型代码
+        required: true
+        type: string
+      - in: formData
+        name: func_id
+        description: 功能ID。编辑时必传。
+        type: integer
+        format: int64
+      - in: formData
+        name: func_name
+        description: 功能名称。必传。
+        required: true
+        type: string
+      - in: formData
+        name: fcda_id
+        description: 端子ID。编辑时必传。
+        type: integer
+        format: int64
+      - in: formData
+        name: fcda_name
+        description: 功能名称。必传。
+        required: true
+        type: string
+      - in: formData
+        name: fcda_match_exp
+        description: 端子匹配表达式。必传。
+        required: true
+        type: string
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
+  /admin/model/function/list:
+    get:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 获取指定模型和装置类型的功能列表
+      description: 获取指定模型和装置类型的功能列表
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: ied_type
+        description: 装置类型
+        required: true
+        type: string
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
   /admin/parse/check_area:
     post:
       tags:

+ 288 - 0
service/swagger/swagger.json

@@ -365,6 +365,294 @@
                 }
             }
         },
+        "/admin/model/function/fcda-ref/list": {
+            "get": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "获取模型装置端子已关联的接收端子",
+                "description": "获取模型装置端子已关联的接收端子",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "from_fcda_id",
+                        "description": "输出装置端子ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
+        "/admin/model/function/fcda-ref/save": {
+            "post": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "保存模型装置端子间关联关系",
+                "description": "保存模型装置端子间关联关系",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "from_ied_type",
+                        "description": "输出装置类型",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "to_ied_type",
+                        "description": "输入装置类型",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "from_fcda_id",
+                        "description": "输出装置端子ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "to_fcda_ids",
+                        "description": "输入装置端子ID列表。多个ID间使用逗号分隔",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "goosesv",
+                        "description": "信号类型。值范围:GOOSE|SV",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
+        "/admin/model/function/fcda/del": {
+            "post": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "删除装置端子",
+                "description": "删除装置端子",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "fcda_id",
+                        "description": "端子ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
+        "/admin/model/function/fcda/list": {
+            "get": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "获取指定模型和装置类型的端子列表",
+                "description": "获取指定模型和装置类型的端子列表",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "ied_type",
+                        "description": "装置类型",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
+        "/admin/model/function/fcda/save": {
+            "post": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "保存模型装置功能及端子信息",
+                "description": "保存装置功能及端子信息",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "ied_type",
+                        "description": "装置类型代码",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "func_id",
+                        "description": "功能ID。编辑时必传。",
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "func_name",
+                        "description": "功能名称。必传。",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "fcda_id",
+                        "description": "端子ID。编辑时必传。",
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "fcda_name",
+                        "description": "功能名称。必传。",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "fcda_match_exp",
+                        "description": "端子匹配表达式。必传。",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
+        "/admin/model/function/list": {
+            "get": {
+                "tags": [
+                    "scd_check_tools/controllersBusAdminController"
+                ],
+                "summary": "获取指定模型和装置类型的功能列表",
+                "description": "获取指定模型和装置类型的功能列表",
+                "parameters": [
+                    {
+                        "in": "formData",
+                        "name": "model_id",
+                        "description": "模型ID",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "in": "formData",
+                        "name": "ied_type",
+                        "description": "装置类型",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "成功",
+                        "schema": {
+                            "$ref": "#/definitions/ResultOK"
+                        }
+                    },
+                    "500": {
+                        "description": "{object} ResultError  失败"
+                    }
+                }
+            }
+        },
         "/admin/parse/check_area": {
             "post": {
                 "tags": [

+ 198 - 0
service/swagger/swagger.yml

@@ -251,6 +251,204 @@ paths:
             $ref: '#/definitions/ResultOK'
         "500":
           description: '{object} ResultError  失败'
+  /admin/model/function/fcda-ref/list:
+    get:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 获取模型装置端子已关联的接收端子
+      description: 获取模型装置端子已关联的接收端子
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: from_fcda_id
+        description: 输出装置端子ID
+        required: true
+        type: integer
+        format: int64
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
+  /admin/model/function/fcda-ref/save:
+    post:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 保存模型装置端子间关联关系
+      description: 保存模型装置端子间关联关系
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: from_ied_type
+        description: 输出装置类型
+        required: true
+        type: string
+      - in: formData
+        name: to_ied_type
+        description: 输入装置类型
+        required: true
+        type: string
+      - in: formData
+        name: from_fcda_id
+        description: 输出装置端子ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: to_fcda_ids
+        description: 输入装置端子ID列表。多个ID间使用逗号分隔
+        required: true
+        type: string
+      - in: formData
+        name: goosesv
+        description: 信号类型。值范围:GOOSE|SV
+        required: true
+        type: string
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
+  /admin/model/function/fcda/del:
+    post:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 删除装置端子
+      description: 删除装置端子
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: fcda_id
+        description: 端子ID
+        required: true
+        type: integer
+        format: int64
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
+  /admin/model/function/fcda/list:
+    get:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 获取指定模型和装置类型的端子列表
+      description: 获取指定模型和装置类型的端子列表
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: ied_type
+        description: 装置类型
+        required: true
+        type: string
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
+  /admin/model/function/fcda/save:
+    post:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 保存模型装置功能及端子信息
+      description: 保存装置功能及端子信息
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: ied_type
+        description: 装置类型代码
+        required: true
+        type: string
+      - in: formData
+        name: func_id
+        description: 功能ID。编辑时必传。
+        type: integer
+        format: int64
+      - in: formData
+        name: func_name
+        description: 功能名称。必传。
+        required: true
+        type: string
+      - in: formData
+        name: fcda_id
+        description: 端子ID。编辑时必传。
+        type: integer
+        format: int64
+      - in: formData
+        name: fcda_name
+        description: 功能名称。必传。
+        required: true
+        type: string
+      - in: formData
+        name: fcda_match_exp
+        description: 端子匹配表达式。必传。
+        required: true
+        type: string
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
+  /admin/model/function/list:
+    get:
+      tags:
+      - scd_check_tools/controllersBusAdminController
+      summary: 获取指定模型和装置类型的功能列表
+      description: 获取指定模型和装置类型的功能列表
+      parameters:
+      - in: formData
+        name: model_id
+        description: 模型ID
+        required: true
+        type: integer
+        format: int64
+      - in: formData
+        name: ied_type
+        description: 装置类型
+        required: true
+        type: string
+      responses:
+        "200":
+          description: 成功
+          schema:
+            $ref: '#/definitions/ResultOK'
+        "500":
+          description: '{object} ResultError  失败'
   /admin/parse/check_area:
     post:
       tags: