瀏覽代碼

Merge branch 'master' into feature/change_log

xyxie 1 年之前
父節點
當前提交
44fba7c11b

+ 52 - 2
controllers/base_from_calculate.go

@@ -806,6 +806,21 @@ func (this *CalculateController) BatchSave() {
 		}
 		sourName = utils.DATA_SOURCE_NAME_CALCULATE_CORRELATION
 		edbInfo, err, errMsg = models.AddCalculateCorrelation(&req, edbCode, uniqueCode, sysUserId, sysUserName)
+	case utils.DATA_SOURCE_CALCULATE_RJZ:
+		if req.Frequency == "日度" {
+			br.Msg = "日度指标无需进行日均值计算"
+			return
+		}
+		if req.Frequency != fromEdbInfo.Frequency {
+			br.Msg = "当前频度和原指标频度不一致"
+			return
+		}
+		if req.Unit != fromEdbInfo.Unit {
+			br.Msg = "单位只允许为和原指标频度保持一致,禁止选择其他单位"
+			return
+		}
+		sourName = "日均值"
+		edbInfo, err = models.AddCalculateRjz(&req, fromEdbInfo, edbCode, uniqueCode, sysUserId, sysUserName)
 	default:
 		// 获取通用的数据源处理服务
 		baseEdbInfoModel = models.GetBaseEdbInfoModel(req.Source)
@@ -1223,6 +1238,21 @@ func (this *CalculateController) BatchEdit() {
 		}
 		sourName = utils.DATA_SOURCE_NAME_CALCULATE_CORRELATION
 		err, errMsg = models.EditCalculateCorrelation(edbInfo, &req)
+	case utils.DATA_SOURCE_CALCULATE_RJZ:
+		if req.Frequency == "日度" {
+			br.Msg = "日度指标无需进行日均值计算"
+			return
+		}
+		if req.Frequency != fromEdbInfo.Frequency {
+			br.Msg = "当前频度和原指标频度不一致"
+			return
+		}
+		if req.Unit != fromEdbInfo.Unit {
+			br.Msg = "单位只允许为和原指标频度保持一致,禁止选择其他单位"
+			return
+		}
+		sourName = "日均值"
+		err = models.EditCalculateRjz(edbInfo, &req, fromEdbInfo)
 	default:
 		// 获取通用的数据源处理服务
 		baseEdbInfoModel = models.GetBaseEdbInfoModel(req.Source)
@@ -1664,6 +1694,24 @@ func (this *CalculateController) Refresh() {
 		}
 	case utils.DATA_SOURCE_CALCULATE_CORRELATION:
 		err, errMsg = models.RefreshAllCalculateCorrelation(edbInfo)
+	case utils.DATA_SOURCE_CALCULATE_RJZ: //刷新日均值
+		calculateRjz, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
+		if err != nil {
+			errMsg = "GetEdbInfoCalculateMappingDetail Err:" + err.Error()
+			break
+		}
+		fromEdbInfo, err := models.GetEdbInfoById(calculateRjz.FromEdbInfoId)
+		if err != nil {
+			errMsg = "GetEdbInfoById Err:" + err.Error()
+			break
+		}
+		//startDate = edbInfo.StartDate
+		endDate = time.Now().Format(utils.FormatDate)
+		err = models.RefreshAllCalculateRjz(edbInfoId, source, fromEdbInfo, calculateRjz.EdbCode, startDate, endDate)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			errMsg = "RefreshAllCalculateRjz Err:" + err.Error()
+			break
+		}
 	default:
 		// 获取通用的数据源处理服务
 		baseEdbInfoModel = models.GetBaseEdbInfoModel(source)
@@ -1904,7 +1952,7 @@ func (this *CalculateController) CalculateComputeCorrelation() {
 		br.ErrMsg = "两个指标不允许为同一个"
 		return
 	}
-	rVal, err, errMsg := models.CalculateComputeCorrelation(&req, fromEdbInfo, secondEdbInfo, nhccDate)
+	aVal, bVal, rVal, err, errMsg := models.CalculateComputeCorrelation(&req, fromEdbInfo, secondEdbInfo, nhccDate)
 	if err != nil {
 		br.Msg = "计算失败"
 		if errMsg != `` {
@@ -1914,9 +1962,11 @@ func (this *CalculateController) CalculateComputeCorrelation() {
 		return
 	}
 
+	valStr := fmt.Sprintf("y = %sx + %s   R²=%f", utils.SubFloatToString(aVal, 4), utils.SubFloatToString(bVal, 4), rVal)
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "计算成功"
-	br.Data = rVal
+	br.Data = valStr
 	br.IsAddLog = true
 }

+ 1 - 0
controllers/base_from_mysteel_chemical.go

@@ -609,6 +609,7 @@ func (this *MySteelChemicalController) AddMysteelIndex() {
 	}
 	if isAdd {
 		mysteelIndexObj.IndexCode = req.EdbCode
+		mysteelIndexObj.TerminalCode = req.TerminalCode
 		mysteelIndexObj.BaseFromMysteelChemicalClassifyId = req.BaseFromMysteelChemicalClassifyId
 		mysteelIndexObj.SysUserId = req.SysUserId
 		mysteelIndexObj.SysUserRealName = req.SysUserRealName

+ 88 - 1
controllers/base_from_smm.go

@@ -153,9 +153,96 @@ func (this *SmmController) HandleExcelData() {
 	}
 
 	// 处理excel表数据
-	services.SmmIndexHandle(req.BaseFilePath, req.RenameFilePath, req.IndexName, req.IndexCode, req.Unit, req.Frequency, req.ExcelDataMap)
+	services.SmmIndexHandle(req.BaseFilePath, req.RenameFilePath, req.IndexName, req.IndexCode, req.Unit, req.Frequency, req.Source, req.ExcelDataMap)
 
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "处理成功"
 }
+
+// AddIndexToDataSource
+// @Title 添加指标到数据源-SMM
+// @Description 添加指标到数据源-SMM
+// @Success 200 {object} models.AddSmmIndexToDataSourceResp
+// @router /add/index/to_data_source [post]
+func (this *SmmController) AddIndexToDataSource() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.AddSmmIndexToDataSourceResp
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	smmIndexObj := new(models.BaseFromSmmIndex)
+	indexItem, err := smmIndexObj.GetSmmIndexItem(req.EdbCode)
+	var isAdd bool
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			isAdd = true
+		} else {
+			br.Msg = "判断指标是否存在失败"
+			br.ErrMsg = "判断指标是否存在失败,Err:" + err.Error()
+			return
+		}
+	}
+	if indexItem == nil {
+		isAdd = true
+	}
+	if isAdd {
+		smmIndexObj.IndexCode = req.EdbCode
+		smmIndexObj.ClassifyId = req.ClassifyId
+		smmIndexObj.CreateTime = time.Now()
+		smmIndexObj.ModifyTime = time.Now()
+		err = smmIndexObj.Add()
+		if err != nil {
+			br.Msg = "新增指标失败"
+			br.ErrMsg = "新增指标失败,Err:" + err.Error()
+			return
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "新增成功"
+}
+
+// GetIndexDetailByCode
+// @Title 获取指标详情
+// @Description 获取指标详情
+// @Success 200 {object} models.GetIndexDetailReq
+// @router /index_detail/from_data_source [post]
+func (this *SmmController) GetIndexDetailFromDataSourceByCode() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.GetIndexDetailReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.IndexCode == "" {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数有误"
+		return
+	}
+
+	indexObj := new(models.BaseFromSmmIndex)
+	item, err := indexObj.GetIndexItem(req.IndexCode)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取指标失败, Err: " + err.Error()
+		return
+	}
+	br.Data = item
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 64 - 0
controllers/base_from_smm_classify.go

@@ -0,0 +1,64 @@
+package controllers
+
+import (
+	"encoding/json"
+	"eta/eta_index_lib/models"
+	"eta/eta_index_lib/utils"
+	"strconv"
+)
+
+// @Title 查询/新增分类
+// @Description 查询/新增分类接口
+// @Param	request	body models.AddSmmClassifyReq true "type json string"
+// @Success 200 {object} models.EdbClassify
+// @router /smm_classify/get_or_add [post]
+func (this *SmmController) SmmGetOrAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.AddSmmClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "请输入分类名称"
+		br.IsSendEmail = false
+		return
+	}
+	if req.ParentId < 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	sysUserId := utils.InitAdminId
+	sysUserName := utils.InitAdminName
+	if req.SysUserId > 0 {
+		sysUserId = strconv.Itoa(req.SysUserId)
+	}
+	if req.SysUserRealName != `` {
+		sysUserName = req.SysUserRealName
+	}
+
+	//添加指标
+	edbClassify, err, errMsg := models.SaveSmmClassify(req.ClassifyName, req.ParentId, req.Level, sysUserId, sysUserName)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = errMsg + ";Err:" + err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	br.Ret = 200
+	br.Msg = "保存成功"
+	br.Success = true
+	br.Data = edbClassify
+}

+ 23 - 20
controllers/base_from_wind.go

@@ -2,6 +2,7 @@ package controllers
 
 import (
 	"encoding/json"
+	"errors"
 	"eta/eta_index_lib/logic"
 	"eta/eta_index_lib/models"
 	"eta/eta_index_lib/services"
@@ -68,23 +69,12 @@ func (this *WindController) Add() {
 		}
 
 		if windUrl == `` {
-			// 先配置中获取,如果有指定配置的话,那么取配置中的数据
-			tmpConfig, err := models.GetConfigDetailByCode("wind_data_url")
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				br.Msg = "获取配置的wind地址失败!"
-				br.ErrMsg = "获取配置的wind地址失败,err:" + err.Error()
+			windUrl, err = GetServerUrl()
+			if err != nil {
+				br.Msg = "获取可以使用的wind地址失败!"
+				br.ErrMsg = "获取可以使用的wind地址失败,err:" + err.Error()
 				return
 			}
-			if tmpConfig != nil {
-				windUrl = tmpConfig.ConfigValue
-			} else {
-				windUrl, err = GetServerUrl(req.EdbCode)
-				if err != nil {
-					br.Msg = "获取使用的wind地址失败!"
-					br.ErrMsg = "获取使用的wind地址失败,err:" + err.Error()
-					return
-				}
-			}
 		}
 
 		if windUrl == `` {
@@ -93,6 +83,10 @@ func (this *WindController) Add() {
 			return
 		}
 
+		// 设置指标与终端关系的缓存
+		windUrlCacheKey := utils.CACHE_WIND_URL + ":" + req.EdbCode
+		_ = utils.Rc.SetNX(windUrlCacheKey, windUrl, utils.GetTodayLastSecond())
+
 		//windUrl = utils.Hz_Wind_Data_Url_LIST[1].Url
 		dataItem, errCode, err := services.GetEdbDataFromWindUrl(windUrl, req.EdbCode, utils.BASE_START_DATE, endDate)
 		//dataItem, errCode, err := services.GetEdbDataFromWind(req.EdbCode, utils.BASE_START_DATE, endDate)
@@ -232,7 +226,20 @@ func (this *WindController) Refresh() {
 }
 
 // GetServerUrl 获取服务器地址
-func GetServerUrl(edbCode string) (windUrl string, err error) {
+func GetServerUrl() (windUrl string, err error) {
+	// 先配置中获取,如果有指定配置的话,那么取配置中的数据
+	tmpConfig, err := models.GetConfigDetailByCode("wind_data_url")
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		err = errors.New("获取配置的wind地址失败,err:" + err.Error())
+		return
+	}
+	err = nil
+	if tmpConfig != nil {
+		windUrl = tmpConfig.ConfigValue
+		return
+	}
+
+	// 配置中没有的话,那么就从分组获取
 	list, err := models.GetServerUrlCountGroupByServerUrl()
 	if err != nil {
 		return
@@ -254,9 +261,5 @@ func GetServerUrl(edbCode string) (windUrl string, err error) {
 		}
 	}
 
-	//windUrl = `http://datawind.hzinsights.com:8040/`
-	// 设置缓存
-	cacheKey := utils.CACHE_WIND_URL + ":" + edbCode
-	_ = utils.Rc.SetNX(cacheKey, windUrl, utils.GetTodayLastSecond())
 	return
 }

+ 1 - 1
controllers/edb_info.go

@@ -97,7 +97,7 @@ func (this *EdbInfoController) Add() {
 	var windUrl string
 	if isAdd {
 		if req.Source == utils.DATA_SOURCE_WIND {
-			windUrl, err = GetServerUrl(req.EdbCode)
+			windUrl, err = GetServerUrl()
 			if err != nil {
 				br.Msg = "判断失败!"
 				br.ErrMsg = "判断失败,Err:" + err.Error()

+ 395 - 0
controllers/exchange_crawler.go

@@ -0,0 +1,395 @@
+package controllers
+
+import (
+	"encoding/json"
+	"eta/eta_index_lib/models"
+	"fmt"
+	"github.com/mozillazg/go-pinyin"
+	"strings"
+	"time"
+)
+
+// 交易所爬虫
+type ExchangeCrawler struct {
+	BaseAuthController
+}
+
+var ineIndexCodeMap = make(map[string]string)
+
+// @Title 刷新数据
+// @Description 刷新数据接口
+// @Param	request	body models.AddEdbClassifyReq true "type json string"
+// @Success 200 {object} models.EdbClassify
+// @router /refresh/ine [post]
+func (this *ExchangeCrawler) RefreshIne() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.RefreshINEExchangeReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	allCode, err := models.GetIndexCodeFromMapping("Ine")
+	if err != nil {
+		fmt.Println("select Code err:", err)
+	}
+	for _, item := range allCode {
+		ineIndexCodeMap[item.IndexName] = item.IndexCode
+	}
+	message := req.Data
+	var position = message.OCursor
+	var tradeDate = message.ReportDate
+	existIndexMap := make(map[string]*models.BaseFromTradeIneIndex)
+
+	//获取所有指标信息
+	allIndex, err := models.GetBaseFromTradeIneIndexAll(req.Date)
+	if err != nil {
+		fmt.Println("select err:", err)
+	}
+	for _, v := range allIndex {
+		indexKey := v.DealName + v.BuyName + v.SoldName
+		existIndexMap[indexKey] = v
+	}
+	var itemVerifyCode int
+	//处理指标
+	for _, p := range position {
+		var item = new(models.BaseFromTradeIneIndex)
+		if p.Rank > 0 && p.Rank < 40 && p.Participantabbr1 != "" {
+			//成交量
+			item.Rank = p.Rank
+			item.DealShortName = p.Participantabbr1
+			item.BuyShortName = p.Participantabbr2
+			item.SoldShortName = p.Participantabbr3
+			item.DealName = strings.Replace(fmt.Sprintf("%s", p.Participantabbr1+"_"+p.Instrumentid+"_成交量(手)"), " ", "", -1)
+			item.BuyName = strings.Replace(fmt.Sprintf("%s", p.Participantabbr2+"_"+p.Instrumentid+"_持买单量(手)"), " ", "", -1)
+			item.SoldName = strings.Replace(fmt.Sprintf("%s", p.Participantabbr3+"_"+p.Instrumentid+"_持卖单量(手)"), " ", "", -1)
+			item.DealCode = IneIndexCodeGenerator(item.DealShortName, item.DealName, p.Instrumentid, "deal")
+			item.BuyCode = IneIndexCodeGenerator(item.BuyShortName, item.BuyName, p.Instrumentid, "buy")
+			item.SoldCode = IneIndexCodeGenerator(item.SoldShortName, item.SoldName, p.Instrumentid, "sold")
+			item.ClassifyName = strings.Replace(p.Productname, " ", "", -1)
+			item.ClassifyType = strings.Replace(p.Instrumentid, " ", "", -1)
+			item.Frequency = "日度"
+			item.CreateTime = time.Now()
+			item.ModifyTime = time.Now()
+			item.DataTime = tradeDate
+
+			if deal, ok := p.Deal.(float64); ok {
+				item.DealValue = int(deal)
+			}
+			if change1, ok := p.Change1.(float64); ok {
+				item.DealChange = int(change1)
+			}
+			if buyIn, ok := p.BuyIn.(float64); ok {
+				item.BuyValue = int(buyIn)
+			}
+			if change2, ok := p.Change2.(float64); ok {
+				item.BuyChange = int(change2)
+			}
+			if soldOut, ok := p.SoldOut.(float64); ok {
+				item.SoldValue = int(soldOut)
+			}
+			if change3, ok := p.Change3.(float64); ok {
+				item.SoldChange = int(change3)
+			}
+
+			itemVerifyCode = item.BuyValue + item.DealValue + item.SoldValue
+			if existIndex, ok := existIndexMap[item.DealName+item.BuyName+item.SoldName]; !ok {
+				newID, err := models.AddBaseFromTradeIneIndex(item)
+				if err != nil {
+					fmt.Println("insert error:", err)
+				}
+				fmt.Println("insert new indexID:", newID)
+			} else if existIndex != nil && itemVerifyCode != (existIndex.DealValue+existIndex.BuyValue+existIndex.SoldValue) {
+				//更新
+				err := models.ModifyBaseFromTradeIneIndex(item.DealValue, item.BuyValue, item.SoldValue, existIndex.BaseFromTradeIneIndexId)
+				if err != nil {
+					fmt.Println("data update err:", err)
+				}
+			}
+		} else if p.Rank == 999 {
+			//Top 20
+			item.Rank = p.Rank
+			item.DealShortName = p.Participantabbr1
+			item.BuyShortName = p.Participantabbr2
+			item.SoldShortName = p.Participantabbr3
+			item.DealName = strings.Replace(fmt.Sprintf("%s", "top20_"+p.Instrumentid+"_成交量(手)"), " ", "", -1)
+			item.BuyName = strings.Replace(fmt.Sprintf("%s", "top20_"+p.Instrumentid+"_持买单量(手)"), " ", "", -1)
+			item.SoldName = strings.Replace(fmt.Sprintf("%s", "top20_"+p.Instrumentid+"_持卖单量(手)"), " ", "", -1)
+			item.DealCode = IneIndexCodeGenerator("top20", item.DealName, p.Instrumentid, "deal")
+			item.BuyCode = IneIndexCodeGenerator("top20", item.BuyName, p.Instrumentid, "buy")
+			item.SoldCode = IneIndexCodeGenerator("top20", item.SoldName, p.Instrumentid, "sold")
+			item.ClassifyName = strings.Replace(p.Productname, " ", "", -1)
+			item.ClassifyType = strings.Replace(p.Instrumentid, " ", "", -1)
+			item.Frequency = "日度"
+			item.CreateTime = time.Now()
+			item.ModifyTime = time.Now()
+			item.DataTime = tradeDate
+
+			if deal, ok := p.Deal.(float64); ok {
+				item.DealValue = int(deal)
+			}
+			if change1, ok := p.Change1.(float64); ok {
+				item.DealChange = int(change1)
+			}
+			if buyIn, ok := p.BuyIn.(float64); ok {
+				item.BuyValue = int(buyIn)
+			}
+			if change2, ok := p.Change2.(float64); ok {
+				item.BuyChange = int(change2)
+			}
+			if soldOut, ok := p.SoldOut.(float64); ok {
+				item.SoldValue = int(soldOut)
+			}
+			if change3, ok := p.Change3.(float64); ok {
+				item.SoldChange = int(change3)
+			}
+
+			itemVerifyCode = item.BuyValue + item.DealValue + item.SoldValue
+			if existIndex, ok := existIndexMap[item.DealName+item.BuyName+item.SoldName]; !ok {
+				newID, err := models.AddBaseFromTradeIneIndex(item)
+				if err != nil {
+					fmt.Println("insert error:", err)
+				}
+				fmt.Println("insert new indexID:", newID)
+			} else if existIndex != nil && itemVerifyCode != (existIndex.DealValue+existIndex.BuyValue+existIndex.SoldValue) {
+				//更新
+				err := models.ModifyBaseFromTradeIneIndex(item.DealValue, item.BuyValue, item.SoldValue, existIndex.BaseFromTradeIneIndexId)
+				if err != nil {
+					fmt.Println("data update err:", err)
+				}
+			}
+		}
+	}
+
+	br.Ret = 200
+	br.Msg = "获取成功"
+	br.Success = true
+}
+
+var indexCodeMap = make(map[string]string)
+
+// @Title 刷新数据
+// @Description 刷新数据接口
+// @Param	request	body models.AddEdbClassifyReq true "type json string"
+// @Success 200 {object} models.EdbClassify
+// @router /refresh/sh [post]
+func (this *ExchangeCrawler) RefreshSH() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.RefreshSHExchangeReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	allCode, err := models.GetIndexCodeFromMapping("SH")
+	if err != nil {
+		fmt.Println("select Code err:", err)
+		return
+	}
+	for _, item := range allCode {
+		indexCodeMap[item.IndexName] = item.IndexCode
+	}
+
+	message := req.Data
+	var position = message.Position
+	var tradeDate = message.ReportDate
+	existIndexMap := make(map[string]*models.BaseFromTradeShanghaiIndex)
+
+	//获取所有指标信息
+	allIndex, err := models.GetBaseFromTradeShangHaiIndexAll(req.Date)
+	if err != nil {
+		fmt.Println("select err:", err)
+	}
+	for _, v := range allIndex {
+		indexKey := v.DealName + v.BuyName + v.SoldName
+		existIndexMap[indexKey] = v
+	}
+	var itemVerifyCode int
+	//处理指标
+	for _, p := range position {
+		var item = new(models.BaseFromTradeShanghaiIndex)
+		if p.Rank > 0 && p.Rank < 40 && p.ParticipantName1 != "" {
+			if strings.Replace(p.ProductName, " ", "", -1) != "20号胶" && strings.Replace(p.ProductName, " ", "", -1) != "低硫燃料油" {
+				contractCode := strings.Replace(p.ContractCode, " ", "", -1)
+				//成交量
+				item.Rank = p.Rank
+				item.DealShortName = strings.Replace(p.ParticipantName1, " ", "", -1)
+				item.BuyShortName = strings.Replace(p.ParticipantName2, " ", "", -1)
+				item.SoldShortName = strings.Replace(p.ParticipantName3, " ", "", -1)
+				item.DealName = strings.Replace(fmt.Sprintf("%s", p.ParticipantName1+"_"+p.ContractCode+"_成交量(手)"), " ", "", -1)
+				item.BuyName = strings.Replace(fmt.Sprintf("%s", p.ParticipantName2+"_"+p.ContractCode+"_持买单量(手)"), " ", "", -1)
+				item.SoldName = strings.Replace(fmt.Sprintf("%s", p.ParticipantName3+"_"+p.ContractCode+"_持卖单量(手)"), " ", "", -1)
+				item.DealCode = ShIndexCodeGenerator(item.DealShortName, item.DealName, contractCode, "deal")
+				item.BuyCode = ShIndexCodeGenerator(item.BuyShortName, item.BuyName, contractCode, "buy")
+				item.SoldCode = ShIndexCodeGenerator(item.SoldShortName, item.SoldName, contractCode, "sold")
+				item.ClassifyName = strings.Replace(p.ProductName, " ", "", -1)
+				item.ClassifyType = strings.Replace(p.ContractCode, " ", "", -1)
+				item.Frequency = "日度"
+				item.CreateTime = time.Now()
+				item.ModifyTime = time.Now()
+				item.DataTime = tradeDate
+
+				if deal, ok := p.Deal.(float64); ok {
+					item.DealValue = int(deal)
+				}
+				if change1, ok := p.Change1.(float64); ok {
+					item.DealChange = int(change1)
+				}
+				if buyIn, ok := p.BuyIn.(float64); ok {
+					item.BuyValue = int(buyIn)
+				}
+				if change2, ok := p.Change2.(float64); ok {
+					item.BuyChange = int(change2)
+				}
+				if soldOut, ok := p.SoldOut.(float64); ok {
+					item.SoldValue = int(soldOut)
+				}
+				if change3, ok := p.Change3.(float64); ok {
+					item.SoldChange = int(change3)
+				}
+
+				itemVerifyCode = item.BuyValue + item.DealValue + item.SoldValue
+				if existIndex, ok := existIndexMap[item.DealName+item.BuyName+item.SoldName]; !ok {
+					newID, e := models.AddBaseFromTradeShangHaiIndex(item)
+					if e != nil {
+						err = e
+						fmt.Println("insert error:", err)
+					}
+					fmt.Println("insert new indexID:", newID)
+				} else if existIndex != nil && itemVerifyCode != (existIndex.DealValue+existIndex.BuyValue+existIndex.SoldValue) {
+					//更新
+					err = models.ModifyBaseFromTradeShangHaiIndex(item.DealValue, item.BuyValue, item.SoldValue, existIndex.BaseFromTradeShangHaiIndexId)
+					if err != nil {
+						fmt.Println("data update err:", err)
+					}
+				}
+			}
+		} else if p.Rank == 999 {
+			if strings.Replace(p.ProductName, " ", "", -1) != "20号胶" && strings.Replace(p.ProductName, " ", "", -1) != "低硫燃料油" {
+				contractCode := strings.Replace(p.ContractCode, " ", "", -1)
+				//Top 20
+				item.Rank = p.Rank
+				item.DealShortName = strings.Replace(p.ParticipantName1, " ", "", -1)
+				item.BuyShortName = strings.Replace(p.ParticipantName2, " ", "", -1)
+				item.SoldShortName = strings.Replace(p.ParticipantName3, " ", "", -1)
+				item.DealName = strings.Replace(fmt.Sprintf("%s", "top20_"+p.ContractCode+"_成交量(手)"), " ", "", -1)
+				item.BuyName = strings.Replace(fmt.Sprintf("%s", "top20_"+p.ContractCode+"_持买单量(手)"), " ", "", -1)
+				item.SoldName = strings.Replace(fmt.Sprintf("%s", "top20_"+p.ContractCode+"_持卖单量(手)"), " ", "", -1)
+				item.DealCode = ShIndexCodeGenerator("top20", item.DealName, contractCode, "deal")
+				item.BuyCode = ShIndexCodeGenerator("top20", item.BuyName, contractCode, "buy")
+				item.SoldCode = ShIndexCodeGenerator("top20", item.SoldName, contractCode, "sold")
+				item.ClassifyName = strings.Replace(p.ProductName, " ", "", -1)
+				item.ClassifyType = strings.Replace(p.ContractCode, " ", "", -1)
+				item.Frequency = "日度"
+				item.CreateTime = time.Now()
+				item.ModifyTime = time.Now()
+				item.DataTime = tradeDate
+
+				if deal, ok := p.Deal.(float64); ok {
+					item.DealValue = int(deal)
+				}
+				if change1, ok := p.Change1.(float64); ok {
+					item.DealChange = int(change1)
+				}
+				if buyIn, ok := p.BuyIn.(float64); ok {
+					item.BuyValue = int(buyIn)
+				}
+				if change2, ok := p.Change2.(float64); ok {
+					item.BuyChange = int(change2)
+				}
+				if soldOut, ok := p.SoldOut.(float64); ok {
+					item.SoldValue = int(soldOut)
+				}
+				if change3, ok := p.Change3.(float64); ok {
+					item.SoldChange = int(change3)
+				}
+
+				itemVerifyCode = item.BuyValue + item.DealValue + item.SoldValue
+				if existIndex, ok := existIndexMap[item.DealName+item.BuyName+item.SoldName]; !ok {
+					newID, e := models.AddBaseFromTradeShangHaiIndex(item)
+					if e != nil {
+						err = e
+						fmt.Println("insert error:", err)
+					}
+					fmt.Println("insert new indexID:", newID)
+				} else if existIndex != nil && itemVerifyCode != (existIndex.DealValue+existIndex.BuyValue+existIndex.SoldValue) {
+					//更新
+					err = models.ModifyBaseFromTradeShangHaiIndex(item.DealValue, item.BuyValue, item.SoldValue, existIndex.BaseFromTradeShangHaiIndexId)
+					if err != nil {
+						fmt.Println("data update err:", err)
+					}
+				}
+			}
+		}
+	}
+
+	br.Ret = 200
+	br.Msg = "获取成功"
+	br.Success = true
+}
+
+func ShIndexCodeGenerator(shortName, indexName, contractCode, suffix string) string {
+	if shortName == "" {
+		return ""
+	}
+	strResult := ""
+	if shortName != "top20" {
+		//取公司全拼
+		a := pinyin.NewArgs()
+		rows := pinyin.LazyPinyin(shortName, a)
+		for i := 0; i < len(rows); i++ {
+			strResult += rows[i]
+		}
+	} else {
+		strResult = "top20"
+	}
+	indexCode, _ := indexCodeMap[indexName]
+	if indexCode == "" {
+		indexCode = strResult + contractCode + suffix
+		indexCode = strings.Replace(indexCode, " ", "", -1)
+		indexCodeMap[indexName] = indexCode
+		err := models.AddBaseFromTradeMapping(indexName, indexCode, "SH")
+		if err != nil {
+			fmt.Println("add Code err:", err)
+		}
+	}
+	return strings.Replace(indexCode, " ", "", -1)
+}
+
+func IneIndexCodeGenerator(shortName, indexName, Instrumentid, suffix string) string {
+	if shortName == "" {
+		return ""
+	}
+	strResult := ""
+	if shortName != "top20" {
+		//取公司全拼
+		a := pinyin.NewArgs()
+		rows := pinyin.LazyPinyin(shortName, a)
+		for i := 0; i < len(rows); i++ {
+			strResult += rows[i]
+		}
+	} else {
+		strResult = "top20"
+	}
+	ineIndexCode, _ := ineIndexCodeMap[indexName]
+	if ineIndexCode == "" {
+		ineIndexCode = strResult + Instrumentid + suffix
+		ineIndexCode = strings.Replace(ineIndexCode, " ", "", -1)
+		ineIndexCodeMap[indexName] = ineIndexCode
+		err := models.AddBaseFromTradeMapping(indexName, ineIndexCode, "INE")
+		if err != nil {
+			fmt.Println("add Code err:", err)
+		}
+	}
+	return strings.Replace(ineIndexCode, " ", "", -1)
+}

+ 1 - 0
go.mod

@@ -8,6 +8,7 @@ require (
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/go-sql-driver/mysql v1.6.0
 	github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b
+	github.com/mozillazg/go-pinyin v0.20.0
 	github.com/nosixtools/solarlunar v0.0.0-20211112060703-1b6dea7b4a19
 	github.com/olivere/elastic/v7 v7.0.32
 	github.com/rdlucklib/rdluck_tools v1.0.3

+ 2 - 0
go.sum

@@ -323,6 +323,8 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ=
+github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=

+ 11 - 11
models/base_from_adjust.go

@@ -281,8 +281,8 @@ func RefreshAllAdjustEdb(edbInfo *EdbInfo, fromEdbInfo *EdbInfo) (err error) {
 	{
 		var tmpCondition string
 		var tmpPars []interface{}
-		condition += " AND edb_info_id=? AND data_time > ? "
-		pars = append(pars, fromEdbInfo.EdbInfoId, edbAdjustConf.SourceEndDate)
+		tmpCondition += " AND edb_info_id=? AND data_time > ? "
+		tmpPars = append(tmpPars, edbInfo.EdbInfoId, edbAdjustConf.SourceEndDate)
 		existDataList, tmpErr := GetEdbDataListAllByTo(to, tmpCondition, tmpPars, edbInfo.Source, 1)
 		if tmpErr != nil {
 			err = tmpErr
@@ -331,17 +331,17 @@ func RefreshAllAdjustEdb(edbInfo *EdbInfo, fromEdbInfo *EdbInfo) (err error) {
 		if err != nil {
 			return
 		}
-	}
 
-	// 变更数据调整配置表的实际结束日期
-	{
-		var fromEdbEndDate time.Time
-		if fromEdbInfo.EndDate != `0000-00-00` {
-			fromEdbEndDate, _ = time.Parse(utils.FormatDate, fromEdbInfo.EndDate)
+		// 变更数据调整配置表的实际结束日期
+		{
+			var fromEdbEndDate time.Time
+			if fromEdbInfo.EndDate != `0000-00-00` {
+				fromEdbEndDate, _ = time.Parse(utils.FormatDate, fromEdbInfo.EndDate)
+			}
+			edbAdjustConf.SourceEndDate = fromEdbEndDate
+			edbAdjustConf.ModifyTime = time.Now()
+			_, err = to.Update(edbAdjustConf, "SourceEndDate", "ModifyTime")
 		}
-		edbAdjustConf.SourceEndDate = fromEdbEndDate
-		edbAdjustConf.ModifyTime = time.Now()
-		_, err = to.Update(edbAdjustConf, "SourceEndDate", "ModifyTime")
 	}
 
 	return

+ 32 - 3
models/base_from_calculate.go

@@ -363,7 +363,11 @@ func RefreshAllCalculate(edbInfoIdArr []*EdbInfo, edbInfoId, source int, edbCode
 func refreshAllCalculate(to orm.TxOrmer, edbInfoIdArr []*EdbInfo, edbInfoId, source int, edbCode, formulaStr, startDate, endDate string, edbInfoIdBytes []string) (err error) {
 	realSaveDataMap := make(map[string]map[int]float64)
 	saveDataMap := make(map[string]map[int]float64)
-	dateList := make([]string, 0)
+
+	// 最小的结束日期 , 最晚的数据开始日期
+	var minLatestDate, maxStartDate time.Time
+	dateList := make([]string, 0) // 第一个指标的日期数据
+
 	for edbInfoIndex, v := range edbInfoIdArr {
 		var condition string
 		var pars []interface{}
@@ -382,6 +386,9 @@ func refreshAllCalculate(to orm.TxOrmer, edbInfoIdArr []*EdbInfo, edbInfoId, sou
 		if err != nil {
 			return err
 		}
+
+		lenData := len(dataList)
+
 		for _, dv := range dataList {
 			if val, ok := realSaveDataMap[dv.DataTime]; ok {
 				if _, ok := val[v.EdbInfoId]; !ok {
@@ -409,10 +416,22 @@ func refreshAllCalculate(to orm.TxOrmer, edbInfoIdArr []*EdbInfo, edbInfoId, sou
 				dateList = append(dateList, dv.DataTime)
 			}
 		}
+
+		if lenData > 0 {
+			tmpLatestDate, _ := time.ParseInLocation(utils.FormatDate, dataList[lenData-1].DataTime, time.Local)
+			if minLatestDate.IsZero() || minLatestDate.After(tmpLatestDate) {
+				minLatestDate = tmpLatestDate
+			}
+
+			tmpStartDate, _ := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
+			if maxStartDate.IsZero() || maxStartDate.Before(tmpStartDate) {
+				maxStartDate = tmpStartDate
+			}
+		}
 	}
 
 	//数据处理,将日期内不全的数据做补全
-	handleDateSaveDataMap(dateList, realSaveDataMap, saveDataMap, edbInfoIdArr)
+	handleDateSaveDataMap(dateList, maxStartDate, minLatestDate, realSaveDataMap, saveDataMap, edbInfoIdArr)
 
 	formulaMap := utils.CheckFormula(formulaStr)
 	addSql := ` INSERT INTO edb_data_calculate(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
@@ -650,8 +669,18 @@ func CheckFormula2(edbInfoArr []*EdbInfo, formulaMap map[string]string, formulaS
 }
 
 // 处理整个数据
-func handleDateSaveDataMap(dateList []string, realSaveDataMap, saveDataMap map[string]map[int]float64, edbInfoIdArr []*EdbInfo) {
+func handleDateSaveDataMap(dateList []string, maxStartDate, minLatestDate time.Time, realSaveDataMap, saveDataMap map[string]map[int]float64, edbInfoIdArr []*EdbInfo) {
 	for _, date := range dateList {
+		dateTime, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
+		// 如果当前日期早于数据的最大开始日期,那么不处理,进入下一个循环
+		if dateTime.Before(maxStartDate) {
+			continue
+		}
+		// 如果当前日期晚于数据的最小结束日期,那么不处理,直接返回了
+		if dateTime.After(minLatestDate) {
+			return
+		}
+
 		tmpDataMap := realSaveDataMap[date]
 		for _, edbInfo := range edbInfoIdArr {
 			tmpEdbInfoId := edbInfo.EdbInfoId // 当前指标id

+ 1 - 0
models/base_from_mysteel_chemical.go

@@ -446,6 +446,7 @@ func (r *BaseFromMysteelChemicalData) Add(list []BaseFromMysteelChemicalData) (e
 
 type AddMysteelIndexResp struct {
 	EdbCode                           string `description:"指标编码"`
+	TerminalCode                      string `description:"指标终端编码"`
 	BaseFromMysteelChemicalClassifyId int    `description:"指标分类"`
 	SysUserId                         int    `description:"操作人id"`
 	SysUserRealName                   string `description:"操作人真实名称"`

+ 83 - 0
models/base_from_sh.go

@@ -262,3 +262,86 @@ func RefreshEdbDataFromSh(edbInfoId int, edbCode, startDate string) (err error)
 	}
 	return
 }
+
+type RefreshSHExchangeReq struct {
+	Url      string `description:"交易所链接"`
+	Exchange string `description:"交易所"`
+	Date     string `description:"日期"`
+	Data     SHMessage
+}
+
+type Position []struct {
+	ContractCode     string      `json:"INSTRUMENTID"`
+	ProductSortNo    int         `json:"PRODUCTSORTNO"`
+	Rank             int         `json:"RANK"`
+	ParticipantID1   string      `json:"PARTICIPANTID1"`
+	ParticipantName1 string      `json:"PARTICIPANTABBR1"`
+	Deal             interface{} `json:"CJ1"`
+	Change1          interface{} `json:"CJ1_CHG"`
+	ParticipantID2   string      `json:"PARTICIPANTID2"`
+	ParticipantName2 string      `json:"PARTICIPANTABBR2"`
+	BuyIn            interface{} `json:"CJ2"`
+	Change2          interface{} `json:"CJ2_CHG"`
+	ParticipantID3   string      `json:"PARTICIPANTID3"`
+	ParticipantName3 string      `json:"PARTICIPANTABBR3"`
+	SoldOut          interface{} `json:"CJ3"`
+	Change3          interface{} `json:"CJ3_CHG"`
+	ProductName      string      `json:"PRODUCTNAME"`
+}
+
+type SHMessage struct {
+	Position   Position `json:"o_cursor"`
+	Length     string   `json:"showlength"`
+	Code       int      `json:"o_code"`
+	Msg        string   `json:"o_msg"`
+	ReportDate string   `json:"report_date"`
+	UpdateDate string   `json:"update_date"`
+	PrintDate  string   `json:"print_date"`
+}
+
+type BaseFromTradeShanghaiIndex struct {
+	BaseFromTradeShangHaiIndexId int `orm:"column(base_from_trade_shanghai_index_id);pk"`
+	Rank                         int
+	DealShortName                string
+	DealName                     string
+	DealCode                     string
+	DealValue                    int
+	DealChange                   int
+	BuyShortName                 string
+	BuyName                      string
+	BuyCode                      string
+	BuyValue                     int
+	BuyChange                    int
+	SoldShortName                string
+	SoldName                     string
+	SoldCode                     string
+	SoldValue                    int
+	SoldChange                   int
+	Frequency                    string
+	ClassifyName                 string
+	ClassifyType                 string
+	CreateTime                   time.Time
+	ModifyTime                   time.Time
+	DataTime                     string
+}
+
+func AddBaseFromTradeShangHaiIndex(item *BaseFromTradeShanghaiIndex) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+func GetBaseFromTradeShangHaiIndexAll(dateStr string) (list []*BaseFromTradeShanghaiIndex, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM base_from_trade_shanghai_index WHERE data_time=?`
+	_, err = o.Raw(sql, dateStr).QueryRows(&list)
+	return
+}
+
+func ModifyBaseFromTradeShangHaiIndex(dealValue, buyValue, soldValue int, dataId int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE base_from_trade_shanghai_index SET deal_value=?,buy_value=?,sold_value=?,modify_time=NOW() WHERE base_from_trade_shanghai_index_id=? `
+	_, err = o.Raw(sql, dealValue, buyValue, soldValue, dataId).Exec()
+	return
+}
+

+ 98 - 0
models/base_from_shfe.go

@@ -260,3 +260,101 @@ func RefreshEdbDataFromShfe(edbInfoId int, edbCode, startDate string) (err error
 	}
 	return
 }
+
+type BaseFromTradeIneIndex struct {
+	BaseFromTradeIneIndexId int `orm:"column(base_from_trade_ine_index_id);pk"`
+	Rank                    int
+	DealShortName           string
+	DealName                string
+	DealCode                string
+	DealValue               int
+	DealChange              int
+	BuyShortName            string
+	BuyName                 string
+	BuyCode                 string
+	BuyValue                int
+	BuyChange               int
+	SoldShortName           string
+	SoldName                string
+	SoldCode                string
+	SoldValue               int
+	SoldChange              int
+	Frequency               string
+	ClassifyName            string
+	ClassifyType            string
+	CreateTime              time.Time
+	ModifyTime              time.Time
+	DataTime                string
+}
+
+type BaseFromTradeMapping struct {
+	BaseFromTradeMappingId int `orm:"column(base_from_trade_mapping_id);pk"`
+	IndexName              string
+	IndexCode              string
+	Exchange               string
+}
+
+func AddBaseFromTradeIneIndex(item *BaseFromTradeIneIndex) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+func GetBaseFromTradeIneIndexAll(dateStr string) (list []*BaseFromTradeIneIndex, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM base_from_trade_ine_index where data_time=?`
+	_, err = o.Raw(sql, dateStr).QueryRows(&list)
+	return
+}
+
+func ModifyBaseFromTradeIneIndex(dealValue, buyValue, soldValue int, dataId int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE base_from_trade_ine_index SET deal_value=?,buy_value=?,sold_value=?,modify_time=NOW() WHERE base_from_trade_ine_index_id=? `
+	_, err = o.Raw(sql, dealValue, buyValue, soldValue, dataId).Exec()
+	return
+}
+
+func GetIndexCodeFromMapping(exchange string) (list []*BaseFromTradeMapping, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM base_from_trade_mapping where exchange=?`
+	_, err = o.Raw(sql, exchange).QueryRows(&list)
+	return
+}
+
+func AddBaseFromTradeMapping(indexName, indexCode, exchange string) (err error) {
+	o := orm.NewOrm()
+	sql := "Insert Into base_from_trade_mapping(index_name,index_code,exchange) Values('" + indexName + "','" + indexCode + "','" + exchange + "')"
+	_, err = o.Raw(sql).Exec()
+	return
+}
+
+type RefreshINEExchangeReq struct {
+	Date     string `description:"日期"`
+	Data     IneJSONData
+}
+
+type IneJSONData struct {
+	OCursor    []OCursor   `json:"o_cursor"`
+	OCode      interface{} `json:"o_code"`
+	OMsg       string      `json:"o_msg"`
+	ReportDate string      `json:"report_date"`
+	UpdateDate string      `json:"update_date"`
+}
+type OCursor struct {
+	Instrumentid     string      `json:"INSTRUMENTID"`
+	Participantid3   string      `json:"PARTICIPANTID3"`
+	Participantid2   string      `json:"PARTICIPANTID2"`
+	Participantid1   string      `json:"PARTICIPANTID1"`
+	Participantabbr3 string      `json:"PARTICIPANTABBR3"`
+	Participantabbr2 string      `json:"PARTICIPANTABBR2"`
+	Rank             int         `json:"RANK"`
+	Participantabbr1 string      `json:"PARTICIPANTABBR1"`
+	BuyIn            interface{} `json:"CJ2"`
+	Deal             interface{} `json:"CJ1"`
+	Change1          interface{} `json:"CJ1_CHG"`
+	Change3          interface{} `json:"CJ3_CHG"`
+	Productname      string      `json:"Productname"`
+	Productsortno    interface{} `json:"PRODUCTSORTNO"`
+	SoldOut          interface{} `json:"CJ3"`
+	Change2          interface{} `json:"CJ2_CHG"`
+}

+ 36 - 0
models/base_from_smm.go

@@ -191,6 +191,7 @@ func RefreshEdbDataFromSmm(edbInfoId int, edbCode, startDate string) (err error)
 
 type BaseFromSmmIndex struct {
 	BaseFromSmmIndexId int64 `orm:"column(base_from_smm_index_id);pk"`
+	ClassifyId         int
 	Interface          string
 	Name               string
 	IndexCode          string
@@ -227,6 +228,13 @@ func (d *BaseFromSmmIndex) GetSmmIndexItem(indexCode string) (item *BaseFromSmmI
 	return
 }
 
+// Add 新增
+func (m *BaseFromSmmIndex) Add() (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(m)
+	return
+}
+
 func GetBaseFromSmmDataBySmmCode(smmCode string) (list []*BaseFromSmmData, err error) {
 	o := orm.NewOrm()
 	sql := ` SELECT * FROM base_from_smm_data WHERE index_code=? `
@@ -260,6 +268,7 @@ type HandleSmmExcelDataReq struct {
 	BaseFilePath   string
 	RenameFilePath string
 	IndexName      string
+	Source         string
 	IndexCode      string
 	Unit           string
 	Frequency      string
@@ -292,3 +301,30 @@ func MultiUpdateBaseFromSmmDataValue(items []*BaseFromSmmData) (err error) {
 	}
 	return
 }
+
+type AddSmmIndexToDataSourceResp struct {
+	EdbCode         string `description:"指标编码"`
+	ClassifyId      int    `description:"指标分类"`
+	SysUserId       int    `description:"操作人id"`
+	SysUserRealName string `description:"操作人真实名称"`
+}
+
+func (m *BaseFromSmmIndex) GetIndexItem(indexCode string) (item *BaseFromSmmIndex, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM base_from_smm_index WHERE index_code = ? `
+	err = o.Raw(sql, indexCode).QueryRow(&item)
+	return
+}
+
+// 修改
+func (m *BaseFromSmmIndex) Update(updateParams, whereParam map[string]interface{}) (err error) {
+	to := orm.NewOrm()
+	ptrStructOrTableName := "base_from_smm_index"
+
+	qs := to.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range whereParam {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err = qs.Update(updateParams)
+	return
+}

+ 85 - 0
models/base_from_smm_classify.go

@@ -0,0 +1,85 @@
+package models
+
+import (
+	"eta/eta_index_lib/utils"
+	"github.com/beego/beego/v2/client/orm"
+	"strconv"
+	"time"
+)
+
+type BaseFromSmmClassify struct {
+	ClassifyId      int       `orm:"column(classify_id);pk"`
+	ClassifyName    string    `description:"分类名称"`
+	ParentId        int       `description:"父级id"`
+	SysUserId       int       `description:"创建人id"`
+	SysUserRealName string    `description:"创建人姓名"`
+	Level           int       `description:"层级"`
+	Sort            int       `description:"排序字段,越小越靠前,默认值:10"`
+	ModifyTime      time.Time `description:"修改时间"`
+	CreateTime      time.Time `description:"创建时间"`
+}
+
+func AddSmmClassify(item *BaseFromSmmClassify) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type AddSmmClassifyReq struct {
+	ClassifyName    string `description:"分类名称"`
+	ParentId        int    `description:"父级id,第一级传0"`
+	Level           int    `description:"层级,第一级传0,其余传上一级的层级"`
+	SysUserId       int    `description:"操作人id"`
+	SysUserRealName string `description:"操作人真实名称"`
+}
+
+// 判断分类名称是否存在
+func GetSmmClassify(classifyName string, parentId int) (item *BaseFromSmmClassify, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM base_from_smm_classify WHERE parent_id=? AND classify_name=? `
+	err = o.Raw(sql, parentId, classifyName).QueryRow(&item)
+	return
+}
+
+// 添加指标分类
+func SaveSmmClassify(classifyName string, parentId, level int, sysUserId, sysUserName string) (classifyInfo *BaseFromSmmClassify, err error, errMsg string) {
+	edbClassify, err := GetSmmClassify(classifyName, parentId)
+
+	var isAdd bool
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			isAdd = true
+		} else {
+			errMsg = `判断名称是否已存在失败`
+			return
+		}
+	}
+
+	if edbClassify != nil && edbClassify.ClassifyId > 0 {
+		classifyInfo = edbClassify
+		return edbClassify, nil, ""
+	} else {
+		isAdd = true
+	}
+	if isAdd {
+		sysUserIdInt, _ := strconv.Atoi(sysUserId)
+		//获取该层级下最大的排序数
+		maxSort, err := GetMysteelClassifyMaxSort(parentId)
+		classifyInfo = &BaseFromSmmClassify{
+			ClassifyName:    classifyName,
+			ParentId:        parentId,
+			CreateTime:      time.Now(),
+			ModifyTime:      time.Now(),
+			SysUserId:       sysUserIdInt,
+			SysUserRealName: sysUserName,
+			Level:           level + 1,
+			Sort:            maxSort,
+		}
+		classifyId, err := AddSmmClassify(classifyInfo)
+		if err != nil {
+			errMsg = "保存分类失败"
+		}
+		classifyInfo.ClassifyId = int(classifyId)
+	}
+	return
+}

+ 148 - 143
models/base_predict_from_calculate.go

@@ -90,138 +90,138 @@ func EditPredictCalculate(edbInfo *EdbInfo, calculateMappingList []*EdbInfoCalcu
 }
 
 // AddPredictCalculateData 新增预测计算(运算)指标的数据
-func AddPredictCalculateDataBak(edbInfoIdList []*EdbInfo, edbInfoId int, edbCode, formulaStr string, edbInfoIdBytes []string) (latestDateStr string, latestValue float64, err error) {
-	o := orm.NewOrm()
-	defer func() {
-		if err != nil {
-			utils.FileLog.Info(fmt.Sprintf("Calculate Err:%s" + err.Error()))
-		}
-	}()
-
-	var minLatestDate time.Time
-	oldSaveDataMap := make(map[string]map[int]float64)
-	saveDataMap := make(map[string]map[int]float64)
-	dateList := make([]string, 0)
-
-	for edbInfoIndex, v := range edbInfoIdList {
-		tmpLatestDate, tmpErr := time.ParseInLocation(utils.FormatDate, v.LatestDate, time.Local)
-		if tmpErr != nil {
-			err = errors.New(`最近的日期格式化失败;日期:` + v.LatestDate + `;err:` + tmpErr.Error())
-			return
-		}
-		// 如果不存在最小的真实数据日期,那么将当前指标的真实数据日期给赋值;
-		// 如果存在最小的真实数据日期,同时当前指标的真实数据日期 早于 最小的真实数据日期, 那么将当前指标的真实数据日期给赋值;
-		if minLatestDate.IsZero() || tmpLatestDate.Before(minLatestDate) {
-			minLatestDate = tmpLatestDate
-		}
-
-		dataList, tmpErr := GetPredictEdbDataListAll(v, 1)
-		if tmpErr != nil {
-			err = tmpErr
-			return
-		}
-		dataMap := make(map[string]float64)
-		for _, dv := range dataList {
-			// 现有实际数据
-			if val, ok := oldSaveDataMap[dv.DataTime]; ok {
-				if _, ok := val[v.EdbInfoId]; !ok {
-					val[v.EdbInfoId] = dv.Value
-				}
-			} else {
-				temp := make(map[int]float64)
-				temp[v.EdbInfoId] = dv.Value
-				oldSaveDataMap[dv.DataTime] = temp
-			}
-
-			// 待处理的数据
-			if val, ok := saveDataMap[dv.DataTime]; ok {
-				if _, ok := val[v.EdbInfoId]; !ok {
-					val[v.EdbInfoId] = dv.Value
-				}
-			} else {
-				temp := make(map[int]float64)
-				temp[v.EdbInfoId] = dv.Value
-				saveDataMap[dv.DataTime] = temp
-			}
-
-			// 以第一个指标的日期作为基准日期
-			if edbInfoIndex == 0 {
-				dateList = append(dateList, dv.DataTime)
-			}
-		}
-		item := new(PredictCalculateItems)
-		item.EdbInfoId = v.EdbInfoId
-		item.DataMap = dataMap
-	}
-
-	//数据处理,将日期内不全的数据做补全
-	handleDateSaveDataMap(dateList, oldSaveDataMap, saveDataMap, edbInfoIdList)
-
-	formulaMap := utils.CheckFormula(formulaStr)
-	addSql := ` INSERT INTO edb_data_predict_calculate (edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
-	nowStr := time.Now().Format(utils.FormatDateTime)
-	var isAdd bool
-
-	if !minLatestDate.IsZero() {
-		latestDateStr = minLatestDate.Format(utils.FormatDate)
-	}
-	for sk, sv := range saveDataMap {
-		formulaStr = strings.ToUpper(formulaStr)
-		formulaFormStr := ReplaceFormula(edbInfoIdList, sv, formulaMap, formulaStr, edbInfoIdBytes)
-		if formulaStr == "" {
-			return
-		}
-		if formulaFormStr != "" {
-			expression := formula.NewExpression(formulaFormStr)
-			calResult, tmpErr := expression.Evaluate()
-			if tmpErr != nil {
-				err = errors.New("计算失败:Err:" + tmpErr.Error() + ";formulaStr:" + formulaFormStr)
-				fmt.Println(err)
-				return
-			}
-			calVal, tmpErr := calResult.Float64()
-			if tmpErr != nil {
-				err = errors.New("计算失败:获取计算值失败 Err:" + tmpErr.Error() + ";formulaStr:" + formulaFormStr)
-				fmt.Println(err)
-				return
-			}
-
-			//需要存入的数据
-			{
-				if latestDateStr == sk {
-					nanCheck := fmt.Sprintf("%0.f", calVal)
-					// 分母为0.0的报错
-					if nanCheck == "NaN" || nanCheck == "+Inf" || nanCheck == "-Inf" {
-						err = errors.New("计算失败 分母为0:Err: formulaStr:" + formulaFormStr)
-						fmt.Println(err)
-						return
-					}
-					latestValue, _ = decimal.NewFromFloat(calVal).Truncate(4).Float64() //保留4位小数
-				}
-				dataTime, _ := time.ParseInLocation(utils.FormatDate, sk, time.Local)
-				timestamp := dataTime.UnixNano() / 1e6
-				timeStr := fmt.Sprintf("%d", timestamp)
-				addSql += "("
-				addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + sk + "'" + "," + utils.SubFloatToString(calVal, 4) + "," + "'" + nowStr + "'" +
-					"," + "'" + nowStr + "'" + "," + "'" + timeStr + "'"
-				addSql += "),"
-				isAdd = true
-			}
-		} else {
-			fmt.Println("formulaFormStr is empty")
-		}
-	}
-	if isAdd {
-		addSql = strings.TrimRight(addSql, ",")
-		_, err = o.Raw(addSql).Exec()
-		if err != nil {
-			fmt.Println("AddPredictCalculate Err:" + err.Error())
-			//errMsg = " tx.Exec Err :" + err.Error()
-			return
-		}
-	}
-	return
-}
+//func AddPredictCalculateDataBak(edbInfoIdList []*EdbInfo, edbInfoId int, edbCode, formulaStr string, edbInfoIdBytes []string) (latestDateStr string, latestValue float64, err error) {
+//	o := orm.NewOrm()
+//	defer func() {
+//		if err != nil {
+//			utils.FileLog.Info(fmt.Sprintf("Calculate Err:%s" + err.Error()))
+//		}
+//	}()
+//
+//	var minLatestDate time.Time
+//	oldSaveDataMap := make(map[string]map[int]float64)
+//	saveDataMap := make(map[string]map[int]float64)
+//	dateList := make([]string, 0)
+//
+//	for edbInfoIndex, v := range edbInfoIdList {
+//		tmpLatestDate, tmpErr := time.ParseInLocation(utils.FormatDate, v.LatestDate, time.Local)
+//		if tmpErr != nil {
+//			err = errors.New(`最近的日期格式化失败;日期:` + v.LatestDate + `;err:` + tmpErr.Error())
+//			return
+//		}
+//		// 如果不存在最小的真实数据日期,那么将当前指标的真实数据日期给赋值;
+//		// 如果存在最小的真实数据日期,同时当前指标的真实数据日期 早于 最小的真实数据日期, 那么将当前指标的真实数据日期给赋值;
+//		if minLatestDate.IsZero() || tmpLatestDate.Before(minLatestDate) {
+//			minLatestDate = tmpLatestDate
+//		}
+//
+//		dataList, tmpErr := GetPredictEdbDataListAll(v, 1)
+//		if tmpErr != nil {
+//			err = tmpErr
+//			return
+//		}
+//		dataMap := make(map[string]float64)
+//		for _, dv := range dataList {
+//			// 现有实际数据
+//			if val, ok := oldSaveDataMap[dv.DataTime]; ok {
+//				if _, ok := val[v.EdbInfoId]; !ok {
+//					val[v.EdbInfoId] = dv.Value
+//				}
+//			} else {
+//				temp := make(map[int]float64)
+//				temp[v.EdbInfoId] = dv.Value
+//				oldSaveDataMap[dv.DataTime] = temp
+//			}
+//
+//			// 待处理的数据
+//			if val, ok := saveDataMap[dv.DataTime]; ok {
+//				if _, ok := val[v.EdbInfoId]; !ok {
+//					val[v.EdbInfoId] = dv.Value
+//				}
+//			} else {
+//				temp := make(map[int]float64)
+//				temp[v.EdbInfoId] = dv.Value
+//				saveDataMap[dv.DataTime] = temp
+//			}
+//
+//			// 以第一个指标的日期作为基准日期
+//			if edbInfoIndex == 0 {
+//				dateList = append(dateList, dv.DataTime)
+//			}
+//		}
+//		item := new(PredictCalculateItems)
+//		item.EdbInfoId = v.EdbInfoId
+//		item.DataMap = dataMap
+//	}
+//
+//	//数据处理,将日期内不全的数据做补全
+//	handleDateSaveDataMap(dateList, oldSaveDataMap, saveDataMap, edbInfoIdList)
+//
+//	formulaMap := utils.CheckFormula(formulaStr)
+//	addSql := ` INSERT INTO edb_data_predict_calculate (edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+//	nowStr := time.Now().Format(utils.FormatDateTime)
+//	var isAdd bool
+//
+//	if !minLatestDate.IsZero() {
+//		latestDateStr = minLatestDate.Format(utils.FormatDate)
+//	}
+//	for sk, sv := range saveDataMap {
+//		formulaStr = strings.ToUpper(formulaStr)
+//		formulaFormStr := ReplaceFormula(edbInfoIdList, sv, formulaMap, formulaStr, edbInfoIdBytes)
+//		if formulaStr == "" {
+//			return
+//		}
+//		if formulaFormStr != "" {
+//			expression := formula.NewExpression(formulaFormStr)
+//			calResult, tmpErr := expression.Evaluate()
+//			if tmpErr != nil {
+//				err = errors.New("计算失败:Err:" + tmpErr.Error() + ";formulaStr:" + formulaFormStr)
+//				fmt.Println(err)
+//				return
+//			}
+//			calVal, tmpErr := calResult.Float64()
+//			if tmpErr != nil {
+//				err = errors.New("计算失败:获取计算值失败 Err:" + tmpErr.Error() + ";formulaStr:" + formulaFormStr)
+//				fmt.Println(err)
+//				return
+//			}
+//
+//			//需要存入的数据
+//			{
+//				if latestDateStr == sk {
+//					nanCheck := fmt.Sprintf("%0.f", calVal)
+//					// 分母为0.0的报错
+//					if nanCheck == "NaN" || nanCheck == "+Inf" || nanCheck == "-Inf" {
+//						err = errors.New("计算失败 分母为0:Err: formulaStr:" + formulaFormStr)
+//						fmt.Println(err)
+//						return
+//					}
+//					latestValue, _ = decimal.NewFromFloat(calVal).Truncate(4).Float64() //保留4位小数
+//				}
+//				dataTime, _ := time.ParseInLocation(utils.FormatDate, sk, time.Local)
+//				timestamp := dataTime.UnixNano() / 1e6
+//				timeStr := fmt.Sprintf("%d", timestamp)
+//				addSql += "("
+//				addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + sk + "'" + "," + utils.SubFloatToString(calVal, 4) + "," + "'" + nowStr + "'" +
+//					"," + "'" + nowStr + "'" + "," + "'" + timeStr + "'"
+//				addSql += "),"
+//				isAdd = true
+//			}
+//		} else {
+//			fmt.Println("formulaFormStr is empty")
+//		}
+//	}
+//	if isAdd {
+//		addSql = strings.TrimRight(addSql, ",")
+//		_, err = o.Raw(addSql).Exec()
+//		if err != nil {
+//			fmt.Println("AddPredictCalculate Err:" + err.Error())
+//			//errMsg = " tx.Exec Err :" + err.Error()
+//			return
+//		}
+//	}
+//	return
+//}
 
 func AddPredictCalculateData(edbInfoIdList []*EdbInfo, edbInfo *EdbInfo, edbCode, formulaStr string, edbInfoIdBytes []string) (latestDateStr string, latestValue float64, err error) {
 	o := orm.NewOrm()
@@ -267,20 +267,30 @@ func RefreshAllPredictCalculate(edbInfoIdList []*EdbInfo, edbInfoId, source int,
 func refreshAllPredictCalculate(to orm.TxOrmer, edbInfoIdList []*EdbInfo, edbInfoId, source int, edbCode, formulaStr, startDate string, edbInfoIdBytes []string) (latestDateStr string, latestValue float64, err error) {
 	fmt.Println("startDate:", startDate)
 
-	var minLatestDate time.Time
+	// 最小的结束日期 , 最晚的数据开始日期
+	var minLatestDate, maxStartDate time.Time
+	dateList := make([]string, 0) // 第一个指标的日期数据
+
 	realSaveDataMap := make(map[string]map[int]float64)
 	saveDataMap := make(map[string]map[int]float64)
-	dateList := make([]string, 0)
 
 	for edbInfoIndex, v := range edbInfoIdList {
 		tmpLatestDate, tmpErr := time.ParseInLocation(utils.FormatDate, v.LatestDate, time.Local)
 		if tmpErr != nil {
-			err = errors.New(`最近的日期格式化失败;日期:` + v.LatestDate + `;err:` + tmpErr.Error())
+			err = errors.New(`最近的日期格式化失败;日期:` + v.EndDate + `;err:` + tmpErr.Error())
 			return
 		}
 		if minLatestDate.IsZero() || tmpLatestDate.Before(minLatestDate) {
 			minLatestDate = tmpLatestDate
 		}
+		tmpStartDate, tmpErr := time.ParseInLocation(utils.FormatDate, v.StartDate, time.Local)
+		if tmpErr != nil {
+			err = errors.New(`最近的日期格式化失败;日期:` + v.StartDate + `;err:` + tmpErr.Error())
+			return
+		}
+		if maxStartDate.IsZero() || maxStartDate.Before(tmpStartDate) {
+			maxStartDate = tmpStartDate
+		}
 
 		// 获取关联指标数据
 		dataList, tmpErr := GetPredictEdbDataListAllByStartDate(v, 1, startDate)
@@ -288,7 +298,7 @@ func refreshAllPredictCalculate(to orm.TxOrmer, edbInfoIdList []*EdbInfo, edbInf
 			err = tmpErr
 			return
 		}
-		dataMap := make(map[string]float64)
+
 		for _, dv := range dataList { // 现有实际数据
 			if val, ok := realSaveDataMap[dv.DataTime]; ok {
 				if _, ok := val[v.EdbInfoId]; !ok {
@@ -310,19 +320,14 @@ func refreshAllPredictCalculate(to orm.TxOrmer, edbInfoIdList []*EdbInfo, edbInf
 				temp[v.EdbInfoId] = dv.Value
 				saveDataMap[dv.DataTime] = temp
 			}
-
-			// 以第一个指标的日期作为基准日期
 			if edbInfoIndex == 0 {
 				dateList = append(dateList, dv.DataTime)
 			}
 		}
-		item := new(CalculateItems)
-		item.EdbInfoId = v.EdbInfoId
-		item.DataMap = dataMap
 	}
 
-	//数据处理,将日期内不全的数据做补
-	handleDateSaveDataMap(dateList, realSaveDataMap, saveDataMap, edbInfoIdList)
+	//数据处理,将日期内不全的数据做填补
+	handleDateSaveDataMap(dateList, maxStartDate, minLatestDate, realSaveDataMap, saveDataMap, edbInfoIdList)
 
 	formulaMap := utils.CheckFormula(formulaStr)
 	addSql := ` INSERT INTO edb_data_predict_calculate (edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `

+ 3 - 0
models/db.go

@@ -98,5 +98,8 @@ func initBaseIndex() {
 		new(BaseFromSmmData),
 		new(BaseFromMysteelChemicalIndex),
 		new(BaseFromMysteelChemicalData),
+		new(BaseFromTradeShanghaiIndex),
+		new(BaseFromTradeIneIndex),
+		new(BaseFromSmmClassify),
 	)
 }

+ 5 - 1
models/edb_data_calculate_nhcc.go

@@ -651,7 +651,7 @@ func refreshAllCalculateNhcc(to orm.TxOrmer, edbInfo *EdbInfo, existItemA, exist
 }
 
 // CalculateComputeCorrelation 计算相关性结果
-func CalculateComputeCorrelation(req *EdbInfoCalculateBatchSaveReq, firstEdbInfo, secondEdbInfo *EdbInfo, nhccDate NhccDate) (r float64, err error, errMsg string) {
+func CalculateComputeCorrelation(req *EdbInfoCalculateBatchSaveReq, firstEdbInfo, secondEdbInfo *EdbInfo, nhccDate NhccDate) (a, b, r float64, err error, errMsg string) {
 	var existItemA, existItemB *EdbInfoCalculateMapping
 	//第一个指标
 	{
@@ -725,6 +725,10 @@ func CalculateComputeCorrelation(req *EdbInfoCalculateBatchSaveReq, firstEdbInfo
 		}
 		coordinateData = append(coordinateData, tmpCoordinate)
 	}
+	// 计算线性方程公式
+	a, b = utils.GetLinearResult(coordinateData)
+
+	// 计算相关性
 	r = utils.ComputeCorrelation(coordinateData)
 
 	return

+ 362 - 0
models/edb_data_calculate_rjz.go

@@ -0,0 +1,362 @@
+package models
+
+import (
+	"errors"
+	"eta/eta_index_lib/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/shopspring/decimal"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// AddCalculateRjz 日均值
+func AddCalculateRjz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbInfo, edbCode, uniqueCode string, sysUserId int, sysUserRealName string) (edbInfo *EdbInfo, err error) {
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("AddCalculateRjz,Err:" + err.Error())
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+	if req.EdbInfoId <= 0 {
+		edbInfo = new(EdbInfo)
+		edbInfo.Source = utils.DATA_SOURCE_CALCULATE_RJZ
+		edbInfo.SourceName = "日均值"
+		edbInfo.EdbCode = edbCode
+		edbInfo.EdbName = req.EdbName
+		edbInfo.EdbNameSource = req.EdbName
+		edbInfo.Frequency = req.Frequency
+		edbInfo.Unit = req.Unit
+		edbInfo.ClassifyId = req.ClassifyId
+		edbInfo.SysUserId = sysUserId
+		edbInfo.SysUserRealName = sysUserRealName
+		edbInfo.CreateTime = time.Now()
+		edbInfo.ModifyTime = time.Now()
+		edbInfo.UniqueCode = uniqueCode
+		edbInfo.CalculateFormula = req.Formula
+		edbInfo.EdbType = 2
+		newEdbInfoId, tmpErr := to.Insert(edbInfo)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		edbInfo.EdbInfoId = int(newEdbInfoId)
+
+		//关联关系
+		{
+			calculateMappingItem := new(EdbInfoCalculateMapping)
+			calculateMappingItem.CreateTime = time.Now()
+			calculateMappingItem.ModifyTime = time.Now()
+			calculateMappingItem.Sort = 1
+			calculateMappingItem.EdbCode = edbCode
+			calculateMappingItem.EdbInfoId = edbInfo.EdbInfoId
+			calculateMappingItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
+			calculateMappingItem.FromEdbCode = fromEdbInfo.EdbCode
+			calculateMappingItem.FromEdbName = fromEdbInfo.EdbName
+			calculateMappingItem.FromSource = fromEdbInfo.Source
+			calculateMappingItem.FromSourceName = fromEdbInfo.SourceName
+			calculateMappingItem.FromTag = ""
+			calculateMappingItem.Source = edbInfo.Source
+			calculateMappingItem.SourceName = edbInfo.SourceName
+			_, err = to.Insert(calculateMappingItem)
+			if err != nil {
+				return
+			}
+		}
+
+	} else {
+		edbInfo, err = GetEdbInfoById(req.EdbInfoId)
+		if err != nil {
+			return
+		}
+		dataTableName := GetEdbDataTableName(utils.DATA_SOURCE_CALCULATE_RJZ)
+		deleteSql := ` DELETE FROM %s WHERE edb_info_id=? `
+		deleteSql = fmt.Sprintf(deleteSql, dataTableName)
+		_, err = to.Raw(deleteSql, req.EdbInfoId).Exec()
+		if err != nil {
+			return
+		}
+	}
+
+	//计算数据
+	err = refreshAllCalculateRjz(to, edbInfo.EdbInfoId, edbInfo.Source, fromEdbInfo, edbCode, "", "")
+
+	return
+}
+
+// EditCalculateRjz 日均值
+func EditCalculateRjz(edbInfo *EdbInfo, req *EdbInfoCalculateBatchEditReq, fromEdbInfo *EdbInfo) (err error) {
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("EditCalculateRjz,Err:" + err.Error())
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	//修改指标信息
+	edbInfo.EdbName = req.EdbName
+	edbInfo.EdbNameSource = req.EdbName
+	edbInfo.Frequency = req.Frequency
+	edbInfo.Unit = req.Unit
+	edbInfo.ClassifyId = req.ClassifyId
+	edbInfo.ModifyTime = time.Now()
+	_, err = to.Update(edbInfo, "EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId", "ModifyTime")
+	if err != nil {
+		return
+	}
+
+	//判断计算指标是否被更换
+	var existCondition string
+	var existPars []interface{}
+	existCondition += " AND edb_info_id=? AND from_edb_info_id=? "
+	existPars = append(existPars, edbInfo.EdbInfoId, req.FromEdbInfoId)
+
+	count, err := GetEdbInfoCalculateCountByCondition(existCondition, existPars)
+	if err != nil {
+		err = errors.New("判断指标是否改变失败,Err:" + err.Error())
+		return
+	}
+	if count > 0 { // 指标未被替换,无需重新计算
+		return
+	}
+
+	//删除,计算指标关联的,基础指标的关联关系
+	sql := ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id = ? `
+	_, err = to.Raw(sql, edbInfo.EdbInfoId).Exec()
+	if err != nil {
+		return
+	}
+	//清空原有数据
+	sql = ` DELETE FROM edb_data_calculate_rjz WHERE edb_info_id = ? `
+	_, err = to.Raw(sql, edbInfo.EdbInfoId).Exec()
+	if err != nil {
+		return
+	}
+	//关联关系
+	{
+		calculateMappingItem := &EdbInfoCalculateMapping{
+			EdbInfoCalculateMappingId: 0,
+			EdbInfoId:                 edbInfo.EdbInfoId,
+			Source:                    utils.DATA_SOURCE_CALCULATE_RJZ,
+			SourceName:                "日均值",
+			EdbCode:                   edbInfo.EdbCode,
+			FromEdbInfoId:             fromEdbInfo.EdbInfoId,
+			FromEdbCode:               fromEdbInfo.EdbCode,
+			FromEdbName:               fromEdbInfo.EdbName,
+			FromSource:                fromEdbInfo.Source,
+			FromSourceName:            fromEdbInfo.SourceName,
+			FromTag:                   "",
+			Sort:                      1,
+			CreateTime:                time.Now(),
+			ModifyTime:                time.Now(),
+		}
+		_, err = to.Insert(calculateMappingItem)
+		if err != nil {
+			return
+		}
+	}
+
+	//计算数据
+	err = refreshAllCalculateRjz(to, edbInfo.EdbInfoId, edbInfo.Source, fromEdbInfo, edbInfo.EdbCode, "", "")
+
+	return
+}
+
+// RefreshAllCalculateRjz 刷新所有日均值数据
+func RefreshAllCalculateRjz(edbInfoId, source int, fromEdbInfo *EdbInfo, edbCode, startDate, endDate string) (err error) {
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("RefreshAllCalculateRjz,Err:" + err.Error())
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	//计算数据
+	err = refreshAllCalculateRjz(to, edbInfoId, source, fromEdbInfo, edbCode, startDate, endDate)
+	return
+}
+
+// refreshAllCalculateRjz
+func refreshAllCalculateRjz(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo *EdbInfo, edbCode, startDate, endDate string) (err error) {
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+
+	//计算数据
+	var condition string
+	var pars []interface{}
+	condition += " AND edb_info_id=? "
+	pars = append(pars, fromEdbInfo.EdbInfoId)
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+	//if endDate != "" {
+	//	condition += " AND data_time<=? "
+	//	pars = append(pars, endDate)
+	//}
+
+	dataList, err := GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 0)
+	if err != nil {
+		return err
+	}
+	var dateArr []string
+	dataMap := make(map[string]*EdbInfoSearchData)
+	for _, v := range dataList {
+		dateArr = append(dateArr, v.DataTime)
+		dataMap[v.DataTime] = v
+	}
+	fmt.Println("source:", source)
+	//获取指标所有数据
+	existDataList := make([]*EdbData, 0)
+	dataTableName := GetEdbDataTableName(source)
+	fmt.Println("dataTableName:", dataTableName)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	_, err = to.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return err
+	}
+	existDataMap := make(map[string]string)
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v.Value
+	}
+	fmt.Println("existDataMap:", existDataMap)
+	addSql := ` INSERT INTO edb_data_calculate_rjz(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existAddDataMap := make(map[string]string)
+	for _, av := range dateArr {
+		currentItem := dataMap[av]
+		if currentItem != nil {
+			//当前日期
+			currentDate, err := time.ParseInLocation(utils.FormatDate, av, time.Local)
+			if err != nil {
+				return err
+			}
+			//根据频度计算需要均分的天数
+			days, err := GetRjzFrequencyDays(currentDate, fromEdbInfo.Frequency)
+			val := rjzDiv(currentItem.Value, days)
+
+			timestamp := currentDate.UnixNano() / 1e6
+			timestampStr := fmt.Sprintf("%d", timestamp)
+			if existVal, ok := existDataMap[av]; !ok {
+				if _, existOk := existAddDataMap[av]; !existOk {
+					addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+					isAdd = true
+				}
+				existAddDataMap[av] = av
+			} else {
+				existValDecimal, err := decimal.NewFromString(existVal)
+				existStr := existValDecimal.String()
+				if existStr != val {
+					sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+					sql = fmt.Sprintf(sql, dataTableName)
+					_, err = to.Raw(sql, val, edbInfoId, av).Exec()
+					if err != nil {
+						return err
+					}
+				}
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		_, err = to.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+func GetRjzFrequencyDays(currDate time.Time, frequency string) (days int, err error) {
+	switch frequency {
+	case "周度", "周":
+		days = 7
+	case "旬度":
+		if currDate.Day() <= 20 { // 1旬和2旬都是10天
+			days = 10
+		} else {
+			// 下旬,多种可能,最大天数可能存在8天,9天,10天,11天,
+			currT := time.Date(currDate.Year(), currDate.Month(), 20, 0, 0, 0, 0, time.Local)
+			nextT := time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, time.Local).AddDate(0, 0, -1)
+			days = utils.GetTimeSubDay(currT, nextT)
+		}
+	case "月度":
+		//统计当月的天数
+		currMonthFd := time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, time.Local)
+		nextMonthFd := time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, time.Local)
+		days = utils.GetTimeSubDay(currMonthFd, nextMonthFd)
+	case "季度":
+		curr0T := time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, time.Local)
+		curr1T := time.Date(currDate.Year(), 3, 31, 0, 0, 0, 0, time.Local)
+		curr2T := time.Date(currDate.Year(), 6, 30, 0, 0, 0, 0, time.Local)
+		curr3T := time.Date(currDate.Year(), 9, 30, 0, 0, 0, 0, time.Local)
+		curr4T := time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, time.Local)
+
+		if currDate.Month() < 4 { // 1季度
+			days = utils.GetTimeSubDay(curr0T, curr1T)
+		} else if currDate.Month() < 7 { // 2季度
+			days = utils.GetTimeSubDay(curr1T, curr2T)
+		} else if currDate.Month() < 10 { // 3季度
+			days = utils.GetTimeSubDay(curr2T, curr3T)
+		} else {
+			// 4季度
+			days = utils.GetTimeSubDay(curr3T, curr4T)
+		}
+	case "年度":
+		//统计当前年份的天数,明年1月1日-今天年1月1日
+		currentYearFd := time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, time.Local)
+		nextYearFd := currentYearFd.AddDate(1, 0, 0)
+		days = utils.GetTimeSubDay(currentYearFd, nextYearFd)
+	case "半年度":
+		curr0T := time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, time.Local)
+		curr1T := time.Date(currDate.Year(), 6, 30, 0, 0, 0, 0, time.Local)
+		curr2T := time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, time.Local)
+
+		if currDate.Month() <= 6 { // 上半年
+			days = utils.GetTimeSubDay(curr0T, curr1T)
+		} else {
+			// 下半年
+			days = utils.GetTimeSubDay(curr1T, curr2T)
+		}
+	default:
+		days = 1
+		return
+	}
+	return
+}
+
+func rjzDiv(a float64, b int) string {
+	var valStr string
+	if b != 0 {
+		af := decimal.NewFromFloat(a)
+		bf := decimal.NewFromFloat(float64(b))
+		val, _ := af.Div(bf).Float64()
+		valStr = decimal.NewFromFloat(val).Round(4).String()
+	} else {
+		valStr = "0"
+	}
+	return valStr
+}

+ 4 - 0
models/edb_data_table.go

@@ -149,6 +149,10 @@ func GetEdbDataTableName(source int) (tableName string) {
 		tableName = "edb_data_calculate_zsxy" // 指数修匀->72
 	case utils.DATA_SOURCE_PREDICT_CALCULATE_ZSXY:
 		tableName = "edb_data_predict_calculate_zsxy" // 预测指数修匀->73
+	case utils.DATA_SOURCE_CALCULATE_ZDYFX:
+		tableName = "edb_data_calculate_zdyfx" // 自定义分析->74
+	case utils.DATA_SOURCE_CALCULATE_RJZ: //日均值75
+		tableName = "edb_data_calculate_rjz"
 	default:
 		tableName = ""
 	}

+ 38 - 10
models/edb_info.go

@@ -238,6 +238,14 @@ func ModifyEdbInfoMaxAndMinInfo(edbInfoId int, item *EdbInfoMaxAndMinInfo) (err
 	return
 }
 
+// ModifyEdbTimeAndLastInfo 修改指标的最新数据信息(除上下限)
+func ModifyEdbTimeAndLastInfo(edbInfoId int, item *EdbInfoMaxAndMinInfo) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE edb_info SET start_date = ?, end_date = ?, is_update = 2,latest_date = ?, latest_value = ?, modify_time = NOW() WHERE edb_info_id = ?`
+	_, err = o.Raw(sql, item.MinDate, item.MaxDate, item.MaxDate, item.LatestValue, edbInfoId).Exec()
+	return
+}
+
 // GetEdbDataCount 获取edb指标数据的数量; order:1升序,其余值为降序
 func GetEdbDataCount(condition string, pars []interface{}, source int) (count int, err error) {
 	o := orm.NewOrm()
@@ -373,10 +381,6 @@ func GetEdbInfoByCondition(condition string, pars []interface{}, order int) (ite
 
 // UnifiedModifyEdbInfoMaxAndMinInfo 统一修改指标的最大最小值
 func UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo *EdbInfo) (err error, errMsg string) {
-	// ETA1.0.3改-如果指标有手动保存过, 那么就不更新指标的最大最小值
-	if edbInfo.ManualSave == 1 {
-		return
-	}
 	// 修改最大最小值
 	maxAndMinItem, err := GetEdbInfoMaxAndMinInfo(edbInfo.Source, edbInfo.EdbCode)
 	if err != nil {
@@ -391,11 +395,21 @@ func UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo *EdbInfo) (err error, errMsg stri
 	}
 
 	if maxAndMinItem != nil {
-		err = ModifyEdbInfoMaxAndMinInfo(edbInfo.EdbInfoId, maxAndMinItem)
-		if err != nil {
-			errMsg = "刷新指标失败!"
-			err = errors.New("修改指标最大最小值失败,err:" + err.Error())
-			return
+		// ETA1.0.3改-如果指标有手动保存过, 那么就不更新指标的最大最小值
+		if edbInfo.ManualSave == 1 {
+			err = ModifyEdbTimeAndLastInfo(edbInfo.EdbInfoId, maxAndMinItem)
+			if err != nil {
+				errMsg = "刷新指标失败!"
+				err = errors.New("修改指标最新日期和数据失败,err:" + err.Error())
+				return
+			}
+		} else {
+			err = ModifyEdbInfoMaxAndMinInfo(edbInfo.EdbInfoId, maxAndMinItem)
+			if err != nil {
+				errMsg = "刷新指标失败!"
+				err = errors.New("修改指标最大最小值失败,err:" + err.Error())
+				return
+			}
 		}
 	}
 	// 修改关联的预测指标
@@ -1067,6 +1081,20 @@ func EdbInfoAdd(req *AddEdbInfoParams, serverUrl string, sysUserId int, sysUserR
 		edbType = 2 //计算指标
 	}
 
+	// 钢联化工需要校验下信息是否完整
+	if source == utils.DATA_SOURCE_MYSTEEL_CHEMICAL {
+		indexObj := new(BaseFromMysteelChemicalIndex)
+		tmpItem, tmpErr := indexObj.GetIndexItem(req.EdbCode)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		if tmpItem == nil || tmpItem.IndexName == `` {
+			err = errors.New("指标信息不全")
+			return
+		}
+	}
+
 	edbInfo.EdbCode = req.EdbCode
 	edbInfo.EdbName = req.EdbName
 	edbInfo.EdbNameSource = req.EdbName
@@ -1080,7 +1108,7 @@ func EdbInfoAdd(req *AddEdbInfoParams, serverUrl string, sysUserId int, sysUserR
 	edbInfo.ModifyTime = time.Now()
 	edbInfo.ServerUrl = serverUrl
 	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
-	edbInfo.UniqueCode = utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
+	edbInfo.UniqueCode = utils.MD5(utils.DATA_PREFIX + "_" + req.EdbCode + timestamp)
 	itemVal, err := GetEdbInfoMaxAndMinInfo(source, req.EdbCode)
 	if itemVal != nil && err == nil {
 		edbInfo.MaxValue = itemVal.MaxValue

+ 22 - 9
models/predict_edb.go

@@ -49,18 +49,22 @@ func RefreshCalculateByRuleBy9(rule CalculateRule) (resultDataList []*EdbInfoSea
 func CalculateByRuleBy9(to orm.TxOrmer, rule CalculateRule) (resultDataList []*EdbInfoSearchData, err error) {
 	realSaveDataMap := make(map[string]map[int]float64)
 	saveDataMap := make(map[string]map[int]float64)
-	dateList := make([]string, 0)
+
+	// 最小的结束日期 , 最晚的数据开始日期
+	var minLatestDate, maxStartDate time.Time
+	dateList := make([]string, 0) // 第一个指标的日期数据
 
 	formulaStr := strings.ToUpper(rule.Formula)
 	// 获取关联指标数据
-	for edbInfoIndex, v := range rule.EdbInfoList {
+	for _, v := range rule.EdbInfoList {
 		dataList, tmpErr := GetPredictEdbDataListAll(v, 1)
 		if tmpErr != nil {
 			err = tmpErr
 			return
 		}
-		dataMap := make(map[string]float64)
-		for _, dv := range dataList {
+
+		lenData := len(dataList)
+		for edbInfoIndex, dv := range dataList {
 			// 现有实际数据
 			if val, ok := realSaveDataMap[dv.DataTime]; ok {
 				if _, ok := val[v.EdbInfoId]; !ok {
@@ -88,13 +92,22 @@ func CalculateByRuleBy9(to orm.TxOrmer, rule CalculateRule) (resultDataList []*E
 				dateList = append(dateList, dv.DataTime)
 			}
 		}
-		item := new(CalculateItems)
-		item.EdbInfoId = v.EdbInfoId
-		item.DataMap = dataMap
+
+		if lenData > 0 {
+			tmpLatestDate, _ := time.ParseInLocation(utils.FormatDate, dataList[lenData-1].DataTime, time.Local)
+			if minLatestDate.IsZero() || minLatestDate.After(tmpLatestDate) {
+				minLatestDate = tmpLatestDate
+			}
+
+			tmpStartDate, _ := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
+			if maxStartDate.IsZero() || maxStartDate.Before(tmpStartDate) {
+				maxStartDate = tmpStartDate
+			}
+		}
 	}
 
-	//数据处理,将日期内不全的数据做补全
-	handleDateSaveDataMap(dateList, realSaveDataMap, saveDataMap, rule.EdbInfoList)
+	//数据处理,将日期内不全的数据做
+	handleDateSaveDataMap(dateList, maxStartDate, minLatestDate, realSaveDataMap, saveDataMap, rule.EdbInfoList)
 
 	// 添加数据
 	addDataList := make([]*PredictEdbRuleData, 0)

+ 45 - 0
routers/commentsRouter.go

@@ -286,6 +286,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_index_lib/controllers:ExchangeCrawler"] = append(beego.GlobalControllerRouter["eta/eta_index_lib/controllers:ExchangeCrawler"],
+        beego.ControllerComments{
+            Method: "RefreshIne",
+            Router: `/refresh/ine`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_index_lib/controllers:ExchangeCrawler"] = append(beego.GlobalControllerRouter["eta/eta_index_lib/controllers:ExchangeCrawler"],
+        beego.ControllerComments{
+            Method: "RefreshSH",
+            Router: `/refresh/sh`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_index_lib/controllers:FuBaoController"] = append(beego.GlobalControllerRouter["eta/eta_index_lib/controllers:FuBaoController"],
         beego.ControllerComments{
             Method: "Add",
@@ -799,6 +817,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_index_lib/controllers:SmmController"] = append(beego.GlobalControllerRouter["eta/eta_index_lib/controllers:SmmController"],
+        beego.ControllerComments{
+            Method: "AddIndexToDataSource",
+            Router: `/add/index/to_data_source`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_index_lib/controllers:SmmController"] = append(beego.GlobalControllerRouter["eta/eta_index_lib/controllers:SmmController"],
         beego.ControllerComments{
             Method: "HandleExcelData",
@@ -808,6 +835,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_index_lib/controllers:SmmController"] = append(beego.GlobalControllerRouter["eta/eta_index_lib/controllers:SmmController"],
+        beego.ControllerComments{
+            Method: "GetIndexDetailFromDataSourceByCode",
+            Router: `/index_detail/from_data_source`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_index_lib/controllers:SmmController"] = append(beego.GlobalControllerRouter["eta/eta_index_lib/controllers:SmmController"],
         beego.ControllerComments{
             Method: "Refresh",
@@ -817,6 +853,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_index_lib/controllers:SmmController"] = append(beego.GlobalControllerRouter["eta/eta_index_lib/controllers:SmmController"],
+        beego.ControllerComments{
+            Method: "SmmGetOrAdd",
+            Router: `/smm_classify/get_or_add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_index_lib/controllers:StockPlantController"] = append(beego.GlobalControllerRouter["eta/eta_index_lib/controllers:StockPlantController"],
         beego.ControllerComments{
             Method: "Calculate",

+ 5 - 0
routers/router.go

@@ -186,6 +186,11 @@ func init() {
 				&controllers.EdbInfoCalculateController{},
 			),
 		),
+		beego.NSNamespace("/exchange_crawler",
+			beego.NSInclude(
+				&controllers.ExchangeCrawler{},
+			),
+		),
 	)
 	beego.AddNamespace(ns)
 }

+ 20 - 1
services/base_from_smm.go

@@ -1,6 +1,7 @@
 package services
 
 import (
+	"errors"
 	"eta/eta_index_lib/logic"
 	"eta/eta_index_lib/models"
 	"eta/eta_index_lib/services/alarm_msg"
@@ -10,7 +11,7 @@ import (
 	"time"
 )
 
-func SmmIndexHandle(baseFilePath, renameFilePath, indexName, indexCode, unit, frequency string, excelDataMap map[string]string) {
+func SmmIndexHandle(baseFilePath, renameFilePath, indexName, indexCode, unit, frequency, source string, excelDataMap map[string]string) {
 	var err error
 
 	errMsgList := make([]string, 0)
@@ -63,6 +64,7 @@ func SmmIndexHandle(baseFilePath, renameFilePath, indexName, indexCode, unit, fr
 		indexObj.IndexName = indexName
 		indexObj.Unit = unit
 		indexObj.Frequency = frequency
+		indexObj.Interface = source
 		indexObj.ModifyTime = time.Now()
 		indexObj.CreateTime = time.Now()
 		indexObj.BaseFileName = baseFilePath
@@ -87,6 +89,23 @@ func SmmIndexHandle(baseFilePath, renameFilePath, indexName, indexCode, unit, fr
 			exitDataMap[v.DataTime] = v
 		}
 		indexId = item.BaseFromSmmIndexId
+		//修改指标信息
+		updateParams := make(map[string]interface{})
+		updateParams["index_name"] = indexName
+		updateParams["frequency"] = frequency
+		updateParams["unit"] = unit
+		updateParams["interface"] = source
+		updateParams["modify_time"] = time.Now()
+
+		whereParam := make(map[string]interface{})
+		whereParam["index_code"] = indexCode
+
+		smmIndexObj := new(models.BaseFromSmmIndex)
+		err = smmIndexObj.Update(updateParams, whereParam)
+		if err != nil {
+			err = errors.New("smm index update err:" + err.Error())
+			return
+		}
 	}
 
 	// 遍历excel数据,然后跟现有的数据做校验,不存在则入库

+ 4 - 3
services/base_from_ths.go

@@ -29,11 +29,12 @@ func GetEdbDataFromThs(edbCode, startDate, endDate string) (item models.EdbDataF
 	//if utils.BusinessCode == utils.HZ_TRIAL_BUSSINESS_CODE { // 体验版也走客户端
 	//	return getEdbDataFromThsApp(edbCode, startDate, endDate, 0)
 	//}
-	if utils.RunMode == `release` { // 生产环境走官方http请求,测试环境走终端
+	// 如果没有配置,获取配置的方式是api,那么就走官方接口
+	if utils.ThsDataMethod == "" || utils.ThsDataMethod == "api" {
 		return getEdbDataFromThsHttp(edbCode, startDate, endDate)
-	} else {
-		return getEdbDataFromThsApp(edbCode, startDate, endDate, 0)
 	}
+
+	return getEdbDataFromThsApp(edbCode, startDate, endDate, 0)
 }
 
 // getEdbDataFromThs 获取同花顺接口数据

+ 10 - 2
services/base_from_ths_http.go

@@ -186,8 +186,12 @@ func postCurl(urlStr string, dataMap map[string]interface{}, num int) (body []by
 	req.Header.Add("Content-Type", "application/json")
 	req.Header.Add("access_token", token)
 
-	res, _ := netHttp.DefaultClient.Do(req)
+	res, err := netHttp.DefaultClient.Do(req)
+	if err != nil {
+		return
+	}
 	defer res.Body.Close()
+
 	//解析resp并且存入关联表
 	body, err = io.ReadAll(res.Body)
 	if err != nil {
@@ -301,8 +305,12 @@ func getAccessToken() (tokenData TokenData, err error) {
 	req.Header.Add("Content-Type", "application/json")
 	req.Header.Add("refresh_token", utils.ThsRefreshToken)
 
-	res, _ := netHttp.DefaultClient.Do(req)
+	res, err := netHttp.DefaultClient.Do(req)
+	if err != nil {
+		return
+	}
 	defer res.Body.Close()
+
 	body, err := io.ReadAll(res.Body)
 	if err != nil {
 		err = errors.New("NewRequest Err:" + err.Error())

+ 0 - 70
utils/common.go

@@ -7,7 +7,6 @@ import (
 	"encoding/base64"
 	"encoding/hex"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"github.com/shopspring/decimal"
 	"image"
@@ -849,75 +848,6 @@ func GetNowYearLastDay() time.Time {
 }
 
 // CalculationDate 计算两个日期之间相差n年m月y天
-func CalculationDate(startDate, endDate time.Time) (beetweenDay string, err error) {
-	//startDate := time.Date(2021, 3, 28, 0, 0, 0, 0, time.Now().Location())
-	//endDate := time.Date(2022, 3, 31, 0, 0, 0, 0, time.Now().Location())
-	numYear := endDate.Year() - startDate.Year()
-
-	numMonth := int(endDate.Month()) - int(startDate.Month())
-
-	numDay := 0
-	//获取截止月的总天数
-	endDateDays := getMonthDay(endDate.Year(), int(endDate.Month()))
-
-	//获取截止月的前一个月
-	endDatePrevMonthDate := endDate.AddDate(0, -1, 0)
-	//获取截止日期的上一个月的总天数
-	endDatePrevMonthDays := getMonthDay(endDatePrevMonthDate.Year(), int(endDatePrevMonthDate.Month()))
-	//获取开始日期的的月份总天数
-	startDateMonthDays := getMonthDay(startDate.Year(), int(startDate.Month()))
-
-	//判断,截止月是否完全被选中,如果相等,那么代表截止月份全部天数被选择
-	if endDate.Day() == endDateDays {
-		numDay = startDateMonthDays - startDate.Day() + 1
-
-		//如果剩余天数正好与开始日期的天数是一致的,那么月份加1
-		if numDay == startDateMonthDays {
-			numMonth++
-			numDay = 0
-			//超过月份了,那么年份加1
-			if numMonth == 12 {
-				numYear++
-				numMonth = 0
-			}
-		}
-	} else {
-		numDay = endDate.Day() - startDate.Day() + 1
-	}
-
-	//天数小于0,那么向月份借一位
-	if numDay < 0 {
-		//向上一个月借一个月的天数
-		numDay += endDatePrevMonthDays
-
-		//总月份减去一个月
-		numMonth = numMonth - 1
-	}
-
-	//月份小于0,那么向年份借一位
-	if numMonth < 0 {
-		//向上一个年借12个月
-		numMonth += 12
-
-		//总年份减去一年
-		numYear = numYear - 1
-	}
-	if numYear < 0 {
-		err = errors.New("日期异常")
-		return
-	}
-
-	if numYear > 0 {
-		beetweenDay += fmt.Sprint(numYear, "年")
-	}
-	if numMonth > 0 {
-		beetweenDay += fmt.Sprint(numMonth, "个月")
-	}
-	if numDay > 0 {
-		beetweenDay += fmt.Sprint(numDay, "天")
-	}
-	return
-}
 
 // FormatPrice 格式化展示金额数字(财务金额展示,小数点前,每三位用,隔开)    1,234,567,898.55
 func FormatPrice(price float64) (str string) {

+ 6 - 0
utils/config.go

@@ -61,6 +61,7 @@ var (
 	EDB_DATA_LIMIT        = 10
 	Hz_Wind_Data_Url_LIST []WindUrlMap // wind接口服务地址配置(客户本地机器,是个list列表)
 
+	ThsDataMethod   string //同花顺数据获取的方式,app是通过终端;api是通过接口
 	ThsRefreshToken string // 同花顺的刷新token
 )
 
@@ -190,6 +191,11 @@ func init() {
 		}
 
 		ThsRefreshToken = config["ths_refresh_token"] //同花顺的刷新token
+		ThsDataMethod = config["ths_data_method"]     // 同花顺数据获取的方式
+		// 默认走api接口
+		if ThsDataMethod == `` {
+			ThsDataMethod = "api"
+		}
 	}
 
 	// ES配置

+ 2 - 0
utils/constants.go

@@ -95,6 +95,8 @@ const (
 	DATA_SOURCE_FUBAO                                           //富宝数据->71
 	DATA_SOURCE_CALCULATE_ZSXY                                  // 指数修匀->72
 	DATA_SOURCE_PREDICT_CALCULATE_ZSXY                          // 预测指数修匀->73
+	DATA_SOURCE_CALCULATE_ZDYFX                                 // 自定义分析->74
+	DATA_SOURCE_CALCULATE_RJZ                                   // 日均值计算->75
 )
 
 // 指标来源的中文展示