123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- package bo
- import (
- "errors"
- "fmt"
- "scd_check_tools/logger"
- "scd_check_tools/models/enum"
- "scd_check_tools/tools"
- "strconv"
- "strings"
- "github.com/astaxie/beego/orm"
- )
- //系统内置模型-装置功能管理
- type T_data_model_func_def struct {
- Id int `orm:"pk"`
- ModelId int // '模型ID' ,
- IedType string // '装置类型;关联代码:device_type',
- FuncName string // '功能名称',
- FuncFcdaId int `orm:"-"`
- FcdaName string `orm:"-"` // 端子设计名称
- FcdaMatchExp string `orm:"-"` // 端子匹配表达式
- Svorgoose string `orm:"-"`
- Inorout string `orm:"-"`
- ReceiveIedType string `orm:"-"`
- Cr int // '创建人' ,
- Ct string `orm:"-"` // '创建时间' ,
- Ur int // '更新人' ,
- Ut string `orm:"-"` // '更新时间'
- }
- //内置检测模型-装置功能管理对象
- type SysCheckModelIedFuncMgr struct {
- Model T_data_model_func_def
- DeviceBaseModel
- }
- var sysCheckModel_iedFuncDesc = "内置检测模型-装置功能管理"
- func init() {
- orm.RegisterModel(new(T_data_model_func_def))
- }
- //保存检测模型装置功能信息
- func (c *SysCheckModelIedFuncMgr) Save() (funcid, fcdaid int, err error) {
- dblog := new(SystemLog)
- dblog.SetUserInfo(c.GetUserInfo())
- dblog.Audittype = enum.AuditType_check_model
- dblog.Logtype = enum.LogType_Insert
- dblog.Eventtype = enum.OptEventType_Bus
- dblog.Eventlevel = enum.OptEventLevel_Hight
- db := orm.NewOrm()
- hasName, err := c.Exist()
- if err != nil {
- return 0, 0, err
- }
- if c.Model.Svorgoose != "SV" && c.Model.Svorgoose != "GOOSE" {
- return 0, 0, errors.New("端子信号类型值无效,仅支持SV或GOOSE")
- }
- if !strings.Contains(c.Model.Inorout, "接收") && !strings.Contains(c.Model.Inorout, "输出") {
- return 0, 0, errors.New("端子信号方向值无效,仅支持'接收'或'输出'")
- }
- funcid2 := int64(c.Model.Id)
- db.Begin()
- if c.Model.Id > 0 {
- //编辑
- if hasName > 0 && c.Model.Id != hasName {
- db.Rollback()
- return 0, 0, errors.New("功能名称已存在")
- }
- _, err = db.Update(&c.Model)
- } else {
- //新增
- if hasName > 0 {
- db.Rollback()
- return 0, 0, errors.New("功能名称已存在")
- }
- funcid2, err = db.Insert(&c.Model)
- }
- if err != nil {
- logger.Logger.Error(err)
- dblog.Description = fmt.Sprintf("保存%s信息失败:%s,操作数据:%+v", sysCheckModel_iedFuncDesc, err.Error(), c.Model)
- dblog.Fail2()
- return 0, 0, err
- } else {
- //保存功能-端子定义
- fcdaMgr := new(SysCheckModelIedFuncFcdaMgr)
- fcdaMgr.Model = T_data_model_func_fcda{ModelId: c.Model.ModelId}
- if c.Model.FuncFcdaId > 0 {
- fcdaMgr.Model.Id = c.Model.FuncFcdaId
- }
- fcdaMgr.Model.FcdaMatchExp = c.Model.FcdaMatchExp
- fcdaMgr.Model.FcdaName = c.Model.FcdaName
- fcdaMgr.Model.FuncId = int(funcid2)
- fcdaMgr.Model.Svorgoose = c.Model.Svorgoose
- fcdaMgr.Model.Inorout = c.Model.Inorout
- fcdaMgr.Model.ReceiveIedType = c.Model.ReceiveIedType
- fcdaid, err = fcdaMgr.Save()
- if err != nil {
- db.Rollback()
- logger.Logger.Error(err)
- dblog.Description = fmt.Sprintf("保存%s信息失败:%s,操作数据:%+v", sysCheckModel_iedFuncDesc, err.Error(), c.Model)
- dblog.Fail2()
- return 0, 0, err
- }
- db.Commit()
- fcdaMgr.Model.Id = fcdaid
- dblog.Description = fmt.Sprintf("保存%s信息成功,操作数据:%+v", sysCheckModel_iedFuncDesc, c.Model)
- dblog.Success2()
- return int(funcid2), fcdaMgr.Model.Id, nil
- }
- }
- func (c *SysCheckModelIedFuncMgr) Exist() (int, error) {
- db := orm.NewOrm()
- if c.Model.FuncName == "" {
- return 0, errors.New("功能名称不能为空")
- }
- rowset := []orm.Params{}
- _, err := db.Raw("select id from t_data_model_func_def where model_id=? and ied_type=? and func_name=?", c.Model.ModelId, c.Model.IedType, c.Model.FuncName).Values(&rowset)
- if len(rowset) > 0 {
- id, _ := strconv.Atoi(tools.IsEmpty(rowset[0]["id"]))
- return id, nil
- }
- return 0, err
- }
- func (c *SysCheckModelIedFuncMgr) GetFuncId(modid int, iedtpye, name string) (int, error) {
- rowset := []orm.Params{}
- db := orm.NewOrm()
- _, err := db.Raw("select id from t_data_model_func_def where model_id=? and ied_type=? and func_name=?", modid, iedtpye, name).Values(&rowset)
- if len(rowset) > 0 {
- id, _ := strconv.Atoi(tools.IsEmpty(rowset[0]["id"]))
- return id, nil
- }
- return 0, err
- }
- func (c *SysCheckModelIedFuncMgr) Copy(oldModelid, newModelId int) error {
- db := orm.NewOrm()
- //将原端子关联数据复制到新模型
- _, err := db.Raw("insert into t_data_model_fcda_ref(model_id,relation_ref,from_ied_code,from_func_id,from_fcda_id,to_ied_code,to_func_id,to_fcda_id,goosesv) select ?,relation_ref,from_ied_code,from_func_id,from_fcda_id,to_ied_code,to_func_id,to_fcda_id,goosesv from t_data_model_fcda_ref where model_id=?", newModelId, oldModelid).Exec()
- if err != nil {
- logger.Logger.Error(err)
- return err
- }
- rowset := []orm.Params{}
- db.Raw("select * from t_data_model_func_def where model_id=?", oldModelid).Values(&rowset)
- for _, row := range rowset {
- oldFuncId, _ := strconv.Atoi(tools.IsEmpty(row["id"]))
- //复制功能数据
- newFunc := T_data_model_func_def{
- ModelId: newModelId,
- IedType: tools.IsEmpty(row["ied_type"]),
- FuncName: tools.IsEmpty(row["func_name"]),
- }
- newid, err := db.Insert(&newFunc)
- if err != nil {
- logger.Logger.Error(err)
- return err
- }
- //复制功能下的端子信息
- m1 := new(SysCheckModelIedFuncFcdaMgr)
- m1.Model = T_data_model_func_fcda{ModelId: oldModelid}
- err = m1.Copy(oldFuncId, newModelId, int(newid))
- if err != nil {
- newFunc.Id = int(newid)
- db.Delete(&newFunc)
- return err
- }
- }
- return nil
- }
- //根据model中指定的id删除
- //onlyFunc: true表示只删除功能数据,不进行关联端子删除;false表示需要关联删除端子。默认为关联删除端子
- func (c *SysCheckModelIedFuncMgr) Delete(onlyFunc ...bool) (err error) {
- dblog := new(SystemLog)
- dblog.SetUserInfo(c.GetUserInfo())
- dblog.Audittype = enum.AuditType_check_model
- dblog.Logtype = enum.LogType_Delete
- dblog.Eventtype = enum.OptEventType_Bus
- dblog.Eventlevel = enum.OptEventLevel_Hight
- db := orm.NewOrm()
- funcLst := []orm.Params{}
- if c.Model.Id > 0 {
- _, err = db.Raw("delete from t_data_model_func_def where id=?", c.Model.Id).Exec()
- } else if c.Model.IedType != "" {
- //删除指定装置类型的数据
- db.Raw("select id from t_data_model_func_def where model_id=? and ied_type=?", c.Model.ModelId, c.Model.IedType).Values(&funcLst)
- _, err = db.Raw("delete from t_data_model_func_def where model_id=? and ied_type=?", c.Model.ModelId, c.Model.IedType).Exec()
- } else {
- _, err = db.Raw("delete from t_data_model_func_def where model_id=?", c.Model.ModelId).Exec()
- }
- if err != nil {
- logger.Logger.Error(err)
- dblog.Description = fmt.Sprintf("删除%s(%d)失败:%s", sysCheckModel_iedFuncDesc, c.Model.ModelId, err.Error())
- dblog.Fail2()
- } else {
- isnotdelFcda := false
- if len(onlyFunc) > 0 {
- isnotdelFcda = onlyFunc[0]
- }
- if !isnotdelFcda {
- fcdaMgr := new(SysCheckModelIedFuncFcdaMgr)
- fcdaMgr.Model = T_data_model_func_fcda{ModelId: c.Model.ModelId}
- if c.Model.Id > 0 {
- fcdaMgr.Model.FuncId = c.Model.Id
- }
- if c.Model.IedType != "" {
- //删除所有功能的相关数据
- for _, row := range funcLst {
- fcdaMgr.Model.FuncId, _ = strconv.Atoi(tools.IsEmpty(row["id"]))
- fcdaMgr.Delete()
- }
- } else {
- fcdaMgr.Delete()
- }
- }
- dblog.Description = fmt.Sprintf("删除%s(%d)成功", sysCheckModel_iedFuncDesc, c.Model.ModelId)
- dblog.Success2()
- }
- return err
- }
- func (c *SysCheckModelIedFuncMgr) GetList(modelid int, iedType string) ([]orm.Params, error) {
- /*
- mappresult := new(SysCheckModelIedtypeMappingMgr).GetMappingType(modelid, iedType)
- if mappresult != "" {
- iedType = mappresult
- }
- */
- //获取装置分组信息
- bgm := new(SysCheckModelIedtypeGroupMgr)
- bgm.Model = T_data_model_iedtype_group{ModelId: modelid}
- groupList := bgm.List()
- tmpAry := []string{}
- if len(groupList) > 0 {
- //判断是否是获取的分组装置,是则需要将子装置所有功能返回
- for k, v := range groupList {
- if v == iedType {
- tmpAry = append(tmpAry, k)
- }
- }
- if len(tmpAry) > 0 {
- iedType = strings.Join(tmpAry, "','")
- }
- }
- o := orm.NewOrm()
- sqlParamters := []interface{}{modelid}
- sql := "select t.* from t_data_model_func_def t where t.model_id=? and ied_type in('" + iedType + "')"
- rowset := []orm.Params{}
- _, err := o.Raw(sql, sqlParamters).Values(&rowset)
- if err != nil {
- logger.Logger.Error(err)
- }
- return rowset, err
- }
- //从excel中导入
- func (c *SysCheckModelIedFuncMgr) Imp(param map[string]interface{}) (bool, error) {
- modelId, _ := strconv.Atoi(tools.IsEmpty(param["model_id"]))
- if modelId == 0 {
- return false, errors.New("模型编号不能为空")
- }
- datalist := param["datalist"].([]map[int]string)
- logObj := new(SystemLog)
- logObj.SetUserInfo(c.GetUserInfo())
- logObj.Audittype = enum.AuditType_check_model
- logObj.Eventtype = enum.OptEventType_Bus
- logObj.Eventlevel = enum.OptEventLevel_Hight
- logObj.Logtype = enum.LogType_imp
- logObj.Description = "装置功能及端子导入"
- //模型信息
- modelObj := new(SysCheckModelMgr)
- modelObj.Model.Id = modelId
- modelInfo, dberr := modelObj.One()
- if modelInfo.Id == 0 || dberr != nil {
- return false, errors.New(fmt.Sprintf("无效的模型编号:%d", modelId))
- }
- modelInfoIedTypes := "," + tools.IsEmpty(modelInfo.IedTypes) + ","
- i := 2
- func_id := 0
- fcda_id := 0
- funcMap := map[string]int{} //已处理的功能
- 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()
- autoRows := []T_data_model_func_def{}
- for _, row := range datalist {
- ied_type := strings.ToUpper(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
- }
- func_name := row[3]
- if func_name == "" {
- return false, errors.New(fmt.Sprintf("第%d行:功能名称不能为空", i))
- }
- fcda_name := strings.ReplaceAll(strings.ReplaceAll(row[4], "(", "("), ")", ")")
- if fcda_name == "" {
- return false, errors.New(fmt.Sprintf("第%d行:端子设计名称不能为空", i))
- }
- fcda_match_exp := strings.ReplaceAll(strings.ReplaceAll(row[5], "(", "("), ")", ")")
- if fcda_match_exp == "" {
- return false, errors.New(fmt.Sprintf("第%d行:端子关键词不能为空", i))
- }
- svorgoose := row[6]
- if svorgoose == "" {
- return false, errors.New(fmt.Sprintf("第%d行:信号类型不能为空", i))
- }
- inorout := strings.ReplaceAll(strings.ReplaceAll(row[7], "&", ","), ",", ",")
- if inorout == "" {
- return false, errors.New(fmt.Sprintf("第%d行:信号方向不能为空", i))
- }
- receive_ied_type := strings.ReplaceAll(strings.ReplaceAll(row[8], "&", ","), ",", ",") //对侧接收装置类型
- /*
- tmpAry := strings.Split(receive_ied_type, ",")
- for i, item := range tmpAry {
- if groupList != nil && groupList[item] != "" {
- tmpAry[i] = groupList[item]
- }
- }
- receive_ied_type = strings.Join(tmpAry, ",")
- */
- funckey := fmt.Sprintf("%d%s%s", modelId, ied_type, func_name)
- func_id = funcMap[funckey]
- if func_id == 0 {
- //获取功能id
- func_id, _ = c.GetFuncId(modelId, ied_type, func_name)
- funcMap[funckey] = func_id
- }
- if func_id > 0 {
- fcdaKey := fmt.Sprintf("%d%s", func_id, fcda_name)
- fcda_id = fcdaMap[fcdaKey]
- if fcda_id == 0 {
- fcdaMgr.Model.FuncId = func_id
- fcdaMgr.Model.FcdaName = fcda_name
- _, fcda_id, _ := fcdaMgr.Exist()
- fcdaMap[fcdaKey] = fcda_id
- }
- }
- mod := T_data_model_func_def{}
- if func_id > 0 {
- 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
- mod.Svorgoose = svorgoose
- mod.Inorout = inorout
- mod.ReceiveIedType = receive_ied_type
- c.Model = mod
- funcid, fcdaid, err := c.Save()
- if err != nil {
- return false, errors.New(fmt.Sprintf("第%d行:%s", i, err.Error()))
- }
- mod.Id = funcid
- mod.FuncFcdaId = fcdaid
- autoRows = append(autoRows, mod)
- i = i + 1
- }
- //根据接收装置编码定义,自动建立端子关系
- fcdaMgr.AutoRelation(modelId, autoRows)
- return true, nil
- }
|