package bo import ( "encoding/json" "fmt" "io/fs" "os" "scd_check_tools/logger" "scd_check_tools/models/enum" "scd_check_tools/tools" "strconv" "strings" "github.com/astaxie/beego/orm" "github.com/tealeg/xlsx" ) //检测任务报告模型 type T_data_task_report struct { Id int `orm:"pk"` Name string // '报告名称' , Code string // '报告编号' , TaskId int // '所属检测任务' , State int // '生成状态;1 生成中 2生成结束' , Doc string //'下载路径' , Cr int // '创建人' , Ct string `orm:"-"` // '创建时间' , Ur int // '更新人' , Ut string `orm:"-"` // '更新时间' } //检测任务管理对象 type TaskReportMgr struct { Model T_data_task_report DeviceBaseModel } var modelDesc3 = "检测报告" func init() { orm.RegisterModel(new(T_data_task_report)) } //生成报告 func (c *TaskReportMgr) Make() (reprid int, err error) { taskMgr := new(TaskMgr) taskMgr.Model = T_data_task{Id: c.Model.TaskId} taskinfo, e := taskMgr.One() if e != nil { return 0, e } dblog := new(SystemLog) dblog.SetUserInfo(c.GetUserInfo()) dblog.Audittype = enum.AuditType_check_task dblog.Logtype = enum.LogType_Insert dblog.Eventtype = enum.OptEventType_Bus dblog.Eventlevel = enum.OptEventLevel_Hight //判断报告 是否已生成 tmp, _ := c.One(c.Model.TaskId) if tmp.Id > 0 { c.Model.Id = tmp.Id } db := orm.NewOrm() c.Model.Name = taskinfo.Name c.Model.Code = taskinfo.Code if c.Model.Id == 0 { c.Model.Cr, _ = strconv.Atoi(c.GetUserId()) newid, err2 := db.Insert(&c.Model) err = err2 c.Model.Id = int(newid) } else { c.Model.Ur, _ = strconv.Atoi(c.GetUserId()) _, err = db.Update(&c.Model) } if err != nil { logger.Logger.Error(err) dblog.Description = fmt.Sprintf("生成%s失败:%s,操作数据:%+v", modelDesc3, err.Error(), c.Model) dblog.Fail2() } else { //根据模板生成报告 wordpath, err := c.ToWord(taskinfo) if err != nil { c.Delete() return 0, err } c.Model.Doc = wordpath c.Model.State = 2 _, err = db.Update(&c.Model) dblog.Description = fmt.Sprintf("生成%s成功,操作数据:%+v", modelDesc3, c.Model) dblog.Success2() } return c.Model.Id, err } func (c *TaskReportMgr) List(pageno, pagesize int) ([]orm.Params, int, error) { o := orm.NewOrm() rowset := []orm.Params{} sqlParams := []interface{}{} sql := "select t.name,t.code,t.scd_id,a.scd_name,t1.id report_id, t1.doc,t1.state report_state from t_data_task t left join t_data_task_report t1 on t.id=t1.task_id left join t_scd_scl a on t.scd_id=a.id where t.state=2 " if c.Model.TaskId > 0 { sql = sql + " and t.id=?" sqlParams = append(sqlParams, c.Model.TaskId) } if c.Model.Name != "" { sql = sql + " and t.name like ?" sqlParams = append(sqlParams, "%"+c.Model.Name+"%") } if c.Model.Code != "" { sql = sql + " and t.code like ?" sqlParams = append(sqlParams, "%"+c.Model.Code+"%") } limit := fmt.Sprintf(" order by t.ct desc limit %d,%d", (pageno-1)*pagesize, pagesize) _, err := o.Raw(sql+limit, sqlParams).Values(&rowset) total := []orm.Params{} _, err = o.Raw(strings.Replace(sql, "*", "count(1) cnt", 1), sqlParams).Values(&total) if err != nil { logger.Logger.Error(err) return nil, 0, err } totalCnt := 0 if len(total) > 0 { totalCnt, _ = strconv.Atoi(tools.IsEmpty(total[0]["cnt"])) } return rowset, totalCnt, err } func (c *TaskReportMgr) One(taskid int) (T_data_task_report, error) { o := orm.NewOrm() tmp := T_data_task_report{} if c.Model.Id > 0 { tmp.Id = c.Model.Id err := o.Read(&tmp) return tmp, err } rowset := []orm.Params{} o.Raw("select * from t_data_task_report where task_id=?", taskid).Values(&rowset) if len(rowset) == 0 { return tmp, nil } tmp.Id, _ = strconv.Atoi(tools.IsEmpty(rowset[0]["id"])) tmp.Code = tools.IsEmpty(rowset[0]["code"]) tmp.Name = tools.IsEmpty(rowset[0]["name"]) tmp.TaskId = taskid tmp.Doc = tools.IsEmpty(rowset[0]["doc"]) tmp.State, _ = strconv.Atoi(tools.IsEmpty(rowset[0]["state"])) return tmp, nil } //根据model中指定的id删除检测任务报告 func (c *TaskReportMgr) Delete() (err error) { dblog := new(SystemLog) dblog.SetUserInfo(c.GetUserInfo()) dblog.Audittype = enum.AuditType_check_task dblog.Logtype = enum.LogType_Delete dblog.Eventtype = enum.OptEventType_Bus dblog.Eventlevel = enum.OptEventLevel_Hight db := orm.NewOrm() if c.Model.Id > 0 { db.Read(&c.Model) _, err = db.Delete(&c.Model) } if c.Model.TaskId > 0 { _, err = db.Raw("delete from t_data_task_report where task_id=?", c.Model.TaskId).Exec() } if err != nil { logger.Logger.Error(err) dblog.Description = fmt.Sprintf("删除%s%d失败:%s", modelDesc3, c.Model.TaskId, err.Error()) dblog.Fail2() } else { if c.Model.Doc != "" { //os.RemoveAll("./" + c.Model.Doc) } dblog.Description = fmt.Sprintf("删除%s%d成功", modelDesc3, c.Model.TaskId) dblog.Success2() } return err } func (c *TaskReportMgr) ToWord(taskinfo T_data_task) (path string, err error) { /* fileMgr := new(AttachmentMgr) fileMgr.Model = T_sys_attachment{Id: int32(taskinfo.ReportId)} fileinfo, err := fileMgr.One() if err != nil { return "", err } */ scdmgr := new(ScdMgr) scdParse := new(ScdParse) scdinfo, _ := scdmgr.One(tools.IsEmpty(taskinfo.ScdId)) scdName := tools.IsEmpty(scdinfo["scd_name"]) sdcXmlObj, _ := scdParse.GetScdXmlObjectBySCDID(tools.IsEmpty(taskinfo.ScdId)) reportPath := strings.Join([]string{".", "static", "download", "report"}, string(os.PathSeparator)) os.MkdirAll(reportPath, fs.ModePerm) reportFN := reportPath + string(os.PathSeparator) + fmt.Sprintf("%s.%s", c.Model.Code, "xlsx") logger.Logger.Debug(fmt.Sprintf("正在生成检测报告文件:%s", reportFN)) /* err = os.Rename(fileinfo.SavePath, reportFN) if err != nil { return "", err } */ scdRuleResult := new(ScdNodeRule) scdRuleResult.ScdID = taskinfo.ScdId result, _, err := scdRuleResult.ResultList("", "", "", "", "", "", 1, 1000000) if err != nil { logger.Logger.Error(err) return "", err } //生成报告数据 var file *xlsx.File file = xlsx.NewFile() sheet_fcda, err := file.AddSheet("虚端子关系") if err != nil { logger.Logger.Error(err) return "", err } sheet_c, err := file.AddSheet("测控装置") if err != nil { logger.Logger.Error(err) return "", err } sheet_p, err := file.AddSheet("保护装置") if err != nil { logger.Logger.Error(err) return "", err } sheet_i, err := file.AddSheet("智能终端") if err != nil { logger.Logger.Error(err) return "", err } sheet_m, err := file.AddSheet("合并单元") if err != nil { logger.Logger.Error(err) return "", err } sheet_other, err := file.AddSheet("schema语法和数据模板") if err != nil { logger.Logger.Error(err) return "", err } c.setCaption(sheet_other, fmt.Sprintf("%-%", scdName, "语法校验结果")) //生成标题行 c.addCellValue(sheet_other, []string{"序号", "行号", "等级", "校验结果内容", "应用标准", "标准条款"}) //生成报表数据 iedResultMap := map[string][]orm.Params{} rowInd := 1 for _, row := range result { ied_name := tools.IsEmpty(row["ied_name"]) if ied_name == "" { //生成数据行 c.addCellValue(sheet_other, []string{ fmt.Sprintf("%d", rowInd), tools.IsEmpty(row["line_no"]), tools.IsEmpty(row["alert_level"]), tools.IsEmpty(row["parse_result"]), tools.IsEmpty(row["apply_standard"]), tools.IsEmpty(row["apply_standard_no"]), }) rowInd = rowInd + 1 } else { iedResultMap[ied_name] = append(iedResultMap[ied_name], row) } } crcFilePath := fmt.Sprintf(strings.Join([]string{".", "static", "upload", ""}, string(os.PathSeparator))+"%d.scd.crc", taskinfo.ScdId) crctext, _ := os.ReadFile(crcFilePath) crcMap := map[string]string{} json.Unmarshal(crctext, &crcMap) scdNodeMgr := new(ScdNode) for ied_name, lst := range iedResultMap { iedObj := scdNodeMgr.GetIed(sdcXmlObj, tools.IsEmpty(taskinfo.ScdId), ied_name) sheetObj := new(xlsx.Sheet) //生成装置标题行 switch strings.ToUpper(ied_name[0:1]) { case "C": sheetObj = sheet_c c.setCaption(sheetObj, fmt.Sprintf("%s-装置(%s)校验结果", scdName, ied_name)) c.addCellValue(sheetObj, []string{"装置编号", "装置名称", "厂家", "型号", "类型", "校验码"}) c.addCellValue(sheetObj, []string{ied_name, iedObj.Desc, iedObj.Manufacturer, iedObj.Type, "测控", crcMap[ied_name]}) break case "P": sheetObj = sheet_p c.setCaption(sheetObj, fmt.Sprintf("%s-装置(%s)校验结果", scdName, ied_name)) c.addCellValue(sheetObj, []string{"装置编号", "装置名称", "厂家", "型号", "类型", "校验码"}) c.addCellValue(sheetObj, []string{ied_name, iedObj.Desc, iedObj.Manufacturer, iedObj.Type, "保护装置", crcMap[ied_name]}) break case "I": sheetObj = sheet_i c.setCaption(sheetObj, fmt.Sprintf("%s-装置(%s)校验结果", scdName, ied_name)) c.addCellValue(sheetObj, []string{"装置编号", "装置名称", "厂家", "型号", "类型", "校验码"}) c.addCellValue(sheetObj, []string{ied_name, iedObj.Desc, iedObj.Manufacturer, iedObj.Type, "智能终端", crcMap[ied_name]}) break case "M": sheetObj = sheet_m c.setCaption(sheetObj, fmt.Sprintf("%s-装置(%s)校验结果", scdName, ied_name)) c.addCellValue(sheetObj, []string{"装置编号", "装置名称", "厂家", "型号", "类型", "校验码"}) c.addCellValue(sheetObj, []string{ied_name, iedObj.Desc, iedObj.Manufacturer, iedObj.Type, "合并单元", crcMap[ied_name]}) break default: continue } //装置信息行 c.addCellValue(sheetObj, []string{"序号", "行号", "等级", "校验结果内容", "应用标准", "标准条款"}) //数据行 rowInd := 1 for _, r := range lst { c.addCellValue(sheetObj, []string{ tools.IsEmpty(rowInd), tools.IsEmpty(r["line_no"]), tools.IsEmpty(r["alert_level"]), tools.IsEmpty(r["parse_result"]), tools.IsEmpty(r["apply_standard"]), tools.IsEmpty(r["apply_standard_no"]), }) rowInd = rowInd + 1 } } result = nil iedResultMap = nil //生成端子关系检查结果 checkAreaRe := new(CheckAreaMgr) result, err = checkAreaRe.GetCheckResult(taskinfo.ScdId) if err != nil { logger.Logger.Error(err) return "", err } c.setCaption(sheet_fcda, fmt.Sprintf("%s-端子校验结果", scdName), 6) lastIedName := "" cellNo := 1 for _, row := range result { nowIedName := fmt.Sprintf("%s:%s", tools.IsEmpty(row["ied_name"]), tools.IsEmpty(row["ied_desc"])) if lastIedName == "" || lastIedName != nowIedName { lastIedName = nowIedName c.setCaption(sheet_fcda, lastIedName, 6) c.addCellValue(sheet_fcda, []string{"序号", "外部IED", "发送信号", "本IED", "接收信号", "结论"}) cellNo = 1 } c.addCellValue(sheet_fcda, []string{ fmt.Sprintf("%d", cellNo), fmt.Sprintf("%s:%s", tools.IsEmpty(row["out_ied_name"]), tools.IsEmpty(row["out_ied_desc"])), fmt.Sprintf("%s\n%s", tools.IsEmpty(row["out_fcda_desc"]), tools.IsEmpty(row["out_fcda_addr"])), fmt.Sprintf("%s:%s", tools.IsEmpty(row["ied_name"]), tools.IsEmpty(row["ied_desc"])), fmt.Sprintf("%s\n%s", tools.IsEmpty(row["fcda_desc"]), tools.IsEmpty(row["fcda_addr"])), tools.IsEmpty(row["error_type_desc"]), }) cellNo = cellNo + 1 } err = file.Save(reportFN) if err != nil { logger.Logger.Error(err) return "", err } return reportFN[1:], err } func (c *TaskReportMgr) setCaption(sheet *xlsx.Sheet, caption string, margeNum ...int) *xlsx.Cell { row := sheet.AddRow() cell := row.AddCell() if len(margeNum) > 0 { cell.HMerge = margeNum[0] } else { cell.HMerge = 5 //合并单元格数 } cell.Value = caption style := xlsx.NewStyle() style.Alignment.Horizontal = "center" cell.SetStyle(style) return cell } func (c *TaskReportMgr) addCellValue(sheet *xlsx.Sheet, vs []string) { row := sheet.AddRow() for _, r := range vs { cell := row.AddCell() cell.Value = r style := xlsx.NewStyle() style.Alignment.Horizontal = "left" style.Alignment.WrapText = true cell.SetStyle(style) } }