edb_data_ys.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. /**
  2. * @Author: jgl
  3. * @Date: 2021/9/14 13:33
  4. */
  5. package data_manage
  6. import (
  7. "crypto/md5"
  8. "encoding/hex"
  9. "encoding/json"
  10. "errors"
  11. "eta_gn/eta_api/global"
  12. "eta_gn/eta_api/utils"
  13. "fmt"
  14. "io/ioutil"
  15. "net/http"
  16. "net/url"
  17. "strconv"
  18. "strings"
  19. "time"
  20. )
  21. type BaseFromSmmDataSimple struct {
  22. SmmDataId int `orm:"column(smm_data_id);pk"`
  23. BaseFromSmmIndexId int
  24. IndexCode string
  25. DataTime string
  26. Value string
  27. }
  28. func GetEdbDataYsMaxAndMinDate(edbCode string) (minDate, maxDate string, err error) {
  29. sql := ` SELECT MIN(data_time) AS min_date,MAX(data_time) AS max_date FROM edb_data_ys WHERE edb_code=? `
  30. var tmpDate SmmMaxOrMinDate
  31. err = global.DmSQL["data"].Raw(sql, edbCode).Scan(&tmpDate).Error
  32. if err != nil {
  33. return
  34. }
  35. minDate = tmpDate.MinDate
  36. maxDate = tmpDate.MaxDate
  37. return
  38. }
  39. func SyncSmmIndexDataBase(edbCode, startDate, endDate string) (err error) {
  40. utils.FileLog.Info("start:" + time.Now().Format(utils.FormatDateTime))
  41. var smmCode string
  42. if strings.Contains(edbCode, "#") {
  43. smmCode = strings.Split(edbCode, "#")[0]
  44. } else {
  45. smmCode = edbCode
  46. }
  47. token, err := getToken("pqian@hzinsights.com", "hz123456")
  48. if err != nil {
  49. fmt.Println(err)
  50. return
  51. }
  52. baseSmmItem, err := GetBaseFromSmmBySmmCode(smmCode)
  53. if err != nil {
  54. fmt.Println(err)
  55. return
  56. }
  57. if baseSmmItem == nil {
  58. err = errors.New("GetBaseFromSmmBySmmCode Err:" + err.Error())
  59. return
  60. }
  61. smmIndexAll, err := GetBaseFromSmmIndexBySmmCode(smmCode)
  62. if err != nil {
  63. fmt.Println("GetBaseFromSmmIndex Err:" + err.Error())
  64. return
  65. }
  66. existIndexMap := make(map[string]*BaseFromSmmIndex)
  67. for _, item := range smmIndexAll {
  68. existIndexMap[item.IndexCode] = item
  69. }
  70. ysItem, err := getApiData(token, edbCode, startDate, endDate)
  71. if err != nil {
  72. fmt.Println(err)
  73. return
  74. }
  75. if ysItem != nil && ysItem.Code == 200 {
  76. frequency := ysItem.Data.Frequency
  77. indexMap := make(map[string]int)
  78. smmIndexIdMap := make(map[int]int)
  79. indexCodeMap := make(map[int]string)
  80. indexKey := 0
  81. var isDateIndex int
  82. for fk, fv := range ysItem.Data.Field {
  83. if fv.IsDate == "1" {
  84. isDateIndex = fk
  85. } else {
  86. if !strings.Contains(fv.Name, "产品名称") &&
  87. !strings.Contains(fv.Name, "单位") &&
  88. !strings.Contains(fv.Name, "时间") &&
  89. !strings.Contains(fv.Name, "备注") {
  90. indexMap[fv.DBColName] = fk
  91. indexKey += 1
  92. indexCode := smmCode + "#" + strconv.Itoa(indexKey)
  93. if findItem, ok := existIndexMap[indexCode]; !ok {
  94. ssmIndex := new(BaseFromSmmIndex)
  95. ssmIndex.Interface = smmCode
  96. ssmIndex.Name = baseSmmItem.Name
  97. ssmIndex.IndexCode = indexCode
  98. ssmIndex.IndexName = baseSmmItem.Name + "_" + fv.Name
  99. ssmIndex.Type1 = baseSmmItem.Type1
  100. ssmIndex.Type2 = baseSmmItem.Type2
  101. ssmIndex.Type3 = baseSmmItem.Type3
  102. ssmIndex.Frequency = frequency
  103. ssmIndex.Unit = fv.Unit
  104. ssmIndex.ApiStartTime = baseSmmItem.ApiStartTime
  105. ssmIndex.ApiUpdateTime = baseSmmItem.ApiUpdateTime
  106. ssmIndex.StartTime = baseSmmItem.StartTime
  107. ssmIndex.FinishTime = baseSmmItem.FinishTime
  108. ssmIndex.CreateTime = time.Now()
  109. ssmIndex.ModifyTime = time.Now()
  110. lastIndexId, err := AddBaseFromSmmIndex(ssmIndex)
  111. if err != nil {
  112. err = errors.New("AddBaseFromSmmIndex Err:" + err.Error())
  113. return err
  114. }
  115. smmIndexIdMap[fk] = int(lastIndexId)
  116. indexCodeMap[fk] = indexCode
  117. } else {
  118. smmIndexIdMap[fk] = findItem.BaseFromSmmIndexId
  119. indexCodeMap[fk] = findItem.IndexCode
  120. }
  121. }
  122. }
  123. }
  124. existDataMap := make(map[string]*BaseFromSmmData)
  125. for _, mv := range indexCodeMap {
  126. indexCode := mv
  127. dataAllList, err := GetBaseFromSmmDataAllByIndexCode(indexCode)
  128. if err != nil {
  129. err = errors.New("GetBaseFromSmmData Err:" + err.Error())
  130. return err
  131. }
  132. for _, item := range dataAllList {
  133. key := item.IndexCode + item.DataTime
  134. existDataMap[key] = item
  135. }
  136. }
  137. addExistDataMap := make(map[string]string)
  138. for _, dv := range ysItem.Data.Content {
  139. var dataTime string
  140. dataTime = dv[isDateIndex]
  141. if strings.Contains(dataTime, "Q1") {
  142. dataTime = strings.Replace(dataTime, "Q1", "-01", -1)
  143. dataTime += "-31"
  144. }
  145. if strings.Contains(dataTime, "Q2") {
  146. dataTime = strings.Replace(dataTime, "Q2", "-06", -1)
  147. dataTime += "-30"
  148. }
  149. if strings.Contains(dataTime, "Q3") {
  150. dataTime = strings.Replace(dataTime, "Q3", "-09", -1)
  151. dataTime += "-30"
  152. }
  153. if strings.Contains(dataTime, "Q4") {
  154. dataTime = strings.Replace(dataTime, "Q4", "-12", -1)
  155. dataTime += "-31"
  156. }
  157. if strings.Contains(dataTime, "H1") {
  158. dataTime = strings.Replace(dataTime, "H1", "-06", -1)
  159. dataTime += "-30"
  160. }
  161. if strings.Contains(dataTime, "H2") {
  162. dataTime = strings.Replace(dataTime, "H2", "-12", -1)
  163. dataTime += "-31"
  164. }
  165. if frequency == "月" {
  166. monthDate, err := time.Parse("2006-01", dataTime)
  167. if err != nil {
  168. fmt.Println("time.Parse:" + err.Error())
  169. }
  170. lastTime := monthDate.AddDate(0, 1, -1)
  171. lastYear, lastMonth, lastDay := lastTime.Date()
  172. var lastDate string
  173. if int(lastMonth) < 10 {
  174. lastDate = strconv.Itoa(lastYear) + "-" + "0" + strconv.Itoa(int(lastMonth)) + "-" + strconv.Itoa(lastDay)
  175. } else {
  176. lastDate = strconv.Itoa(lastYear) + "-" + strconv.Itoa(int(lastMonth)) + "-" + strconv.Itoa(lastDay)
  177. }
  178. dataTime = lastDate
  179. } else if frequency == "年" {
  180. dataTime = dataTime + "-12-31"
  181. }
  182. saveDataTime, err := time.Parse(utils.FormatDate, dataTime)
  183. if err != nil {
  184. err = errors.New("time.Parse Err:" + err.Error())
  185. return err
  186. }
  187. timestamp := saveDataTime.UnixNano() / 1e6
  188. //循环指标
  189. for _, v := range indexMap {
  190. indexCode := indexCodeMap[v]
  191. smmIndexId := smmIndexIdMap[v]
  192. dataVal := dv[v]
  193. if indexCode != "" {
  194. key := indexCode + dataTime
  195. val := strings.Replace(dataVal, ",", "", -1)
  196. if findData, dataOk := existDataMap[key]; !dataOk {
  197. if _, addOK := addExistDataMap[key]; !addOK {
  198. if val != "" && val != "-" {
  199. dataItem := new(BaseFromSmmData)
  200. dataItem.BaseFromSmmIndexId = smmIndexId
  201. dataItem.IndexCode = indexCode
  202. dataItem.DataTime = dataTime
  203. dataItem.Value = val
  204. dataItem.CreateTime = time.Now()
  205. dataItem.ModifyTime = time.Now()
  206. dataItem.DataTimestamp = timestamp
  207. _, err = AddBaseFromSmmData(dataItem)
  208. if err != nil && !strings.Contains(err.Error(), "idx_index_code_date") {
  209. fmt.Println("AddBaseFromSmmData Err:" + err.Error())
  210. err = errors.New("AddBaseFromSmmData Err:" + err.Error())
  211. return err
  212. }
  213. }
  214. }
  215. } else {
  216. if findData != nil && findData.Value != val { //修改
  217. if _, addOK := addExistDataMap[key]; !addOK {
  218. if val != "" && val != "-" {
  219. err = ModifyBaseFromSmmData(findData.SmmDataId, val)
  220. if err != nil {
  221. err = errors.New("ModifyBaseFromSmmData Err:" + err.Error())
  222. return err
  223. }
  224. }
  225. }
  226. }
  227. }
  228. addExistDataMap[key] = key
  229. }
  230. }
  231. }
  232. //修改数据开始,结束日期
  233. {
  234. indexList, err := GetBaseFromSmmIndexBySmmCode(smmCode)
  235. if err != nil {
  236. fmt.Println("GetBaseFromSmmIndexBySmmCode Err:" + err.Error())
  237. }
  238. for _, sv := range indexList {
  239. minDate, maxDate, err := GetBaseFromSmmMaxOrMinDate(sv.IndexCode)
  240. if err != nil {
  241. fmt.Println("GetEdbDataSmmMaxOrMinDate Err:" + err.Error())
  242. } else {
  243. err = ModifyBaseFromSmmMinDateAndMaxDate(sv.BaseFromSmmIndexId, minDate, maxDate)
  244. if err != nil {
  245. fmt.Println("ModifyBaseFromSmmMinDateAndMaxDate Err:" + err.Error())
  246. }
  247. }
  248. }
  249. }
  250. }
  251. return
  252. }
  253. const (
  254. dataUrl = "https://dataapi.smm.cn/GetData/" //data url (中文)
  255. //dataUrl = "https://dataapi.smm.cn/GetDataEn/" //data url (english edition)
  256. authUrl = "https://platform.smm.cn/usercenter/auth" // auth url (for all)
  257. )
  258. type TokenResp struct {
  259. Code int `json:"Code"`
  260. Msg string `json:"Msg"`
  261. Data TokenData `json:"Data"`
  262. }
  263. type TokenData struct {
  264. Token string `json:"Token"`
  265. }
  266. // 获取token
  267. func getToken(userName string, password string) (string, error) {
  268. encryptAuth := md5.New()
  269. encryptAuth.Write([]byte(password)) //encrypt password with md5
  270. newPassword := hex.EncodeToString(encryptAuth.Sum(nil))
  271. resp, err := http.PostForm(authUrl, url.Values{"user_name": {userName}, "password": {newPassword}})
  272. if err != nil {
  273. return "", err
  274. }
  275. defer resp.Body.Close()
  276. body, err := ioutil.ReadAll(resp.Body)
  277. if err != nil {
  278. fmt.Println("reponse error", err)
  279. return "", err
  280. }
  281. var bodyJsonContent TokenResp
  282. if err = json.Unmarshal([]byte(body), &bodyJsonContent); err != nil {
  283. fmt.Println(err, "unmarsal failure")
  284. return "", err
  285. }
  286. var token string
  287. if bodyJsonContent.Code == 0 {
  288. token = bodyJsonContent.Data.Token
  289. }
  290. //print(token)
  291. return token, nil
  292. }
  293. // request response
  294. type DataResp struct {
  295. Code int `json:"Code"`
  296. Msg string `json:"Msg"`
  297. Data *ApiData `json:"Data"`
  298. }
  299. // api data response
  300. type ApiData struct {
  301. Status int `json:"Status"` //0 no permission,1 ok
  302. Field []ApiField `json:"Field"`
  303. Content [][]string `json:"Content"`
  304. }
  305. // api title
  306. type ApiField struct {
  307. Unit string `json:"Unit"`
  308. Info string `json:"Info"`
  309. Name string `json:"Name"`
  310. ColumnType string `json:"ColumnType"`
  311. ColIndex uint `json:"ColIndex"`
  312. IsDate string `json:"IsDate"`
  313. }
  314. type YsResult struct {
  315. Code int64 `json:"Code"`
  316. Data struct {
  317. CompanyList []interface{} `json:"CompanyList"`
  318. Content [][]string `json:"Content"`
  319. Field []struct {
  320. ColIndex int64 `json:"ColIndex"`
  321. ColumnType string `json:"ColumnType"`
  322. Info string `json:"Info"`
  323. IsDate string `json:"IsDate"`
  324. Name string `json:"Name"`
  325. Unit string `json:"Unit"`
  326. DBColName string `json:"db_col_name"`
  327. } `json:"Field"`
  328. CountPage int64 `json:"count_page"`
  329. CurrentPage int64 `json:"current_page"`
  330. Frequency string `json:"frequency"`
  331. Mindate string `json:"mindate"`
  332. PageNum int64 `json:"page_num"`
  333. Status int64 `json:"status"`
  334. TotalNum int64 `json:"total_num"`
  335. } `json:"Data"`
  336. Msg string `json:"Msg"`
  337. }
  338. /*
  339. * request data
  340. * sdatetime,edatetime ==>format:yyyy-mm-dd,
  341. * apiName ==> data.metal.com(for english)/data.smm.cn (for chinese)
  342. */
  343. func getApiData(token string, apiName string, sdatetime string, edatetime string) (item *YsResult, err error) {
  344. reqUrl := dataUrl + apiName
  345. resp, err := http.PostForm(reqUrl, url.Values{"token": {token}, "sdatetime": {sdatetime}, "edatetime": {edatetime}})
  346. if err != nil {
  347. return nil, err
  348. }
  349. defer resp.Body.Close()
  350. body, err := ioutil.ReadAll(resp.Body)
  351. if err != nil {
  352. fmt.Println("response error")
  353. return nil, err
  354. }
  355. utils.FileLog.Info("ys result:" + string(body))
  356. dataJsonContent := new(YsResult)
  357. if err = json.Unmarshal([]byte(body), &dataJsonContent); err != nil {
  358. fmt.Println(err, "data unmarshal failure")
  359. return nil, err
  360. }
  361. if dataJsonContent.Code == 200 && len(dataJsonContent.Data.Content) > 0 {
  362. return dataJsonContent, nil
  363. } else {
  364. err = errors.New("code:" + strconv.Itoa(int(dataJsonContent.Code)) + "msg:" + dataJsonContent.Msg)
  365. }
  366. return nil, nil
  367. }