package data import ( "errors" "eta/eta_api/models" "eta/eta_api/models/data_manage" "eta/eta_api/models/system" "eta/eta_api/services/alarm_msg" "eta/eta_api/utils" "fmt" "github.com/shopspring/decimal" "github.com/tealeg/xlsx" "strconv" "strings" "time" ) func GetManualSysUser(keyWord string) (list []*data_manage.ManualSysUser, err error) { //departmentId := 1 list = make([]*data_manage.ManualSysUser, 0) departmentItems, err := system.GetSysDepartmentAll() if err != nil { return list, err } for _, dv := range departmentItems { department := new(data_manage.ManualSysUser) department.ItemId = dv.DepartmentId * 10000 department.ItemName = dv.DepartmentName fmt.Println(department.ItemId, department.ItemName) //GetSysuserList var condition string var pars []interface{} if keyWord != "" { condition += ` AND (real_name LIKE ? OR admin_name LIKE ? OR mobile LIKE ? ) ` pars = utils.GetLikeKeywordPars(pars, keyWord, 3) } sysUsers, err := system.GetSysUserItems(condition, pars) if err != nil { return list, err } groups, err := system.GetSysGroupByDepartmentId(dv.DepartmentId) if err != nil { return list, err } dg := make([]*data_manage.ManualSysUser, 0) for _, v := range groups { group := new(data_manage.ManualSysUser) group.ItemId = v.DepartmentId * 100000 group.ItemName = v.GroupName for _, sv := range sysUsers { user := new(data_manage.ManualSysUser) user.ItemId = sv.AdminId user.ItemName = sv.RealName if sv.GroupId == v.GroupId { group.Children = append(group.Children, user) } } if len(group.Children) > 0 { dg = append(dg, group) } } if len(groups) <= 0 { group := new(data_manage.ManualSysUser) group.ItemId = dv.DepartmentId * 100000 group.ItemName = "无分组" for _, sv := range sysUsers { user := new(data_manage.ManualSysUser) user.ItemId = sv.AdminId user.ItemName = sv.RealName if sv.DepartmentId == dv.DepartmentId && sv.GroupId == 0 { group.Children = append(group.Children, user) } } if len(group.Children) > 0 { dg = append(dg, group) } } if len(dg) > 0 { department.Children = dg list = append(list, department) } } return } // GetManualEdbClassifyListByAdminId // @Description: 根据账户类型获取手工指标分类ID集合 // @author: Roc // @datetime 2024-07-16 13:18:39 // @param adminId int64 // @return classifyIdList []int // @return err error func GetManualEdbClassifyListByAdminId(adminId int64) (classifyIdList []int, err error) { var list []*models.EdbdataClassify if adminId <= 0 { list, err = models.GetAllChildManualEdbClassify() } else { userClassifyList, _ := models.GetManualUserClassify(int(adminId)) var userClassifyIdList []int for _, v := range userClassifyList { userClassifyIdList = append(userClassifyIdList, v.ClassifyId) } list, err = models.GetChildManualEdbClassifyByIdList(userClassifyIdList) } if err != nil { return } for _, classify := range list { classifyIdList = append(classifyIdList, classify.ClassifyId) } return } type ManualIndexSource2EdbReq struct { EdbCode string EdbName string Frequency string Unit string ClassifyId int AdminId int AdminRealName string } // ManualIndexSource2Edb // @Description: 新增手工数据源到指标库 // @author: Roc // @datetime 2024-07-26 13:23:19 // @param req ManualIndexSource2EdbReq // @param lang string // @return edb *data_manage.EdbInfo // @return err error // @return errMsg string // @return skip bool func ManualIndexSource2Edb(req ManualIndexSource2EdbReq, lang string) (edb *data_manage.EdbInfo, err error, errMsg string, skip bool) { if req.EdbCode == "" { err = fmt.Errorf("指标ID为空") return } defer func() { if err != nil { tips := fmt.Sprintf("ManualIndexSource2Edb新增失败, Err: %s", err.Error()) fmt.Println(tips) utils.FileLog.Info(tips) } }() source := utils.DATA_SOURCE_MANUAL // 是否已有指标数据 dataList, e := data_manage.GetEdbDataAllByEdbCode(req.EdbCode, source, utils.DATA_SUB_SOURCE_EDB, utils.EDB_DATA_LIMIT) if e != nil { err = fmt.Errorf("获取指标数据失败, Err: %s", e.Error()) return } // 新增指标数据 if len(dataList) == 0 { res, e := AddEdbData(source, req.EdbCode, req.Frequency) if e != nil { err = fmt.Errorf("index_lib: 新增指标数据失败, Err: %s", e.Error()) return } if res == nil { err = fmt.Errorf("index_lib: 新增指标数据失败, res nil") return } if res.Ret != 200 { err = fmt.Errorf("index_lib: 新增指标数据失败, Ret: %d", res.Ret) return } } // 是否新增过指标 exist, e := data_manage.GetEdbInfoByEdbCode(source, req.EdbCode) if e != nil && e.Error() != utils.ErrNoRow() { err = fmt.Errorf("获取指标是否存在失败, err: %s", e.Error()) return } if exist != nil { skip = true return } // 开始结束时间 var startDate, endDate string minMax, e := data_manage.GetEdbInfoMaxAndMinInfo(source, utils.DATA_SUB_SOURCE_EDB, req.EdbCode) if e != nil && e.Error() != utils.ErrNoRow() { err = fmt.Errorf("MinMax: 获取指标极值失败, err: %s", e.Error()) return } if minMax != nil { startDate = minMax.MinDate endDate = minMax.MaxDate } // 新增指标库 edbInfo, e, msg, _ := EdbInfoAdd(source, utils.DATA_SUB_SOURCE_EDB, req.ClassifyId, req.EdbCode, req.EdbName, req.Frequency, req.Unit, startDate, endDate, req.AdminId, req.AdminRealName, lang) if e != nil { errMsg = msg err = fmt.Errorf("EdbInfo: 新增指标失败, err: %s", e.Error()) return } edb = edbInfo // 新增es go AddOrEditEdbInfoToEs(edbInfo.EdbInfoId) return } // ImportManualData // @Description: 数据导入 // @author: Roc // @datetime 2024-08-01 11:27:21 // @param path string // @param sysUser *system.Admin // @return successCount int // @return failCount int // @return err error // @return errMsg string func ImportManualData(path string, sysUser *system.Admin) (successCount, failCount int, indexCount int, err error, errMsg string) { // 错误信息 errMsgList := make([]string, 0) // 操作记录 recordMap := make(map[string]string) defer func() { recordList := make([]*models.EdbinfoOpRecord, 0) for tradeCode, remark := range recordMap { recordList = append(recordList, &models.EdbinfoOpRecord{ TradeCode: tradeCode, Remark: remark, UserId: sysUser.AdminId, UserName: sysUser.RealName, CreateTime: time.Now(), }) // 修改最大最小值 go ModifyManualEdbMaxMinDate(tradeCode) } if len(recordList) > 0 { go func() { obj := models.EdbinfoOpRecord{} _ = obj.MulCreate(recordList) }() } // 错误信息记录 if len(errMsgList) > 0 { utils.FileLog.Info("导入失败, errMsgList: %v", strings.Join(errMsgList, "\n")) } }() errMsg = `导入失败` xlFile, err := xlsx.OpenFile(path) if err != nil { fmt.Println(err.Error()) return } if len(xlFile.Sheets) <= 0 { errMsg = "导入模板异常" err = errors.New(errMsg) return } //导入失败数据 failDataList := make([]*models.EdbdataImportFail, 0) var indexDataList []ImportManualIndexData // 指标名称列表 indexNameList := make([]string, 0) // 模板校验,然后处理成标准化格式 for _, sheet := range xlFile.Sheets { var tmpIndexDataList []ImportManualIndexData var tmpFailDataList []*models.EdbdataImportFail rowList := sheet.Rows if len(rowList) <= 0 { errMsg = sheet.Name + "页异常" err = errors.New(errMsg) return } templateType := 1 // 模板类型 minCellNum := 6 // 模板最小列数 headerCell := rowList[0].Cells // 确定模板 for _, v := range headerCell { if v.String() == "导入模板2/Import Template 2" { templateType = 2 minCellNum = 2 break } } // 如果小于最少列数,则报错 if len(headerCell) < minCellNum { errMsg = sheet.Name + "页模板异常" err = errors.New(errMsg) return } switch templateType { case 2: // 模板2需要走对应的取数逻辑 tmpIndexDataList, tmpFailDataList, err, errMsg = getDataByTemplate2(sheet, sysUser.AdminId) default: // 模板1需要走对应的取数逻辑 tmpIndexDataList, tmpFailDataList, err, errMsg = getDataByTemplate1(sheet, sysUser.AdminId) } indexDataList = append(indexDataList, tmpIndexDataList...) failDataList = append(failDataList, tmpFailDataList...) } indexDataListMap := make(map[string]ImportManualIndexData) for _, v := range indexDataList { indexData, ok := indexDataListMap[v.IndexName] if !ok { // 没有就赋值 indexDataListMap[v.IndexName] = v indexNameList = append(indexNameList, v.IndexName) continue } indexData.Unit = v.Unit indexData.ClassName = v.ClassName indexData.Frequency = v.Frequency indexData.DataMap = v.DataMap } if len(indexNameList) <= 0 { return } //超管账号可以查看分类下的所有频度数据 userId := sysUser.AdminId if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN { userId = 0 } //获取账户所拥有权限的分类id集合 classifyNameStrList, edbDataClassifyMap, err := GetEdbClassifyNameListByAdminId(int64(userId)) if err != nil { errMsg = "获取分类数据失败" return } //指标map targetMap := make(map[string]*models.Edbinfo) defer func() { for _, target := range targetMap { //结束后,清除掉对应的缓存 key := "import:edbinfo:data:" + target.TradeCode utils.Rc.Delete(key) //将该指标的code加入到 “手工数据导入后刷新” 缓存 if utils.Re == nil { err := utils.Rc.LPush(utils.CACHE_IMPORT_MANUAL_DATA, target.TradeCode) if err != nil { fmt.Println("CACHE_IMPORT_MANUAL_DATA LPush Err:" + err.Error()) } } } }() // 所有的指标数据map edbCodeDataMap := make(map[string]map[string]string) { // 获取指标信息 manualIndexList, tmpErr := models.GetEdbinfoListBySecNameList(indexNameList) if tmpErr != nil { err = tmpErr errMsg = "获取指标信息失败" return } tradeCodeList := make([]string, 0) for _, v := range manualIndexList { targetMap[v.SecName] = v tradeCodeList = append(tradeCodeList, v.TradeCode) recordMap[v.TradeCode] = "更新数据" } // 获取明细数据 dataList, tmpErr := models.GetTargetsDataListByCodeList(tradeCodeList) if tmpErr != nil { err = tmpErr errMsg = "获取指标明细数据失败" return } for _, tmpData := range dataList { _, ok := edbCodeDataMap[tmpData.TradeCode] if !ok { edbCodeDataMap[tmpData.TradeCode] = make(map[string]string) } edbCodeDataMap[tmpData.TradeCode][tmpData.Dt] = tmpData.Close } } //// TODO 成功数量超过20个指标,那就不导入了 //if len(targetMap) >= 150 { // failItem := new(models.EdbdataImportFail) // failItem.SysUserId = strconv.Itoa(sysUser.AdminId) // failItem.ClassifyName = classifyName // failItem.CreateDate = createDate // failItem.SecName = secName // failItem.Close = closeVal // failItem.Remark = "导入指标数量过多" // failItem.Frequency = frequency // failItem.Unit = unit // failDataList = append(failDataList, failItem) // //go utils.SendEmail(utils.APPNAME+"失败提醒", "导入数据 获取分类:Err:"+err.Error(), utils.EmailSendToUsers) // continue //} addDataList := make([]*models.Edbdata, 0) for _, v := range indexDataListMap { if len(v.DataMap) <= 0 { continue } var tmpDate, tmpValue string for date, val := range v.DataMap { tmpDate = date tmpValue = val break } // 指标名称是空的,说明是空列 if v.IndexName == `` { continue } if !strings.Contains(strings.Join(classifyNameStrList, ","), v.ClassName) { failItem := &models.EdbdataImportFail{ ClassifyName: v.ClassName, CreateDate: tmpDate, SecName: v.IndexName, Close: tmpValue, Remark: "没有该品种分类权限", SysUserId: fmt.Sprint(sysUser.AdminId), Frequency: v.Frequency, Unit: v.Unit, } failDataList = append(failDataList, failItem) continue } //获取指标分类信息 classify, ok := edbDataClassifyMap[v.ClassName] if !ok { failItem := &models.EdbdataImportFail{ ClassifyName: v.ClassName, CreateDate: tmpDate, SecName: v.IndexName, Close: tmpValue, Remark: "指标分类不存在", SysUserId: fmt.Sprint(sysUser.AdminId), Frequency: v.Frequency, Unit: v.Unit, } failDataList = append(failDataList, failItem) continue } target, ok := targetMap[v.IndexName] if !ok { if v.Frequency == "" { failItem := &models.EdbdataImportFail{ ClassifyName: v.ClassName, CreateDate: tmpDate, SecName: v.IndexName, Close: tmpValue, Remark: "新增指标失败,频度字段为空", SysUserId: fmt.Sprint(sysUser.AdminId), Frequency: v.Frequency, Unit: v.Unit, } failDataList = append(failDataList, failItem) continue } if v.Unit == "" { failItem := &models.EdbdataImportFail{ ClassifyName: v.ClassName, CreateDate: tmpDate, SecName: v.IndexName, Close: tmpValue, Remark: "新增指标失败,单位字段为空", SysUserId: fmt.Sprint(sysUser.AdminId), Frequency: v.Frequency, Unit: v.Unit, } failDataList = append(failDataList, failItem) continue } tmpErr := AddEdbInfo(v.IndexName, v.Unit, v.Frequency, "", sysUser.Mobile, classify.ClassifyId, sysUser.AdminId, sysUser.RealName) if tmpErr != nil { fmt.Println("line 158") failItem := &models.EdbdataImportFail{ ClassifyName: v.ClassName, CreateDate: tmpDate, SecName: v.IndexName, Close: tmpValue, Remark: "新增指标失败", SysUserId: fmt.Sprint(sysUser.AdminId), Frequency: v.Frequency, Unit: v.Unit, } failDataList = append(failDataList, failItem) continue } // 新增指标记录数 indexCount++ tmpTarget, tmpErr := models.GetTargetBySecName(v.IndexName) target = tmpTarget targetMap[v.IndexName] = target recordMap[target.TradeCode] = "创建指标" } if target == nil { fmt.Println("指标不存在") failItem := &models.EdbdataImportFail{ ClassifyName: v.ClassName, CreateDate: tmpDate, SecName: v.IndexName, Close: tmpValue, Remark: "指标不存在", SysUserId: fmt.Sprint(sysUser.AdminId), Frequency: v.Frequency, Unit: v.Unit, } failDataList = append(failDataList, failItem) continue } //设置10分钟缓存,不允许其他地方删除 key := "import:edbinfo:data:" + target.TradeCode utils.Rc.SetNX(key, 1, time.Second*600) //更新指标信息 { if v.Frequency == "" { failItem := &models.EdbdataImportFail{ ClassifyName: v.ClassName, CreateDate: tmpDate, SecName: v.IndexName, Close: tmpValue, Remark: "更新指标失败,频度字段为空", SysUserId: fmt.Sprint(sysUser.AdminId), Frequency: v.Frequency, Unit: v.Unit, } failDataList = append(failDataList, failItem) continue } if v.Unit == "" { failItem := &models.EdbdataImportFail{ ClassifyName: v.ClassName, CreateDate: tmpDate, SecName: v.IndexName, Close: tmpValue, Remark: "更新指标失败,单位字段为空", SysUserId: fmt.Sprint(sysUser.AdminId), Frequency: v.Frequency, Unit: v.Unit, } failDataList = append(failDataList, failItem) continue } updateCols := make([]string, 0) //更新指标分类 if target.ClassifyId <= 0 && classify.ClassifyId > 0 { target.ClassifyId = classify.ClassifyId updateCols = append(updateCols, "ClassifyId") } if target.Frequency != v.Frequency { target.Frequency = v.Frequency target.NoticeTime = "" updateCols = append(updateCols, "Frequency", "NoticeTime") } if target.Unit != v.Unit { target.Unit = v.Unit updateCols = append(updateCols, "Unit") } if len(updateCols) > 0 { _ = target.Update(updateCols) } } { // 判断指标数据列表是否已经存在 tmpDataMap, ok := edbCodeDataMap[target.TradeCode] if !ok { tmpDataMap = make(map[string]string) edbCodeDataMap[target.TradeCode] = tmpDataMap } for createDate, closeVal := range v.DataMap { //判断数据是否已经存在 tmpVal, ok := tmpDataMap[createDate] //数据已存在,进行更新操作 if ok { if tmpVal != closeVal { edbCodeDataMap[target.TradeCode][createDate] = closeVal tmpErr := models.ModifyTargetsDataByImport(target.TradeCode, createDate, closeVal) if tmpErr != nil { errMsgList = append(errMsgList, fmt.Sprintf("%s修改数据失败,日期:%s,值:%v,Err:%s", target.TradeCode, createDate, closeVal, tmpErr.Error())) } } } else { //数据不存在,进行新增操作 if target.TradeCode != "" && createDate != "" && closeVal != "" { addDataList = append(addDataList, &models.Edbdata{ TradeCode: target.TradeCode, Dt: createDate, Close: closeVal, ModifyTime: time.Now(), }) edbCodeDataMap[target.TradeCode][createDate] = closeVal } } successCount++ } } } // 批量添加明细数据 if len(addDataList) > 0 { tmpErr := models.OnlyMultiAddEdbdata(addDataList) if tmpErr != nil { fmt.Println("line 221") errMsgList = append(errMsgList, fmt.Sprintf("批量添加明细数据失败,Err:%s", tmpErr.Error())) } } // 失败数量 failCount = len(failDataList) //fmt.Println("failDataList:", len(failDataList)) if failCount > 0 { //先删除导入失败记录 _ = models.DelEdbDataImportFail(sysUser.AdminId) // 批量添加导入失败记录 err = models.MultiAddEdbdataImportFail(failDataList) if err != nil { go alarm_msg.SendAlarmMsg("导入数据 新增失败记录失败,Err:"+err.Error(), 3) //go utils.SendEmail(utils.APPNAME+"失败提醒", "导入数据 新增失败记录失败:Err:"+err.Error(), utils.EmailSendToUsers) } { //错误信息字符串切片,最后作为发送邮件通知使用 failContents := make([]string, 0) for _, v := range failDataList { failContents = append(failContents, fmt.Sprint(v.SecName, "导入失败:", v.Remark)) } utils.FileLog.Info("导入数据 存在部分数据导入失败:" + strings.Join(failContents, ";")) //导入失败的话,最后统一邮件提醒就好啦,不需要每次都去提醒 go alarm_msg.SendAlarmMsg("导入数据 存在部分数据导入失败:"+strings.Join(failContents, ";"), 3) } } return } // ImportManualIndexData // @Description: excel模板后的内容 type ImportManualIndexData struct { IndexName string `description:"指标名称"` Unit string `description:"单位"` ClassName string `description:"所属品种"` Frequency string `description:"频度"` DataMap map[string]string `description:"时间数据"` } // getDataByTemplate1 // @Description: 根据模板1获取数据 // @author: Roc // @datetime 2024-07-24 16:17:45 // @param sheet *xlsx.Sheet // @return indexDataList []ImportManualIndexData // @return err error // @return errMsg string func getDataByTemplate1(sheet *xlsx.Sheet, sysUserId int) (indexDataList []ImportManualIndexData, failDataList []*models.EdbdataImportFail, err error, errMsg string) { fmt.Println("sheet name: ", sheet.Name) indexDataList = make([]ImportManualIndexData, 0) indexDataListMap := make(map[string]ImportManualIndexData, 0) failDataList = make([]*models.EdbdataImportFail, 0) //遍历行读取 maxRow := sheet.MaxRow fmt.Println("maxRow:", maxRow) // 表头信息 if maxRow <= 2 { errMsg = "模板异常1" err = errors.New(errMsg) return } // 表头校验 { headerRow := sheet.Row(1) cells := headerRow.Cells if len(cells) < 6 { errMsg = "导入文件异常,请下载最新导入模板文件" err = errors.New(errMsg) return } templateFail := false if cells[0].Value != "品种/Variety" { templateFail = true } if cells[1].Value != "指标名称/Indicator Name" { templateFail = true } if cells[2].Value != "指标日期/Indicator Date" { templateFail = true } if cells[3].Value != "值/Value" { templateFail = true } if cells[4].Value != "频度/Frequency" { templateFail = true } if cells[5].Value != "单位/Unit" { templateFail = true } if templateFail { errMsg = "导入文件异常,请下载最新导入模板文件" err = errors.New(errMsg) return } } for i := 2; i < maxRow; i++ { row := sheet.Row(i) cells := row.Cells lenCell := len(cells) // 过滤空白行 if lenCell <= 0 { continue } if lenCell < 6 { if cells[0].Value == `` { continue } errMsg = "导入文件异常,请下载最新导入模板文件" err = errors.New(errMsg) return } classifyName := strings.TrimSpace(cells[0].Value) //分类 if classifyName == "" { //过滤空白行 continue } // 指标名称 cell1 := cells[1].Value indexName := strings.TrimSpace(cell1) if indexName == "" { //过滤空白行 continue } //createDate := utils.ConvertToFormatDay(cell1) //录入日期 createDate := cells[2].Value //指标日期 frequency := strings.TrimSpace(cells[4].String()) //频度 unit := strings.TrimSpace(cells[5].String()) //单位 closeVal := cells[3].Value //值 if strings.Contains(closeVal, "#N/A") { continue } currDate, tmpErr := getExcelDate(createDate) if tmpErr != nil { failDataList = append(failDataList, &models.EdbdataImportFail{ //Id: 0, ClassifyName: classifyName, CreateDate: createDate, SecName: indexName, Close: closeVal, Remark: "日期格式异常", SysUserId: strconv.Itoa(sysUserId), Frequency: frequency, Unit: unit, }) continue } closeValFloat, tmpErr := cells[3].Float() //值 if tmpErr != nil { failDataList = append(failDataList, &models.EdbdataImportFail{ //Id: 0, ClassifyName: classifyName, CreateDate: currDate, SecName: indexName, Close: cells[3].Value, Remark: "值类型异常", SysUserId: strconv.Itoa(sysUserId), Frequency: frequency, Unit: unit, }) continue } newDecimal := decimal.NewFromFloat(closeValFloat) newDecimal.Round(4) closeVal = newDecimal.String() if strings.Contains(closeVal, "#N/A") { continue } _, ok := indexDataListMap[indexName] if !ok { indexDataListMap[indexName] = ImportManualIndexData{ IndexName: indexName, Unit: unit, ClassName: classifyName, Frequency: frequency, DataMap: make(map[string]string), } } indexDataListMap[indexName].DataMap[currDate] = closeVal } for _, v := range indexDataListMap { indexDataList = append(indexDataList, v) } return } // getDataByTemplate2 // @Description: 根据模板2获取数据 // @author: Roc // @datetime 2024-07-24 16:17:56 // @param sheet *xlsx.Sheet // @return indexDataList []ImportManualIndexData // @return err error // @return errMsg string func getDataByTemplate2(sheet *xlsx.Sheet, sysUserId int) (indexDataList []ImportManualIndexData, failDataList []*models.EdbdataImportFail, err error, errMsg string) { //fmt.Println("sheet name: ", sheet.Name) indexDataList = make([]ImportManualIndexData, 0) failDataList = make([]*models.EdbdataImportFail, 0) //遍历行读取 maxRow := sheet.MaxRow //fmt.Println("maxRow:", maxRow) varietyList := make([]string, 0) indexNameList := make([]string, 0) unitList := make([]string, 0) frequencyList := make([]string, 0) // make(map[指标下标]map[日期]值) indexDateValueMap := make(map[int]map[string]string) // 表头信息 if maxRow <= 4 { errMsg = "模板异常1" err = errors.New(errMsg) return } // 表头处理 for i := 1; i <= 4; i++ { row := sheet.Row(i) cells := row.Cells //if len(cells) < 1 { // errMsg = "模板异常2" // err = errors.New(errMsg) // return //} switch i { case 1: for k, v := range cells { if k == 0 { continue } varietyList = append(varietyList, strings.TrimSpace(v.String())) } case 2: for k, v := range cells { if k == 0 { continue } indexNameList = append(indexNameList, strings.TrimSpace(v.String())) } case 3: for k, v := range cells { if k == 0 { continue } unitList = append(unitList, strings.TrimSpace(v.String())) } case 4: for k, v := range cells { if k == 0 { continue } frequencyList = append(frequencyList, strings.TrimSpace(v.String())) } } } maxNameIndex := len(indexNameList) - 1 maxUnitIndex := len(unitList) - 1 maxClassNameIndex := len(varietyList) - 1 maxFrequencyIndex := len(frequencyList) - 1 // 数据处理 for i := 5; i < maxRow; i++ { row := sheet.Row(i) cells := row.Cells //if len(cells) < 1 { // errMsg = "模板异常2" // err = errors.New(errMsg) // return //} // 当前日期 var currDate string // 日期是否异常,异常的话,就跳过,进入下一行数据处理 var dateErr bool var emptyDate bool // 数据处理 for k, v := range cells { if k == 0 { // 空日期数据 if v.Value == `` { emptyDate = true continue } tmpCurrDate, tmpErr := getExcelDate(v.Value) if tmpErr != nil { dateErr = true } currDate = tmpCurrDate continue } key := k - 1 // 空日期数据,那就不处理了,不记录该行错误信息 if emptyDate { continue } // 日期异常,所以不处理该行了同时记录该行错误信息 if dateErr { var indexName, unit, classifyName, frequency string if key <= maxNameIndex { indexName = indexNameList[key] } if key <= maxUnitIndex { unit = unitList[key] } if key <= maxClassNameIndex { classifyName = varietyList[key] } if key <= maxFrequencyIndex { frequency = frequencyList[key] } failDataList = append(failDataList, &models.EdbdataImportFail{ //Id: 0, ClassifyName: classifyName, CreateDate: currDate, SecName: indexName, Close: v.Value, Remark: "日期格式异常", SysUserId: strconv.Itoa(sysUserId), Frequency: frequency, Unit: unit, }) continue } _, ok := indexDateValueMap[key] if !ok { indexDateValueMap[key] = make(map[string]string) } closeVal := v.Value //值 // 没有数据,说明是空串 if strings.Contains(closeVal, "#N/A") { indexDateValueMap[key][currDate] = "" continue } closeValFloat, tmpErr := v.Float() //值 if tmpErr != nil { // TODO 错误数据记录 //failItem := new(models.EdbdataImportFail) //failItem.SysUserId = strconv.Itoa(sysUser.AdminId) //failItem.ClassifyName = classifyName //failItem.CreateDate = createDate //failItem.SecName = secName //failItem.Close = cells[3].Value //failItem.Remark = "值类型异常" //failItem.Frequency = frequency //failItem.Unit = unit //failDataList = append(failDataList, failItem) indexDateValueMap[key][currDate] = "" continue } newDecimal := decimal.NewFromFloat(closeValFloat) newDecimal.Round(4) closeVal = newDecimal.String() if strings.Contains(closeVal, "#N/A") { indexDateValueMap[key][currDate] = "" continue } indexDateValueMap[key][currDate] = closeVal } } for i, indexName := range indexNameList { var unit, classifyName, frequency string if i <= maxUnitIndex { unit = unitList[i] } if i <= maxClassNameIndex { classifyName = varietyList[i] } if i <= maxFrequencyIndex { frequency = frequencyList[i] } indexData := ImportManualIndexData{ IndexName: indexName, Unit: unit, ClassName: classifyName, Frequency: frequency, DataMap: indexDateValueMap[i], } indexDataList = append(indexDataList, indexData) } return } // getExcelDate // @Description: 获取excel的日期 // @author: Roc // @datetime 2024-07-23 17:26:12 // @param createDate string // @return newCreateDate string // @return err error func getExcelDate(createDate string) (newCreateDate string, err error) { if strings.Contains(createDate, "-") { //如果是带有 - 的普通日期格式文本 _, err = time.Parse("2006-1-2", createDate) if err == nil { newCreateDate = createDate } } else if strings.Contains(createDate, "/") { //如果是带有 / 的普通日期格式文本 createDateTime, timeErr := time.Parse("2006/1/2", createDate) if timeErr != nil { err = timeErr } else { newCreateDate = createDateTime.Format("2006-01-02") } } else { //可能是excel的日期格式 _, tmpErr := strconv.Atoi(createDate) if tmpErr != nil { err = tmpErr } else { newCreateDate = utils.ConvertToFormatDay(createDate) //录入日期 } } return } // ModifyManualEdbMaxMinDate // @Description: 修改手动录入的edb数据的最大最小日期 // @author: Roc // @datetime 2024-08-01 15:34:31 // @param tradeCode string func ModifyManualEdbMaxMinDate(tradeCode string) { // 获取最大最小日期 item, err := models.GetEdbdataMaxMinDate(tradeCode) if err != nil { return } // 最新值 latestValue, err := models.GetEdbdataLatestValue(tradeCode) if err != nil { return } // 修改指标的最大最小日期和最新值 err = models.ModifyEdbinfoMaxMinDate(tradeCode, item.MinDate, item.MaxDate, latestValue) return } // GetUserManualClassifyIdList // @Description: 获取用户手动录入的分类id列表 // @author: Roc // @datetime 2024-08-02 15:09:11 // @param userId int // @return classifyIdList []int // @return err error func GetUserManualClassifyIdList(userId int) (classifyIdList []int, err error) { classifyIdList = make([]int, 0) // 获取有用权限的分类 classifyList, err := models.GetEdbdataClassify(int64(userId)) if err != nil { return } if len(classifyList) > 0 { for _, v := range classifyList { classifyIdList = append(classifyIdList, v.ClassifyId) if v.Child != nil && len(v.Child) > 0 { for _, v2 := range v.Child { classifyIdList = append(classifyIdList, v2.ClassifyId) } } } } return }