check_sysmodel_ied_func.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. package bo
  2. import (
  3. "errors"
  4. "fmt"
  5. "regexp"
  6. "scd_check_tools/logger"
  7. "scd_check_tools/models/enum"
  8. "scd_check_tools/tools"
  9. "strconv"
  10. "strings"
  11. "github.com/astaxie/beego/orm"
  12. )
  13. //系统内置模型-装置功能管理
  14. type T_data_model_func_def struct {
  15. Id int `orm:"pk"`
  16. ModelId int // '模型ID' ,
  17. IedType string // '装置类型;关联代码:device_type',
  18. FuncName string // '功能名称',
  19. FuncFcdaId int `orm:"-"`
  20. FcdaName string `orm:"-"` // 端子设计名称
  21. FcdaMatchExp string `orm:"-"` // 端子匹配表达式
  22. Svorgoose string `orm:"-"`
  23. Inorout string `orm:"-"`
  24. ReceiveIedType string `orm:"-"`
  25. Cr int // '创建人' ,
  26. Ct string `orm:"-"` // '创建时间' ,
  27. Ur int // '更新人' ,
  28. Ut string `orm:"-"` // '更新时间'
  29. }
  30. //内置检测模型-装置功能管理对象
  31. type SysCheckModelIedFuncMgr struct {
  32. Model T_data_model_func_def
  33. DeviceBaseModel
  34. }
  35. var sysCheckModel_iedFuncDesc = "内置检测模型-装置功能管理"
  36. func init() {
  37. orm.RegisterModel(new(T_data_model_func_def))
  38. }
  39. //保存检测模型装置功能信息
  40. func (c *SysCheckModelIedFuncMgr) Save() (funcid, fcdaid int, err error) {
  41. dblog := new(SystemLog)
  42. dblog.SetUserInfo(c.GetUserInfo())
  43. dblog.Audittype = enum.AuditType_check_model
  44. dblog.Logtype = enum.LogType_Insert
  45. dblog.Eventtype = enum.OptEventType_Bus
  46. dblog.Eventlevel = enum.OptEventLevel_Hight
  47. db := orm.NewOrm()
  48. hasName, err := c.Exist()
  49. if err != nil {
  50. return 0, 0, err
  51. }
  52. if c.Model.Svorgoose != "SV" && c.Model.Svorgoose != "GOOSE" {
  53. return 0, 0, errors.New("端子信号类型值无效,仅支持SV或GOOSE")
  54. }
  55. if !strings.Contains(c.Model.Inorout, "接收") && !strings.Contains(c.Model.Inorout, "输出") {
  56. return 0, 0, errors.New("端子信号方向值无效,仅支持'接收'或'输出'")
  57. }
  58. funcid2 := int64(c.Model.Id)
  59. db.Begin()
  60. if c.Model.Id > 0 {
  61. //编辑
  62. if hasName > 0 && c.Model.Id != hasName {
  63. db.Rollback()
  64. return 0, 0, errors.New("功能名称已存在")
  65. }
  66. _, err = db.Update(&c.Model)
  67. } else {
  68. //新增
  69. if hasName > 0 {
  70. db.Rollback()
  71. return 0, 0, errors.New("功能名称已存在")
  72. }
  73. funcid2, err = db.Insert(&c.Model)
  74. }
  75. if err != nil {
  76. logger.Logger.Error(err)
  77. dblog.Description = fmt.Sprintf("保存%s信息失败:%s,操作数据:%+v", sysCheckModel_iedFuncDesc, err.Error(), c.Model)
  78. dblog.Fail2()
  79. return 0, 0, err
  80. } else {
  81. //保存功能-端子定义
  82. fcdaMgr := new(SysCheckModelIedFuncFcdaMgr)
  83. fcdaMgr.Model = T_data_model_func_fcda{ModelId: c.Model.ModelId}
  84. if c.Model.FuncFcdaId > 0 {
  85. fcdaMgr.Model.Id = c.Model.FuncFcdaId
  86. }
  87. fcdaMgr.Model.FcdaMatchExp = c.Model.FcdaMatchExp
  88. fcdaMgr.Model.FcdaName = c.Model.FcdaName
  89. fcdaMgr.Model.FuncId = int(funcid2)
  90. fcdaMgr.Model.Svorgoose = c.Model.Svorgoose
  91. fcdaMgr.Model.Inorout = c.Model.Inorout
  92. fcdaMgr.Model.ReceiveIedType = c.Model.ReceiveIedType
  93. fcdaid, err = fcdaMgr.Save()
  94. if err != nil {
  95. db.Rollback()
  96. logger.Logger.Error(err)
  97. dblog.Description = fmt.Sprintf("保存%s信息失败:%s,操作数据:%+v", sysCheckModel_iedFuncDesc, err.Error(), c.Model)
  98. dblog.Fail2()
  99. return 0, 0, err
  100. }
  101. db.Commit()
  102. fcdaMgr.Model.Id = fcdaid
  103. dblog.Description = fmt.Sprintf("保存%s信息成功,操作数据:%+v", sysCheckModel_iedFuncDesc, c.Model)
  104. dblog.Success2()
  105. return int(funcid2), fcdaMgr.Model.Id, nil
  106. }
  107. }
  108. func (c *SysCheckModelIedFuncMgr) Exist() (int, error) {
  109. db := orm.NewOrm()
  110. if c.Model.FuncName == "" {
  111. return 0, errors.New("功能名称不能为空")
  112. }
  113. rowset := []orm.Params{}
  114. _, 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)
  115. if len(rowset) > 0 {
  116. id, _ := strconv.Atoi(tools.IsEmpty(rowset[0]["id"]))
  117. return id, nil
  118. }
  119. return 0, err
  120. }
  121. func (c *SysCheckModelIedFuncMgr) GetFuncId(modid int, iedtpye, name string) (int, error) {
  122. rowset := []orm.Params{}
  123. db := orm.NewOrm()
  124. _, 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)
  125. if len(rowset) > 0 {
  126. id, _ := strconv.Atoi(tools.IsEmpty(rowset[0]["id"]))
  127. return id, nil
  128. }
  129. return 0, err
  130. }
  131. func (c *SysCheckModelIedFuncMgr) Copy(oldModelid, newModelId int) error {
  132. db := orm.NewOrm()
  133. //将原端子关联数据复制到新模型
  134. _, 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()
  135. if err != nil {
  136. logger.Logger.Error(err)
  137. return err
  138. }
  139. rowset := []orm.Params{}
  140. db.Raw("select * from t_data_model_func_def where model_id=?", oldModelid).Values(&rowset)
  141. for _, row := range rowset {
  142. oldFuncId, _ := strconv.Atoi(tools.IsEmpty(row["id"]))
  143. //复制功能数据
  144. newFunc := T_data_model_func_def{
  145. ModelId: newModelId,
  146. IedType: tools.IsEmpty(row["ied_type"]),
  147. FuncName: tools.IsEmpty(row["func_name"]),
  148. }
  149. newid, err := db.Insert(&newFunc)
  150. if err != nil {
  151. logger.Logger.Error(err)
  152. return err
  153. }
  154. //复制功能下的端子信息
  155. m1 := new(SysCheckModelIedFuncFcdaMgr)
  156. m1.Model = T_data_model_func_fcda{ModelId: oldModelid}
  157. err = m1.Copy(oldFuncId, newModelId, int(newid))
  158. if err != nil {
  159. newFunc.Id = int(newid)
  160. db.Delete(&newFunc)
  161. return err
  162. }
  163. }
  164. return nil
  165. }
  166. //根据model中指定的id删除
  167. //onlyFunc: true表示只删除功能数据,不进行关联端子删除;false表示需要关联删除端子。默认为关联删除端子
  168. func (c *SysCheckModelIedFuncMgr) Delete(onlyFunc ...bool) (err error) {
  169. dblog := new(SystemLog)
  170. dblog.SetUserInfo(c.GetUserInfo())
  171. dblog.Audittype = enum.AuditType_check_model
  172. dblog.Logtype = enum.LogType_Delete
  173. dblog.Eventtype = enum.OptEventType_Bus
  174. dblog.Eventlevel = enum.OptEventLevel_Hight
  175. db := orm.NewOrm()
  176. funcLst := []orm.Params{}
  177. if c.Model.Id > 0 {
  178. _, err = db.Raw("delete from t_data_model_func_def where id=?", c.Model.Id).Exec()
  179. } else if c.Model.IedType != "" {
  180. //删除指定装置类型的数据
  181. db.Raw("select id from t_data_model_func_def where model_id=? and ied_type=?", c.Model.ModelId, c.Model.IedType).Values(&funcLst)
  182. _, err = db.Raw("delete from t_data_model_func_def where model_id=? and ied_type=?", c.Model.ModelId, c.Model.IedType).Exec()
  183. } else {
  184. _, err = db.Raw("delete from t_data_model_func_def where model_id=?", c.Model.ModelId).Exec()
  185. }
  186. if err != nil {
  187. logger.Logger.Error(err)
  188. dblog.Description = fmt.Sprintf("删除%s(%d)失败:%s", sysCheckModel_iedFuncDesc, c.Model.ModelId, err.Error())
  189. dblog.Fail2()
  190. } else {
  191. isnotdelFcda := false
  192. if len(onlyFunc) > 0 {
  193. isnotdelFcda = onlyFunc[0]
  194. }
  195. if !isnotdelFcda {
  196. fcdaMgr := new(SysCheckModelIedFuncFcdaMgr)
  197. fcdaMgr.Model = T_data_model_func_fcda{ModelId: c.Model.ModelId}
  198. if c.Model.Id > 0 {
  199. fcdaMgr.Model.FuncId = c.Model.Id
  200. }
  201. if c.Model.IedType != "" {
  202. //删除所有功能的相关数据
  203. for _, row := range funcLst {
  204. fcdaMgr.Model.FuncId, _ = strconv.Atoi(tools.IsEmpty(row["id"]))
  205. fcdaMgr.Delete()
  206. }
  207. } else {
  208. fcdaMgr.Delete()
  209. }
  210. }
  211. dblog.Description = fmt.Sprintf("删除%s(%d)成功", sysCheckModel_iedFuncDesc, c.Model.ModelId)
  212. dblog.Success2()
  213. }
  214. return err
  215. }
  216. func (c *SysCheckModelIedFuncMgr) GetList(modelid int, iedType string) ([]orm.Params, error) {
  217. /*
  218. mappresult := new(SysCheckModelIedtypeMappingMgr).GetMappingType(modelid, iedType)
  219. if mappresult != "" {
  220. iedType = mappresult
  221. }
  222. */
  223. //获取装置分组信息
  224. bgm := new(SysCheckModelIedtypeGroupMgr)
  225. bgm.Model = T_data_model_iedtype_group{ModelId: modelid}
  226. groupList := bgm.List()
  227. tmpAry := []string{}
  228. if len(groupList) > 0 {
  229. //判断是否是获取的分组装置,是则需要将子装置所有功能返回
  230. for k, v := range groupList {
  231. if v == iedType {
  232. tmpAry = append(tmpAry, k)
  233. }
  234. }
  235. if len(tmpAry) > 0 {
  236. iedType = strings.Join(tmpAry, "','")
  237. }
  238. }
  239. o := orm.NewOrm()
  240. sqlParamters := []interface{}{modelid}
  241. sql := "select t.* from t_data_model_func_def t where t.model_id=? and ied_type in('" + iedType + "')"
  242. rowset := []orm.Params{}
  243. _, err := o.Raw(sql, sqlParamters).Values(&rowset)
  244. if err != nil {
  245. logger.Logger.Error(err)
  246. }
  247. return rowset, err
  248. }
  249. //从excel中导入
  250. func (c *SysCheckModelIedFuncMgr) Imp(param map[string]interface{}) (bool, error) {
  251. modelId, _ := strconv.Atoi(tools.IsEmpty(param["model_id"]))
  252. if modelId == 0 {
  253. return false, errors.New("模型编号不能为空")
  254. }
  255. datalist := param["datalist"].([]map[int]string)
  256. logObj := new(SystemLog)
  257. logObj.SetUserInfo(c.GetUserInfo())
  258. logObj.Audittype = enum.AuditType_check_model
  259. logObj.Eventtype = enum.OptEventType_Bus
  260. logObj.Eventlevel = enum.OptEventLevel_Hight
  261. logObj.Logtype = enum.LogType_imp
  262. logObj.Description = "装置功能及端子导入"
  263. //模型信息
  264. modelObj := new(SysCheckModelMgr)
  265. modelObj.Model.Id = modelId
  266. modelInfo, dberr := modelObj.One()
  267. if modelInfo.Id == 0 || dberr != nil {
  268. return false, errors.New(fmt.Sprintf("无效的模型编号:%d", modelId))
  269. }
  270. modelInfoIedTypes := map[string][]string{} //"," + tools.IsEmpty(modelInfo.IedTypes) + ","
  271. for _, t := range strings.Split(tools.IsEmpty(modelInfo.IedTypes), ",") {
  272. /*
  273. t1 := strings.Split(t, "-")[0] //装置编码是否有套别
  274. if modelInfoIedTypes[t1] == nil {
  275. modelInfoIedTypes[t1] = []string{t}
  276. } else {
  277. modelInfoIedTypes[t1] = append(modelInfoIedTypes[t1], t)
  278. }
  279. */
  280. modelInfoIedTypes[t] = []string{t}
  281. }
  282. i := 2
  283. func_id := 0
  284. fcda_id := 0
  285. funcMap := map[string]int{} //已处理的功能
  286. fcdaMap := map[string]int{}
  287. fcdaMgr := new(SysCheckModelIedFuncFcdaMgr)
  288. fcdaMgr.Model.ModelId = modelId
  289. autoRows := []T_data_model_func_def{}
  290. for _, row := range datalist {
  291. ied_type := strings.ToUpper(row[2])
  292. if ied_type == "" {
  293. return false, errors.New(fmt.Sprintf("第%d行:装置类型编码不能为空", i))
  294. }
  295. ttt := modelInfoIedTypes[ied_type]
  296. if ttt == nil {
  297. //模型中未发现该装置类型
  298. continue
  299. }
  300. func_name := row[3]
  301. if func_name == "" {
  302. return false, errors.New(fmt.Sprintf("第%d行:功能名称不能为空", i))
  303. }
  304. fcda_name := strings.ReplaceAll(strings.ReplaceAll(row[4], "(", "("), ")", ")")
  305. if fcda_name == "" {
  306. return false, errors.New(fmt.Sprintf("第%d行:端子设计名称不能为空", i))
  307. }
  308. fcda_match_exp := strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(row[5], "(", "("), ")", ")"), "|", "|")
  309. if fcda_match_exp == "" {
  310. return false, errors.New(fmt.Sprintf("第%d行:端子关键词不能为空", i))
  311. }
  312. _, err2 := regexp.Compile(fcda_match_exp)
  313. if err2 != nil {
  314. return false, errors.New(fmt.Sprintf("第%d行:端子关键词%s格式有错误", i, fcda_match_exp))
  315. }
  316. svorgoose := row[6]
  317. if svorgoose == "" {
  318. return false, errors.New(fmt.Sprintf("第%d行:信号类型不能为空", i))
  319. }
  320. inorout := strings.ReplaceAll(strings.ReplaceAll(row[7], "&", ","), ",", ",")
  321. if inorout == "" {
  322. return false, errors.New(fmt.Sprintf("第%d行:信号方向不能为空", i))
  323. }
  324. receive_ied_type := strings.ReplaceAll(strings.ReplaceAll(row[8], "&", ","), ",", ",") //对侧接收装置类型
  325. for tj, t := range ttt {
  326. funckey := fmt.Sprintf("%d%s%s", modelId, t, func_name)
  327. func_id = funcMap[funckey]
  328. if func_id == 0 {
  329. //获取功能id
  330. func_id, _ = c.GetFuncId(modelId, t, func_name)
  331. funcMap[funckey] = func_id
  332. }
  333. if func_id > 0 {
  334. fcdaKey := fmt.Sprintf("%d%s", func_id, fcda_name)
  335. fcda_id = fcdaMap[fcdaKey]
  336. if fcda_id == 0 {
  337. fcdaMgr.Model.FuncId = func_id
  338. fcdaMgr.Model.FcdaName = fcda_name
  339. _, fcda_id, _ := fcdaMgr.Exist()
  340. fcdaMap[fcdaKey] = fcda_id
  341. }
  342. }
  343. mod := T_data_model_func_def{}
  344. if func_id > 0 {
  345. mod.Id = func_id
  346. }
  347. mod.ModelId = modelId
  348. mod.IedType = t
  349. mod.FuncFcdaId = fcda_id
  350. mod.FuncName = func_name
  351. mod.FcdaName = fcda_name
  352. mod.FcdaMatchExp = fcda_match_exp
  353. mod.Svorgoose = svorgoose
  354. mod.Inorout = inorout
  355. if modelInfoIedTypes[receive_ied_type] != nil {
  356. mod.ReceiveIedType = modelInfoIedTypes[receive_ied_type][0]
  357. } else {
  358. mod.ReceiveIedType = receive_ied_type
  359. }
  360. c.Model = mod
  361. funcid, fcdaid, err := c.Save()
  362. if err != nil {
  363. return false, errors.New(fmt.Sprintf("第%d行:%s", i, err.Error()))
  364. }
  365. mod.Id = funcid
  366. mod.FuncFcdaId = fcdaid
  367. if tj == 0 {
  368. //模型中存在多个同类装置时,仅第一个类型装置才自动建立关联,其他的均通过手动关联
  369. autoRows = append(autoRows, mod)
  370. }
  371. }
  372. i = i + 1
  373. }
  374. //根据接收装置编码定义,自动建立端子关系
  375. fcdaMgr.AutoRelation(modelId, autoRows)
  376. return true, nil
  377. }