Переглянути джерело

fix:新增存量装置数据计算

Roc 2 роки тому
батько
коміт
961bf9237a

+ 182 - 0
controllers/base_from_stock_plant.go

@@ -0,0 +1,182 @@
+package controllers
+
+import (
+	"encoding/json"
+	"hongze/hongze_edb_lib/logic"
+	"hongze/hongze_edb_lib/models"
+	"hongze/hongze_edb_lib/models/supply_analysis"
+	"hongze/hongze_edb_lib/utils"
+	"strconv"
+	"time"
+)
+
+// StockPlantController 存量装置
+type StockPlantController struct {
+	BaseAuthController
+}
+
+// Calculate
+// @Title 计算减产数
+// @Description 计算减产数
+// @Success 200 {object} supply_analysis.CalculateVarietyReq
+// @router /calculate [post]
+func (this *StockPlantController) Calculate() {
+	br := new(models.BaseResponse).Init()
+	var cacheKey string
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req supply_analysis.CalculateVarietyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.VarietyId <= 0 {
+		br.Msg = "请选择品种!"
+		br.ErrMsg = "请选择品种"
+		return
+	}
+
+	//cacheKey = utils.CACHE_STOCK_PLANT_CALCULATE + strconv.Itoa(req.VarietyId)
+	//if utils.Rc.IsExist(cacheKey) {
+	//	br.Ret = 501
+	//	br.Success = true
+	//	br.Msg = "系统处理中,请稍后重试"
+	//	return
+	//}
+
+	utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
+	defer func() {
+		utils.Rc.Delete(cacheKey)
+	}()
+
+	err = supply_analysis.Calculate(req.VarietyId, req.AdminId, req.AdminName)
+	if err != nil {
+		br.Msg = "获取指标信息失败!"
+		br.ErrMsg = "获取指标信息失败 AddEdbDataFromManual,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 新增手工指标接口
+// @Description 新增手工指标接口
+// @Success 200 {object} models.AddEdbInfoReq
+// @router /add [post]
+func (this *StockPlantController) Add() {
+	br := new(models.BaseResponse).Init()
+	var cacheKey string
+	defer func() {
+		utils.Rc.Delete(cacheKey)
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	source := utils.DATA_SOURCE_MANUAL
+	var req models.AddEdbInfoReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.EdbCode == "" {
+		br.Msg = "请输入指标编码!"
+		br.ErrMsg = "请输入指标编码,指标编码为空"
+		return
+	}
+	cacheKey = utils.CACHE_EDB_DATA_ADD + strconv.Itoa(source) + "_" + req.EdbCode
+	if !utils.Rc.IsExist(cacheKey) {
+		utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
+		err = models.AddEdbDataFromManual(req.EdbCode)
+		if err != nil {
+			br.Msg = "获取指标信息失败!"
+			br.ErrMsg = "获取指标信息失败 AddEdbDataFromManual,Err:" + err.Error()
+			return
+		}
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+	} else {
+		br.Ret = 501
+		br.Success = true
+		br.Msg = "系统处理中,请稍后重试"
+	}
+}
+
+// @Title 刷新手工指标接口
+// @Description 刷新手工指标接口
+// @Success 200 {object} models.RefreshEdbInfoReq
+// @router /refresh [post]
+func (this *StockPlantController) Refresh() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	source := utils.DATA_SOURCE_MANUAL
+	var req models.RefreshEdbInfoReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.EdbCode == "" {
+		br.Msg = "请输入指标编码!"
+		br.ErrMsg = "请输入指标编码,指标编码为空"
+		return
+	}
+	if req.EdbInfoId <= 0 {
+		br.Msg = "请输入指标ID!"
+		br.ErrMsg = "请输入指标ID"
+		return
+	}
+
+	cacheKey := utils.CACHE_EDB_DATA_REFRESH + strconv.Itoa(source) + "_" + req.EdbCode
+	if utils.Rc.IsExist(cacheKey) {
+		br.Ret = 501
+		br.Success = true
+		br.Msg = "系统处理中,请稍后重试"
+		return
+	}
+
+	// 设置缓存
+	utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
+	defer func() {
+		utils.Rc.Delete(cacheKey)
+	}()
+	// 获取指标详情
+	edbInfo, err := models.GetEdbInfoByEdbCode(source, req.EdbCode)
+	if err != nil {
+		br.Msg = "指标不存在!"
+		br.ErrMsg = "指标不存在"
+		return
+	}
+
+	req.StartDate = `` // 开始日期也给过滤吧,万一研究员补充了之前的数据呢,还是过滤掉吧
+	err = models.RefreshEdbDataFromManual(req.EdbInfoId, req.EdbCode, req.StartDate)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "刷新指标信息失败!"
+		br.ErrMsg = "刷新指标信息失败 RefreshEdbDataFromManual,Err:" + err.Error()
+		return
+	}
+	// 更新指标最大最小值
+	err, errMsg := models.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo)
+	if err != nil {
+		br.Msg = errMsg
+		br.ErrMsg = err.Error()
+		return
+	}
+
+	// 更新ES
+	go logic.UpdateEs(edbInfo.EdbInfoId)
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 15 - 0
models/db.go

@@ -4,6 +4,7 @@ import (
 	"github.com/beego/beego/v2/client/orm"
 	_ "github.com/go-sql-driver/mysql"
 	"hongze/hongze_edb_lib/models/future_good"
+	"hongze/hongze_edb_lib/models/supply_analysis"
 	"hongze/hongze_edb_lib/utils"
 	"time"
 )
@@ -54,6 +55,9 @@ func init() {
 
 	// 注册期货数据 数据表
 	initFutureGood()
+
+	// 供应分析 数据表
+	initSupplyAnalysis()
 }
 
 // initFutureGood 注册期货数据 数据表
@@ -64,3 +68,14 @@ func initFutureGood() {
 		new(future_good.FutureGoodEdbData), //期货指标数据表
 	)
 }
+
+// initSupplyAnalysis 供应分析
+func initSupplyAnalysis() {
+	orm.RegisterModel(
+		new(supply_analysis.Variety),
+		new(supply_analysis.VarietyAdminPermission),
+		new(supply_analysis.VarietyEdbInfo),
+		new(supply_analysis.VarietyPlant),
+		new(supply_analysis.BaseFromStockPlantData),
+	)
+}

+ 386 - 0
models/supply_analysis/base_from_stock_plant_data.go

@@ -0,0 +1,386 @@
+package supply_analysis
+
+import (
+	"errors"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/shopspring/decimal"
+	"hongze/hongze_edb_lib/utils"
+	"time"
+)
+
+// BaseFromStockPlantData base_from_stock_plant_data 存量装置的指标的计算数据
+type BaseFromStockPlantData struct {
+	StockPlantDataId int       `orm:"column(stock_plant_data_id);pk"`
+	VarietyEdbId     int       `description:"指标id"`
+	DataTime         time.Time `description:"数据日期"`
+	Value            float64   `description:"数据值"`
+	ModifyTime       time.Time `description:"修改时间"`
+	CreateTime       time.Time `description:"创建时间"`
+	DataTimestamp    int64     `description:"数据日期时间戳"`
+}
+
+// CalculateVarietyReq 重新计算请求
+type CalculateVarietyReq struct {
+	VarietyId int    `description:"品种id"`
+	AdminId   int    `description:"操作人id"`
+	AdminName string `description:"操作人名称"`
+}
+
+func Calculate(varietyId int, sysUserId int, sysUserName string) (err error) {
+	varietyInfo, err := GetVarietyById(varietyId)
+	if err != nil {
+		return
+	}
+
+	// 获取所有的装置
+	plantList, err := GetAllVarietyPlantByVarietyId(varietyId)
+	if err != nil {
+		return
+	}
+
+	// 获取所有的指标
+	varietyEdbInfoList, err := GetAllVarietyEdbInfoByVarietyId(varietyId)
+	if err != nil {
+		return
+	}
+
+	// 维修数据的开始日期和结束日期
+	var startDate, endDate time.Time
+	//所有设备在该日期的减产数
+	maintenanceDataMap := make(map[time.Time][]float64)
+
+	for _, plantInfo := range plantList {
+		// 开始检修日期
+		if startDate.IsZero() || plantInfo.MaintenanceDate.Before(startDate) {
+			startDate = plantInfo.MaintenanceDate
+		}
+		// 结束检修日期
+		if endDate.IsZero() || plantInfo.ResumptionDate.After(endDate) {
+			endDate = plantInfo.ResumptionDate
+		}
+
+		for tmpDate := plantInfo.MaintenanceDate; !tmpDate.After(plantInfo.ResumptionDate); tmpDate = tmpDate.AddDate(0, 0, 1) {
+			dataList, ok := maintenanceDataMap[tmpDate]
+			if !ok {
+				dataList = make([]float64, 0)
+			}
+			dataList = append(dataList, plantInfo.AverageDailyCapacityReduction)
+			maintenanceDataMap[tmpDate] = dataList
+		}
+	}
+
+	// 产生的数据的结束日期
+	var lastDate time.Time
+
+	currDate := time.Now()
+	currHour := currDate.Hour()
+	if currHour < 22 {
+		lastDate, _ = time.ParseInLocation(utils.FormatDate, currDate.Format(utils.FormatDate), time.Local)
+	} else {
+		lastDate, _ = time.ParseInLocation(utils.FormatDate, currDate.AddDate(0, 0, 1).Format(utils.FormatDate), time.Local)
+	}
+	lastDate = lastDate.AddDate(1, 0, 0) //业务需要计算的数据日期往当前日期后面加上一年
+
+	// 计算出数据
+	dataMap := make(map[time.Time]float64)
+	for tmpDate := startDate; !tmpDate.After(lastDate); tmpDate = tmpDate.AddDate(0, 0, 1) {
+		var calculateVal float64
+		tmpDataList, ok := maintenanceDataMap[tmpDate]
+		// 如果没有维修数据,那么退出当前循环,进入下一个循环
+		if !ok {
+			calculateVal = 0
+		} else {
+			for _, tmpVal := range tmpDataList {
+				calculateVal += tmpVal
+			}
+		}
+
+		dataMap[tmpDate] = calculateVal
+	}
+
+	to, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+
+	defer func() {
+		if err != nil {
+			fmt.Println("Calculate,Err:" + err.Error())
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	for _, varietyEdbInfo := range varietyEdbInfoList {
+		err = calculateEdb(to, varietyEdbInfo, dataMap, startDate, lastDate)
+		if err != nil {
+			return
+		}
+	}
+
+	// 更新最后分析的人员信息
+	varietyInfo.LastUpdateSysUserId = sysUserId
+	varietyInfo.LastUpdateSysUserRealName = sysUserName
+	varietyInfo.ModifyTime = time.Now()
+	_, err = to.Update(varietyInfo, "LastUpdateSysUserId", "LastUpdateSysUserRealName", "ModifyTime")
+
+	return
+}
+
+func calculateEdb(to orm.TxOrmer, varietyEdbInfo *VarietyEdbInfo, dataMap map[time.Time]float64, startDate, lastDate time.Time) (err error) {
+	sql := `SELECT * FROM base_from_stock_plant_data WHERE variety_edb_id = ? `
+	var list []*BaseFromStockPlantData
+	_, err = to.Raw(sql, varietyEdbInfo.VarietyEdbId).QueryRows(&list)
+	if err != nil {
+		return
+	}
+
+	addList := make([]*BaseFromStockPlantData, 0)
+	deleteIdMap := make(map[int]int, 0)
+
+	existData := make(map[time.Time]*BaseFromStockPlantData)
+	for _, v := range list {
+		existData[v.DataTime] = v
+		deleteIdMap[v.StockPlantDataId] = v.StockPlantDataId
+	}
+
+	tmpDataList := make([]float64, 0) // 每天的值
+	var preSumValDeci decimal.Decimal // 上一期的值
+	switch varietyEdbInfo.Source {
+	//1:影响周度产量;2:周度产量变动;3:影响月度产量;4:月度产量变动
+	case 1, 2:
+		// 期间周度数据
+		for tmpDate := startDate; !tmpDate.After(lastDate); tmpDate = tmpDate.AddDate(0, 0, 1) {
+			tmpData, ok := dataMap[tmpDate]
+			if !ok {
+				continue
+			}
+			tmpDataList = append(tmpDataList, tmpData)
+
+			if tmpDate.Weekday() != 0 {
+				// 如果不是周日,那么就退出当前循环
+				continue
+			}
+
+			timestamp := tmpDate.UnixNano() / 1e6
+
+			// 日期期间汇总数据
+			var sumVal float64
+			for _, tmpVal := range tmpDataList {
+				sumVal += tmpVal
+			}
+			sumValDeci := decimal.NewFromFloat(sumVal)
+
+			var currVal float64
+			if varietyEdbInfo.Source == 2 { // 如果是变动的话,那么是
+				currVal, _ = (decimal.NewFromFloat(sumVal).Sub(preSumValDeci)).Round(4).Float64()
+			} else {
+				currVal, _ = sumValDeci.Round(4).Float64()
+			}
+			preSumValDeci = sumValDeci       // 赋值给上一个周期的截止值
+			tmpDataList = make([]float64, 0) //重置值列表,便于下一个周期计算
+
+			existItem, ok := existData[tmpDate]
+			if !ok {
+				addList = append(addList, &BaseFromStockPlantData{
+					//StockPlantDataId: 0,
+					VarietyEdbId:  varietyEdbInfo.VarietyEdbId,
+					DataTime:      tmpDate,
+					Value:         currVal,
+					ModifyTime:    time.Now(),
+					CreateTime:    time.Now(),
+					DataTimestamp: timestamp,
+				})
+			} else {
+				if existItem.Value != currVal {
+					existItem.Value = currVal
+					existItem.ModifyTime = time.Now()
+					_, err = to.Update(existItem, "Value", "ModifyTime")
+					if err != nil {
+						return
+					}
+				}
+
+				delete(deleteIdMap, existItem.StockPlantDataId)
+			}
+		}
+
+		// 最后一周,不满一周时的计算
+		lastDateWeek := lastDate.Weekday()
+		if lastDateWeek != 0 {
+			// 如果最后一天不是周日,那么需要把日期调整到周日
+			subDay := 7 - lastDateWeek
+			tmpDate := lastDate.AddDate(0, 0, int(subDay))
+			existItem, ok := existData[tmpDate]
+
+			timestamp := tmpDate.UnixNano() / 1e6
+			// 日期期间汇总数据
+			var sumVal float64
+			for _, tmpVal := range tmpDataList {
+				sumVal += tmpVal
+			}
+			sumValDeci := decimal.NewFromFloat(sumVal)
+
+			var currVal float64
+			if varietyEdbInfo.Source == 2 { // 如果是变动的话,那么是
+				currVal, _ = (decimal.NewFromFloat(sumVal).Sub(preSumValDeci)).Round(4).Float64()
+			} else {
+				currVal, _ = sumValDeci.Round(4).Float64()
+			}
+			if !ok {
+				addList = append(addList, &BaseFromStockPlantData{
+					//StockPlantDataId: 0,
+					VarietyEdbId:  varietyEdbInfo.VarietyEdbId,
+					DataTime:      tmpDate,
+					Value:         currVal,
+					ModifyTime:    time.Now(),
+					CreateTime:    time.Now(),
+					DataTimestamp: timestamp,
+				})
+			} else {
+				if existItem.Value != currVal {
+					existItem.Value = currVal
+					existItem.ModifyTime = time.Now()
+					_, err = to.Update(existItem, "Value", "ModifyTime")
+					if err != nil {
+						return
+					}
+				}
+
+				delete(deleteIdMap, existItem.StockPlantDataId)
+			}
+		}
+
+	case 3, 4:
+		// 期间月度数据
+		for tmpDate := startDate; !tmpDate.After(lastDate); tmpDate = tmpDate.AddDate(0, 0, 1) {
+			tmpData, ok := dataMap[tmpDate]
+			if !ok {
+				continue
+			}
+			tmpDataList = append(tmpDataList, tmpData)
+
+			if tmpDate.AddDate(0, 0, 1).Day() != 1 {
+				// 如果不是每个月的最后一日,那么就退出当前循环
+				continue
+			}
+
+			timestamp := tmpDate.UnixNano() / 1e6
+
+			// 日期期间汇总数据
+			var sumVal float64
+			for _, tmpVal := range tmpDataList {
+				sumVal += tmpVal
+			}
+			sumValDeci := decimal.NewFromFloat(sumVal)
+
+			var currVal float64
+			if varietyEdbInfo.Source == 2 { // 如果是变动的话,那么是
+				currVal, _ = (decimal.NewFromFloat(sumVal).Sub(preSumValDeci)).Round(4).Float64()
+			} else {
+				currVal, _ = sumValDeci.Round(4).Float64()
+			}
+			preSumValDeci = sumValDeci       // 赋值给上一个周期的截止值
+			tmpDataList = make([]float64, 0) //重置值列表,便于下一个周期计算
+
+			existItem, ok := existData[tmpDate]
+			if !ok {
+				addList = append(addList, &BaseFromStockPlantData{
+					//StockPlantDataId: 0,
+					VarietyEdbId:  varietyEdbInfo.VarietyEdbId,
+					DataTime:      tmpDate,
+					Value:         currVal,
+					ModifyTime:    time.Now(),
+					CreateTime:    time.Now(),
+					DataTimestamp: timestamp,
+				})
+			} else {
+				if existItem.Value != currVal {
+					existItem.Value = currVal
+					existItem.ModifyTime = time.Now()
+					_, err = to.Update(existItem, "Value", "ModifyTime")
+					if err != nil {
+						return
+					}
+				}
+
+				delete(deleteIdMap, existItem.StockPlantDataId)
+			}
+		}
+
+		// 最后一月,不满一月时的计算
+		currMonthEndDay := time.Date(lastDate.Year(), lastDate.Month(), 1, 0, 0, 0, 0, time.Local).AddDate(0, 1, -1)
+		if lastDate.Equal(currMonthEndDay) {
+			// 如果最后一天不是当月的最后一天,那么需要把日期调整到当月的最后一天
+			tmpDate := currMonthEndDay
+			existItem, ok := existData[tmpDate]
+
+			timestamp := tmpDate.UnixNano() / 1e6
+			// 日期期间汇总数据
+			var sumVal float64
+			for _, tmpVal := range tmpDataList {
+				sumVal += tmpVal
+			}
+			sumValDeci := decimal.NewFromFloat(sumVal)
+
+			var currVal float64
+			if varietyEdbInfo.Source == 2 { // 如果是变动的话,那么是
+				currVal, _ = (decimal.NewFromFloat(sumVal).Sub(preSumValDeci)).Round(4).Float64()
+			} else {
+				currVal, _ = sumValDeci.Round(4).Float64()
+			}
+			if !ok {
+				addList = append(addList, &BaseFromStockPlantData{
+					//StockPlantDataId: 0,
+					VarietyEdbId:  varietyEdbInfo.VarietyEdbId,
+					DataTime:      tmpDate,
+					Value:         currVal,
+					ModifyTime:    time.Now(),
+					CreateTime:    time.Now(),
+					DataTimestamp: timestamp,
+				})
+			} else {
+				if existItem.Value != currVal {
+					existItem.Value = currVal
+					existItem.ModifyTime = time.Now()
+					_, err = to.Update(existItem, "Value", "ModifyTime")
+					if err != nil {
+						return
+					}
+				}
+
+				delete(deleteIdMap, existItem.StockPlantDataId)
+			}
+		}
+	default:
+		err = errors.New("错误的指标类型")
+		return
+	}
+
+	// 需要添加的指标数据
+	lenAddList := len(addList)
+	if lenAddList > 0 {
+		_, err = to.InsertMulti(lenAddList, addList)
+		if err != nil {
+			return
+		}
+	}
+
+	// 删除不存在的数据
+	lenDeleteIdMap := len(deleteIdMap)
+	if len(deleteIdMap) > 0 {
+		deleteIdList := make([]int, 0)
+		for _, v := range deleteIdMap {
+			deleteIdList = append(deleteIdList, v)
+		}
+		sql = ` DELETE FROM base_from_stock_plant_data WHERE stock_plant_data_id in (` + utils.GetOrmInReplace(lenDeleteIdMap) + `) `
+		_, err = to.Raw(sql, deleteIdList).Exec()
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}

+ 214 - 0
models/supply_analysis/variety.go

@@ -0,0 +1,214 @@
+package supply_analysis
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// Variety variety 品种表
+type Variety struct {
+	VarietyId                 int       `orm:"column(variety_id);pk"`
+	VarietyName               string    `description:"品种名称"`
+	LastUpdateSysUserId       int       `description:"最后更新人id"`
+	LastUpdateSysUserRealName string    `description:"最后更新人名称"`
+	SysUserId                 int       `description:"创建人id"`
+	SysUserRealName           string    `description:"创建人姓名"`
+	ModifyTime                time.Time `description:"修改时间"`
+	CreateTime                time.Time `description:"创建时间"`
+}
+
+// GetVarietyById 根据品种id获取品种详情
+func GetVarietyById(id int) (item *Variety, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM variety WHERE variety_id = ?`
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+// GetVarietyByName 根据品种名称获取品种详情
+func GetVarietyByName(name string) (item *Variety, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM variety WHERE variety_name = ?`
+	err = o.Raw(sql, name).QueryRow(&item)
+	return
+}
+
+// AddVariety 添加品种
+func AddVariety(item *Variety) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// CreateVariety 添加品种
+func CreateVariety(item *Variety, adminIdList []int) (err error) {
+	to, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+	lastId, err := to.Insert(item)
+	if err != nil {
+		return
+	}
+
+	item.VarietyId = int(lastId)
+
+	varietyAdminPermissionList := make([]*VarietyAdminPermission, 0)
+	for _, adminId := range adminIdList {
+		varietyAdminPermissionList = append(varietyAdminPermissionList, &VarietyAdminPermission{
+			//Id:              0,
+			VarietyId:  item.VarietyId,
+			SysUserId:  adminId,
+			CreateTime: time.Now(),
+		})
+	}
+	if len(varietyAdminPermissionList) > 0 {
+		_, err = to.InsertMulti(len(varietyAdminPermissionList), varietyAdminPermissionList)
+	}
+
+	return
+}
+
+// EditVariety 编辑品种
+func EditVariety(item *Variety, adminIdList []int) (err error) {
+	to, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	_, err = to.Update(item, "VarietyName", "LastUpdateSysUserId", "LastUpdateSysUserRealName", "ModifyTime")
+	if err != nil {
+		return
+	}
+
+	// 删除历史的权限配置
+	sql := `DELETE FROM variety_admin_permission where variety_id = ? `
+	_, err = to.Raw(sql, item.VarietyId).Exec()
+	if err != nil {
+		return
+	}
+
+	// 添加新的权限配置
+	varietyAdminPermissionList := make([]*VarietyAdminPermission, 0)
+	for _, adminId := range adminIdList {
+		varietyAdminPermissionList = append(varietyAdminPermissionList, &VarietyAdminPermission{
+			//Id:              0,
+			VarietyId:  item.VarietyId,
+			SysUserId:  adminId,
+			CreateTime: time.Now(),
+		})
+	}
+	if len(varietyAdminPermissionList) > 0 {
+		_, err = to.InsertMulti(len(varietyAdminPermissionList), varietyAdminPermissionList)
+	}
+
+	return
+}
+
+// VarietyItem 列表页返回的数据结构
+type VarietyItem struct {
+	VarietyId                 int           `orm:"column(variety_id);pk"`
+	VarietyName               string        `description:"品种名称"`
+	LastUpdateSysUserId       int           `description:"最后更新人id"`
+	LastUpdateSysUserRealName string        `description:"最后更新人名称"`
+	PermissionUserId          string        `description:"有操作权限的用户id" json:"-"`
+	ModifyTime                string        `description:"修改时间"`
+	CreateTime                string        `description:"创建时间"`
+	Button                    VarietyButton `description:"操作按钮权限"`
+}
+
+type VarietyButton struct {
+	Edit    bool `description:"操作权限"`
+	Delete  bool `description:"删除权限"`
+	Analyse bool `description:"分析权限"`
+}
+
+// GetListBySuperAdminPage 不区分是否有分析权限的获取分页数据
+func (item Variety) GetListBySuperAdminPage(condition string, pars []interface{}, startSize, pageSize int) (total int, items []*VarietyItem, err error) {
+	o := orm.NewOrm()
+	baseSql := ` FROM ( SELECT a.*, GROUP_CONCAT(DISTINCT b.sys_user_id ORDER BY b.sys_user_id ASC SEPARATOR ',') AS permission_user_id FROM variety a 
+				LEFT JOIN variety_admin_permission b on a.variety_id=b.variety_id 
+				LEFT JOIN variety_edb_info c on a.variety_id=c.variety_id WHERE 1=1 `
+	if condition != "" {
+		baseSql += condition
+	}
+	baseSql += ` GROUP BY a.variety_id ) d `
+	// 数据总数
+	totalSql := `SELECT COUNT(1) total ` + baseSql
+	err = o.Raw(totalSql, pars).QueryRow(&total)
+	if err != nil {
+		return
+	}
+
+	// 列表页数据
+	listSql := `SELECT * ` + baseSql + ` ORDER BY modify_time DESC,variety_id DESC LIMIT ?,?`
+	_, err = o.Raw(listSql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// GetListByPage 获取分页数据
+func (item Variety) GetListByPage(condition string, pars []interface{}, startSize, pageSize int) (total int, items []*VarietyItem, err error) {
+	o := orm.NewOrm()
+	baseSql := ` FROM ( SELECT a.*, GROUP_CONCAT(DISTINCT b.sys_user_id ORDER BY b.sys_user_id ASC SEPARATOR ',') AS permission_user_id FROM variety a 
+				JOIN variety_admin_permission b on a.variety_id=b.variety_id 
+				JOIN variety_edb_info c on a.variety_id=c.variety_id WHERE 1=1 `
+	if condition != "" {
+		baseSql += condition
+	}
+	baseSql += ` GROUP BY a.variety_id ) d `
+	// 数据总数
+	totalSql := `SELECT COUNT(1) total ` + baseSql
+	err = o.Raw(totalSql, pars).QueryRow(&total)
+	if err != nil {
+		return
+	}
+
+	// 列表页数据
+	listSql := `SELECT * ` + baseSql + ` ORDER BY modify_time DESC,variety_id DESC LIMIT ?,?`
+	_, err = o.Raw(listSql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// Update 更基础信息
+func (variety *Variety) Update(cols []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(variety, cols...)
+	return
+}
+
+// GetVarietyMaxSort 获取图表分类下最大的排序数
+func GetVarietyMaxSort(parentId int) (sort int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT Max(sort) AS sort FROM future_good_chart_classify WHERE parent_id=? AND is_delete=0 `
+	err = o.Raw(sql, parentId).QueryRow(&sort)
+	return
+}
+
+type VarietyView struct {
+	VarietyId   int    `orm:"column(future_good_chart_classify_id);pk"`
+	VarietyName string `description:"分类名称"`
+	ParentId    int    `description:"父级id"`
+}
+
+func GetVarietyViewById(classifyId int) (item *VarietyView, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM future_good_chart_classify WHERE future_good_chart_classify_id=? AND is_delete=0 `
+	err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}

+ 22 - 0
models/supply_analysis/variety_admin_permission.go

@@ -0,0 +1,22 @@
+package supply_analysis
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// VarietyAdminPermission variety_admin_permission 品种权限表
+type VarietyAdminPermission struct {
+	Id         int       `orm:"column(id);pk"`
+	VarietyId  int       `description:"品种id"`
+	SysUserId  int       `description:"用户id"`
+	CreateTime time.Time `description:"添加时间"`
+}
+
+// GetVarietyPermissionByVarietyIdAndUserId 根据品种id和用户id获取权限记录表
+func GetVarietyPermissionByVarietyIdAndUserId(varietyId, sysUserId int) (item *VarietyAdminPermission, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM variety_admin_permission a  WHERE variety_id = ? AND sys_user_id = ? ORDER BY id desc `
+	err = o.Raw(sql, varietyId, sysUserId).QueryRow(&item)
+	return
+}

+ 91 - 0
models/supply_analysis/variety_edb_info.go

@@ -0,0 +1,91 @@
+package supply_analysis
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// VarietyEdbInfo variety_edb_info 品种指标表
+type VarietyEdbInfo struct {
+	VarietyEdbId int       `orm:"column(variety_edb_id);pk"`
+	VarietyId    int       `description:"品种id"`
+	EdbName      string    `description:"品种指标名称"`
+	Frequency    string    `description:"频度"`
+	StartDate    time.Time `description:"开始日期"`
+	EndDate      time.Time `description:"结束日期"`
+	EdbInfoId    int       `description:"指标id"`
+	EdbCode      string    `description:"品种编码"`
+	Source       int       `description:"来源,1:影响周度产量;2:周度产量变动;3:影响月度产量;4:月度产量变动"`
+	ModifyTime   time.Time `description:"更新时间"`
+	CreateTime   time.Time `description:"添加时间"`
+}
+
+// GetAllVarietyEdbInfoByVarietyId 根据品种id获取所有的指标
+func GetAllVarietyEdbInfoByVarietyId(varietyId int) (items []*VarietyEdbInfo, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM variety_edb_info AS a WHERE a.variety_id = ? ORDER BY a.variety_edb_id ASC `
+	_, err = o.Raw(sql, varietyId).QueryRows(&items)
+	return
+}
+
+// BatchCreateVarietyEdbInfo 批量插入
+func BatchCreateVarietyEdbInfo(list []*VarietyEdbInfo) (err error) {
+	num := len(list)
+	if num <= 0 {
+		return
+	}
+
+	o := orm.NewOrm()
+	_, err = o.InsertMulti(num, list)
+
+	return
+}
+
+// GetCountVarietyEdbByVarietyId 根据品种id获取添加到已经生成的指标数量(不管是否加入到ETA指标库)
+func GetCountVarietyEdbByVarietyId(varietyId int) (total int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT count(1) total FROM variety_edb_info AS a WHERE a.variety_id = ?`
+	err = o.Raw(sql, varietyId).QueryRow(&total)
+	return
+}
+
+// GetCountVarietyEdbInfoByVarietyId 根据品种id获取添加到ETA指标库的指标数量
+func GetCountVarietyEdbInfoByVarietyId(varietyId int) (total int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT count(1) total FROM variety_edb_info AS a
+			JOIN edb_info b on a.edb_info_id=b.edb_info_id
+			WHERE a.variety_id = ? and a.edb_info_id >0`
+	err = o.Raw(sql, varietyId).QueryRow(&total)
+	return
+}
+
+// VarietyEdbInfoItem 品种指标表(展示使用)
+type VarietyEdbInfoItem struct {
+	VarietyEdbId int                  `orm:"column(variety_edb_id);pk"`
+	VarietyId    int                  `description:"品种id"`
+	EdbName      string               `description:"品种指标名称"`
+	Frequency    string               `description:"频度"`
+	StartDate    string               `description:"开始日期"`
+	EndDate      string               `description:"结束日期"`
+	EdbInfoId    int                  `description:"指标id" json:"-"`
+	EdbCode      string               `description:"品种编码"`
+	ClassifyName string               `description:"分类名称"`
+	Source       int                  `description:"来源,1:影响周度产量;2:周度产量变动;3:影响月度产量;4:月度产量变动" json:"-"`
+	ModifyTime   string               `description:"最近一次更新时间"`
+	CreateTime   string               `description:"添加时间"`
+	Button       VarietyEdbInfoButton `description:"操作按钮权限"`
+}
+
+type VarietyEdbInfoButton struct {
+	Copy bool `description:"复制数据权限"`
+	Show bool `description:"查看数据权限"`
+	Add  bool `description:"添加到指标库"`
+}
+
+// GetAllVarietyEdbInfoItemByVarietyId 根据品种id获取所有的指标
+func GetAllVarietyEdbInfoItemByVarietyId(varietyId int) (items []*VarietyEdbInfoItem, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM variety_edb_info AS a WHERE a.variety_id = ? ORDER BY a.variety_edb_id ASC `
+	_, err = o.Raw(sql, varietyId).QueryRows(&items)
+	return
+}

+ 109 - 0
models/supply_analysis/variety_plant.go

@@ -0,0 +1,109 @@
+package supply_analysis
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// VarietyPlant variety_plant 品种装置表
+type VarietyPlant struct {
+	VarietyPlantId                int       `orm:"column(variety_plant_id);pk"`
+	VarietyId                     int       `description:"品种id"`
+	Province                      string    `description:"所属省份"`
+	City                          string    `description:"所属城市"`
+	FactoryName                   string    `description:"工厂名称"`
+	PlantName                     string    `description:"装置/产线名称"`
+	MaintenanceDate               time.Time `description:"检修日期"`
+	ResumptionDate                time.Time `description:"复产日期"`
+	AnnualCapacity                float64   `description:"年产能"`
+	Coefficient                   float64   `description:"降负系数"`
+	AverageDailyCapacityReduction float64   `description:"日均产量减量"`
+	SysUserId                     int       `description:"添加人id"`
+	SysUserRealName               string    `description:"添加人真实姓名"`
+	ModifyTime                    time.Time `description:"最近一次更新时间"`
+	CreateTime                    time.Time `description:"添加时间"`
+}
+
+// GetAllVarietyPlantByVarietyId 根据品种id获取所有的装置
+func GetAllVarietyPlantByVarietyId(varietyId int) (items []*VarietyPlant, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM variety_plant a  WHERE variety_id = ? ORDER BY variety_plant_id desc `
+	_, err = o.Raw(sql, varietyId).QueryRows(&items)
+	return
+}
+
+// AddVarietyPlant 添加future_good_chart分类
+func AddVarietyPlant(item *VarietyPlant) (err error) {
+	o := orm.NewOrm()
+	lastId, err := o.Insert(item)
+	if err != nil {
+		return
+	}
+	item.VarietyPlantId = int(lastId)
+
+	return
+}
+
+// Update 更新基础信息
+func (varietyPlant *VarietyPlant) Update(cols []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(varietyPlant, cols...)
+	return
+}
+
+// GetVarietyPlantById 根据品种装置id获取品种装置详情
+func GetVarietyPlantById(id int) (item *VarietyPlant, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM variety_plant WHERE variety_plant_id = ?`
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+// VarietyPlantItem 品种装置数据(展示使用)
+type VarietyPlantItem struct {
+	VarietyPlantId                int                `orm:"column(variety_plant_id);pk"`
+	VarietyId                     int                `description:"品种id"`
+	Province                      string             `description:"所属省份"`
+	City                          string             `description:"所属城市"`
+	FactoryName                   string             `description:"工厂名称"`
+	PlantName                     string             `description:"装置/产线名称"`
+	MaintenanceDate               string             `description:"检修日期"`
+	ResumptionDate                string             `description:"复产日期"`
+	AnnualCapacity                float64            `description:"年产能"`
+	Coefficient                   float64            `description:"降负系数"`
+	AverageDailyCapacityReduction float64            `description:"日均产量减量"`
+	SysUserId                     int                `description:"添加人id"`
+	SysUserRealName               string             `description:"添加人真实姓名"`
+	ModifyTime                    string             `description:"最近一次更新时间"`
+	CreateTime                    string             `description:"添加时间"`
+	Button                        VarietyPlantButton `description:"操作按钮权限"`
+}
+
+type VarietyPlantButton struct {
+	Edit   bool `description:"操作权限"`
+	Delete bool `description:"删除权限"`
+}
+
+// GetAllVarietyPlantItemByVarietyId 根据品种id获取所有的装置
+func GetAllVarietyPlantItemByVarietyId(varietyId int) (items []*VarietyPlantItem, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM variety_plant a  WHERE variety_id = ? ORDER BY variety_plant_id desc `
+	_, err = o.Raw(sql, varietyId).QueryRows(&items)
+	return
+}
+
+// GetCountVarietyPlantByVarietyId 根据品种id获取所有的装置数量
+func GetCountVarietyPlantByVarietyId(varietyId int) (total int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT count(1) total FROM variety_plant a  WHERE variety_id = ? `
+	err = o.Raw(sql, varietyId).QueryRow(&total)
+	return
+}
+
+// DeleteVarietyPlantById 根据装置id删除
+func DeleteVarietyPlantById(id int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM variety_plant WHERE variety_plant_id = ?`
+	_, err = o.Raw(sql, id).Exec()
+	return
+}

+ 27 - 0
routers/commentsRouter.go

@@ -493,6 +493,33 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_edb_lib/controllers:StockPlantController"] = append(beego.GlobalControllerRouter["hongze/hongze_edb_lib/controllers:StockPlantController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_edb_lib/controllers:StockPlantController"] = append(beego.GlobalControllerRouter["hongze/hongze_edb_lib/controllers:StockPlantController"],
+        beego.ControllerComments{
+            Method: "Calculate",
+            Router: `/calculate`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_edb_lib/controllers:StockPlantController"] = append(beego.GlobalControllerRouter["hongze/hongze_edb_lib/controllers:StockPlantController"],
+        beego.ControllerComments{
+            Method: "Refresh",
+            Router: `/refresh`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_edb_lib/controllers:ThsController"] = append(beego.GlobalControllerRouter["hongze/hongze_edb_lib/controllers:ThsController"],
         beego.ControllerComments{
             Method: "Add",

+ 5 - 0
routers/router.go

@@ -150,6 +150,11 @@ func init() {
 				&controllers.BaiinfoController{},
 			),
 		),
+		beego.NSNamespace("/stock_plant",
+			beego.NSInclude(
+				&controllers.StockPlantController{},
+			),
+		),
 	)
 	beego.AddNamespace(ns)
 }

+ 55 - 54
utils/constants.go

@@ -29,56 +29,56 @@ const (
 
 // 数据来源渠道
 const (
-	DATA_SOURCE_THS                         = iota + 1 //同花顺
-	DATA_SOURCE_WIND                                   //wind
-	DATA_SOURCE_PB                                     //彭博
-	DATA_SOURCE_CALCULATE                              //指标运算
-	DATA_SOURCE_CALCULATE_LJZZY                        //累计值转月
-	DATA_SOURCE_CALCULATE_TBZ                          //同比值
-	DATA_SOURCE_CALCULATE_TCZ                          //同差值
-	DATA_SOURCE_CALCULATE_NSZYDPJJS                    //N数值移动平均计算
-	DATA_SOURCE_MANUAL                                 //手工指标
-	DATA_SOURCE_LZ                                     //隆众
-	DATA_SOURCE_YS                                     //有色
-	DATA_SOURCE_CALCULATE_HBZ                          //环比值->12
-	DATA_SOURCE_CALCULATE_HCZ                          //环差值->13
-	DATA_SOURCE_CALCULATE_BP                           //变频->14
-	DATA_SOURCE_GL                                     //钢联->15
-	DATA_SOURCE_ZZ                                     //郑商所->16
-	DATA_SOURCE_DL                                     //大商所->17
-	DATA_SOURCE_SH                                     //上期所->18
-	DATA_SOURCE_CFFEX                                  //中金所->19
-	DATA_SOURCE_SHFE                                   //上期能源->20
-	DATA_SOURCE_GIE                                    //欧洲天然气->21
-	DATA_SOURCE_CALCULATE_TIME_SHIFT                   //时间移位->22
-	DATA_SOURCE_CALCULATE_ZJPJ                         //直接拼接->23
-	DATA_SOURCE_CALCULATE_LJZTBPJ                      //累计值同比拼接->24
-	DATA_SOURCE_LT                                     //路透->25
-	DATA_SOURCE_COAL                                   //煤炭网->26
-	DATA_SOURCE_PYTHON                                 //python代码->27
-	DATA_SOURCE_PB_FINANCE                             //彭博财务数据->28
-	DATA_SOURCE_GOOGLE_TRAVEL                          //谷歌出行数据->29
-	DATA_SOURCE_PREDICT                                //普通预测指标->30
-	DATA_SOURCE_PREDICT_CALCULATE                      //预测指标运算->31
-	DATA_SOURCE_PREDICT_CALCULATE_TBZ                  //预测指标 - 同比值->32
-	DATA_SOURCE_PREDICT_CALCULATE_TCZ                  //预测指标 - 同差值->33
-	DATA_SOURCE_MYSTEEL_CHEMICAL                       //钢联化工->34
-	DATA_SOURCE_CALCULATE_CJJX                         //超季节性->35
-	DATA_SOURCE_EIA_STEO                               //eia steo报告->36
-	DATA_SOURCE_CALCULATE_NHCC                         //计算指标(拟合残差)->37
-	DATA_SOURCE_COM_TRADE                              //联合国商品贸易数据->38
-	DATA_SOURCE_PREDICT_CALCULATE_NSZYDPJJS            //预测指标 - N数值移动平均计算 -> 39
-	DATA_SOURCE_CALCULATE_ADJUST                       //数据调整->40
-	DATA_SOURCE_SCI                                    //卓创数据(红桃三)->41
-	DATA_SOURCE_PREDICT_CALCULATE_LJZZY                //预测指标 - 累计值转月->42
-	DATA_SOURCE_PREDICT_CALCULATE_HBZ                  //预测指标 - 环比值->43
-	DATA_SOURCE_PREDICT_CALCULATE_HCZ                  //预测指标 - 环差值->44
-	DATA_SOURCE_PREDICT_CALCULATE_BP                   //预测指标 - 变频->45
-	DATA_SOURCE_PREDICT_CALCULATE_TIME_SHIFT           //预测指标 - 时间移位->46
-	DATA_SOURCE_PREDICT_CALCULATE_ZJPJ                 //预测指标 - 直接拼接->47
-	DATA_SOURCE_PREDICT_CALCULATE_LJZTBPJ              //预测指标 - 累计值同比拼接->48
-	DATA_SOURCE_PREDICT_CALCULATE_CJJX                 //预测指标 - 超季节性->49
-	DATA_SOURCE_PREDICT_CALCULATE_NHCC                 //预测指标 - 计算指标(拟合残差)->50
+	DATA_SOURCE_THS                          = iota + 1 //同花顺
+	DATA_SOURCE_WIND                                    //wind
+	DATA_SOURCE_PB                                      //彭博
+	DATA_SOURCE_CALCULATE                               //指标运算
+	DATA_SOURCE_CALCULATE_LJZZY                         //累计值转月
+	DATA_SOURCE_CALCULATE_TBZ                           //同比值
+	DATA_SOURCE_CALCULATE_TCZ                           //同差值
+	DATA_SOURCE_CALCULATE_NSZYDPJJS                     //N数值移动平均计算
+	DATA_SOURCE_MANUAL                                  //手工指标
+	DATA_SOURCE_LZ                                      //隆众
+	DATA_SOURCE_YS                                      //有色
+	DATA_SOURCE_CALCULATE_HBZ                           //环比值->12
+	DATA_SOURCE_CALCULATE_HCZ                           //环差值->13
+	DATA_SOURCE_CALCULATE_BP                            //变频->14
+	DATA_SOURCE_GL                                      //钢联->15
+	DATA_SOURCE_ZZ                                      //郑商所->16
+	DATA_SOURCE_DL                                      //大商所->17
+	DATA_SOURCE_SH                                      //上期所->18
+	DATA_SOURCE_CFFEX                                   //中金所->19
+	DATA_SOURCE_SHFE                                    //上期能源->20
+	DATA_SOURCE_GIE                                     //欧洲天然气->21
+	DATA_SOURCE_CALCULATE_TIME_SHIFT                    //时间移位->22
+	DATA_SOURCE_CALCULATE_ZJPJ                          //直接拼接->23
+	DATA_SOURCE_CALCULATE_LJZTBPJ                       //累计值同比拼接->24
+	DATA_SOURCE_LT                                      //路透->25
+	DATA_SOURCE_COAL                                    //煤炭网->26
+	DATA_SOURCE_PYTHON                                  //python代码->27
+	DATA_SOURCE_PB_FINANCE                              //彭博财务数据->28
+	DATA_SOURCE_GOOGLE_TRAVEL                           //谷歌出行数据->29
+	DATA_SOURCE_PREDICT                                 //普通预测指标->30
+	DATA_SOURCE_PREDICT_CALCULATE                       //预测指标运算->31
+	DATA_SOURCE_PREDICT_CALCULATE_TBZ                   //预测指标 - 同比值->32
+	DATA_SOURCE_PREDICT_CALCULATE_TCZ                   //预测指标 - 同差值->33
+	DATA_SOURCE_MYSTEEL_CHEMICAL                        //钢联化工->34
+	DATA_SOURCE_CALCULATE_CJJX                          //超季节性->35
+	DATA_SOURCE_EIA_STEO                                //eia steo报告->36
+	DATA_SOURCE_CALCULATE_NHCC                          //计算指标(拟合残差)->37
+	DATA_SOURCE_COM_TRADE                               //联合国商品贸易数据->38
+	DATA_SOURCE_PREDICT_CALCULATE_NSZYDPJJS             //预测指标 - N数值移动平均计算 -> 39
+	DATA_SOURCE_CALCULATE_ADJUST                        //数据调整->40
+	DATA_SOURCE_SCI                                     //卓创数据(红桃三)->41
+	DATA_SOURCE_PREDICT_CALCULATE_LJZZY                 //预测指标 - 累计值转月->42
+	DATA_SOURCE_PREDICT_CALCULATE_HBZ                   //预测指标 - 环比值->43
+	DATA_SOURCE_PREDICT_CALCULATE_HCZ                   //预测指标 - 环差值->44
+	DATA_SOURCE_PREDICT_CALCULATE_BP                    //预测指标 - 变频->45
+	DATA_SOURCE_PREDICT_CALCULATE_TIME_SHIFT            //预测指标 - 时间移位->46
+	DATA_SOURCE_PREDICT_CALCULATE_ZJPJ                  //预测指标 - 直接拼接->47
+	DATA_SOURCE_PREDICT_CALCULATE_LJZTBPJ               //预测指标 - 累计值同比拼接->48
+	DATA_SOURCE_PREDICT_CALCULATE_CJJX                  //预测指标 - 超季节性->49
+	DATA_SOURCE_PREDICT_CALCULATE_NHCC                  //预测指标 - 计算指标(拟合残差)->50
 	DATA_SOURCE_CALCULATE_JP                            //降频->51
 	DATA_SOURCE_CALCULATE_NH                            //年化->52
 	DATA_SOURCE_CALCULATE_KSZS                          //扩散指数->53
@@ -186,8 +186,9 @@ const (
 )
 
 const (
-	CACHE_EDB_DATA_ADD     = "CACHE_EDB_DATA_ADD_"
-	CACHE_EDB_DATA_REFRESH = "CACHE_EDB_DATA_REFRESH_"
-	CACHE_WIND_URL         = "CACHE_WIND_URL"
-	CACHE_CHART_INFO_DATA  = "chart:info:data:" //图表数据
+	CACHE_EDB_DATA_ADD          = "CACHE_EDB_DATA_ADD_"
+	CACHE_EDB_DATA_REFRESH      = "CACHE_EDB_DATA_REFRESH_"
+	CACHE_WIND_URL              = "CACHE_WIND_URL"
+	CACHE_CHART_INFO_DATA       = "chart:info:data:"             //图表数据
+	CACHE_STOCK_PLANT_CALCULATE = "CACHE_STOCK_PLANT_CALCULATE_" // 库存装置减产计算
 )