init_calculate_index.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package services
  2. import (
  3. "bytes"
  4. "crypto/md5"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "github.com/shopspring/decimal"
  9. "github.com/xuri/excelize/v2"
  10. "hongze/hz_eta_data/models"
  11. "hongze/hz_eta_data/utils"
  12. "io/ioutil"
  13. "net/http"
  14. "os"
  15. "path/filepath"
  16. "reflect"
  17. "sort"
  18. "strconv"
  19. "strings"
  20. "time"
  21. )
  22. //初始化计算指标数据
  23. //classifyId:=685
  24. const (
  25. HZ_DATA_API = "https://hzdataapi.hzinsights.com/hzdataapi/"
  26. )
  27. func InitCalculateIndex() {
  28. //读取基础指标
  29. var err error
  30. defer func() {
  31. if err != nil {
  32. fmt.Println("InitBaseIndexData Err:" + err.Error())
  33. }
  34. }()
  35. //读取excel
  36. path, err := filepath.Abs(os.Args[0])
  37. if err != nil {
  38. fmt.Println(err)
  39. }
  40. dir := filepath.Dir(path)
  41. fmt.Println("dir:" + dir)
  42. dataPath := dir + "/docs/逸诺指标库(基础).xlsx"
  43. fmt.Println("dataPath:" + dataPath)
  44. f, err := excelize.OpenFile(dataPath)
  45. if err != nil {
  46. fmt.Println(err)
  47. return
  48. }
  49. defer func() {
  50. // Close the spreadsheet.
  51. if err := f.Close(); err != nil {
  52. fmt.Println(err)
  53. }
  54. }()
  55. rows, err := f.GetRows("edb_info")
  56. if err != nil {
  57. fmt.Println(err)
  58. return
  59. }
  60. method := "edb_index/detail"
  61. edbLibIndexMethod := "/edb_info/detail"
  62. var needAddIndexArr []string
  63. for rk, row := range rows {
  64. if rk <= 0 {
  65. continue
  66. }
  67. var indexCode string
  68. for ck, colCell := range row {
  69. switch ck {
  70. case 0:
  71. indexCode = colCell
  72. }
  73. }
  74. fmt.Println(rk, indexCode)
  75. if indexCode == "" {
  76. fmt.Println("指标编码不能为空")
  77. return
  78. }
  79. params := make(map[string]interface{})
  80. params["EdbCode"] = indexCode
  81. result, err := hzDataHttpPost(method, params)
  82. if err != nil {
  83. fmt.Println("hzDataHttpPost Err:" + err.Error())
  84. return
  85. }
  86. utils.FileLog.Info("hzDataHttpPost:" + string(result))
  87. resp := new(models.EdbInfoResp)
  88. err = json.Unmarshal([]byte(result), &resp)
  89. if err != nil {
  90. fmt.Println("json.Unmarshal Err:" + err.Error())
  91. return
  92. }
  93. if resp.Ret != 200 && !strings.Contains(resp.ErrMsg, "QuerySeter") {
  94. fmt.Println("resp Err:" + resp.ErrMsg)
  95. return
  96. }
  97. //指标信息不存在
  98. if resp.Data.EdbInfoId <= 0 {
  99. fmt.Println("指标:" + indexCode + ";不存在")
  100. f.SetCellStr("edb_info", "H"+strconv.Itoa(rk+1), "不存在")
  101. continue
  102. }
  103. //判断是否存在计算指标
  104. if len(resp.Data.CalculateList) <= 0 {
  105. f.SetCellStr("edb_info", "H"+strconv.Itoa(rk+1), "不存在")
  106. continue
  107. }
  108. //存在计算指标
  109. for _, cv := range resp.Data.CalculateList {
  110. //计算指标所依赖的基础指标
  111. var total int
  112. for _, bv := range cv.BaseEdbInfoCode {
  113. //判断基础指标是否存在
  114. indexMap := make(map[string]interface{})
  115. indexMap["EdbCode"] = bv.FromEdbCode
  116. result, err := PostEdbLib(indexMap, edbLibIndexMethod)
  117. if err != nil {
  118. utils.FileLog.Info("获取计算指标所依赖的基础指标失败:" + err.Error() + " result:" + string(result))
  119. return
  120. }
  121. indexResp := new(models.EdbInfoResp)
  122. err = json.Unmarshal(result, &indexResp)
  123. if err != nil {
  124. utils.FileLog.Info("json.Unmarshal 获取计算指标所依赖的基础指标失败:" + err.Error())
  125. return
  126. }
  127. if indexResp.Ret != 200 {
  128. fmt.Println("获取计算指标所依赖的基础指标失败 Err:" + indexResp.Msg)
  129. return
  130. }
  131. if resp.Data.EdbInfoId > 0 {
  132. total++
  133. }
  134. }
  135. if total == len(cv.BaseEdbInfoCode) {
  136. needAddIndexArr = append(needAddIndexArr, cv.EdbCode)
  137. }
  138. }
  139. }
  140. f.Save()
  141. for k, v := range needAddIndexArr { //需要同步的计算指标
  142. fmt.Println(k, v)
  143. }
  144. }
  145. func hzDataHttpPost(method string, postDataMap map[string]interface{}) (result string, err error) {
  146. bytesData, err := handlePostData(postDataMap)
  147. if err != nil {
  148. return
  149. }
  150. client := &http.Client{}
  151. req, err := http.NewRequest("POST", HZ_DATA_API+method, bytes.NewReader(bytesData))
  152. if err != nil {
  153. return "", err
  154. }
  155. req.Header.Set("content-type", "application/json")
  156. resp, err := client.Do(req)
  157. if err != nil {
  158. return "", err
  159. }
  160. body, err := ioutil.ReadAll(resp.Body)
  161. if err != nil {
  162. return "", err
  163. }
  164. result = string(body)
  165. return
  166. }
  167. // handlePostData 处理post请求数据
  168. func handlePostData(postDataMap map[string]interface{}) (bytesData []byte, err error) {
  169. postDataMap["nonce_str"] = utils.GetRandString(16) // 随机字符串
  170. postDataMap["timestamp"] = time.Now().Unix() //当前格林威治时间,int64类型
  171. postDataMap["appid"] = utils.APPID //当前格林威治时间,int64类型
  172. // 待签名数据
  173. signData := convertParamInterface(postDataMap)
  174. sign, err := getSignData(signData)
  175. if err != nil {
  176. return
  177. }
  178. postDataMap["sign"] = sign //签名
  179. bytesData, err = json.Marshal(postDataMap)
  180. return
  181. }
  182. // 将请求传入的数据格式转换成签名需要的格式(目前只能处理简单的类型,数组、对象暂不支持)
  183. func convertParamInterface(params map[string]interface{}) (signData map[string]string) {
  184. signData = make(map[string]string)
  185. for key := range params {
  186. val := ``
  187. //fmt.Println("key", key, ";val:", params[key], ";type:", reflect.TypeOf(params[key]))
  188. //signData[key] = params[key][0]
  189. tmpVal := params[key]
  190. switch reflect.TypeOf(tmpVal).Kind() {
  191. case reflect.String:
  192. val = fmt.Sprint(tmpVal)
  193. case reflect.Int, reflect.Int16, reflect.Int64, reflect.Int32, reflect.Int8:
  194. val = fmt.Sprint(tmpVal)
  195. case reflect.Uint, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint64:
  196. val = fmt.Sprint(tmpVal)
  197. case reflect.Bool:
  198. val = fmt.Sprint(tmpVal)
  199. case reflect.Float64:
  200. decimalNum := decimal.NewFromFloat(tmpVal.(float64))
  201. val = decimalNum.String()
  202. //val = strconv.FormatFloat(tmpVal.(float64), 'E', -1, 64) //float64
  203. case reflect.Float32:
  204. decimalNum := decimal.NewFromFloat32(tmpVal.(float32))
  205. val = decimalNum.String()
  206. }
  207. signData[key] = val
  208. }
  209. return signData
  210. }
  211. // getSignData 获取参数签名
  212. func getSignData(postData map[string]string) (sign string, err error) {
  213. appid := utils.APPID
  214. if appid == "" {
  215. err = errors.New("参数异常,缺少appid")
  216. return
  217. }
  218. secret := utils.SECRET
  219. if secret == "" {
  220. err = errors.New("参数异常,缺少secret")
  221. return
  222. }
  223. if postData["nonce_str"] == "" {
  224. err = errors.New("参数异常,缺少随机字符串")
  225. return
  226. }
  227. if postData["timestamp"] == "" {
  228. err = errors.New("参数异常,缺少时间戳")
  229. return
  230. }
  231. //先取出除sign外的所有的提交的参数key
  232. var keys []string
  233. for k := range postData {
  234. if k != "sign" {
  235. keys = append(keys, k)
  236. }
  237. }
  238. //1,根据参数名称的ASCII码表的顺序排序
  239. sort.Strings(keys)
  240. //2 根据排序后的参数名称,取出对应的值,并拼接字符串
  241. var signStr string
  242. for _, v := range keys {
  243. signStr += v + "=" + postData[v] + "&"
  244. }
  245. //3,全转小写(md5(拼装的字符串后+分配给你的app_secret))
  246. //sign := strings.ToLower(fmt.Sprintf("%x", md5.Sum([]byte(strings.Trim(signStr, "&")+key))))
  247. //md5.Sum([]byte(signStr+"key="+key)) 这是md5加密出来后的每个字符的ascall码,需要再转换成对应的字符
  248. //3,全转大写(md5(拼装的字符串后+分配给你的app_secret))
  249. sign = strings.ToUpper(fmt.Sprintf("%x", md5.Sum([]byte(signStr+"secret="+secret))))
  250. return
  251. }