package chart

import (
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"hongze/hongze_yb/global"
	edbDataModel "hongze/hongze_yb/models/tables/edb_data"
	"hongze/hongze_yb/utils"
	"io/ioutil"
	"net/http"
	"net/url"
	"reflect"
	"strconv"
	"strings"
	"time"
)

type EdbDataFromThs struct {
	DataVol   int64       	`json:"dataVol"`
	Errmsg    string      	`json:"errmsg"`
	Errorcode int64       	`json:"errorcode"`
	Perf      interface{} 	`json:"perf"`
	Tables    []struct {
		ID    []string  	`json:"id"`
		Time  []string  	`json:"time"`
		Value []float64 	`json:"value"`
	}						`json:"tables"`
}

func RefreshEdbDataByThs(edbInfoId int, edbCode, startDate, endDate string) (err error) {
	HzServerDataUrl := ""
	if global.CONFIG.Serve.RunMode == "release" {
		HzServerDataUrl = "http://172.19.173.231:7000/"
	} else {
		HzServerDataUrl = "http://139.196.136.213:7000/"
	}

	thsUrl := HzServerDataUrl + `edbInfo/ths?EdbCode=%s&StartDate=%s&EndDate=%s`
	thsUrl = fmt.Sprintf(thsUrl, edbCode, startDate, endDate)
	//utils.FileLog.Info("thsUrl:%s", thsUrl)

	reqRes, err := http.Get(thsUrl)
	if err != nil {
		return
	}
	defer reqRes.Body.Close()
	body, err := ioutil.ReadAll(reqRes.Body)
	if err != nil {
		return
	}

	fmt.Println("GetEdbDataByThs body:")
	fmt.Println(string(body))

	item := new(EdbDataFromThs)
	err = json.Unmarshal(body, &item)
	if err != nil {
		return
	}
	if item.Errorcode != 0 {
		err = errors.New(string(body))
		return
	}
	if len(item.Tables) > 0 {
		table := item.Tables[0]
		dataLen := len(table.Time)
		addSql := ` INSERT INTO edb_data_ths(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
		nowStr := time.Now().Format(utils.FormatDateTime)
		var isAdd bool
		for i := 0; i < dataLen; i++ {
			eDate := table.Time[i]
			sValue := table.Value[i]

			count, err := edbDataModel.GetEdbDataThsByCodeAndDate(edbCode, eDate)
			if err != nil && err != utils.ErrNoRow {
				return err
			}
			if count <= 0 {
				dataTime, err := time.Parse(utils.FormatDate, eDate)
				if err != nil {

				}
				timestamp := dataTime.UnixNano() / 1e6
				timeStr := fmt.Sprintf("%d", timestamp)

				addSql += "("
				addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + eDate + "'" + "," + utils.SubFloatToString(sValue, 30) + "," + "'" + nowStr + "'" +
					"," + "'" + nowStr + "'" + "," + "1"
				addSql += "," + "'" + timeStr + "'"
				addSql += "),"
				isAdd = true
			} else {
				err = edbDataModel.ModifyEdbDataThs(int64(edbInfoId), eDate, sValue)
				if err != nil {
					return err
				}
			}
		}

		if isAdd {
			addSql = strings.TrimRight(addSql, ",")
			err = edbDataModel.AddEdbDataThsBySql(addSql)
			if err != nil {
				fmt.Println("AddEdbDataThs Err", err.Error())
				return
			}
		}
	}

	return
}

type EdbDataFromWind struct {
	Close  map[string]float64 `json:"CLOSE"`
	Dt     map[string]int64   `json:"DT"`
	ErrMsg string
}

func RefreshEdbDataByWind(edbInfoId int, edbCode, startDate, endDate string) (err error) {
	defer func() {
		if err != nil {
			fmt.Println("GetEdbDataByWind Err:" + err.Error())
		}
	}()

	fmt.Println("startDate,endDate:",startDate,endDate)

	thsUrl := utils.Hz_Data_Url + `edbInfo/wind?EdbCode=%s&StartDate=%s&EndDate=%s`
	thsUrl = fmt.Sprintf(thsUrl, edbCode, startDate, endDate)
	//utils.FileLog.Info("thsUrl:%s", thsUrl)

	reqRes, err := http.Get(thsUrl)
	if err != nil {
		return
	}
	defer reqRes.Body.Close()
	body, err := ioutil.ReadAll(reqRes.Body)
	if err != nil {
		return
	}
	
	fmt.Println("GetEdbDataByThs body:")
	fmt.Println(string(body))
	//utils.FileLog.Info("wind result:"+string(body))

	item := new(EdbDataFromWind)
	err = json.Unmarshal(body, &item)
	if err != nil {
		return
	}
	addSql := ` INSERT INTO edb_data_wind(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	nowStr := time.Now().Format(utils.FormatDateTime)
	var isAdd bool
	for k, v := range item.Dt {
		timeStr := fmt.Sprintf("%d", v)

		v = v / 1000
		t := time.Unix(v, 0)
		dateTime := t.Format(utils.FormatDate)
		val := item.Close[k]

		count, err := edbDataModel.GetEdbDataWindByCodeAndDate(edbCode, dateTime)
		if err != nil && err != utils.ErrNoRow {
			return err
		}
		if count <= 0 {
			isAdd = true
			fmt.Println(dateTime)
			addSql += "("
			addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + dateTime + "'" + "," + utils.SubFloatToString(val, 30) + "," + "'" + nowStr + "'" +
				"," + "'" + nowStr + "'" + "," + "1"
			addSql += "," + "'" + timeStr + "'"
			addSql += "),"
		} else {
			err = edbDataModel.ModifyEdbDataWind(int64(edbInfoId), dateTime, val)
			if err != nil {
				return err
			}
		}
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = edbDataModel.AddEdbDataWindBySql(addSql)
		if err != nil {
			fmt.Println("AddEdbDataWind Err", err.Error())
			return
		}
	}
	return
}

type EdbDataFromPb struct {
	Date   map[string]int64   `json:"date"`
	Ticker map[string]string  `json:"ticker"`
	Field  map[string]string  `json:"field"`
	Value  map[string]float64 `json:"value"`
}

func RefreshEdbDataByPb(edbInfoId int, edbCode, startDate, endDate string) (err error) {
	refreshEdbCode := edbCode
	edbCode = url.QueryEscape(edbCode)
	bpUrl := utils.Hz_Data_PB_Url + `edbInfo/pb?EdbCode=%s&StartDate=%s&EndDate=%s`
	bpUrl = fmt.Sprintf(bpUrl, edbCode, startDate, endDate)
	//utils.FileLog.Info("bpUrl+" + bpUrl)

	reqRes, err := http.Get(bpUrl)
	if err != nil {
		return
	}
	defer reqRes.Body.Close()
	body, err := ioutil.ReadAll(reqRes.Body)
	if err != nil {
		return
	}
	fmt.Println("RefreshEdbDataByPb body:")
	fmt.Println(string(body))
	//utils.FileLog.Info("RefreshEdbDataByPb:" + string(body))

	item := new(EdbDataFromPb)
	err = json.Unmarshal(body, &item)
	if err != nil {
		return
	}
	if len(item.Date) > 0 {
		dateMap := item.Date
		pbList := make([]*edbDataModel.EdbDataPb, 0)
		for k, v := range dateMap {
			timestamp := v
			v = v / 1000
			t := time.Unix(v, 0)
			dateTime := t.Format(utils.FormatDate)

			val := item.Value[k]
			field := item.Field[k]
			ticker := item.Ticker[k]
			if field == "PX_LAST" {
				//判断数据是否已经存在
				count, err := edbDataModel.GetEdbDataPbByCodeAndDate(refreshEdbCode, dateTime)
				if err != nil && err != utils.ErrNoRow {
					return err
				}
				fmt.Println("field:", field)
				if count <= 0 {
					item := new(edbDataModel.EdbDataPb)
					item.EdbCode, _ = url.QueryUnescape(edbCode)
					item.EdbInfoId = edbInfoId
					item.CreateTime = time.Now()
					item.ModifyTime = time.Now()
					item.DataTime = dateTime
					item.Value = val
					item.Status = 1
					item.Field = field
					item.Ticker = ticker
					item.DataTimestamp = timestamp
					pbList = append(pbList, item)
				} else {
					err = edbDataModel.ModifyEdbDataPb(edbInfoId, dateTime, val)
					if err != nil {
						return err
					}
				}
			}
		}

		if len(pbList) > 0 {
			err = edbDataModel.AddEdbDataPb(pbList)
			if err != nil {
				fmt.Println("AddEdbDataPb Err", err.Error())
				return
			}
		}
	}

	return
}

//刷新手工指标数据
func RefreshAllEdbDataByManual(edbInfoId, source int, edbCode string) (err error) {
	tx := global.MYSQL["data"].Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	if err != nil {
		return
	}
	edbInfoIdStr := strconv.Itoa(edbInfoId)
	//计算数据
	var condition string
	var pars []interface{}

	if edbCode != "" {
		condition += " AND TRADE_CODE=? "
		pars = append(pars, edbCode)
	}

	manualDataList, err := edbDataModel.GetEdbdataManualByTradeCode(condition, pars)
	//获取指标所有数据
	existDataList := make([]*edbDataModel.EdbDataBase, 0)
	dataTableName := edbDataModel.GetEdbDataTableName(source)
	sql := `SELECT * FROM %s WHERE edb_info_id=? `
	sql = fmt.Sprintf(sql, dataTableName)
	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&existDataList).Error
	//_, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
	if err != nil {
		return err
	}

	existDataMap := make(map[string]*edbDataModel.EdbDataBase)
	for _, v := range existDataList {
		existDataMap[v.DataTime] = v
	}

	addSql := ` INSERT INTO edb_data_manual(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	var isAdd bool
	manualMap := make(map[string]*edbDataModel.ManualEdbdata)
	for _, v := range manualDataList {
		item := v
		if findItem, ok := existDataMap[v.Dt]; !ok {
			eDate := item.Dt
			sValue := item.Close

			dataTime, err := time.Parse(utils.FormatDate, eDate)
			if err != nil {
				return err
			}
			timestamp := dataTime.UnixNano() / 1e6
			timeStr := fmt.Sprintf("%d", timestamp)

			addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
			isAdd = true
		} else {
			if findItem.Value != item.Close {
				sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
				sql = fmt.Sprintf(sql, dataTableName)
				err = tx.Exec(sql, item.Close, edbInfoId, item.Dt).Error
				//err = global.MYSQL["data"].Exec(sql, item.Close, edbInfoId, item.Dt).Error
				//_, err = o.Raw(sql, item.Close, edbInfoId, item.Dt).Exec()
				if err != nil {
					return err
				}
			}
		}
		manualMap[v.Dt] = v
	}
	for _, v := range existDataList {
		if _, ok := manualMap[v.DataTime]; !ok {
			go func() {
				sql := ` DELETE FROM %s WHERE edb_data_id=? `
				tableName := edbDataModel.GetEdbDataTableName(utils.DATA_SOURCE_MANUAL)
				sql = fmt.Sprintf(sql, tableName)
				err = tx.Exec(sql, v.EdbInfoId).Error
				//err = global.MYSQL["data"].Exec(sql, edbDataId).Error
			}()
			//go DeleteEdbDataByIdAndSource(v.EdbDataId, utils.DATA_SOURCE_MANUAL)
		}
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = tx.Exec(addSql).Error
		//_, err = o.Raw(addSql).Exec()
		if err != nil {
			fmt.Println("RefreshAllEdbDataByManual add Err", err.Error())
			return
		}
	}
	return
}

func DeleteEdbDataByIdAndSource(edbDataId, source int) (err error) {
	sql := ` DELETE FROM %s WHERE edb_data_id=? `
	tableName := edbDataModel.GetEdbDataTableName(source)
	sql = fmt.Sprintf(sql, tableName)
	err = global.MYSQL["data"].Exec(sql, edbDataId).Error

	return
}

func GetAddSql(edbInfoId, edbCode, dataTime, timestampStr string, value string) (addSql string) {
	nowStr := time.Now().Format(utils.FormatDateTime)
	addSql += "("
	addSql += edbInfoId + "," + "'" + edbCode + "'" + "," + "'" + dataTime + "'" + "," + value + "," + "'" + nowStr + "'" +
		"," + "'" + nowStr + "'" + "," + "1"
	addSql += "," + "'" + timestampStr + "'"
	addSql += "),"
	return
}

//刷新隆众指标数据
func RefreshEdbDataByLz(edbInfoId int, edbCode, startDate, endDate string) (err error) {

	tx := global.MYSQL["data"].Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	if err != nil {
		return
	}
	edbInfoIdStr := strconv.Itoa(edbInfoId)
	//计算数据
	var condition string
	var pars []interface{}

	if edbCode != "" {
		condition += " AND b.lz_code=? "
		pars = append(pars, edbCode)
	}

	if startDate != "" {
		condition += " AND a.data_time>=? "
		pars = append(pars, startDate)
	}

	if endDate != "" {
		condition += " AND a.data_time<=? "
		pars = append(pars, endDate)
	}

	lzDataList, err := edbDataModel.GetLzSurveyDataByTradeCode(condition, pars)

	addSql := ` INSERT INTO edb_data_lz(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	var isAdd bool
	for _, v := range lzDataList {
		item := v
		count, err := edbDataModel.GetEdbDataLzByCodeAndDate(edbCode, v.DataTime)
		if err != nil && err != utils.ErrNoRow {
			return err
		}
		if count <= 0 {
			nowStr := time.Now().Format(utils.FormatDateTime)
			eDate := item.DataTime
			sValue := item.InputValue
			dataTime, err := time.Parse(utils.FormatDate, eDate)
			if err != nil {
				return err
			}
			timestamp := dataTime.UnixNano() / 1e6
			timeStr := fmt.Sprintf("%d", timestamp)
			addSql += "("
			addSql += edbInfoIdStr + "," + "'" + edbCode + "'" + "," + "'" + eDate + "'" + "," + sValue + "," + "'" + nowStr + "'" +
				"," + "'" + nowStr + "'" + "," + "1" + "," + "'" + timeStr + "'"
			addSql += "),"
			isAdd = true
		} else {
			//edbInfoId int64, dataTime, value string
			//o := orm.NewOrm()
			//o.Using("data")
			sql := ` UPDATE edb_data_lz SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
			err = tx.Exec(sql, v.InputValue, int64(edbInfoId), v.DataTime).Error
			//_, err = o.Raw(sql, value, edbInfoId, dataTime).Exec()

			//err = ModifyEdbDataLz(int64(edbInfoId), v.DataTime, v.InputValue)
			if err != nil {
				return err
			}
		}
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = tx.Exec(addSql).Error
		//_, err = o.Raw(addSql).Exec()
		if err != nil {
			return err
		}
	}

	return
}

//全部刷新有色数据
func RefreshAllEdbDataByYs(edbInfoId, source int, edbCode, startDate, endDate string) (err error) {

	tx := global.MYSQL["data"].Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	if err != nil {
		return
	}
	edbInfoIdStr := strconv.Itoa(edbInfoId)
	//获取数据
	err = SyncSmmIndexDataBase(edbCode, startDate, endDate)
	if err != nil {
		err = errors.New("SyncSmmIndexDataBase Err:" + err.Error())
		return err
	}
	//获取已存在指标所有数据
	existDataList := make([]*edbDataModel.EdbDataBase, 0)
	dataTableName := edbDataModel.GetEdbDataTableName(source)
	sql := `SELECT * FROM %s WHERE edb_info_id=? `
	sql = fmt.Sprintf(sql, dataTableName)

	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&existDataList).Error
	//_, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
	if err != nil {
		return err
	}
	existDataMap := make(map[string]string)
	for _, v := range existDataList {
		existDataMap[v.DataTime] = v.Value
	}

	smmDateList := make([]*edbDataModel.BaseFromSmmDataSimple, 0)
	smmSql := ` SELECT * FROM base_from_smm_data WHERE index_code=? AND data_time>=? `
	err = global.MYSQL["data"].Raw(smmSql, edbCode, startDate).Scan(&existDataList).Error
	//_, err = o.Raw(smmSql, edbCode, startDate).QueryRows(&smmDateList)
	if err != nil {
		return err
	}

	addSql := ` INSERT INTO edb_data_ys(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	var isAdd bool
	for _, sv := range smmDateList {
		if existVal, ok := existDataMap[sv.DataTime]; !ok {
			dataTime, err := time.Parse(utils.FormatDate, sv.DataTime)
			if err != nil {
				return err
			}
			timestamp := dataTime.UnixNano() / 1e6
			timeStr := fmt.Sprintf("%d", timestamp)
			addSql += GetAddSql(edbInfoIdStr, edbCode, sv.DataTime, timeStr, sv.Value)
			isAdd = true
		} else {
			if existVal != sv.Value {
				sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
				sql = fmt.Sprintf(sql, dataTableName)

				err = tx.Exec(sql, sv.Value, edbInfoId, sv.DataTime).Error
				//_, err = o.Raw(sql, sv.Value, edbInfoId, sv.DataTime).Exec()
				if err != nil {
					return err
				}
			}
		}
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = tx.Exec(addSql).Error
		//_, err = o.Raw(addSql).Exec()
		if err != nil {
			return err
		}
	}
	return
}

const (
	dataUrl = "https://dataapi.smm.cn/GetData/" //data url (中文)
	//dataUrl = "https://dataapi.smm.cn/GetDataEn/" //data url (english edition)
	authUrl = "https://platform.smm.cn/usercenter/auth" // auth url (for all)
)

type TokenResp struct {
	Code int       `json:"Code"`
	Msg  string    `json:"Msg"`
	Data TokenData `json:"Data"`
}

type TokenData struct {
	Token string `json:"Token"`
}

//获取token
func getToken(userName string, password string) (string, error) {
	encryptAuth := md5.New()
	encryptAuth.Write([]byte(password)) //encrypt password with md5
	newPassword := hex.EncodeToString(encryptAuth.Sum(nil))

	resp, err := http.PostForm(authUrl, url.Values{"user_name": {userName}, "password": {newPassword}})
	if err != nil {
		return "", err
	}

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("reponse error", err)
		return "", err
	}

	var bodyJsonContent TokenResp

	if err = json.Unmarshal([]byte(body), &bodyJsonContent); err != nil {
		fmt.Println(err, "unmarsal failure")
		return "", err
	}

	var token string
	if bodyJsonContent.Code == 0 {
		token = bodyJsonContent.Data.Token
	}

	//print(token)
	return token, nil
}

func SyncSmmIndexDataBase(edbCode, startDate, endDate string) (err error) {
	//utils.FileLog.Info("start:" + time.Now().Format(utils.FormatDateTime))

	var smmCode string
	if strings.Contains(edbCode, "#") {
		smmCode = strings.Split(edbCode, "#")[0]
	} else {
		smmCode = edbCode
	}
	token, err := getToken("pqian@hzinsights.com", "hz123456")
	if err != nil {
		fmt.Println(err)
		return
	}
	baseSmmItem, err := edbDataModel.GetBaseFromSmmBySmmCode(smmCode)
	if err != nil {
		fmt.Println(err)
		return
	}

	if baseSmmItem == nil {
		err = errors.New("GetBaseFromSmmBySmmCode Err:" + err.Error())
		return
	}

	smmIndexAll, err := edbDataModel.GetBaseFromSmmIndexBySmmCode(smmCode)
	if err != nil {
		fmt.Println("GetBaseFromSmmIndex Err:" + err.Error())
		return
	}
	existIndexMap := make(map[string]*edbDataModel.BaseFromSmmIndex)
	for _, item := range smmIndexAll {
		existIndexMap[item.IndexCode] = item
	}

	ysItem, err := getApiData(token, edbCode, startDate, endDate)
	if err != nil {
		fmt.Println(err)
		return
	}
	if ysItem != nil && ysItem.Code == 200 {

		frequency := ysItem.Data.Frequency

		indexMap := make(map[string]int)
		smmIndexIdMap := make(map[int]int)
		indexCodeMap := make(map[int]string)

		indexKey := 0
		var isDateIndex int
		for fk, fv := range ysItem.Data.Field {
			if fv.IsDate == "1" {
				isDateIndex = fk
			} else {
				if !strings.Contains(fv.Name, "产品名称") &&
					!strings.Contains(fv.Name, "单位") &&
					!strings.Contains(fv.Name, "时间") &&
					!strings.Contains(fv.Name, "备注") {

					indexMap[fv.DBColName] = fk

					indexKey += 1
					indexCode := smmCode + "#" + strconv.Itoa(indexKey)

					if findItem, ok := existIndexMap[indexCode]; !ok {
						ssmIndex := new(edbDataModel.BaseFromSmmIndex)
						ssmIndex.Interface = smmCode
						ssmIndex.Name = baseSmmItem.Name
						ssmIndex.IndexCode = indexCode
						ssmIndex.IndexName = baseSmmItem.Name + "_" + fv.Name
						ssmIndex.Type1 = baseSmmItem.Type1
						ssmIndex.Type2 = baseSmmItem.Type2
						ssmIndex.Type3 = baseSmmItem.Type3
						ssmIndex.Frequency = frequency
						ssmIndex.Unit = fv.Unit
						ssmIndex.ApiStartTime = baseSmmItem.ApiStartTime
						ssmIndex.ApiUpdateTime = baseSmmItem.ApiUpdateTime
						ssmIndex.StartTime = baseSmmItem.StartTime
						ssmIndex.FinishTime = baseSmmItem.FinishTime
						ssmIndex.CreateTime = time.Now()
						ssmIndex.ModifyTime = time.Now()
						lastIndexId, err := edbDataModel.AddBaseFromSmmIndex(ssmIndex)
						if err != nil {
							err = errors.New("AddBaseFromSmmIndex Err:" + err.Error())
							return err
						}
						smmIndexIdMap[fk] = int(lastIndexId)
						indexCodeMap[fk] = indexCode
					} else {
						smmIndexIdMap[fk] = findItem.BaseFromSmmIndexId
						indexCodeMap[fk] = findItem.IndexCode
					}
				}
			}
		}

		existDataMap := make(map[string]*edbDataModel.BaseFromSmmData)
		for _, mv := range indexCodeMap {
			indexCode := mv
			dataAllList, err := edbDataModel.GetBaseFromSmmDataAllByIndexCode(indexCode)
			if err != nil {
				err = errors.New("GetBaseFromSmmData Err:" + err.Error())
				return err
			}
			for _, item := range dataAllList {
				key := item.IndexCode + item.DataTime
				existDataMap[key] = item
			}
		}

		addExistDataMap := make(map[string]string)

		for _, dv := range ysItem.Data.Content {
			var dataTime string
			dataTime = dv[isDateIndex]
			if strings.Contains(dataTime, "Q1") {
				dataTime = strings.Replace(dataTime, "Q1", "-01", -1)
				dataTime += "-31"
			}
			if strings.Contains(dataTime, "Q2") {
				dataTime = strings.Replace(dataTime, "Q2", "-06", -1)
				dataTime += "-30"
			}
			if strings.Contains(dataTime, "Q3") {
				dataTime = strings.Replace(dataTime, "Q3", "-09", -1)
				dataTime += "-30"
			}
			if strings.Contains(dataTime, "Q4") {
				dataTime = strings.Replace(dataTime, "Q4", "-12", -1)
				dataTime += "-31"
			}

			if strings.Contains(dataTime, "H1") {
				dataTime = strings.Replace(dataTime, "H1", "-06", -1)
				dataTime += "-30"
			}

			if strings.Contains(dataTime, "H2") {
				dataTime = strings.Replace(dataTime, "H2", "-12", -1)
				dataTime += "-31"
			}

			if frequency == "月" {
				monthDate, err := time.Parse("2006-01", dataTime)
				if err != nil {
					fmt.Println("time.Parse:" + err.Error())
				}
				lastTime := monthDate.AddDate(0, 1, -1)
				lastYear, lastMonth, lastDay := lastTime.Date()
				var lastDate string
				if int(lastMonth) < 10 {
					lastDate = strconv.Itoa(lastYear) + "-" + "0" + strconv.Itoa(int(lastMonth)) + "-" + strconv.Itoa(lastDay)
				} else {
					lastDate = strconv.Itoa(lastYear) + "-" + strconv.Itoa(int(lastMonth)) + "-" + strconv.Itoa(lastDay)
				}
				dataTime = lastDate
			} else if frequency == "年" {
				dataTime = dataTime + "-12-31"
			}
			saveDataTime, err := time.Parse(utils.FormatDate, dataTime)
			if err != nil {
				err = errors.New("time.Parse Err:" + err.Error())
				return err
			}
			timestamp := saveDataTime.UnixNano() / 1e6
			//循环指标
			for _, v := range indexMap {

				indexCode := indexCodeMap[v]
				smmIndexId := smmIndexIdMap[v]
				dataVal := dv[v]

				if indexCode != "" {

					key := indexCode + dataTime
					val := strings.Replace(dataVal, ",", "", -1)
					if findData, dataOk := existDataMap[key]; !dataOk {
						if _, addOK := addExistDataMap[key]; !addOK {
							if val != "" && val != "-" {
								dataItem := new(edbDataModel.BaseFromSmmData)
								dataItem.BaseFromSmmIndexId = smmIndexId
								dataItem.IndexCode = indexCode
								dataItem.DataTime = dataTime
								dataItem.Value = val
								dataItem.CreateTime = time.Now()
								dataItem.ModifyTime = time.Now()
								dataItem.DataTimestamp = timestamp
								_, err = edbDataModel.AddBaseFromSmmData(dataItem)
								if err != nil && !strings.Contains(err.Error(), "idx_index_code_date") {
									fmt.Println("AddBaseFromSmmData Err:" + err.Error())
									err = errors.New("AddBaseFromSmmData Err:" + err.Error())
									return err
								}
							}
						}
					} else {
						if findData != nil && findData.Value != val { //修改
							if _, addOK := addExistDataMap[key]; !addOK {
								if val != "" && val != "-" {
									err = edbDataModel.ModifyBaseFromSmmData(findData.SmmDataId, val)
									if err != nil {
										err = errors.New("ModifyBaseFromSmmData Err:" + err.Error())
										return err
									}
								}
							}
						}
					}
					addExistDataMap[key] = key
				}
			}
		}

		//修改数据开始，结束日期
		{
			indexList, err := edbDataModel.GetBaseFromSmmIndexBySmmCode(smmCode)
			if err != nil {
				fmt.Println("GetBaseFromSmmIndexBySmmCode Err:" + err.Error())
			}
			for _, sv := range indexList {
				minDate, maxDate, err := edbDataModel.GetBaseFromSmmMaxOrMinDate(sv.IndexCode)
				if err != nil {
					fmt.Println("GetEdbDataSmmMaxOrMinDate Err:" + err.Error())
				} else {
					err = edbDataModel.ModifyBaseFromSmmMinDateAndMaxDate(sv.BaseFromSmmIndexId, minDate, maxDate)
					if err != nil {
						fmt.Println("ModifyBaseFromSmmMinDateAndMaxDate Err:" + err.Error())
					}
				}
			}
		}
	}

	return
}

/*
 * request data
 * sdatetime,edatetime ==>format:yyyy-mm-dd,
 * apiName ==> data.metal.com(for english)/data.smm.cn (for chinese)
 */
func getApiData(token string, apiName string, sdatetime string, edatetime string) (item *edbDataModel.YsResult, err error) {
	reqUrl := dataUrl + apiName
	resp, err := http.PostForm(reqUrl, url.Values{"token": {token}, "sdatetime": {sdatetime}, "edatetime": {edatetime}})
	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("response error")
		return nil, err
	}
	//utils.FileLog.Info("ys result:" + string(body))
	dataJsonContent := new(edbDataModel.YsResult)
	if err = json.Unmarshal([]byte(body), &dataJsonContent); err != nil {
		fmt.Println(err, "data unmarshal failure")
		return nil, err
	}

	if dataJsonContent.Code == 200 && len(dataJsonContent.Data.Content) > 0 {
		return dataJsonContent, nil
	} else {
		err = errors.New("code:" + strconv.Itoa(int(dataJsonContent.Code)) + "msg:" + dataJsonContent.Msg)
	}
	return nil, nil
}

func RefreshEdbDataByGl(edbInfoId int, edbCode, startDate, endDate string) (err error) {
	tx := global.MYSQL["data"].Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	if err != nil {
		return
	}
	edbInfoIdStr := strconv.Itoa(edbInfoId)
	//计算数据
	var condition string
	var pars []interface{}

	if edbCode != "" {
		condition += " AND INDEX_CODE=? "
		pars = append(pars, edbCode)
	}

	if startDate != "" {
		condition += " AND DATA_DATE>=? "
		pars = append(pars, startDate)
	}

	if endDate != "" {
		condition += " AND DATA_DATE<=? "
		pars = append(pars, endDate)
	}

	glDataList, err := edbDataModel.GetGlDataByTradeCode(condition, pars)

	addSql := ` INSERT INTO edb_data_gl(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	var isAdd bool
	existMap := make(map[string]string)
	for _, v := range glDataList {
		item := v
		if _, ok := existMap[v.DataTime]; !ok {
			count, err := edbDataModel.GetEdbDataGlByCodeAndDate(edbCode, v.DataTime)
			if err != nil && err != utils.ErrNoRow {
				return err
			}
			if count <= 0 {
				eDate := item.DataTime
				sValue := item.InputValue
				if sValue != "" {
					dataTime, err := time.Parse(utils.FormatDate, eDate)
					if err != nil {
						return err
					}
					timestamp := dataTime.UnixNano() / 1e6
					timeStr := fmt.Sprintf("%d", timestamp)
					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
					isAdd = true
				}
			} else {
				updateSql := ` UPDATE edb_data_gl SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
				//err = global.MYSQL["data"].Exec(sql, value, edbInfoId, dataTime).Error
				err = tx.Exec(updateSql, v.InputValue, edbInfoId, v.DataTime).Error
				//err = edbDataModel.ModifyEdbDataGl(int64(edbInfoId), v.DataTime, v.InputValue)
				if err != nil {
					return err
				}
			}
		}
		existMap[v.DataTime] = v.InputValue
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = tx.Exec(addSql).Error
		//_, err = o.Raw(addSql).Exec()
		if err != nil {
			return err
		}
	}
	return
}

// RefreshEdbDataByZz 刷新路透社数据
func RefreshAllEdbDataByLt(edbInfoId, source int, edbCode, startDate, endDate string) (err error) {
	// 获取路透社数据
	ltDataList, err := QueryEdbDataByLt(edbCode, startDate, endDate)
	if err != nil {
		return
	}

	tx := global.MYSQL["data"].Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	//获取指标所有数据
	dataList := make([]*edbDataModel.EdbDataBase, 0)
	dataTableName := edbDataModel.GetEdbDataTableName(source)
	sql := `SELECT * FROM %s WHERE edb_info_id=? `
	sql = fmt.Sprintf(sql, dataTableName)
	err = global.MYSQL["data"].Raw(sql, dataTableName).Scan(&dataList).Error
	//_, err = o.Raw(sql, edbInfoId).QueryRows(&dataList)
	if err != nil {
		return err
	}
	dataMap := make(map[string]string)
	for _, v := range dataList {
		dataMap[v.DataTime] = v.Value
	}
	edbInfoIdStr := strconv.Itoa(edbInfoId)

	addSql := ` INSERT INTO edb_data_lt(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	var isAdd bool

	for timestampInt, edbValue := range ltDataList {
		dataTime := time.Unix(timestampInt/1000, 0)

		//校验数据类型对不对
		valType := reflect.TypeOf(edbValue)
		if valType == nil {
			continue
		}
		if valType.String() != "float64" {
			continue
		}
		sValue := edbValue.(float64)

		eDate := dataTime.Format(utils.FormatDate)
		if err != nil {
			return err
		}

		saveValue := utils.SubFloatToString(sValue, 30)
		if existVal, ok := dataMap[eDate]; !ok {
			timestamp := dataTime.UnixNano() / 1e6
			timeStr := fmt.Sprintf("%d", timestamp)

			addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, saveValue)
			isAdd = true
		} else {
			if existVal != saveValue {
				sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
				sql = fmt.Sprintf(sql, dataTableName)
				err = tx.Exec(sql, sValue, edbInfoId, eDate).Error
				//_, err = o.Raw(sql, sValue, edbInfoId, eDate).Exec()
				if err != nil {
					return err
				}
			}
		}
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = tx.Exec(addSql).Error
		//_, err = o.Raw(addSql).Exec()
		if err != nil {
			fmt.Println("RefreshAllEdbDataByLt add Err", err.Error())
			return
		}
	}
	return
}

// QueryEdbDataByLt 获取路透社数据
func QueryEdbDataByLt(edbCode, startDate, endDate string) (dataList map[int64]interface{}, err error) {
	dataList = make(map[int64]interface{})

	ltUrl := utils.Hz_Data_LT_Url + `edbInfo/ek?EdbCode=%s&StartDate=%s&EndDate=%s`
	ltUrl = fmt.Sprintf(ltUrl, edbCode, startDate, endDate)
	//utils.FileLogData.Info("ltUrl:%s", ltUrl)
	//body, err := http.Get(ltUrl)

	reqRes, err := http.Get(ltUrl)
	if err != nil {
		return
	}
	defer reqRes.Body.Close()
	body, err := ioutil.ReadAll(reqRes.Body)
	if err != nil {
		return
	}

	//utils.FileLogData.Info("lt result:%s", string(body))

	//if err != nil {
	//	return
	//}
	//fmt.Println(string(body))
	item := new(edbDataModel.EdbDataFromLt)
	err = json.Unmarshal(body, &item)

	if err != nil {
		return
	}
	dataList = item.Close
	return
}

// RefreshEdbDataByZz 刷新郑商所指标数据
func RefreshEdbDataByZz(edbInfoId int, edbCode, startDate, endDate string) (err error) {

	tx := global.MYSQL["data"].Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	if err != nil {
		return
	}
	var suffix string
	if strings.Contains(edbCode, "deal") {
		suffix = "deal"
	} else if strings.Contains(edbCode, "buy") {
		suffix = "buy"
	} else if strings.Contains(edbCode, "sold") {
		suffix = "sold"
	}
	edbInfoIdStr := strconv.Itoa(edbInfoId)
	//计算数据
	var condition string
	var pars []interface{}

	if edbCode != "" {
		if suffix == "deal" {
			condition += " AND deal_code=? "
		} else if suffix == "buy" {
			condition += " AND buy_code=? "
		} else {
			condition += " AND sold_code=? "
		}
		pars = append(pars, edbCode)
	}

	if startDate != "" {
		condition += " AND data_time>=? "
		pars = append(pars, startDate)
	}

	if endDate != "" {
		condition += " AND data_time<=? "
		pars = append(pars, endDate)
	}

	glDataList, err := edbDataModel.GetZzDataByTradeCode(condition, pars)

	addSql := ` INSERT INTO edb_data_zz(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	var isAdd bool
	existMap := make(map[string]string)
	for _, v := range glDataList {
		var value string
		if suffix == "deal" {
			value = v.DealValue
		} else if suffix == "buy" {
			value = v.BuyValue
		} else {
			value = v.SoldValue
		}
		item := v
		itemValue := value
		if _, ok := existMap[v.DataTime]; !ok {
			count, err := edbDataModel.GetEdbDataZzByCodeAndDate(edbCode, v.DataTime)
			if err != nil && err != utils.ErrNoRow {
				return err
			}
			if count <= 0 {
				eDate := item.DataTime
				sValue := itemValue
				if sValue != "" {
					dataTime, err := time.Parse(utils.FormatDate, eDate)
					if err != nil {
						return err
					}
					timestamp := dataTime.UnixNano() / 1e6
					timeStr := fmt.Sprintf("%d", timestamp)
					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
					isAdd = true
				}
			} else {
				updateSql := ` UPDATE edb_data_zz SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
				err = tx.Exec(updateSql, value, edbInfoId, v.DataTime).Error
				if err != nil {
					return err
				}
			}
		}
		existMap[v.DataTime] = value
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = tx.Exec(addSql).Error
		//_, err = o.Raw(addSql).Exec()
		if err != nil {
			return err
		}
	}
	return
}

func RefreshEdbDataByDl(edbInfoId int, edbCode, startDate, endDate string) (err error) {

	tx := global.MYSQL["data"].Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	if err != nil {
		return
	}
	var suffix string
	if strings.Contains(edbCode, "deal") {
		suffix = "deal"
	} else if strings.Contains(edbCode, "buy") {
		suffix = "buy"
	} else if strings.Contains(edbCode, "sold") {
		suffix = "sold"
	}
	edbInfoIdStr := strconv.Itoa(edbInfoId)
	//计算数据
	var condition string
	var pars []interface{}

	if edbCode != "" {
		if suffix == "deal" {
			condition += " AND deal_code=? "
		} else if suffix == "buy" {
			condition += " AND buy_code=? "
		} else {
			condition += " AND sold_code=? "
		}
		pars = append(pars, edbCode)
	}

	if startDate != "" {
		condition += " AND data_time>=? "
		pars = append(pars, startDate)
	}

	if endDate != "" {
		condition += " AND data_time<=? "
		pars = append(pars, endDate)
	}

	glDataList, err := edbDataModel.GetDlDataByTradeCode(condition, pars)

	addSql := ` INSERT INTO edb_data_dl(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	var isAdd bool
	existMap := make(map[string]string)
	for _, v := range glDataList {
		var value string
		if suffix == "deal" {
			value = v.DealValue
		} else if suffix == "buy" {
			value = v.BuyValue
		} else {
			value = v.SoldValue
		}
		item := v
		itemValue := value
		if _, ok := existMap[v.DataTime]; !ok {
			count, err := edbDataModel.GetEdbDataDlByCodeAndDate(edbCode, v.DataTime)
			if err != nil && err != utils.ErrNoRow {
				return err
			}
			if count <= 0 {
				eDate := item.DataTime
				sValue := itemValue
				if sValue != "" {
					dataTime, err := time.Parse(utils.FormatDate, eDate)
					if err != nil {
						return err
					}
					timestamp := dataTime.UnixNano() / 1e6
					timeStr := fmt.Sprintf("%d", timestamp)
					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
					isAdd = true
				}
			} else {
				updataSql := ` UPDATE edb_data_dl SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
				err = tx.Exec(updataSql, value, edbInfoId, v.DataTime).Error
				if err != nil {
					return err
				}
			}
		}
		existMap[v.DataTime] = value
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = tx.Exec(addSql).Error
		if err != nil {
			return err
		}
	}

	return
}

// RefreshEdbDataBySh 刷新上期所指标数据
func RefreshEdbDataBySh(edbInfoId int, edbCode, startDate, endDate string) (err error) {

	tx := global.MYSQL["data"].Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	if err != nil {
		return
	}
	var suffix string
	if strings.Contains(edbCode, "deal") {
		suffix = "deal"
	} else if strings.Contains(edbCode, "buy") {
		suffix = "buy"
	} else if strings.Contains(edbCode, "sold") {
		suffix = "sold"
	}
	edbInfoIdStr := strconv.Itoa(edbInfoId)
	//计算数据
	var condition string
	var pars []interface{}

	if edbCode != "" {
		if suffix == "deal" {
			condition += " AND deal_code=? "
		} else if suffix == "buy" {
			condition += " AND buy_code=? "
		} else {
			condition += " AND sold_code=? "
		}
		pars = append(pars, edbCode)
	}

	if startDate != "" {
		condition += " AND data_time>=? "
		pars = append(pars, startDate)
	}

	if endDate != "" {
		condition += " AND data_time<=? "
		pars = append(pars, endDate)
	}

	glDataList, err := edbDataModel.GetShDataByTradeCode(condition, pars)

	addSql := ` INSERT INTO edb_data_sh(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	var isAdd bool
	existMap := make(map[string]string)
	for _, v := range glDataList {
		var value string
		if suffix == "deal" {
			value = v.DealValue
		} else if suffix == "buy" {
			value = v.BuyValue
		} else {
			value = v.SoldValue
		}
		item := v
		itemValue := value
		if _, ok := existMap[v.DataTime]; !ok {
			count, err := edbDataModel.GetEdbDataShByCodeAndDate(edbCode, v.DataTime)
			if err != nil && err != utils.ErrNoRow {
				return err
			}
			if count <= 0 {
				eDate := item.DataTime
				sValue := itemValue
				if sValue != "" {
					dataTime, err := time.Parse(utils.FormatDate, eDate)
					if err != nil {
						return err
					}
					timestamp := dataTime.UnixNano() / 1e6
					timeStr := fmt.Sprintf("%d", timestamp)
					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
					isAdd = true
				}
			} else {
				updataSql := ` UPDATE edb_data_sh SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
				err = tx.Exec(updataSql, value, edbInfoId, v.DataTime).Error
				if err != nil {
					return err
				}
			}
		}
		existMap[v.DataTime] = value
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = tx.Exec(addSql).Error
		//_, err = o.Raw(addSql).Exec()
		if err != nil {
			return err
		}
	}

	return
}

// RefreshEdbDataByCffex 刷新中金所指标数据
func RefreshEdbDataByCffex(edbInfoId int, edbCode, startDate, endDate string) (err error) {
	tx := global.MYSQL["data"].Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	if err != nil {
		return
	}
	var suffix string
	if strings.Contains(edbCode, "deal") {
		suffix = "deal"
	} else if strings.Contains(edbCode, "buy") {
		suffix = "buy"
	} else if strings.Contains(edbCode, "sold") {
		suffix = "sold"
	}
	edbInfoIdStr := strconv.Itoa(edbInfoId)
	//计算数据
	var condition string
	var pars []interface{}

	if edbCode != "" {
		if suffix == "deal" {
			condition += " AND deal_code=? "
		} else if suffix == "buy" {
			condition += " AND buy_code=? "
		} else {
			condition += " AND sold_code=? "
		}
		pars = append(pars, edbCode)
	}

	if startDate != "" {
		condition += " AND data_time>=? "
		pars = append(pars, startDate)
	}

	if endDate != "" {
		condition += " AND data_time<=? "
		pars = append(pars, endDate)
	}

	glDataList, err := edbDataModel.GetCffexDataByTradeCode(condition, pars)

	addSql := ` INSERT INTO edb_data_cffex(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	var isAdd bool
	existMap := make(map[string]string)
	for _, v := range glDataList {
		var value string
		if suffix == "deal" {
			value = v.DealValue
		} else if suffix == "buy" {
			value = v.BuyValue
		} else {
			value = v.SoldValue
		}
		item := v
		itemValue := value
		if _, ok := existMap[v.DataTime]; !ok {
			count, err := edbDataModel.GetEdbDataCffexByCodeAndDate(edbCode, v.DataTime)
			if err != nil && err != utils.ErrNoRow {
				return err
			}
			if count <= 0 {
				eDate := item.DataTime
				sValue := itemValue
				if sValue != "" {
					dataTime, err := time.Parse(utils.FormatDate, eDate)
					if err != nil {
						return err
					}
					timestamp := dataTime.UnixNano() / 1e6
					timeStr := fmt.Sprintf("%d", timestamp)
					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
					isAdd = true
				}
			} else {
				updateSql := ` UPDATE edb_data_cffex SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
				err = tx.Exec(updateSql, value, edbInfoId, v.DataTime).Error

				if err != nil {
					return err
				}
			}
		}
		existMap[v.DataTime] = value
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = tx.Exec(addSql).Error
		//_, err = o.Raw(addSql).Exec()
		if err != nil {
			return err
		}
	}
	return
}

// RefreshEdbDataByShfe 刷新上期能源指标数据
func RefreshEdbDataByShfe(edbInfoId int, edbCode, startDate, endDate string) (err error) {

	tx := global.MYSQL["data"].Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	if err != nil {
		return
	}
	var suffix string
	if strings.Contains(edbCode, "deal") {
		suffix = "deal"
	} else if strings.Contains(edbCode, "buy") {
		suffix = "buy"
	} else if strings.Contains(edbCode, "sold") {
		suffix = "sold"
	}
	edbInfoIdStr := strconv.Itoa(edbInfoId)
	//计算数据
	var condition string
	var pars []interface{}

	if edbCode != "" {
		if suffix == "deal" {
			condition += " AND deal_code=? "
		} else if suffix == "buy" {
			condition += " AND buy_code=? "
		} else {
			condition += " AND sold_code=? "
		}
		pars = append(pars, edbCode)
	}

	if startDate != "" {
		condition += " AND data_time>=? "
		pars = append(pars, startDate)
	}

	if endDate != "" {
		condition += " AND data_time<=? "
		pars = append(pars, endDate)
	}

	glDataList, err := edbDataModel.GetShfeDataByTradeCode(condition, pars)

	addSql := ` INSERT INTO edb_data_ine(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	var isAdd bool
	existMap := make(map[string]string)
	for _, v := range glDataList {
		var value string
		if suffix == "deal" {
			value = v.DealValue
		} else if suffix == "buy" {
			value = v.BuyValue
		} else {
			value = v.SoldValue
		}
		item := v
		itemValue := value
		if _, ok := existMap[v.DataTime]; !ok {
			count, err := edbDataModel.GetEdbDataShfeByCodeAndDate(edbCode, v.DataTime)
			if err != nil && err != utils.ErrNoRow {
				return err
			}
			if count <= 0 {
				eDate := item.DataTime
				sValue := itemValue
				if sValue != "" {
					dataTime, err := time.Parse(utils.FormatDate, eDate)
					if err != nil {
						return err
					}
					timestamp := dataTime.UnixNano() / 1e6
					timeStr := fmt.Sprintf("%d", timestamp)
					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
					isAdd = true
				}
			} else {
				updateSql := ` UPDATE edb_data_ine SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
				err = tx.Exec(updateSql, value, edbInfoId, v.DataTime).Error
				if err != nil {
					return err
				}
			}
		}
		existMap[v.DataTime] = value
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = tx.Exec(addSql).Error
		if err != nil {
			return err
		}
	}
	return
}

// RefreshEdbDataByGie 刷新欧洲天然气指标数据
func RefreshEdbDataByGie(edbInfoId int, edbCode, startDate, endDate string) (err error) {

	tx := global.MYSQL["data"].Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	if err != nil {
		fmt.Println("refresh err:", err)
		return
	}
	var suffix string
	l := len(edbCode)
	if strings.Contains(edbCode[l-2:], "GS") {
		suffix = "GS"
	} else if strings.Contains(edbCode[l-1:], "F") {
		suffix = "F"
	} else if strings.Contains(edbCode[l-1:], "T") {
		suffix = "T"
	} else if strings.Contains(edbCode[l-2:], "In") {
		suffix = "In"
	} else if strings.Contains(edbCode[l-3:], "Out") {
		suffix = "Out"
	} else if strings.Contains(edbCode[l-3:], "WGV") {
		suffix = "WGV"
	} else if strings.Contains(edbCode[l-2:], "IC") {
		suffix = "IC"
	} else if strings.Contains(edbCode[l-2:], "WC") {
		suffix = "WC"
	} else {
		suffix = ""
	}
	edbInfoIdStr := strconv.Itoa(edbInfoId)
	//计算数据
	var condition string
	var pars []interface{}

	if edbCode != "" {
		condition += " AND eic_code=? "
		pars = append(pars, edbCode[:l-len(suffix)])
	}

	if startDate != "" {
		condition += " AND gas_day_started_on>=? "
		pars = append(pars, startDate)
	}

	if endDate != "" {
		condition += " AND gas_day_started_on<=? "
		pars = append(pars, endDate)
	}

	eicDataList, err := edbDataModel.GetGieDataByTradeCode(condition, pars)
	fmt.Println("eicDataList", len(eicDataList))
	addSql := ` INSERT INTO edb_data_gie(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
	var isAdd bool
	existMap := make(map[string]string)
	for _, v := range eicDataList {
		var value string
		if suffix == "GS" {
			value = v.GasInStorage
		} else if suffix == "F" {
			value = v.Full
		} else if suffix == "T" {
			value = v.Trend
		} else if suffix == "In" {
			value = v.Injection
		} else if suffix == "Out" {
			value = v.Withdrawal
		} else if suffix == "WGV" {
			value = v.WorkingGasVolume
		} else if suffix == "IC" {
			value = v.InjectionCapacity
		} else if suffix == "WC" {
			value = v.WithdrawalCapacity
		}
		item := v
		itemValue := value
		if _, ok := existMap[v.GasDayStartedOn]; !ok {
			count, err := edbDataModel.GetEdbDataGieByCodeAndDate(edbCode, v.GasDayStartedOn)
			if err != nil && err != utils.ErrNoRow {
				return err
			}
			if count <= 0 {
				eDate := item.GasDayStartedOn
				sValue := itemValue
				if sValue != "" {
					dataTime, err := time.Parse(utils.FormatDate, eDate)
					if err != nil {
						return err
					}
					timestamp := dataTime.UnixNano() / 1e6
					timeStr := fmt.Sprintf("%d", timestamp)
					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
					isAdd = true
				}
			} else {
				updateSql := ` UPDATE edb_data_gie SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
				err = tx.Exec(updateSql, value, edbInfoId, v.GasDayStartedOn).Error
				if err != nil {
					return err
				}
			}
		}
		existMap[v.GasDayStartedOn] = value
	}
	if isAdd {
		addSql = strings.TrimRight(addSql, ",")
		err = tx.Exec(addSql).Error
		if err != nil {
			return err
		}
	}
	return
}