package controllers

import (
	"encoding/json"
	"eta_gn/eta_index_lib/logic"
	"eta_gn/eta_index_lib/models"
	"eta_gn/eta_index_lib/models/mgo"
	"eta_gn/eta_index_lib/services"
	"eta_gn/eta_index_lib/utils"
	"fmt"
	"strconv"
	"strings"
	"time"
)

// ThsHfController 同花顺高频数据
type ThsHfController struct {
	BaseAuthController
}

// GetData
// @Title 同花顺高频数据-获取数据
// @Description 同花顺高频数据-获取数据
// @Success 200 {object} models.ThsHfSearchEdbReq
// @router /hf/edb_data [post]
func (this *ThsHfController) GetData() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var params models.ThsHfSearchEdbReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &params); e != nil {
		br.Msg = "参数解析异常"
		br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
		return
	}
	params.StockCode = strings.TrimSpace(params.StockCode)
	if params.StockCode == "" {
		br.Msg = "请输入证券代码"
		return
	}
	stockCodes := strings.Split(params.StockCode, ",")
	if len(stockCodes) == 0 {
		br.Msg = "请输入证券代码"
		return
	}
	if len(stockCodes) > 10 {
		br.Msg = "最多输入10个证券代码"
		return
	}
	params.EdbCode = strings.TrimSpace(params.EdbCode)
	if params.EdbCode == "" {
		br.Msg = "请输入指标代码"
		return
	}
	edbCodes := strings.Split(params.EdbCode, ",")
	if len(edbCodes) == 0 {
		br.Msg = "请输入指标代码"
		return
	}
	if len(edbCodes) > 20 {
		br.Msg = "最多选择/输入20个指标代码"
		return
	}
	if params.StartTime == "" {
		br.Msg = "请选择起始时间"
		return
	}
	_, e := time.ParseInLocation(utils.FormatDateTime, params.StartTime, time.Local)
	if e != nil {
		br.Msg = "起始时间格式有误"
		br.ErrMsg = fmt.Sprintf("起始时间格式有误, %v", e)
		return
	}
	// 结束时间选填, 不填则为当前时间
	if params.EndTime != "" {
		_, e := time.ParseInLocation(utils.FormatDateTime, params.EndTime, time.Local)
		if e != nil {
			br.Msg = "截止时间格式有误"
			br.ErrMsg = fmt.Sprintf("截止时间格式有误, %v", e)
			return
		}
	}
	if params.EndTime == "" {
		params.EndTime = time.Now().Local().Format(utils.FormatDateTime)
	}
	if !utils.InArrayByInt(models.ThsHfPeriodArr, params.Interval) {
		br.Msg = "时间周期有误"
		br.ErrMsg = fmt.Sprintf("时间周期有误, Interval: %d", params.Interval)
		return
	}
	if params.CPS != "" && !utils.InArrayByStr(models.ThsHfCPSArr, params.CPS) {
		br.Msg = "复权方式有误"
		br.ErrMsg = fmt.Sprintf("复权方式有误, CPS: %s", params.CPS)
		return
	}
	if params.BaseDate != "" {
		_, e = time.ParseInLocation(utils.FormatDate, params.BaseDate, time.Local)
		if e != nil {
			br.Msg = "复权基点格式有误"
			br.ErrMsg = fmt.Sprintf("复权基点格式有误, %v", e)
			return
		}
	}
	if params.Fill != "" && !utils.InArrayByStr(models.ThsHfFillArr, params.Fill) {
		br.Msg = "非交易间隔处理有误"
		br.ErrMsg = fmt.Sprintf("非交易间隔处理有误, Fill: %s", params.Fill)
		return
	}

	// 根据配置获取指标数据
	indexes, e := services.GetEdbDataFromThsHf(params, "")
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = fmt.Sprintf("获取同花顺高频指标失败, %v", e)
		return
	}

	br.Data = indexes
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// BaseAdd
// @Title 同花顺高频数据-新增至数据源
// @Description 同花顺高频数据-新增至数据源
// @Success 200 {object} models.ThsHfBaseAddReq
// @router /hf/base/add [post]
func (this *ThsHfController) BaseAdd() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var params models.ThsHfBaseAddReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &params); e != nil {
		br.Msg = "参数解析异常"
		br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
		return
	}
	params.StockCode = strings.TrimSpace(params.StockCode)
	if params.StockCode == "" {
		br.Msg = "请输入证券代码"
		return
	}
	params.EdbCode = strings.TrimSpace(params.EdbCode)
	if params.EdbCode == "" {
		br.Msg = "请输入指标代码"
		return
	}
	if params.StartTime == "" {
		br.Msg = "请选择起始时间"
		return
	}
	startTime, e := time.ParseInLocation(utils.FormatDateTime, params.StartTime, time.Local)
	if e != nil {
		br.Msg = "起始时间格式有误"
		br.ErrMsg = fmt.Sprintf("起始时间格式有误, %v", e)
		return
	}
	var endTime time.Time
	if params.EndTime != "" {
		ed, e := time.ParseInLocation(utils.FormatDateTime, params.EndTime, time.Local)
		if e != nil {
			br.Msg = "截止时间格式有误"
			br.ErrMsg = fmt.Sprintf("截止时间格式有误, %v", e)
			return
		}
		endTime = ed
	}
	if !utils.InArrayByInt(models.ThsHfPeriodArr, params.Interval) {
		br.Msg = "时间周期有误"
		br.ErrMsg = fmt.Sprintf("时间周期有误, Interval: %d", params.Interval)
		return
	}
	if params.CPS != "" && !utils.InArrayByStr(models.ThsHfCPSArr, params.CPS) {
		br.Msg = "复权方式有误"
		br.ErrMsg = fmt.Sprintf("复权方式有误, CPS: %s", params.CPS)
		return
	}
	if params.BaseDate != "" {
		_, e = time.ParseInLocation(utils.FormatDate, params.BaseDate, time.Local)
		if e != nil {
			br.Msg = "复权基点格式有误"
			br.ErrMsg = fmt.Sprintf("复权基点格式有误, %v", e)
			return
		}
	}
	if params.Fill != "" && !utils.InArrayByStr(models.ThsHfFillArr, params.Fill) {
		br.Msg = "非交易间隔处理有误"
		br.ErrMsg = fmt.Sprintf("非交易间隔处理有误, Fill: %s", params.Fill)
		return
	}
	if params.ClassifyId <= 0 {
		br.Msg = "请选择分类"
		return
	}
	params.IndexName = strings.TrimSpace(params.IndexName)
	if params.IndexName == "" {
		br.Msg = "请输入指标名称"
		return
	}
	if params.Frequency == "" {
		br.Msg = "请输入频度"
		return
	}

	// 缓存
	source := utils.DATA_SOURCE_THS
	subSource := utils.DATA_SUB_SOURCE_HIGH_FREQUENCY
	cacheKey := fmt.Sprintf("%s_%d_%d_%s_%s", utils.CACHE_BASE_EDB_ADD, source, subSource, params.StockCode, params.EdbCode)
	defer func() {
		_ = utils.Rc.Delete(cacheKey)
	}()
	if utils.Rc.IsExist(cacheKey) {
		br.Ret = 501
		br.Success = true
		br.Msg = "系统处理中,请稍后重试"
		return
	}
	utils.Rc.SetNX(cacheKey, 1, 3*time.Minute)

	// 已添加则忽略
	indexOb := new(models.BaseFromThsHfIndex)
	{
		cond := fmt.Sprintf(" AND %s = ? AND %s = ?", indexOb.Cols().StockCode, indexOb.Cols().Indicator)
		pars := make([]interface{}, 0)
		pars = append(pars, params.StockCode, params.EdbCode)
		item, e := indexOb.GetItemByCondition(cond, pars, "")
		if e != nil && e.Error() != utils.ErrNoRow() {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("获取原始指标失败, %v", e)
			return
		}
		if item != nil {
			br.Ret = 200
			br.Success = true
			br.Msg = "操作成功"
			return
		}
	}

	// 获取指标数据
	var apiPars models.ThsHfSearchEdbReq
	apiPars.StockCode = params.StockCode
	apiPars.EdbCode = params.EdbCode
	apiPars.StartTime = params.StartTime
	apiPars.EndTime = params.EndTime
	apiPars.Interval = params.Interval
	apiPars.Fill = params.Fill
	apiPars.CPS = params.CPS
	apiPars.BaseDate = params.BaseDate
	indexes, e := services.GetEdbDataFromThsHf(apiPars, "")
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("获取同花顺高频指标失败, %v", e)
		return
	}
	if len(indexes) == 0 {
		br.Msg = "未搜索到指标"
		br.ErrMsg = "未搜索到指标"
		return
	}
	indexWithData := indexes[0]

	indexItem := new(models.BaseFromThsHfIndex)
	indexItem.BaseFromThsHfClassifyId = params.ClassifyId
	indexItem.IndexCode = fmt.Sprintf("%s%s%s%s", utils.ThsHf, params.StockCode, params.EdbCode, params.Frequency)
	indexItem.IndexName = params.IndexName
	indexItem.Unit = params.Unit
	indexItem.Frequency = params.Frequency
	indexItem.StartDate = startTime
	indexItem.EndDate = endTime
	indexItem.SysUserId = params.SysAdminId
	indexItem.SysUserRealName = params.SysAdminName
	terminal, e := services.GetFirstTerminal(utils.DATA_SOURCE_THS, "")
	if e != nil {
		br.Msg = "终端未配置"
		br.ErrMsg = fmt.Sprintf("终端未配置, %v", e)
		return
	}
	indexItem.TerminalCode = terminal.TerminalCode
	indexItem.StockCode = params.StockCode
	indexItem.Indicator = params.EdbCode
	b, e := json.Marshal(apiPars)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("API入参JSON格式化失败, %v", e)
		return
	}
	indexItem.ApiPars = string(b)
	if len(indexWithData.IndexData) > 0 {
		indexItem.StartDate = indexWithData.IndexData[0].DataTime
		indexItem.EndDate = indexWithData.IndexData[len(indexWithData.IndexData)-1].DataTime
		lastVal, e := utils.FormatFloatPlaces(indexWithData.IndexData[0].Value, 4)
		if e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("格式化最新值失败, val: %v, err: %v", indexWithData.IndexData[0].Value, e)
			return
		}
		indexItem.LatestValue = lastVal
	}
	indexItem.CreateTime = time.Now().Local()
	indexItem.ModifyTime = time.Now().Local()

	// 新增指标
	if e := indexItem.Create(); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("新增指标失败, %v", e)
		return
	}

	// 新增数据
	if utils.UseMongo {
		dataList := make([]interface{}, 0)
		for _, v := range indexWithData.IndexData {
			newVal, e := utils.FormatFloatPlaces(v.Value, 4)
			if e != nil {
				utils.FileLog.Info(fmt.Sprintf("FormatFloatPlaces err: %v", e))
				continue
			}

			dataList = append(dataList, &mgo.BaseFromThsHfData{
				BaseFromThsHfIndexId: int64(indexItem.BaseFromThsHfIndexId),
				IndexCode:            indexItem.IndexCode,
				DataTime:             v.DataTime,
				Value:                newVal,
				UniqueCode:           utils.MD5(fmt.Sprint(indexItem.IndexCode, v.DataTime.Format(utils.FormatDateTimeMinute))),
				CreateTime:           time.Now().Local(),
				ModifyTime:           time.Now().Local(),
				DataTimestamp:        v.DataTime.UnixNano() / 1e6,
			})
		}
		dataOb := new(mgo.BaseFromThsHfData)
		if e = dataOb.BatchInsertData(500, dataList); e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("批量新增数据失败-Mongo, %v", e)
			return
		}
	} else {
		dataOb := new(models.BaseFromThsHfData)
		itemData := make([]*models.BaseFromThsHfData, 0)
		for _, v := range indexWithData.IndexData {
			newVal, e := utils.FormatFloatPlaces(v.Value, 4)
			if e != nil {
				utils.FileLog.Info(fmt.Sprintf("FormatFloatPlaces err: %v", e))
				continue
			}

			t := new(models.BaseFromThsHfData)
			t.BaseFromThsHfIndexId = indexItem.BaseFromThsHfIndexId
			t.IndexCode = indexItem.IndexCode
			t.DataTime = v.DataTime
			t.Value = newVal
			t.UniqueCode = utils.MD5(fmt.Sprint(indexItem.IndexCode, v.DataTime.Format(utils.FormatDateTimeMinute)))
			t.CreateTime = time.Now().Local()
			t.ModifyTime = time.Now().Local()
			t.DataTimestamp = v.DataTime.UnixNano() / 1e6
			itemData = append(itemData, t)
		}
		if e = dataOb.CreateMulti(itemData); e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("批量新增数据失败-MySQL, %v", e)
			return
		}
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// BaseRefresh
// @Title 同花顺高频数据-数据源刷新
// @Description 同花顺高频数据-数据源刷新
// @Success 200 {object} models.ThsHfBaseRefreshReq
// @router /hf/base/refresh [post]
func (this *ThsHfController) BaseRefresh() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var params models.ThsHfBaseRefreshReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &params); e != nil {
		br.Msg = "参数解析异常"
		br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
		return
	}
	params.BaseIndexCode = strings.TrimSpace(params.BaseIndexCode)
	if params.BaseIndexCode == "" {
		br.Msg = "参数异常"
		br.ErrMsg = fmt.Sprintf("参数异常, BaseIndexCode: %s", params.BaseIndexCode)
		return
	}
	if params.RefreshType <= 0 {
		params.RefreshType = 1
	}

	indexItem := new(models.BaseFromThsHfIndex)
	{
		ob := new(models.BaseFromThsHfIndex)
		cond := fmt.Sprintf(" AND %s = ?", ob.Cols().IndexCode)
		pars := make([]interface{}, 0)
		pars = append(pars, params.BaseIndexCode)
		item, e := ob.GetItemByCondition(cond, pars, "")
		if e != nil {
			if e.Error() == utils.ErrNoRow() {
				br.Msg = "指标不存在"
				return
			}
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("获取源指标失败, %v", e)
			return
		}
		indexItem = item
	}

	source := utils.DATA_SOURCE_THS
	subSource := utils.DATA_SUB_SOURCE_HIGH_FREQUENCY
	cacheKey := fmt.Sprintf("%s_%d_%d_%s_%s", utils.CACHE_BASE_EDB_REFRESH, source, subSource, indexItem.StockCode, indexItem.Indicator)
	defer func() {
		_ = utils.Rc.Delete(cacheKey)
	}()
	if utils.Rc.IsExist(cacheKey) {
		br.Ret = 501
		br.Success = true
		br.Msg = "系统处理中,请稍后重试"
		return
	}
	utils.Rc.SetNX(cacheKey, 1, 3*time.Minute)

	// API参数
	var apiPars models.ThsHfSearchEdbReq
	if e := json.Unmarshal([]byte(indexItem.ApiPars), &apiPars); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("源指标API参数异常, %v", e)
		return
	}
	// 刷新6小时: 指标开始时间前推6小时; 全部: API参数中的开始时间
	if params.RefreshType == 1 {
		apiPars.StartTime = indexItem.StartDate.Add(-6 * time.Hour).Format(utils.FormatDateTime)
	}
	// 若API参数中的结束时间不为空, 且不在EndDate之后, 那么不再刷新该指标
	if apiPars.EndTime != "" {
		apiEnd, e := time.ParseInLocation(utils.FormatDateTime, apiPars.EndTime, time.Local)
		if e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("API参数结束时间有误, %v", e)
			return
		}
		if !apiEnd.After(indexItem.EndDate) {
			br.Ret = 200
			br.Success = true
			br.Msg = "该指标无需刷新"
			return
		}
	}

	// API-获取指标数据
	indexes, e := services.GetEdbDataFromThsHf(apiPars, indexItem.TerminalCode)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("获取同花顺高频指标失败, %v", e)
		return
	}
	if len(indexes) == 0 {
		br.Msg = "未搜索到指标"
		br.ErrMsg = fmt.Sprintf("未搜索到指标, StockCode: %s, Indicator: %s", indexItem.StockCode, indexItem.Indicator)
		return
	}
	indexWithData := indexes[0]

	// 写入指标数据
	if utils.UseMongo {
		if e = services.RefreshThsHfBaseIndexMgo(indexItem, indexWithData, apiPars.StartTime); e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("写入源指标数据失败-Mongo, %v", e)
			return
		}
	} else {
		if e = services.RefreshThsHfBaseIndex(indexItem, indexWithData, apiPars.StartTime); e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("写入源指标数据失败, %v", e)
			return
		}
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// EdbAdd
// @Title 同花顺高频数据-新增至指标库
// @Description 同花顺高频数据-新增至指标库
// @Success 200 {object} models.ThsHfEdbAddReq
// @router /hf/edb/add [post]
func (this *ThsHfController) EdbAdd() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var params models.ThsHfEdbAddReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &params); e != nil {
		br.Msg = "参数解析异常"
		br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
		return
	}
	if params.NewIndex == nil {
		br.Msg = "参数有误"
		br.ErrMsg = "参数有误, 指标信息有误"
		return
	}
	params.NewIndex.NewIndexName = strings.TrimSpace(params.NewIndex.NewIndexName)
	if params.NewIndex.NewIndexName == "" {
		br.Msg = "请输入指标名称"
		return
	}
	if params.NewIndex.ClassifyId <= 0 {
		br.Msg = "请选择分类"
		return
	}
	if params.NewIndex.Unit == "" {
		params.NewIndex.Unit = "无"
	}
	if params.NewIndex.NewFrequency == "" {
		br.Msg = "请输入频度"
		return
	}

	// 校验转换规则
	convertRule := params.ConvertRule
	if convertRule.ConvertType != 1 && convertRule.ConvertType != 2 {
		br.Msg = "请选择数据转换方式"
		return
	}
	if convertRule.ConvertType == 1 {
		if convertRule.ConvertFixed.FixedDay != 1 && convertRule.ConvertFixed.FixedDay != 2 {
			br.Msg = "请选择指定时间"
			return
		}
		if convertRule.ConvertFixed.FixedTime == "" {
			br.Msg = "请选择指定时间"
			return
		}
		timePrefix := time.Now().Local().Format(utils.FormatDate)
		st := fmt.Sprintf("%s %s", timePrefix, convertRule.ConvertFixed.FixedTime)
		_, e := time.Parse(utils.FormatDateTime, st)
		if e != nil {
			br.Msg = "指定时间格式有误"
			return
		}
	}
	if convertRule.ConvertType == 2 {
		if convertRule.ConvertArea.StartDay != 1 && convertRule.ConvertArea.StartDay != 2 {
			br.Msg = "请选择起始时间"
			return
		}
		if convertRule.ConvertArea.StartTime == "" {
			br.Msg = "请选择起始时间"
			return
		}
		var startTimePre string
		if convertRule.ConvertArea.StartDay == 1 {
			startTimePre = time.Now().Local().Format(utils.FormatDate)
		}
		if convertRule.ConvertArea.StartDay == 2 {
			startTimePre = time.Now().Local().AddDate(0, 0, -1).Format(utils.FormatDate)
		}
		st := fmt.Sprintf("%s %s", startTimePre, convertRule.ConvertArea.StartTime)
		startTime, e := time.Parse(utils.FormatDateTime, st)
		if e != nil {
			br.Msg = "起始时间格式有误"
			return
		}

		if convertRule.ConvertArea.EndDay != 1 && convertRule.ConvertArea.EndDay != 2 {
			br.Msg = "请选择截止时间"
			return
		}
		if convertRule.ConvertArea.EndTime == "" {
			br.Msg = "请选择截止时间"
			return
		}
		var endTimePre string
		if convertRule.ConvertArea.EndDay == 1 {
			endTimePre = time.Now().Local().Format(utils.FormatDate)
		}
		if convertRule.ConvertArea.EndDay == 2 {
			endTimePre = time.Now().Local().AddDate(0, 0, -1).Format(utils.FormatDate)
		}
		ed := fmt.Sprintf("%s %s", endTimePre, convertRule.ConvertArea.EndTime)
		endTime, e := time.Parse(utils.FormatDateTime, ed)
		if e != nil {
			br.Msg = "截止时间格式有误"
			return
		}
		if startTime.After(endTime) {
			br.Msg = "起始日期不可早于截止日期"
			return
		}
	}
	convertRuleByte, e := json.Marshal(params.ConvertRule)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("转换规则JSON格式化失败, %v", e)
		return
	}

	// 缓存
	source := utils.DATA_SOURCE_THS
	subSource := utils.DATA_SUB_SOURCE_HIGH_FREQUENCY
	cacheKey := fmt.Sprintf("%s_%d_%d_%s_%s_%s", utils.CACHE_EDB_DATA_ADD, source, subSource, params.NewIndex.StockCode, params.NewIndex.EdbCode, params.NewIndex.NewFrequency)
	defer func() {
		_ = utils.Rc.Delete(cacheKey)
	}()
	if utils.Rc.IsExist(cacheKey) {
		br.Ret = 501
		br.Success = true
		br.Msg = "系统处理中,请稍后重试"
		return
	}
	utils.Rc.SetNX(cacheKey, 1, 3*time.Minute)

	// 校验指标/分类
	baseIndexOb := new(models.BaseFromThsHfIndex)
	baseIndex, e := baseIndexOb.GetItemById(params.NewIndex.IndexId)
	if e != nil {
		br.Msg = "原指标不存在"
		br.ErrMsg = fmt.Sprintf("原指标不存在, %v", e)
		return
	}
	_, e = models.GetEdbClassifyById(params.NewIndex.ClassifyId)
	if e != nil {
		br.Msg = "分类信息有误"
		br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
		return
	}

	// 判断指标名称是否已存在
	{
		var cond string
		var pars []interface{}
		if this.Lang == utils.EnLangVersion {
			cond += " AND edb_name_en = ? "
		} else {
			cond += " AND edb_name = ?"
		}
		pars = append(pars, params.NewIndex.NewIndexName)
		count, e := models.GetEdbInfoCountByCondition(cond, pars)
		if e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("获取重名指标失败, %v", e)
			return
		}
		if count > 0 {
			br.Msg = "指标名称已存在"
			return
		}
	}

	// 排序/指标编码
	sortMax, e := models.GetEdbClassifyMaxSort(params.NewIndex.ClassifyId, 0)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("获取最大排序失败, %v", e)
		return
	}
	edbCode, e := utils.GenerateEdbCode(1, "")
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("生成指标编码失败, %v", e)
		return
	}
	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)

	thsOb := new(models.EdbThsHf)
	var addPars models.ThsHfAddBaseParams
	addPars.EdbCode = edbCode
	addPars.EdbName = params.NewIndex.NewIndexName
	addPars.Unit = params.NewIndex.Unit
	addPars.Frequency = params.NewIndex.NewFrequency
	addPars.Sort = sortMax + 1
	addPars.ClassifyId = params.NewIndex.ClassifyId
	addPars.SysUserId = params.NewIndex.SysAdminId
	addPars.SysUserRealName = params.NewIndex.SysAdminName
	addPars.UniqueCode = uniqueCode
	addPars.ConvertRule = string(convertRuleByte)
	edbInfo, e := thsOb.Add(addPars, baseIndex)
	if e != nil {
		br.Msg = "新增失败"
		br.ErrMsg = fmt.Sprintf("新增指标失败, %v", e)
		return
	}

	// 更新指标最值
	if e = thsOb.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo); e != nil {
		br.Msg = "刷新指标失败"
		br.ErrMsg = fmt.Sprintf("更新指标最值失败, %v", e)
		return
	}

	// 添加到es
	go logic.UpdateEs(edbInfo.EdbInfoId)

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// EdbRefresh
// @Title 同花顺高频数据-指标库刷新
// @Description 同花顺高频数据-指标库刷新
// @Success 200 {object} models.RefreshEdbInfoReq
// @router /hf/edb/refresh [post]
func (this *ThsHfController) EdbRefresh() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req models.RefreshEdbInfoReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.EdbCode == "" {
		br.Msg = "请输入指标编码!"
		br.ErrMsg = "请输入指标编码,指标编码为空"
		return
	}
	if req.EdbInfoId < 0 {
		br.Msg = "请输入指标ID!"
		br.ErrMsg = "请输入指标ID"
		return
	}
	thsOb := new(models.EdbThsHf)
	source := thsOb.GetSource()
	subSource := thsOb.GetSubSource()
	cacheKey := fmt.Sprintf("%s_%d_%d_%s", utils.CACHE_EDB_DATA_REFRESH, source, subSource, req.EdbCode)
	if utils.Rc.IsExist(cacheKey) {
		br.Ret = 501
		br.Success = true
		br.Msg = "系统处理中,请稍后重试"
		return
	}
	utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
	defer func() {
		_ = utils.Rc.Delete(cacheKey)
	}()

	// 获取指标详情
	edbInfo, e := models.GetEdbInfoByEdbCode(source, req.EdbCode)
	if e != nil {
		br.Msg = "指标不存在"
		br.ErrMsg = fmt.Sprintf("指标不存在, %v", e)
		return
	}

	// 获取指标关联信息
	baseMapping := new(models.BaseFromEdbMapping)
	{
		ob := new(models.BaseFromEdbMapping)
		cond := fmt.Sprintf(" AND %s = ? AND %s = ? AND %s = ?", ob.Cols().EdbCode, ob.Cols().Source, ob.Cols().SubSource)
		pars := make([]interface{}, 0)
		pars = append(pars, req.EdbCode, thsOb.GetSource(), thsOb.GetSubSource())
		mapping, e := ob.GetItemByCondition(cond, pars, "")
		if e != nil {
			br.Msg = "刷新失败"
			br.ErrMsg = fmt.Sprintf("指标关联信息有误, %v", e)
			return
		}
		baseMapping = mapping
	}

	// 刷新指标
	if e = thsOb.Refresh(edbInfo, baseMapping, req.StartDate); e != nil {
		br.Msg = "刷新指标失败"
		br.ErrMsg = fmt.Sprintf("刷新指标失败, %v", e)
		return
	}

	// 更新指标最值
	if e = thsOb.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo); e != nil {
		br.Msg = "刷新指标失败"
		br.ErrMsg = fmt.Sprintf("更新指标最值失败, %v", e)
		return
	}

	// 更新ES
	go logic.UpdateEs(edbInfo.EdbInfoId)

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}