package service import ( "encoding/json" "errors" "fmt" "math/rand" "rtzh_elec_temperature/enum" "rtzh_elec_temperature/global" "rtzh_elec_temperature/logger" "rtzh_elec_temperature/models/bo" "rtzh_elec_temperature/tools" "strconv" "strings" "time" "github.com/astaxie/beego/orm" "github.com/spf13/cast" ) type DataoptimizeService struct { BaseService } //优化数据值 /* @param modelid 模型id @param deviceid 设备id @param mpname 需要优化的测点名称 @param pushallvalues 当前接收到的所有测点值 */ func (t *DataoptimizeService) OptimizeValue(modelid int, deviceid int32, attrname string, pushallvalues map[string]interface{}) float64 { //获取填充状态 ruleFillState := t.GetRuleStatus() if _, h := pushallvalues[attrname]; !h { //当测点未采集到数据时 //判断是否开启了缺点填充 if ruleFillState["deletion_fill_rule"] == "1" { return t.getDeletionFillValue(ruleFillState, modelid, deviceid, attrname, pushallvalues) } return cast.ToFloat64(global.NullNumber) } originvalue := cast.ToFloat64(pushallvalues[attrname]) //判断是否有针对当前设备配置优化 if ruleFillState["invalid_fill_rule"] == "1" { //获取当前测点的范围优化配置 return t.getInvalidFillValue(originvalue, ruleFillState, modelid, deviceid, attrname, pushallvalues) } return originvalue } //生成无效范围填充值 func (t *DataoptimizeService) getInvalidFillValue(v float64, ruleFillState map[string]string, modelid int, deviceid int32, attrname string, pushallvalues map[string]interface{}) float64 { invalid_fill_rowset, _ := t.InvalidOptimizeCnfList() if invalid_fill_rowset != nil { for _, row := range invalid_fill_rowset { if tools.IsEmpty(deviceid) == tools.IsEmpty(row["device_id"]) && tools.IsEmpty(modelid) == tools.IsEmpty(row["model_id"]) { cnf := tools.IsEmpty(row["fill_cnf"]) if cnf != "" { //应用规则 cnfObj := map[string]interface{}{} json.Unmarshal([]byte(cnf), &cnfObj) if cnfObj != nil { //获取该测点的指定填充测点配置 pointFillCnf := cnfObj[attrname] if pointFillCnf != nil { fillpoints := pointFillCnf.(map[string]interface{})["value"].([]interface{}) minvalue := cast.ToFloat64(fillpoints[0]) maxvalue := cast.ToFloat64(fillpoints[1]) //logger.Logger.Debug(fmt.Sprintf("=====无效值判断。当前值%f 范围最小值:%f 最大值%:%f", v, minvalue, maxvalue)) if v <= minvalue || v >= maxvalue { //采集数值不在有效范围内 invalid_show_rule, _ := bo.GetSysParamValue("invalid_show_rule", "0") if invalid_show_rule == "2" { //应用填充规则 return t.getDeletionFillValue(ruleFillState, modelid, deviceid, attrname, pushallvalues) } if invalid_show_rule == "0" { //不显示。前端显示为空 return cast.ToFloat64(global.NullNumber) } //使用的字符填充。在查询数据时需要针对-99999的测点值替换为设置的填充字符返回 v, _ = strconv.ParseFloat(global.ReplaceNumber, 64) return v } } } } } } } return v } //生成缺点填充值 func (t *DataoptimizeService) getDeletionFillValue(ruleFillState map[string]string, modelid int, deviceid int32, attrname string, pushallvalues map[string]interface{}) float64 { //判断是相邻测点填充还是指定测点填充 if ruleFillState["deletion_fill_randompoint"] == "1" { //获取当前采集中的同类测点,再随机获取其中一个测点的值 pointTypeCode := attrname[0:3] for tmpAttrname, v := range pushallvalues { if tmpAttrname != attrname && tmpAttrname[0:3] == pointTypeCode && tools.IsEmpty(v) != "" { //logger.Logger.Debug(fmt.Sprintf("====当前缺点测点%s,使用测点%s数据进行填充:%+v", attrname, tmpAttrname, v)) return cast.ToFloat64(v) } } } else if ruleFillState["deletion_fill_specifypoint"] == "1" { deletion_fill_rule_rowset, _ := t.DeletionOptimizeCnfList() //logger.Logger.Debug(fmt.Sprintf("当前采集属性%s的缺点填充:%+v", attrname, deletion_fill_rule_rowset)) if deletion_fill_rule_rowset != nil { //优先查找针对设备配置的缺点填充规则 deletionRuleCnf, _ := t.DeletionOptimizeCnfMap() if deletionRuleCnf == nil { return cast.ToFloat64(global.NullNumber) } deletionRuleCnfByMD := deletionRuleCnf[fmt.Sprintf("%d%d", modelid, deviceid)] if deletionRuleCnfByMD != nil { //logger.Logger.Debug(fmt.Sprintf("设备%s缺点填充规则:%+v", tools.IsEmpty(deviceid), row["fill_cnf"])) cnf := tools.IsEmpty(deletionRuleCnfByMD["fill_cnf"]) if cnf != "" { //应用规则 cnfObj := []map[string]interface{}{} json.Unmarshal([]byte(cnf), &cnfObj) if cnfObj != nil { //获取该测点的指定填充测点配置 for _, cnfObjItem := range cnfObj { if tools.IsEmpty(cnfObjItem["attrname"]) == attrname { pointFillCnf := cnfObjItem["value"] if pointFillCnf != nil { fillpoints := pointFillCnf.([]interface{}) if len(fillpoints) > 0 { //随机获取一个测点 rand.Seed(time.Now().Unix()) ind := rand.Intn(len(fillpoints) - 1) tmpObj := fillpoints[ind].(map[string]interface{}) return cast.ToFloat64(pushallvalues[tools.IsEmpty(tmpObj["attrname"])]) } } } } } } } //logger.Logger.Debug(fmt.Sprintf("未找到设备%d及测点%s的填充设置,采用通用配置!", deviceid, attrname)) deletionRuleCnfByMD = deletionRuleCnf[fmt.Sprintf("%d0", modelid)] //查找模型通用配置 if deletionRuleCnfByMD != nil { cnf := tools.IsEmpty(deletionRuleCnfByMD["fill_cnf"]) if cnf != "" { //应用规则 cnfObj := []map[string]interface{}{} json.Unmarshal([]byte(cnf), &cnfObj) if cnfObj != nil { //获取该测点的指定填充测点配置 for _, cnfObjItem := range cnfObj { if tools.IsEmpty(cnfObjItem["attrname"]) == attrname { pointFillCnf := cnfObjItem["value"] if pointFillCnf != nil { fillpoints := pointFillCnf.([]interface{}) if len(fillpoints) > 0 { //随机获取一个测点 rand.Seed(time.Now().Unix()) ind := rand.Intn(len(fillpoints) - 1) tmpObj := fillpoints[ind].(map[string]interface{}) return cast.ToFloat64(pushallvalues[tools.IsEmpty(tmpObj["attrname"])]) } } } } } } } } } return cast.ToFloat64(global.NullNumber) } //查询缺点数据填充规则配置 func (t *DataoptimizeService) DeletionOptimizeCnfList() ([]orm.Params, error) { key := "optimize_deletion_fillrule" if v, h := global.GoCahce.Get(key); h { return v.([]orm.Params), nil } db := orm.NewOrm() sql := "select * from t_data_optimize_deletion_fillrule" rowset := []orm.Params{} _, err := db.Raw(sql).Values(&rowset) if err != nil { logger.Logger.Error(err) return nil, err } global.GoCahce.Set(key, rowset, -1) return rowset, err } //查询缺点数据填充规则配置。以Map返回,key为模型id+设备id func (t *DataoptimizeService) DeletionOptimizeCnfMap() (map[string]orm.Params, error) { key := "optimize_deletion_fillrule_map" if v, h := global.GoCahce.Get(key); h { return v.(map[string]orm.Params), nil } rowset, err := t.DeletionOptimizeCnfList() result := map[string]orm.Params{} if err == nil { for _, row := range rowset { k := fmt.Sprintf("%v%v", row["model_id"], row["device_id"]) result[k] = row } global.GoCahce.Set(key, result, -1) } return result, err } //查询无效数据填充规则配置 func (t *DataoptimizeService) InvalidOptimizeCnfList() ([]orm.Params, error) { key := "optimize_invalid_fillrule" if v, h := global.GoCahce.Get(key); h { return v.([]orm.Params), nil } db := orm.NewOrm() sql := "select * from t_data_optimize_invalid_fillrule" rowset := []orm.Params{} _, err := db.Raw(sql).Values(&rowset) if err != nil { logger.Logger.Error(err) return nil, err } global.GoCahce.Set(key, rowset, -1) return rowset, err } //查询无效数据填充规则配置。以Map返回,key为模型id+设备id func (t *DataoptimizeService) InvalidOptimizeCnfMap() (map[string]orm.Params, error) { key := "optimize_invalid_fillrule_map" if v, h := global.GoCahce.Get(key); h { return v.(map[string]orm.Params), nil } rowset, err := t.InvalidOptimizeCnfList() result := map[string]orm.Params{} if err == nil { for _, row := range rowset { k := fmt.Sprintf("%v%v", row["model_id"], row["device_id"]) result[k] = row } global.GoCahce.Set(key, result, -1) } return result, err } //编辑数据优化配置 //optimizetype:填充规则类型。invalid:无效数据填充 deletion:缺点数据填充 //modelid:模型id.指定了deviceid时可以不指定该参数 //deviceid:设备ID.指定了modelid时可以不指定该参数 //cnf:配置内容。json格式 func (t *DataoptimizeService) EditOptimize(optimizetype string, modelid int64, deviceid int32, cnf string) error { var err error db := orm.NewOrm() key := "optimize_deletion_fillrule" tn := "t_data_optimize_deletion_fillrule" if optimizetype == "invalid" { tn = "t_data_optimize_invalid_fillrule" key = "optimize_invalid_fillrule" } sql := "REPLACE INTO " + tn + "(model_id,device_id,fill_cnf,cr,ct)values(?,?,?,?,now()) " sqlParas := []interface{}{modelid, deviceid, cnf, t.UserInfo.Id} _, err = db.Raw(sql, sqlParas).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sql, sqlParas)) new(bo.SystemLog).Fail( enum.AuditType_Dataoptimize, enum.LogType_Update, enum.OptEventType_Bus, enum.OptEventLevel_Hight, fmt.Sprintf("编辑数据优化配置,操作数据:%+v", cnf), map[string]interface{}{ "name": t.UserInfo.Usrname, "ip": t.UserInfo.Ip, }, ) } else { global.GoCahce.Delete(key) //清除缓存。下次查询时重新缓存最新数据 global.GoCahce.Delete(fmt.Sprintf("%s_map", key)) new(bo.SystemLog).Success( enum.AuditType_Dataoptimize, enum.LogType_Update, enum.OptEventType_Bus, enum.OptEventLevel_Hight, fmt.Sprintf("编辑数据优化配置,操作数据:%+v", cnf), map[string]interface{}{ "name": t.UserInfo.Usrname, "ip": t.UserInfo.Ip, }, ) } return err } //删除指定设备的数据优化配置 //deviceid:设备ID func (t *DataoptimizeService) DeleteOptimize(optimizetype string, deviceid int32) error { var err error db := orm.NewOrm() tn := "t_data_optimize_invalid_fillrule" if optimizetype == "deletion" { tn = "t_data_optimize_deletion_fillrule" } _, err = db.Raw("delete from "+tn+" where device_id=?", deviceid).Exec() if err != nil { logger.Logger.Error(err) return err } global.GoCahce.Delete(strings.ReplaceAll(tn, "t_data_", "")) global.GoCahce.Delete(strings.ReplaceAll(tn, "t_data_", "") + "_map") new(bo.SystemLog).Success( enum.AuditType_Dataoptimize, enum.LogType_Delete, enum.OptEventType_Bus, enum.OptEventLevel_Hight, "删除数据填充规则", map[string]interface{}{ "name": t.UserInfo.Usrname, "ip": t.UserInfo.Ip, }, ) return err } //删除指定设备的某个测点的数据优化配置 //deviceid:设备ID //attrname:模型属性名 func (t *DataoptimizeService) DeleteAttrnameOptimize(optimizetype string, deviceid int32, attrname string) error { var err error db := orm.NewOrm() tn := "t_data_optimize_invalid_fillrule" if optimizetype == "deletion" { tn = "t_data_optimize_deletion_fillrule" } rowset := []orm.Params{} _, err = db.Raw("select * from "+tn+" where device_id=?", deviceid).Values(&rowset) if err != nil { logger.Logger.Error(err) return err } if len(rowset) == 0 { return nil } foundOne := false for _, row := range rowset { found := false fillcnf := tools.IsEmpty(row["fill_cnf"]) if fillcnf == "" { continue } updateObj := map[string]interface{}{"n": nil} if optimizetype == "deletion" { fillcnfobj := []map[string]interface{}{} err = json.Unmarshal([]byte(fillcnf), &fillcnfobj) if err != nil { logger.Logger.Error(err, fillcnf) return err } newFillcnfObj := []map[string]interface{}{} for _, cnfitem := range fillcnfobj { if tools.IsEmpty(cnfitem["attrname"]) == attrname { found = true continue } value := cnfitem["value"].([]interface{}) newvalues := []map[string]interface{}{} for _, v1 := range value { v2 := v1.(map[string]interface{}) if tools.IsEmpty(v2["attrname"]) == attrname { found = true continue } newvalues = append(newvalues, v2) } cnfitem["value"] = newvalues newFillcnfObj = append(newFillcnfObj, cnfitem) } if len(newFillcnfObj) > 0 { updateObj["n"] = newFillcnfObj } } else { fillcnfobj := map[string]interface{}{} err = json.Unmarshal([]byte(fillcnf), &fillcnfobj) if err != nil { logger.Logger.Error(err, fillcnf) return err } newFillcnfObj := map[string]interface{}{} for k, cnfitem := range fillcnfobj { if k == attrname { found = true continue } newFillcnfObj[k] = cnfitem } if len(newFillcnfObj) > 0 { updateObj["n"] = newFillcnfObj } } if !found { //没有该测点的配置,不处理 continue } foundOne = true //至少匹配到一条记录 id := tools.IsEmpty(row["id"]) logger.Logger.Debug(updateObj) if updateObj["n"] != nil { newFillcnf, _ := json.Marshal(updateObj["n"]) db.Raw("update "+tn+" set fill_cnf=? where id=?", string(newFillcnf), id).Exec() } else { db.Raw("delete from "+tn+" where id=?", id).Exec() } } if !foundOne { return nil } global.GoCahce.Delete(strings.ReplaceAll(tn, "t_data_", "")) global.GoCahce.Delete(strings.ReplaceAll(tn, "t_data_", "") + "_map") new(bo.SystemLog).Success( enum.AuditType_Dataoptimize, enum.LogType_Delete, enum.OptEventType_Bus, enum.OptEventLevel_Hight, fmt.Sprintf("删除设备%d的测点%s配置的数据填充规则", deviceid, attrname), map[string]interface{}{ "name": t.UserInfo.Usrname, "ip": t.UserInfo.Ip, }, ) return err } //设置填充规则开启状态 func (t *DataoptimizeService) SetRuleStatus(rulecode, value string) error { dict := map[string]string{ "deletion_fill_rule": "数据缺失填充规则", "deletion_fill_specifypoint": "指定测点填充", "deletion_fill_randompoint": "相邻测点填充", "invalid_fill_rule": "无效数据填充规则", "invalid_show_rule": "无效数据显示设置", } memo := dict[rulecode] if memo == "" { return errors.New("无效的规则代码!") } if rulecode != "invalid_show_rule" && value != "1" && value != "0" { return errors.New("无效的规则启用状态值,仅支持1或0!") } if rulecode == "invalid_show_rule" && value != "0" && value != "2" { //字符转成字节,简单拼接成一个长数字 vs := "" for _, by := range []byte(value) { vs = vs + tools.IsEmpty(by) } value = vs } _, err := bo.SaveSysParam(bo.Global_sys_param{ Param_name: rulecode, Param_value: value, Param_memo: memo, }, map[string]interface{}{ "userid": t.UserInfo.Id, "name": t.UserInfo.Usrname, "ip": t.UserInfo.Ip, }) if err == nil { new(bo.SystemLog).Success( enum.AuditType_Dataoptimize, enum.LogType_Update, enum.OptEventType_Bus, enum.OptEventLevel_Hight, "设置数据填充规则启用状态", map[string]interface{}{ "name": t.UserInfo.Usrname, "ip": t.UserInfo.Ip, }, ) } return err } //获取填充规则策略开启状态 func (t *DataoptimizeService) GetRuleStatus() map[string]string { result := map[string]string{} //数据缺失填充规则开启状态。默认开启 result["deletion_fill_rule"], _ = bo.GetSysParamValue("deletion_fill_rule", "1") result["deletion_fill_specifypoint"] = "0" result["deletion_fill_randompoint"] = "0" if result["deletion_fill_rule"] == "1" { //获取指定特定测点填充开启状态 result["deletion_fill_specifypoint"], _ = bo.GetSysParamValue("deletion_fill_specifypoint", "0") //获取相邻测点填充开启状态 result["deletion_fill_randompoint"], _ = bo.GetSysParamValue("deletion_fill_randompoint", "0") } //数据无效填充规则开启状态。默认开启 result["invalid_fill_rule"], _ = bo.GetSysParamValue("invalid_fill_rule", "1") //invalid_show_rule result["invalid_show_rule"], _ = bo.GetSysParamValue("invalid_show_rule", "99999") //默认为不显示,即显示为空 return result } //导出缺点数据规则 func (t *DataoptimizeService) ExpDeletionFillRule(modelid int, deviceid int) (exceldatas []orm.Params, err error) { modelSrv := new(ModelService) deviceSrv := new(DeviceService) modelObj := modelSrv.GetModelInfo(tools.IsEmpty(modelid)) if modelObj == nil { return nil, errors.New("无效的模型ID") } modename := tools.IsEmpty(modelObj.(map[string]interface{})["model_name"]) deviceMp := map[string]orm.Params{} //设备测点列表 modelAttrNames := map[string]interface{}{} //模型属性列表 modelAttrNames = modelSrv.GetModelAttrMap(int64(modelid)) if modelAttrNames == nil { return nil, errors.New("该模型未定义模型属性") } devicename := "" if deviceid > 0 { if v, h := deviceSrv.DeviceNameByID().Load(tools.IsEmpty(deviceid)); h { devicename = tools.IsEmpty(v) } else { return nil, errors.New("无效的设备编号") } deviceMp = deviceSrv.DeviceMpInfo(int32(deviceid)) if deviceMp == nil { return nil, errors.New("该设备未创建任何测点") } } deletionList, err := t.DeletionOptimizeCnfMap() if err != nil { return nil, err } result := []orm.Params{} k := fmt.Sprintf("%d%d", modelid, deviceid) res := deletionList[k] if res != nil { cnf := tools.IsEmpty(res["fill_cnf"]) cnfobj := []map[string]interface{}{} err := json.Unmarshal([]byte(cnf), &cnfobj) if err != nil { logger.Logger.Error(err) return nil, err } for _, item2 := range cnfobj { value := item2["value"].([]interface{}) attr := tools.IsEmpty(item2["attrname"]) mpname := "" fillvalues := []string{} if devicename != "" { mpname = tools.IsEmpty(deviceMp[attr]["mpname"]) for _, vs := range value { tmpVs := vs.(map[string]interface{}) devAttrname := tools.IsEmpty(tmpVs["attrname"]) fillvalues = append(fillvalues, tools.IsEmpty(deviceMp[devAttrname]["mpname"])) } } else { for _, vs := range value { tmpVs := vs.(map[string]interface{}) fillvalues = append(fillvalues, tools.IsEmpty(tmpVs["attrname"])) } } obj := orm.Params{ "modelname": modename, "attrname": attr, "devicename": devicename, "mpname": mpname, "fill": strings.Join(fillvalues, ","), } result = append(result, obj) } } new(bo.SystemLog).Success( enum.AuditType_Dataoptimize, enum.LogType_exp, enum.OptEventType_Bus, enum.OptEventLevel_Hight, "导出缺点数据填充规则", map[string]interface{}{ "name": t.UserInfo.Usrname, "ip": t.UserInfo.Ip, }, ) return result, nil } //导出无效数据规则 func (t *DataoptimizeService) ExpInvalidFillRule(modelid int, deviceid int) (exceldatas []orm.Params, err error) { modelSrv := new(ModelService) deviceSrv := new(DeviceService) modelObj := modelSrv.GetModelInfo(tools.IsEmpty(modelid)) if modelObj == nil { return nil, errors.New("无效的模型ID") } modename := tools.IsEmpty(modelObj.(map[string]interface{})["model_name"]) deviceMp := map[string]orm.Params{} //设备测点列表 modelAttrNames := map[string]interface{}{} //模型属性列表 modelAttrNames = modelSrv.GetModelAttrMap(int64(modelid)) if modelAttrNames == nil { return nil, errors.New("该模型未定义模型属性") } devicename := "" if deviceid > 0 { if v, h := deviceSrv.DeviceNameByID().Load(tools.IsEmpty(deviceid)); h { devicename = tools.IsEmpty(v) } else { return nil, errors.New("无效的设备编号") } deviceMp = deviceSrv.DeviceMpInfo(int32(deviceid)) if deviceMp == nil { return nil, errors.New("该设备未创建任何测点") } } invalidList, err := t.InvalidOptimizeCnfMap() if err != nil { return nil, err } result := []orm.Params{} k := fmt.Sprintf("%d%d", modelid, deviceid) res := invalidList[k] if res != nil { cnf := tools.IsEmpty(res["fill_cnf"]) cnfobj := map[string]interface{}{} err := json.Unmarshal([]byte(cnf), &cnfobj) if err != nil { logger.Logger.Error(err) return nil, err } for attr, item := range cnfobj { item2 := item.(map[string]interface{}) value := item2["value"].([]interface{}) if len(value) == 0 { value = []interface{}{"", ""} } mpname := "" if devicename != "" { mpname = tools.IsEmpty(deviceMp[attr]["mpname"]) } obj := orm.Params{ "modelname": modename, "attrname": attr, "devicename": devicename, "mpname": mpname, "minvalue": tools.IsEmpty(value[0]), "maxvalue": tools.IsEmpty(value[1]), } result = append(result, obj) } } new(bo.SystemLog).Success( enum.AuditType_Dataoptimize, enum.LogType_exp, enum.OptEventType_Bus, enum.OptEventLevel_Hight, "导出无效数据填充规则", map[string]interface{}{ "name": t.UserInfo.Usrname, "ip": t.UserInfo.Ip, }, ) return result, nil } //导入数据规则 func (t *DataoptimizeService) ImpDeletionExcel(param map[string]interface{}) error { exceldatalist := param["datalist"].([]map[int]string) logger.Logger.Debug(fmt.Sprintf("EXCEL Deletion DATA: %+v", exceldatalist)) modelid := "0" //模型ID deviceid := "0" //设备ID modelSrv := new(ModelService) deviceSrv := new(DeviceService) modelnameids := map[string]string{} devicenameids := map[string]string{} fillcnf := map[string][]interface{}{} //填充规则 deviceMp := map[string]interface{}{} //设备测点列表 modelAttrNames := map[string]interface{}{} //模型属性列表 var FindModelAttr = func(lst map[string]interface{}, attrname string) map[string]interface{} { if v, h := lst[attrname]; h { return v.(map[string]interface{}) } return nil } for _, linedata := range exceldatalist { modelid = "0" deviceid = "0" attrname := tools.IsEmpty(linedata[2]) modename := tools.IsEmpty(linedata[1]) if modename == "" { return errors.New("模型名称不能为空") } if attrname == "" { return errors.New("模型属性名称不能为空") } if mid, h := modelnameids[modename]; h { modelid = mid } else { mid := modelSrv.GetModelId(modename) if mid == 0 { return errors.New("无效的模型名称:" + modename) } modelnameids[modename] = tools.IsEmpty(mid) modelid = modelnameids[modename] } if _, h := modelAttrNames[modelid]; !h { modelidint64, _ := strconv.ParseInt(modelid, 10, 64) modelAttrNames[modelid] = modelSrv.GetModelAttrMap(modelidint64) } if FindModelAttr(modelAttrNames[modelid].(map[string]interface{}), attrname) == nil { return errors.New("模型属性名" + attrname + "不存在") } devicename := tools.IsEmpty(linedata[3]) if devicename != "" { mpname := strings.Trim(tools.IsEmpty(linedata[4]), " ") if mpname == "" { return errors.New("设备" + devicename + "的测点名称不能为空") } if mid, h := devicenameids[devicename]; h { deviceid = mid } else { mid, _ := deviceSrv.DeviceIdByDeviceName().Load(devicename) if mid == nil { return errors.New("无效的设备名称:" + devicename) } devicenameids[devicename] = tools.IsEmpty(mid) deviceid = devicenameids[devicename] deviceidint32, _ := strconv.ParseInt(deviceid, 10, 64) dMp := deviceSrv.DeviceMpInfo(int32(deviceidint32)) deviceMp[deviceid] = dMp } if vmplist, h := deviceMp[deviceid]; h { vmplist2 := vmplist.(map[string]orm.Params) if vt1, h1 := vmplist2[attrname]; h1 { if tools.IsEmpty(vt1["mpname"]) != mpname { return errors.New("设备" + devicename + "的模型属性" + attrname + "与测点名称(" + mpname + ")不匹配") } } else { return errors.New("设备" + devicename + "未定义模型属性" + attrname + "的关联测点") } } else { return errors.New("设备" + devicename + "未定义任何测点") } } fillvalue := map[string]interface{}{ "attrname": attrname, "value": []interface{}{}, } //组装填充测点列表 fillmp := strings.Trim(tools.IsEmpty(linedata[5]), " ") if fillmp != "" { fillmp = strings.ReplaceAll(fillmp, ",", ",") fillmps := strings.Split(fillmp, ",") for _, mp := range fillmps { if deviceid != "0" { //设备测点填充 //判断该设备测点中是否存在当前填充测点 vmplist := deviceMp[deviceid].(map[string]orm.Params) foundMp := false for _, mprows := range vmplist { if tools.IsEmpty(mprows["mpname"]) == mp { fillvalue["value"] = append(fillvalue["value"].([]interface{}), map[string]interface{}{ "attrname": tools.IsEmpty(mprows["attrname"]), "mpname": mp, }) foundMp = true break } } if !foundMp { return errors.New("设备" + devicename + "未定义填充测点列表中的测点" + mp) } } else { //模型属性填充 if FindModelAttr(modelAttrNames[modelid].(map[string]interface{}), mp) == nil { return errors.New("填充测点列表中的模型属性名" + mp + "不存在") } fillvalue["value"] = append(fillvalue["value"].([]interface{}), map[string]interface{}{ "attrname": mp, "mpname": mp, }) } } } fillkey := fmt.Sprintf("%s,%s", modelid, deviceid) if _, h := fillcnf[fillkey]; !h { fillcnf[fillkey] = []interface{}{fillvalue} } else { fillcnf[fillkey] = append(fillcnf[fillkey], fillvalue) } } db := orm.NewOrm() for key, t1 := range fillcnf { sql := "replace into t_data_optimize_deletion_fillrule(model_id,device_id,fill_cnf,cr,ct)values(?,?,?,?,now())" ks := strings.Split(key, ",") fillcnfstr, _ := json.Marshal(t1) _, err := db.Raw(sql, ks[0], ks[1], string(fillcnfstr), t.UserInfo.Id).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sql, []interface{}{ks[0], ks[1], string(fillcnfstr), t.UserInfo.Id})) return err } } key := "optimize_deletion_fillrule" global.GoCahce.Delete(key) global.GoCahce.Delete(key + "_map") new(bo.SystemLog).Success( enum.AuditType_Dataoptimize, enum.LogType_imp, enum.OptEventType_Bus, enum.OptEventLevel_Hight, "导入缺点数据填充规则", map[string]interface{}{ "name": t.UserInfo.Usrname, "ip": t.UserInfo.Ip, }, ) return nil } //导入数据规则 func (t *DataoptimizeService) ImpInvalidExcel(param map[string]interface{}) error { exceldatalist := param["datalist"].([]map[int]string) logger.Logger.Debug(fmt.Sprintf("EXCEL Invalid DATA: %+v", exceldatalist)) modelid := "0" //模型ID deviceid := "0" //设备ID modelSrv := new(ModelService) deviceSrv := new(DeviceService) modelnameids := map[string]string{} devicenameids := map[string]string{} fillcnf := map[string]map[string]interface{}{} //填充规则 deviceMp := map[string]interface{}{} //设备测点列表 modelAttrNames := map[string]interface{}{} //模型属性列表 var FindModelAttr = func(lst map[string]interface{}, attrname string) map[string]interface{} { if v, h := lst[attrname]; h { return v.(map[string]interface{}) } return nil } for _, linedata := range exceldatalist { modelid = "0" deviceid = "0" attrname := tools.IsEmpty(linedata[2]) modename := tools.IsEmpty(linedata[1]) minvalue := tools.IsEmpty(linedata[5]) maxvalue := tools.IsEmpty(linedata[6]) if modename == "" { return errors.New("模型名称不能为空") } if attrname == "" { return errors.New("模型属性名称不能为空") } if minvalue == "" { return errors.New("有效最小值不能为空") } _, err := strconv.ParseFloat(minvalue, 64) if err != nil { return errors.New("有效最小值只能为数字") } if maxvalue == "" { return errors.New("有效最大值不能为空") } _, err = strconv.ParseFloat(maxvalue, 64) if err != nil { return errors.New("有效最大值只能为数字") } if mid, h := modelnameids[modename]; h { modelid = mid } else { mid := modelSrv.GetModelId(modename) if mid == 0 { return errors.New("无效的模型名称:" + modename) } modelnameids[modename] = tools.IsEmpty(mid) modelid = modelnameids[modename] } if _, h := modelAttrNames[modelid]; !h { modelidint64, _ := strconv.ParseInt(modelid, 10, 64) modelAttrNames[modelid] = modelSrv.GetModelAttrMap(modelidint64) } if FindModelAttr(modelAttrNames[modelid].(map[string]interface{}), attrname) == nil { return errors.New("模型属性名" + attrname + "不存在") } devicename := tools.IsEmpty(linedata[3]) if devicename != "" { mpname := strings.Trim(tools.IsEmpty(linedata[4]), " ") if mpname == "" { return errors.New("设备" + devicename + "的测点名称不能为空") } if mid, h := devicenameids[devicename]; h { deviceid = mid } else { mid, _ := deviceSrv.DeviceIdByDeviceName().Load(devicename) if mid == nil { return errors.New("无效的设备名称:" + devicename) } devicenameids[devicename] = tools.IsEmpty(mid) deviceid = devicenameids[devicename] deviceidint32, _ := strconv.ParseInt(deviceid, 10, 64) dMp := deviceSrv.DeviceMpInfo(int32(deviceidint32)) deviceMp[deviceid] = dMp } if vmplist, h := deviceMp[deviceid]; h { vmplist2 := vmplist.(map[string]orm.Params) if vt1, h1 := vmplist2[attrname]; h1 { if tools.IsEmpty(vt1["mpname"]) != mpname { return errors.New("设备" + devicename + "的模型属性" + attrname + "与测点名称(" + mpname + ")不匹配") } } else { return errors.New("设备" + devicename + "未定义模型属性" + attrname + "的关联测点") } } else { return errors.New("设备" + devicename + "未定义任何测点") } } fillvalue := map[string]interface{}{ "attrname": attrname, "value": []string{minvalue, maxvalue}, } fillkey := fmt.Sprintf("%s,%s", modelid, deviceid) if _, h := fillcnf[fillkey]; !h { fillcnf[fillkey] = map[string]interface{}{attrname: fillvalue} } fillcnf[fillkey][attrname] = fillvalue } db := orm.NewOrm() for key, t1 := range fillcnf { sql := "replace into t_data_optimize_invalid_fillrule(model_id,device_id,fill_cnf,cr,ct)values(?,?,?,?,now())" ks := strings.Split(key, ",") fillcnfstr, _ := json.Marshal(t1) _, err := db.Raw(sql, ks[0], ks[1], string(fillcnfstr), t.UserInfo.Id).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sql, []interface{}{ks[0], ks[1], string(fillcnfstr), t.UserInfo.Id})) return err } } key := "optimize_invalid_fillrule" global.GoCahce.Delete(key) global.GoCahce.Delete(key + "_map") new(bo.SystemLog).Success( enum.AuditType_Dataoptimize, enum.LogType_imp, enum.OptEventType_Bus, enum.OptEventLevel_Hight, "导入无效数据填充规则", map[string]interface{}{ "name": t.UserInfo.Usrname, "ip": t.UserInfo.Ip, }, ) return nil }