소스 검색

计算指标初始化

tuoling805 1 년 전
부모
커밋
d855e9bfd1
5개의 변경된 파일299개의 추가작업 그리고 3개의 파일을 삭제
  1. BIN
      docs/逸诺指标库(基础).xlsx
  2. 10 0
      models/edb_info.go
  3. 280 0
      services/init_calculate_index.go
  4. 3 3
      services/task.go
  5. 6 0
      utils/config.go

BIN
docs/逸诺指标库(基础).xlsx


+ 10 - 0
models/edb_info.go

@@ -41,6 +41,16 @@ type EdbInfoResp struct {
 		ChartImage       string    `json:"ChartImage"`
 		Calendar         string    `json:"Calendar"`
 		DataDateType     string    `json:"DataDateType"`
+		CalculateList    []*EdbInfoCalculateMapping
 	} `json:"Data"`
 	Success bool `json:"Success"`
 }
+
+type EdbInfoCalculateMapping struct {
+	EdbCode         string                         `description:"指标编码"`
+	BaseEdbInfoCode []*EdbInfoCalculateBaseEdbInfo `description:"依赖的基础指标编码"`
+}
+
+type EdbInfoCalculateBaseEdbInfo struct {
+	FromEdbCode string `description:"指标编码"`
+}

+ 280 - 0
services/init_calculate_index.go

@@ -0,0 +1,280 @@
+package services
+
+import (
+	"bytes"
+	"crypto/md5"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/shopspring/decimal"
+	"github.com/xuri/excelize/v2"
+	"hongze/hz_eta_data/models"
+	"hongze/hz_eta_data/utils"
+	"io/ioutil"
+	"net/http"
+	"os"
+	"path/filepath"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+)
+
+//初始化计算指标数据
+
+//classifyId:=685
+
+const (
+	HZ_DATA_API = "https://hzdataapi.hzinsights.com/hzdataapi/"
+)
+
+func InitCalculateIndex() {
+	//读取基础指标
+	var err error
+
+	defer func() {
+		if err != nil {
+			fmt.Println("InitBaseIndexData Err:" + err.Error())
+		}
+	}()
+
+	//读取excel
+	path, err := filepath.Abs(os.Args[0])
+	if err != nil {
+		fmt.Println(err)
+	}
+
+	dir := filepath.Dir(path)
+	fmt.Println("dir:" + dir)
+	dataPath := dir + "/docs/逸诺指标库(基础).xlsx"
+	fmt.Println("dataPath:" + dataPath)
+	f, err := excelize.OpenFile(dataPath)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	defer func() {
+		// Close the spreadsheet.
+		if err := f.Close(); err != nil {
+			fmt.Println(err)
+		}
+	}()
+	rows, err := f.GetRows("edb_info")
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+
+	method := "edb_index/detail"
+	edbLibIndexMethod := "/edb_info/detail"
+	var needAddIndexArr []string
+
+	for rk, row := range rows {
+		if rk <= 0 {
+			continue
+		}
+		var indexCode string
+		for ck, colCell := range row {
+			switch ck {
+			case 0:
+				indexCode = colCell
+			}
+		}
+
+		fmt.Println(rk, indexCode)
+		if indexCode == "" {
+			fmt.Println("指标编码不能为空")
+			return
+		}
+
+		params := make(map[string]interface{})
+		params["EdbCode"] = indexCode
+		result, err := hzDataHttpPost(method, params)
+		if err != nil {
+			fmt.Println("hzDataHttpPost Err:" + err.Error())
+			return
+		}
+		utils.FileLog.Info("hzDataHttpPost:" + string(result))
+		resp := new(models.EdbInfoResp)
+		err = json.Unmarshal([]byte(result), &resp)
+		if err != nil {
+			fmt.Println("json.Unmarshal Err:" + err.Error())
+			return
+		}
+		if resp.Ret != 200 && !strings.Contains(resp.ErrMsg, "QuerySeter") {
+			fmt.Println("resp Err:" + resp.ErrMsg)
+			return
+		}
+		//指标信息不存在
+		if resp.Data.EdbInfoId <= 0 {
+			fmt.Println("指标:" + indexCode + ";不存在")
+			f.SetCellStr("edb_info", "H"+strconv.Itoa(rk+1), "不存在")
+			continue
+		}
+		//判断是否存在计算指标
+		if len(resp.Data.CalculateList) <= 0 {
+			f.SetCellStr("edb_info", "H"+strconv.Itoa(rk+1), "不存在")
+			continue
+		}
+		//存在计算指标
+		for _, cv := range resp.Data.CalculateList {
+			//计算指标所依赖的基础指标
+			var total int
+			for _, bv := range cv.BaseEdbInfoCode {
+				//判断基础指标是否存在
+				indexMap := make(map[string]interface{})
+				indexMap["EdbCode"] = bv.FromEdbCode
+				result, err := PostEdbLib(indexMap, edbLibIndexMethod)
+				if err != nil {
+					utils.FileLog.Info("获取计算指标所依赖的基础指标失败:" + err.Error() + " result:" + string(result))
+					return
+				}
+
+				indexResp := new(models.EdbInfoResp)
+				err = json.Unmarshal(result, &indexResp)
+				if err != nil {
+					utils.FileLog.Info("json.Unmarshal 获取计算指标所依赖的基础指标失败:" + err.Error())
+					return
+				}
+				if indexResp.Ret != 200 {
+					fmt.Println("获取计算指标所依赖的基础指标失败 Err:" + indexResp.Msg)
+					return
+				}
+				if resp.Data.EdbInfoId > 0 {
+					total++
+				}
+			}
+
+			if total == len(cv.BaseEdbInfoCode) {
+				needAddIndexArr = append(needAddIndexArr, cv.EdbCode)
+			}
+		}
+	}
+	f.Save()
+
+	for k, v := range needAddIndexArr { //需要同步的计算指标
+		fmt.Println(k, v)
+	}
+}
+
+func hzDataHttpPost(method string, postDataMap map[string]interface{}) (result string, err error) {
+	bytesData, err := handlePostData(postDataMap)
+	if err != nil {
+		return
+	}
+
+	client := &http.Client{}
+	req, err := http.NewRequest("POST", HZ_DATA_API+method, bytes.NewReader(bytesData))
+	if err != nil {
+		return "", err
+	}
+	req.Header.Set("content-type", "application/json")
+	resp, err := client.Do(req)
+	if err != nil {
+		return "", err
+	}
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return "", err
+	}
+	result = string(body)
+	return
+}
+
+// handlePostData 处理post请求数据
+func handlePostData(postDataMap map[string]interface{}) (bytesData []byte, err error) {
+	postDataMap["nonce_str"] = utils.GetRandString(16) // 随机字符串
+	postDataMap["timestamp"] = time.Now().Unix()       //当前格林威治时间,int64类型
+	postDataMap["appid"] = utils.APPID                 //当前格林威治时间,int64类型
+	// 待签名数据
+	signData := convertParamInterface(postDataMap)
+	sign, err := getSignData(signData)
+	if err != nil {
+		return
+	}
+	postDataMap["sign"] = sign //签名
+
+	bytesData, err = json.Marshal(postDataMap)
+
+	return
+}
+
+// 将请求传入的数据格式转换成签名需要的格式(目前只能处理简单的类型,数组、对象暂不支持)
+func convertParamInterface(params map[string]interface{}) (signData map[string]string) {
+	signData = make(map[string]string)
+	for key := range params {
+		val := ``
+		//fmt.Println("key", key, ";val:", params[key], ";type:", reflect.TypeOf(params[key]))
+		//signData[key] = params[key][0]
+		tmpVal := params[key]
+		switch reflect.TypeOf(tmpVal).Kind() {
+		case reflect.String:
+			val = fmt.Sprint(tmpVal)
+		case reflect.Int, reflect.Int16, reflect.Int64, reflect.Int32, reflect.Int8:
+			val = fmt.Sprint(tmpVal)
+		case reflect.Uint, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint64:
+			val = fmt.Sprint(tmpVal)
+		case reflect.Bool:
+			val = fmt.Sprint(tmpVal)
+		case reflect.Float64:
+			decimalNum := decimal.NewFromFloat(tmpVal.(float64))
+			val = decimalNum.String()
+			//val = strconv.FormatFloat(tmpVal.(float64), 'E', -1, 64) //float64
+		case reflect.Float32:
+			decimalNum := decimal.NewFromFloat32(tmpVal.(float32))
+			val = decimalNum.String()
+		}
+		signData[key] = val
+	}
+	return signData
+}
+
+// getSignData 获取参数签名
+func getSignData(postData map[string]string) (sign string, err error) {
+	appid := utils.APPID
+	if appid == "" {
+		err = errors.New("参数异常,缺少appid")
+		return
+	}
+
+	secret := utils.SECRET
+	if secret == "" {
+		err = errors.New("参数异常,缺少secret")
+		return
+	}
+
+	if postData["nonce_str"] == "" {
+		err = errors.New("参数异常,缺少随机字符串")
+		return
+	}
+	if postData["timestamp"] == "" {
+		err = errors.New("参数异常,缺少时间戳")
+		return
+	}
+
+	//先取出除sign外的所有的提交的参数key
+	var keys []string
+	for k := range postData {
+		if k != "sign" {
+			keys = append(keys, k)
+		}
+	}
+
+	//1,根据参数名称的ASCII码表的顺序排序
+	sort.Strings(keys)
+
+	//2 根据排序后的参数名称,取出对应的值,并拼接字符串
+	var signStr string
+	for _, v := range keys {
+		signStr += v + "=" + postData[v] + "&"
+	}
+	//3,全转小写(md5(拼装的字符串后+分配给你的app_secret))
+	//sign := strings.ToLower(fmt.Sprintf("%x", md5.Sum([]byte(strings.Trim(signStr, "&")+key))))
+
+	//md5.Sum([]byte(signStr+"key="+key))  这是md5加密出来后的每个字符的ascall码,需要再转换成对应的字符
+	//3,全转大写(md5(拼装的字符串后+分配给你的app_secret))
+	sign = strings.ToUpper(fmt.Sprintf("%x", md5.Sum([]byte(signStr+"secret="+secret))))
+
+	return
+}

+ 3 - 3
services/task.go

@@ -23,8 +23,8 @@ func Task() {
 	IndexSourceMap["wind"] = utils.DATA_SOURCE_WIND
 
 	time.Sleep(3 * time.Second)
-	fmt.Println("start InitMysteelIndex")
-	InitMysteelIndex()
-	fmt.Println("end InitMysteelIndex")
+	fmt.Println("start InitCalculateIndex")
+	InitCalculateIndex()
+	fmt.Println("end InitCalculateIndex")
 	fmt.Println("task end")
 }

+ 6 - 0
utils/config.go

@@ -18,6 +18,12 @@ var (
 	EDB_LIB_Md5_KEY     string
 )
 
+// 弘则
+const (
+	APPID  = "SJCrpOPvagscPxEv"
+	SECRET = "gLLjT72uFHQZEFtaFCuoZegD1z2ezfyX"
+)
+
 func init() {
 	tmpRunMode, err := web.AppConfig.String("run_mode")
 	if err != nil {