package assessment import ( "encoding/json" "eta/eta_api/controllers" "eta/eta_api/models" "eta/eta_api/utils" "fmt" "github.com/rdlucklib/rdluck_tools/paging" "github.com/tealeg/xlsx" "os" "path/filepath" "strconv" "strings" "time" ) // AssessmentVarietyController 考核品种 type AssessmentVarietyController struct { controllers.BaseAuthController } // Add // @Title 新增品种 // @Description 新增品种 // @Param request body models.AssessmentVarietyAddReq true "type json string" // @Success 200 string "操作成功" // @router /variety/add [post] func (this *AssessmentVarietyController) Add() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req models.AssessmentVarietyAddReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e) return } req.VarietyCode = strings.TrimSpace(req.VarietyCode) if req.VarietyCode == "" { br.Msg = "请输入品种编码" return } req.VarietyName = strings.TrimSpace(req.VarietyName) if req.VarietyName == "" { br.Msg = "请输入品种名称" return } if req.MonthlyFluctuate <= 0 { br.Msg = "请输入月度波动阈值" return } if req.WeeklyFluctuate <= 0 { br.Msg = "请输入周度波动阈值" return } disabledVariety := new(models.AssessmentVariety) varietyOb := new(models.AssessmentVariety) mappingOb := new(models.AssessmentResearcherVarietyMapping) // 去重校验:编码唯一 { cond := fmt.Sprintf(` AND %s = ?`, varietyOb.Cols().VarietyCode) pars := make([]interface{}, 0) pars = append(pars, req.VarietyCode) exists, e := varietyOb.GetItemByCondition(cond, pars, "") if e != nil && !utils.IsErrNoRow(e) { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("获取品种失败, %v", e) return } // PS.由于删除品种需要保留历史填报数据,如果品种被删除(即禁用)那么重新启用即可 if exists != nil && exists.AssessmentVarietyId > 0 { if exists.Enabled == models.AssessmentVarietyEnabled { br.Msg = "品种编码已存在,请勿重复添加" return } disabledVariety = exists } } var varietyId int if disabledVariety != nil && disabledVariety.AssessmentVarietyId > 0 { disabledVariety.VarietyName = req.VarietyName disabledVariety.MonthlyFluctuate = req.MonthlyFluctuate disabledVariety.WeeklyFluctuate = req.WeeklyFluctuate disabledVariety.Enabled = models.AssessmentVarietyEnabled disabledVariety.ModifyTime = time.Now().Local() updateCols := []string{varietyOb.Cols().VarietyName, varietyOb.Cols().MonthlyFluctuate, varietyOb.Cols().WeeklyFluctuate, varietyOb.Cols().Enabled, varietyOb.Cols().ModifyTime} if e := disabledVariety.Update(updateCols); e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("重新启用品种失败, %v", e) return } varietyId = disabledVariety.AssessmentVarietyId // 清除原有关联 cond := fmt.Sprintf(`%s = ?`, mappingOb.Cols().VarietyId) pars := make([]interface{}, 0) pars = append(pars, varietyId) if e := mappingOb.RemoveByCondition(cond, pars); e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("清空品种原关联失败, %v", e) return } } else { newVariety := new(models.AssessmentVariety) newVariety.VarietyCode = req.VarietyCode newVariety.VarietyName = req.VarietyName newVariety.MonthlyFluctuate = req.MonthlyFluctuate newVariety.WeeklyFluctuate = req.WeeklyFluctuate newVariety.Enabled = models.AssessmentVarietyEnabled newVariety.CreateTime = time.Now().Local() newVariety.ModifyTime = time.Now().Local() if e := newVariety.Create(); e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("新增品种失败, %v", e) return } varietyId = newVariety.AssessmentVarietyId } // 关联研究员 mappings := make([]*models.AssessmentResearcherVarietyMapping, 0) if len(req.AssessmentResearcherIds) > 0 { researcherOb := new(models.AssessmentResearcher) cond := fmt.Sprintf(` AND %s IN (?)`, researcherOb.Cols().PrimaryId) pars := make([]interface{}, 0) pars = append(pars, req.AssessmentResearcherIds) researchers, e := researcherOb.GetItemsByCondition(cond, pars, []string{}, "") if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取研究员失败, %v", e) return } for _, v := range researchers { m := new(models.AssessmentResearcherVarietyMapping) m.VarietyId = varietyId m.AssessmentResearcherId = v.AssessmentResearcherId m.AdminId = v.AdminId mappings = append(mappings, m) } } if len(mappings) > 0 { if e := mappingOb.CreateMulti(mappings); e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("批量新增研究员品种关联失败, %v", e) return } } br.Ret = 200 br.Success = true br.Msg = "操作成功" } // Edit // @Title 编辑品种 // @Description 编辑品种 // @Param request body models.AssessmentVarietyEditReq true "type json string" // @Success 200 string "操作成功" // @router /variety/edit [post] func (this *AssessmentVarietyController) Edit() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req models.AssessmentVarietyEditReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e) return } if req.AssessmentVarietyId <= 0 { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("参数有误, AssessmentVarietyId: %d", req.AssessmentVarietyId) return } if req.MonthlyFluctuate <= 0 { br.Msg = "请输入月度波动阈值" return } if req.WeeklyFluctuate <= 0 { br.Msg = "请输入周度波动阈值" return } varietyOb := new(models.AssessmentVariety) variety, e := varietyOb.GetItemById(req.AssessmentVarietyId) if e != nil { if utils.IsErrNoRow(e) { br.Msg = "品种不存在,请刷新页面" return } br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("获取品种失败, %v", e) return } if variety.Enabled == models.AssessmentVarietyDisabled { br.Msg = "品种不存在,请刷新页面" return } variety.MonthlyFluctuate = req.MonthlyFluctuate variety.WeeklyFluctuate = req.WeeklyFluctuate variety.ModifyTime = time.Now().Local() updateCols := []string{varietyOb.Cols().MonthlyFluctuate, varietyOb.Cols().WeeklyFluctuate, varietyOb.Cols().ModifyTime} if e := variety.Update(updateCols); e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("更新品种失败, %v", e) return } // 关联研究员,清空后新增 mappingOb := new(models.AssessmentResearcherVarietyMapping) { cond := fmt.Sprintf(`%s = ?`, mappingOb.Cols().VarietyId) pars := make([]interface{}, 0) pars = append(pars, variety.AssessmentVarietyId) if e = mappingOb.RemoveByCondition(cond, pars); e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("清空关联失败, %v", e) return } } mappings := make([]*models.AssessmentResearcherVarietyMapping, 0) if len(req.AssessmentResearcherIds) > 0 { researcherOb := new(models.AssessmentResearcher) cond := fmt.Sprintf(` AND %s IN (?)`, researcherOb.Cols().PrimaryId) pars := make([]interface{}, 0) pars = append(pars, req.AssessmentResearcherIds) researchers, e := researcherOb.GetItemsByCondition(cond, pars, []string{}, "") if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取研究员失败, %v", e) return } for _, v := range researchers { m := new(models.AssessmentResearcherVarietyMapping) m.VarietyId = variety.AssessmentVarietyId m.AssessmentResearcherId = v.AssessmentResearcherId m.AdminId = v.AdminId mappings = append(mappings, m) } } if len(mappings) > 0 { if e := mappingOb.CreateMulti(mappings); e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("批量新增研究员品种关联失败, %v", e) return } } br.Ret = 200 br.Success = true br.Msg = "操作成功" } // Remove // @Title 删除品种 // @Description 删除品种 // @Param request body models.AssessmentVarietyRemoveReq true "type json string" // @Success 200 string "操作成功" // @router /variety/remove [post] func (this *AssessmentVarietyController) Remove() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req models.AssessmentVarietyRemoveReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e) return } if req.AssessmentVarietyId <= 0 { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("参数有误, AssessmentVarietyId: %d", req.AssessmentVarietyId) return } varietyOb := new(models.AssessmentVariety) variety, e := varietyOb.GetItemById(req.AssessmentVarietyId) if e != nil { if utils.IsErrNoRow(e) { br.Ret = 200 br.Success = true br.Msg = "操作成功" return } br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("获取品种失败, %v", e) return } if variety.Enabled == models.AssessmentVarietyDisabled { br.Ret = 200 br.Success = true br.Msg = "操作成功" return } // 由于要保留历史填报数据,这里实际为禁用操作 updateCols := []string{varietyOb.Cols().Enabled, varietyOb.Cols().ModifyTime} variety.Enabled = models.AssessmentVarietyDisabled variety.ModifyTime = time.Now() if e = variety.Update(updateCols); e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("禁用品种失败, %v", e) return } // 关联也不需要清理 //mappingOb := new(models.AssessmentResearcherVarietyMapping) //{ // cond := fmt.Sprintf(`%s = ?`, mappingOb.Cols().VarietyId) // pars := make([]interface{}, 0) // pars = append(pars, variety.AssessmentVarietyId) // if e = mappingOb.RemoveByCondition(cond, pars); e != nil { // br.Msg = "操作失败" // br.ErrMsg = fmt.Sprintf("清空关联失败, %v", e) // return // } //} br.Ret = 200 br.Success = true br.Msg = "操作成功" } // Detail // @Title 品种详情 // @Description 品种详情 // @Param AssessmentVarietyId query int true "品种ID" // @Success 200 string "操作成功" // @router /variety/detail [get] func (this *AssessmentVarietyController) Detail() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } varietyId, _ := this.GetInt("AssessmentVarietyId") if varietyId <= 0 { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("参数有误, VarietyId: %d", varietyId) return } varietyOb := new(models.AssessmentVariety) variety, e := varietyOb.GetItemById(varietyId) if e != nil { if utils.IsErrNoRow(e) { br.Msg = "品种不存在,请重新页面" return } br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取品种失败, %v", e) return } if variety.Enabled == models.AssessmentVarietyDisabled { br.Msg = "品种不存在,请刷新页面" return } resp := variety.Format2Detail() // 获取启用研究员 researcherMapping := make(map[int]*models.AssessmentResearcher) { researcherOb := new(models.AssessmentResearcher) cond := fmt.Sprintf(` AND %s = ?`, researcherOb.Cols().Enabled) pars := make([]interface{}, 0) pars = append(pars, models.AssessmentResearcherEnabled) researchers, e := researcherOb.GetItemsByCondition(cond, pars, []string{}, "") if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取研究员失败, %v", e) return } for _, v := range researchers { researcherMapping[v.AssessmentResearcherId] = v } } // 获取研究员关联 mappings := make([]*models.AssessmentResearcherVarietyMapping, 0) { mappingOb := new(models.AssessmentResearcherVarietyMapping) cond := fmt.Sprintf(` AND %s = ?`, mappingOb.Cols().VarietyId) pars := make([]interface{}, 0) pars = append(pars, variety.AssessmentVarietyId) mappings, e = mappingOb.GetItemsByCondition(cond, pars, []string{}, "") if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取研究员品种关联失败, %v", e) return } } for _, v := range mappings { rs := researcherMapping[v.AssessmentResearcherId] if rs == nil { continue } ar := models.AssessmentResearcherDetail{ AssessmentResearcherId: rs.AssessmentResearcherId, AdminId: v.AdminId, RealName: rs.RealName, Enabled: rs.Enabled, } resp.RelationResearcher = append(resp.RelationResearcher, ar) } br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" } // PageList // @Title 品种列表-分页 // @Description 品种列表-分页 // @Param request body models.AssessmentVarietyPageListReq true "type json string" // @Success 200 string "操作成功" // @router /variety/page_list [get] func (this *AssessmentVarietyController) PageList() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } params := new(models.AssessmentVarietyPageListReq) if e := this.ParseForm(params); e != nil { br.Msg = "获取失败" br.ErrMsg = "参数解析失败, Err: " + e.Error() return } resp := new(models.AssessmentVarietyPageListResp) resp.List = make([]*models.AssessmentVarietyDetail, 0) // 分页 var startSize int if params.PageSize <= 0 { params.PageSize = utils.PageSize20 } if params.CurrentIndex <= 0 { params.CurrentIndex = 1 } startSize = utils.StartIndex(params.CurrentIndex, params.PageSize) // 筛选项 varietyOb := new(models.AssessmentVariety) condVariety := `` parsVariety := make([]interface{}, 0) { if params.AssessmentVarietyIds != "" { var varietyIds []int arr := strings.Split(params.AssessmentVarietyIds, ",") for _, v := range arr { i, _ := strconv.Atoi(v) if i > 0 { varietyIds = append(varietyIds, i) } } if len(varietyIds) == 0 { resp.Paging = paging.GetPaging(params.CurrentIndex, params.PageSize, 0) br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" return } condVariety += fmt.Sprintf(" AND %s IN (?)", varietyOb.Cols().PrimaryId) parsVariety = append(parsVariety, varietyIds) } // 仅显示启用的 if params.OnlyEnabled { condVariety += fmt.Sprintf(` AND %s = ?`, varietyOb.Cols().Enabled) parsVariety = append(parsVariety, models.AssessmentVarietyEnabled) } } // 列表 total, e := varietyOb.GetCountByCondition(condVariety, parsVariety) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取研究员列表总数失败, %v", e) return } varieties, e := varietyOb.GetPageItemsByCondition(condVariety, parsVariety, []string{}, "", startSize, params.PageSize) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取研究员失败, %v", e) return } var varietyIds []int for _, v := range varieties { varietyIds = append(varietyIds, v.AssessmentVarietyId) } if total == 0 || len(varietyIds) == 0 { resp.Paging = paging.GetPaging(params.CurrentIndex, params.PageSize, 0) br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" return } // 获取启用研究员 researcherMapping := make(map[int]*models.AssessmentResearcher) { researcherOb := new(models.AssessmentResearcher) cond := fmt.Sprintf(` AND %s = ?`, researcherOb.Cols().Enabled) pars := make([]interface{}, 0) pars = append(pars, models.AssessmentResearcherEnabled) researchers, e := researcherOb.GetItemsByCondition(cond, pars, []string{}, "") if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取研究员失败, %v", e) return } for _, v := range researchers { researcherMapping[v.AssessmentResearcherId] = v } } // 关联研究员 varietyResearcherMapping := make(map[int][]models.AssessmentResearcherDetail) { mappingOb := new(models.AssessmentResearcherVarietyMapping) cond := fmt.Sprintf(` AND %s IN (?)`, mappingOb.Cols().VarietyId) pars := make([]interface{}, 0) pars = append(pars, varietyIds) list, e := mappingOb.GetItemsByCondition(cond, pars, []string{}, "") if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取研究员品种关联失败, %v", e) return } for _, v := range list { rs := researcherMapping[v.AssessmentResearcherId] if rs == nil { continue } ar := models.AssessmentResearcherDetail{ AssessmentResearcherId: v.AssessmentResearcherId, AdminId: v.AdminId, RealName: rs.RealName, } varietyResearcherMapping[v.VarietyId] = append(varietyResearcherMapping[v.VarietyId], ar) } } for _, v := range varieties { t := v.Format2Detail() t.RelationResearcher = varietyResearcherMapping[v.AssessmentVarietyId] resp.List = append(resp.List, t) } resp.Paging = paging.GetPaging(params.CurrentIndex, params.PageSize, total) br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" } // ImportData // @Title 导入品种数据 // @Description 导入品种数据 // @Success 200 string "操作成功" // @router /variety/import_data [post] func (this *AssessmentVarietyController) ImportData() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } file, header, e := this.GetFile("VarietyData") if e != nil { br.Msg = "导入失败" br.ErrMsg = fmt.Sprintf("获取文件失败, %v", e) return } // 文件格式校验 ext := strings.ToLower(filepath.Ext(header.Filename)) if ext != ".xlsx" && ext != ".xls" { br.Msg = "文件格式有误,请上传Excel文件" _ = file.Close() return } path := "./static/assessment_variety_" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx" defer func() { _ = file.Close() _ = os.Remove(path) }() if e = this.SaveToFile("VarietyData", path); e != nil { br.Msg = "导入失败" br.ErrMsg = fmt.Sprintf("保存文件失败, %v", e) return } xlFile, e := xlsx.OpenFile(path) if e != nil { br.Msg = "导入失败" br.ErrMsg = fmt.Sprintf("打开excel文件失败, %v", e) return } if len(xlFile.Sheets) == 0 { br.Msg = "无有效数据,请检查" br.ErrMsg = "Sheet为空" return } // PS.导入规则:品种管理中的每个品种都需要有对应的日期数据,少一个都不允许上传,允许一次传多周的数据 varieties, weekDates := make([]string, 0), make([]string, 0) varietyNameMatch := make(map[string]*models.AssessmentVariety) varietyDateExist := make(map[string]bool) // [品种-日期]用于校验品种是否和日期一一对应 { varietyOb := new(models.AssessmentVariety) cond := fmt.Sprintf(` AND %s = ?`, varietyOb.Cols().Enabled) pars := make([]interface{}, 0) pars = append(pars, models.AssessmentVarietyEnabled) list, e := varietyOb.GetItemsByCondition(cond, pars, []string{}, "") if e != nil { br.Msg = "导入失败" br.ErrMsg = fmt.Sprintf("获取品种列表失败, %v", e) return } for _, v := range list { varieties = append(varieties, v.VarietyName) varietyNameMatch[v.VarietyName] = v } } rowData := make(map[int]*models.AssessmentVarietyData) titleArr := []string{"品种名称", "当周收盘日期", "当周收盘价", "当周最高价", "当周最低价"} for _, sheet := range xlFile.Sheets { maxRow := sheet.MaxRow colMax := len(titleArr) for i := 0; i < maxRow; i++ { // 检查首行表头 row := sheet.Row(i) cells := row.Cells cellLen := len(cells) if i == 0 { for j := 0; j < colMax; j++ { if cellLen <= j { br.Msg = fmt.Sprintf("第%d列应为%s,请检查表头", j+1, titleArr[j]) return } cv := cells[j] if cv == nil { br.Msg = fmt.Sprintf("第%d列应为%s,请检查表头", j+1, titleArr[j]) return } title := strings.TrimSpace(cv.Value) if titleArr[j] != title { br.Msg = fmt.Sprintf("第%d列应为%s,请检查表头", j+1, titleArr[j]) return } } continue } // 数据行,每格均为必填 for j := 0; j < colMax; j++ { if cellLen <= j { br.Msg = fmt.Sprintf("第%d行第%d列数据有误,请检查", i+1, j+1) return } cv := cells[j] if cv == nil { br.Msg = fmt.Sprintf("第%d行第%d列数据有误,请检查", i+1, j+1) return } val := strings.TrimSpace(cv.Value) if val == "" { br.Msg = fmt.Sprintf("第%d行第%d列数据为空,请检查", i+1, j+1) return } switch j { case 0: // 品种名称 vat := varietyNameMatch[val] if vat == nil { br.Msg = fmt.Sprintf("第%d行第%d列品种不存在,请检查", i+1, j+1) return } rowData[i] = new(models.AssessmentVarietyData) rowData[i].VarietyId = vat.AssessmentVarietyId rowData[i].VarietyName = vat.VarietyName rowData[i].VarietyCode = vat.VarietyCode rowData[i].CreateTime = time.Now().Local() rowData[i].ModifyTime = time.Now().Local() case 1: // 当周收盘日期 d, e := time.ParseInLocation(utils.FormatDate, val, time.Local) if e != nil { br.Msg = fmt.Sprintf("第%d行第%d列日期格式有误,请检查", i+1, j+1) return } rd := rowData[i] if rd == nil { br.Msg = fmt.Sprintf("第%d行第%d列异常,请检查", i+1, j+1) return } rd.WeekDate = d // 加入日期集合,后面统一校验品种和日期是否一一对应 if !utils.InArrayByStr(weekDates, val) { weekDates = append(weekDates, val) } // 品种的日期存在重复需要提示 k := fmt.Sprintf("%s-%s", rd.VarietyName, val) if varietyDateExist[k] { br.Msg = fmt.Sprintf("品种%s%s的数据重复,请检查", rd.VarietyName, val) return } varietyDateExist[k] = true case 2, 3, 4: // 当周收盘价 price, e := strconv.ParseFloat(val, 64) if e != nil { br.Msg = fmt.Sprintf("第%d行第%d列价格异常,请检查", i+1, j+1) return } rd := rowData[i] if rd == nil { br.Msg = fmt.Sprintf("第%d行第%d列异常,请检查", i+1, j+1) return } if j == 2 { rd.CloseValue = price } if j == 3 { rd.HighValue = price } if j == 4 { rd.LowValue = price } } } } } // 校验品种和日期是否一一对应 for _, v := range varieties { for _, d := range weekDates { k := fmt.Sprintf("%s-%s", v, d) if !varietyDateExist[k] { br.Msg = fmt.Sprintf("品种%s%s数据不存在,请确保品种和周度数据一一对应", v, d) return } } } if len(rowData) == 0 { br.Msg = "无有效数据" return } // 获取已有数据根据[品种-日期]判断新增还是更新 dataOb := new(models.AssessmentVarietyData) existsData, e := dataOb.GetItemsByCondition(``, make([]interface{}, 0), []string{}, "") if e != nil { br.Msg = "导入失败" br.ErrMsg = fmt.Sprintf("获取品种数据列表失败, %v", e) return } existsMapping := make(map[string]*models.AssessmentVarietyData) for _, v := range existsData { k := fmt.Sprintf("%s-%s", v.VarietyName, v.WeekDate.Format(utils.FormatDate)) existsMapping[k] = v } insertData, updateData := make([]*models.AssessmentVarietyData, 0), make([]*models.AssessmentVarietyData, 0) for _, v := range rowData { k := fmt.Sprintf("%s-%s", v.VarietyName, v.WeekDate.Format(utils.FormatDate)) exist := existsMapping[k] if exist == nil { insertData = append(insertData, v) continue } // 价格数据一致不更新 if exist.CloseValue == v.CloseValue && exist.HighValue == v.HighValue && exist.LowValue == v.LowValue { continue } exist.CloseValue = v.CloseValue exist.HighValue = v.HighValue exist.LowValue = v.LowValue exist.ModifyTime = time.Now().Local() updateData = append(updateData, exist) } // 新增/更新数据 if len(insertData) > 0 { if e = dataOb.CreateMulti(insertData); e != nil { br.Msg = "导入失败" br.ErrMsg = fmt.Sprintf("新增品种数据失败, %v", e) return } } if len(updateData) > 0 { updateCols := []string{dataOb.Cols().CloseValue, dataOb.Cols().HighValue, dataOb.Cols().LowValue, dataOb.Cols().ModifyTime} for _, v := range updateData { if e = v.Update(updateCols); e != nil { br.Msg = "导入失败" br.ErrMsg = fmt.Sprintf("更新品种数据失败, %v", e) return } } } br.Ret = 200 br.Success = true br.Msg = "操作成功" }