|
@@ -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
|
|
|
|
+}
|