edb_data_ys.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  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. "fmt"
  12. "github.com/beego/beego/v2/client/orm"
  13. "hongze/hongze_chart_lib/utils"
  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) (min_date, max_date string, err error) {
  29. o := orm.NewOrmUsingDB("data")
  30. sql := ` SELECT MIN(data_time) AS min_date,MAX(data_time) AS max_date FROM edb_data_ys WHERE edb_code=? `
  31. err = o.Raw(sql, edbCode).QueryRow(&min_date, &max_date)
  32. return
  33. }
  34. //有色
  35. func GetEdbDataByYs(edbCode, startDate, endDate string) (searchItem *EdbInfoSearch, err error) {
  36. o := orm.NewOrmUsingDB("data")
  37. o.Begin()
  38. searchItem = new(EdbInfoSearch)
  39. searchItem.EdbCode = edbCode
  40. smmBaseDataAll, err := GetBaseFromSmmDataAllByIndexCode(edbCode)
  41. if err != nil && err.Error() != utils.ErrNoRow() {
  42. return
  43. }
  44. var isAdd bool
  45. addSql := ` INSERT INTO edb_data_ys(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
  46. dataList := make([]*EdbInfoSearchData, 0)
  47. existMap := make(map[string]string)
  48. for _, sv := range smmBaseDataAll {
  49. eDate := sv.DataTime
  50. dataTime, err := time.Parse(utils.FormatDate, eDate)
  51. if err != nil {
  52. fmt.Println("time.Parse Err:" + eDate)
  53. return nil, err
  54. }
  55. timestamp := dataTime.UnixNano() / 1e6
  56. timeStr := fmt.Sprintf("%d", timestamp)
  57. if _, ok := existMap[eDate]; !ok {
  58. addSql += GetAddSql("0", edbCode, eDate, timeStr, sv.Value)
  59. isAdd = true
  60. }
  61. existMap[eDate] = sv.Value
  62. }
  63. if isAdd {
  64. addSql = strings.TrimRight(addSql, ",")
  65. utils.FileLog.Info("addSql:" + addSql)
  66. _, err = o.Raw(addSql).Exec()
  67. if err != nil {
  68. return searchItem, err
  69. }
  70. }
  71. if err != nil {
  72. o.Rollback()
  73. } else {
  74. o.Commit()
  75. }
  76. size := utils.EDB_DATA_LIMIT
  77. dataList, err = GetEdbDataAllByEdbCode(edbCode, utils.DATA_SOURCE_YS, size)
  78. if err != nil {
  79. utils.FileLogData.Info("GetEdbDataThsByCode Err:%s", err.Error())
  80. return searchItem, err
  81. }
  82. minDate, maxDate, err := GetEdbDataYsMaxAndMinDate(edbCode)
  83. if err != nil {
  84. return searchItem, err
  85. }
  86. searchItem.DataList = dataList
  87. searchItem.StartDate = minDate
  88. searchItem.EndDate = maxDate
  89. if searchItem.DataList == nil {
  90. searchItem.DataList = make([]*EdbInfoSearchData, 0)
  91. }
  92. return
  93. }
  94. //全部刷新有色数据
  95. func RefreshAllEdbDataByYs(edbInfoId, source int, edbCode, startDate, endDate string) (err error) {
  96. o := orm.NewOrmUsingDB("data")
  97. o.Begin()
  98. defer func() {
  99. if err != nil {
  100. o.Rollback()
  101. } else {
  102. o.Commit()
  103. }
  104. }()
  105. if err != nil {
  106. return
  107. }
  108. edbInfoIdStr := strconv.Itoa(edbInfoId)
  109. //获取数据
  110. err = SyncSmmIndexDataBase(edbCode, startDate, endDate)
  111. if err != nil {
  112. err = errors.New("SyncSmmIndexDataBase Err:" + err.Error())
  113. return err
  114. }
  115. //获取已存在指标所有数据
  116. existDataList := make([]*EdbDataBase, 0)
  117. dataTableName := GetEdbDataTableName(source)
  118. sql := `SELECT * FROM %s WHERE edb_info_id=? `
  119. sql = fmt.Sprintf(sql, dataTableName)
  120. _, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
  121. if err != nil {
  122. return err
  123. }
  124. existDataMap := make(map[string]string)
  125. for _, v := range existDataList {
  126. existDataMap[v.DataTime] = v.Value
  127. }
  128. smmDateList := make([]*BaseFromSmmDataSimple, 0)
  129. smmSql := ` SELECT * FROM base_from_smm_data WHERE index_code=? AND data_time>=? `
  130. _, err = o.Raw(smmSql, edbCode, startDate).QueryRows(&smmDateList)
  131. if err != nil {
  132. return err
  133. }
  134. addSql := ` INSERT INTO edb_data_ys(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
  135. var isAdd bool
  136. for _, sv := range smmDateList {
  137. if existVal, ok := existDataMap[sv.DataTime]; !ok {
  138. dataTime, err := time.Parse(utils.FormatDate, sv.DataTime)
  139. if err != nil {
  140. return err
  141. }
  142. timestamp := dataTime.UnixNano() / 1e6
  143. timeStr := fmt.Sprintf("%d", timestamp)
  144. addSql += GetAddSql(edbInfoIdStr, edbCode, sv.DataTime, timeStr, sv.Value)
  145. isAdd = true
  146. } else {
  147. if existVal != sv.Value {
  148. sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
  149. sql = fmt.Sprintf(sql, dataTableName)
  150. _, err = o.Raw(sql, sv.Value, edbInfoId, sv.DataTime).Exec()
  151. if err != nil {
  152. return err
  153. }
  154. }
  155. }
  156. }
  157. if isAdd {
  158. addSql = strings.TrimRight(addSql, ",")
  159. _, err = o.Raw(addSql).Exec()
  160. if err != nil {
  161. return err
  162. }
  163. }
  164. return
  165. }
  166. func SyncSmmIndexDataBase(edbCode, startDate, endDate string) (err error) {
  167. utils.FileLog.Info("start:" + time.Now().Format(utils.FormatDateTime))
  168. var smmCode string
  169. if strings.Contains(edbCode, "#") {
  170. smmCode = strings.Split(edbCode, "#")[0]
  171. } else {
  172. smmCode = edbCode
  173. }
  174. token, err := getToken("pqian@hzinsights.com", "hz123456")
  175. if err != nil {
  176. fmt.Println(err)
  177. return
  178. }
  179. baseSmmItem, err := GetBaseFromSmmBySmmCode(smmCode)
  180. if err != nil {
  181. fmt.Println(err)
  182. return
  183. }
  184. if baseSmmItem == nil {
  185. err = errors.New("GetBaseFromSmmBySmmCode Err:" + err.Error())
  186. return
  187. }
  188. smmIndexAll, err := GetBaseFromSmmIndexBySmmCode(smmCode)
  189. if err != nil {
  190. fmt.Println("GetBaseFromSmmIndex Err:" + err.Error())
  191. return
  192. }
  193. existIndexMap := make(map[string]*BaseFromSmmIndex)
  194. for _, item := range smmIndexAll {
  195. existIndexMap[item.IndexCode] = item
  196. }
  197. ysItem, err := getApiData(token, edbCode, startDate, endDate)
  198. if err != nil {
  199. fmt.Println(err)
  200. return
  201. }
  202. if ysItem != nil && ysItem.Code == 200 {
  203. frequency := ysItem.Data.Frequency
  204. indexMap := make(map[string]int)
  205. smmIndexIdMap := make(map[int]int)
  206. indexCodeMap := make(map[int]string)
  207. indexKey := 0
  208. var isDateIndex int
  209. for fk, fv := range ysItem.Data.Field {
  210. if fv.IsDate == "1" {
  211. isDateIndex = fk
  212. } else {
  213. if !strings.Contains(fv.Name, "产品名称") &&
  214. !strings.Contains(fv.Name, "单位") &&
  215. !strings.Contains(fv.Name, "时间") &&
  216. !strings.Contains(fv.Name, "备注") {
  217. indexMap[fv.DBColName] = fk
  218. indexKey += 1
  219. indexCode := smmCode + "#" + strconv.Itoa(indexKey)
  220. if findItem, ok := existIndexMap[indexCode]; !ok {
  221. ssmIndex := new(BaseFromSmmIndex)
  222. ssmIndex.Interface = smmCode
  223. ssmIndex.Name = baseSmmItem.Name
  224. ssmIndex.IndexCode = indexCode
  225. ssmIndex.IndexName = baseSmmItem.Name + "_" + fv.Name
  226. ssmIndex.Type1 = baseSmmItem.Type1
  227. ssmIndex.Type2 = baseSmmItem.Type2
  228. ssmIndex.Type3 = baseSmmItem.Type3
  229. ssmIndex.Frequency = frequency
  230. ssmIndex.Unit = fv.Unit
  231. ssmIndex.ApiStartTime = baseSmmItem.ApiStartTime
  232. ssmIndex.ApiUpdateTime = baseSmmItem.ApiUpdateTime
  233. ssmIndex.StartTime = baseSmmItem.StartTime
  234. ssmIndex.FinishTime = baseSmmItem.FinishTime
  235. ssmIndex.CreateTime = time.Now()
  236. ssmIndex.ModifyTime = time.Now()
  237. lastIndexId, err := AddBaseFromSmmIndex(ssmIndex)
  238. if err != nil {
  239. err = errors.New("AddBaseFromSmmIndex Err:" + err.Error())
  240. return err
  241. }
  242. smmIndexIdMap[fk] = int(lastIndexId)
  243. indexCodeMap[fk] = indexCode
  244. } else {
  245. smmIndexIdMap[fk] = findItem.BaseFromSmmIndexId
  246. indexCodeMap[fk] = findItem.IndexCode
  247. }
  248. }
  249. }
  250. }
  251. existDataMap := make(map[string]*BaseFromSmmData)
  252. for _, mv := range indexCodeMap {
  253. indexCode := mv
  254. dataAllList, err := GetBaseFromSmmDataAllByIndexCode(indexCode)
  255. if err != nil {
  256. err = errors.New("GetBaseFromSmmData Err:" + err.Error())
  257. return err
  258. }
  259. for _, item := range dataAllList {
  260. key := item.IndexCode + item.DataTime
  261. existDataMap[key] = item
  262. }
  263. }
  264. addExistDataMap := make(map[string]string)
  265. for _, dv := range ysItem.Data.Content {
  266. var dataTime string
  267. dataTime = dv[isDateIndex]
  268. if strings.Contains(dataTime, "Q1") {
  269. dataTime = strings.Replace(dataTime, "Q1", "-01", -1)
  270. dataTime += "-31"
  271. }
  272. if strings.Contains(dataTime, "Q2") {
  273. dataTime = strings.Replace(dataTime, "Q2", "-06", -1)
  274. dataTime += "-30"
  275. }
  276. if strings.Contains(dataTime, "Q3") {
  277. dataTime = strings.Replace(dataTime, "Q3", "-09", -1)
  278. dataTime += "-30"
  279. }
  280. if strings.Contains(dataTime, "Q4") {
  281. dataTime = strings.Replace(dataTime, "Q4", "-12", -1)
  282. dataTime += "-31"
  283. }
  284. if strings.Contains(dataTime, "H1") {
  285. dataTime = strings.Replace(dataTime, "H1", "-06", -1)
  286. dataTime += "-30"
  287. }
  288. if strings.Contains(dataTime, "H2") {
  289. dataTime = strings.Replace(dataTime, "H2", "-12", -1)
  290. dataTime += "-31"
  291. }
  292. if frequency == "月" {
  293. monthDate, err := time.Parse("2006-01", dataTime)
  294. if err != nil {
  295. fmt.Println("time.Parse:" + err.Error())
  296. }
  297. lastTime := monthDate.AddDate(0, 1, -1)
  298. lastYear, lastMonth, lastDay := lastTime.Date()
  299. var lastDate string
  300. if int(lastMonth) < 10 {
  301. lastDate = strconv.Itoa(lastYear) + "-" + "0" + strconv.Itoa(int(lastMonth)) + "-" + strconv.Itoa(lastDay)
  302. } else {
  303. lastDate = strconv.Itoa(lastYear) + "-" + strconv.Itoa(int(lastMonth)) + "-" + strconv.Itoa(lastDay)
  304. }
  305. dataTime = lastDate
  306. } else if frequency == "年" {
  307. dataTime = dataTime + "-12-31"
  308. }
  309. saveDataTime, err := time.Parse(utils.FormatDate, dataTime)
  310. if err != nil {
  311. err = errors.New("time.Parse Err:" + err.Error())
  312. return err
  313. }
  314. timestamp := saveDataTime.UnixNano() / 1e6
  315. //循环指标
  316. for _, v := range indexMap {
  317. indexCode := indexCodeMap[v]
  318. smmIndexId := smmIndexIdMap[v]
  319. dataVal := dv[v]
  320. if indexCode != "" {
  321. key := indexCode + dataTime
  322. val := strings.Replace(dataVal, ",", "", -1)
  323. if findData, dataOk := existDataMap[key]; !dataOk {
  324. if _, addOK := addExistDataMap[key]; !addOK {
  325. if val != "" && val != "-" {
  326. dataItem := new(BaseFromSmmData)
  327. dataItem.BaseFromSmmIndexId = smmIndexId
  328. dataItem.IndexCode = indexCode
  329. dataItem.DataTime = dataTime
  330. dataItem.Value = val
  331. dataItem.CreateTime = time.Now()
  332. dataItem.ModifyTime = time.Now()
  333. dataItem.DataTimestamp = timestamp
  334. _, err = AddBaseFromSmmData(dataItem)
  335. if err != nil && !strings.Contains(err.Error(), "idx_index_code_date") {
  336. fmt.Println("AddBaseFromSmmData Err:" + err.Error())
  337. err = errors.New("AddBaseFromSmmData Err:" + err.Error())
  338. return err
  339. }
  340. }
  341. }
  342. } else {
  343. if findData != nil && findData.Value != val { //修改
  344. if _, addOK := addExistDataMap[key]; !addOK {
  345. if val != "" && val != "-" {
  346. err = ModifyBaseFromSmmData(findData.SmmDataId, val)
  347. if err != nil {
  348. err = errors.New("ModifyBaseFromSmmData Err:" + err.Error())
  349. return err
  350. }
  351. }
  352. }
  353. }
  354. }
  355. addExistDataMap[key] = key
  356. }
  357. }
  358. }
  359. //修改数据开始,结束日期
  360. {
  361. indexList, err := GetBaseFromSmmIndexBySmmCode(smmCode)
  362. if err != nil {
  363. fmt.Println("GetBaseFromSmmIndexBySmmCode Err:" + err.Error())
  364. }
  365. for _, sv := range indexList {
  366. minDate, maxDate, err := GetBaseFromSmmMaxOrMinDate(sv.IndexCode)
  367. if err != nil {
  368. fmt.Println("GetEdbDataSmmMaxOrMinDate Err:" + err.Error())
  369. } else {
  370. err = ModifyBaseFromSmmMinDateAndMaxDate(sv.BaseFromSmmIndexId, minDate, maxDate)
  371. if err != nil {
  372. fmt.Println("ModifyBaseFromSmmMinDateAndMaxDate Err:" + err.Error())
  373. }
  374. }
  375. }
  376. }
  377. }
  378. return
  379. }
  380. const (
  381. dataUrl = "https://dataapi.smm.cn/GetData/" //data url (中文)
  382. //dataUrl = "https://dataapi.smm.cn/GetDataEn/" //data url (english edition)
  383. authUrl = "https://platform.smm.cn/usercenter/auth" // auth url (for all)
  384. )
  385. type TokenResp struct {
  386. Code int `json:"Code"`
  387. Msg string `json:"Msg"`
  388. Data TokenData `json:"Data"`
  389. }
  390. type TokenData struct {
  391. Token string `json:"Token"`
  392. }
  393. //获取token
  394. func getToken(userName string, password string) (string, error) {
  395. encryptAuth := md5.New()
  396. encryptAuth.Write([]byte(password)) //encrypt password with md5
  397. newPassword := hex.EncodeToString(encryptAuth.Sum(nil))
  398. resp, err := http.PostForm(authUrl, url.Values{"user_name": {userName}, "password": {newPassword}})
  399. if err != nil {
  400. return "", err
  401. }
  402. defer resp.Body.Close()
  403. body, err := ioutil.ReadAll(resp.Body)
  404. if err != nil {
  405. fmt.Println("reponse error", err)
  406. return "", err
  407. }
  408. var bodyJsonContent TokenResp
  409. if err = json.Unmarshal([]byte(body), &bodyJsonContent); err != nil {
  410. fmt.Println(err, "unmarsal failure")
  411. return "", err
  412. }
  413. var token string
  414. if bodyJsonContent.Code == 0 {
  415. token = bodyJsonContent.Data.Token
  416. }
  417. //print(token)
  418. return token, nil
  419. }
  420. //request response
  421. type DataResp struct {
  422. Code int `json:"Code"`
  423. Msg string `json:"Msg"`
  424. Data *ApiData `json:"Data"`
  425. }
  426. //api data response
  427. type ApiData struct {
  428. Status int `json:"Status"` //0 no permission,1 ok
  429. Field []ApiField `json:"Field"`
  430. Content [][]string `json:"Content"`
  431. }
  432. //api title
  433. type ApiField struct {
  434. Unit string `json:"Unit"`
  435. Info string `json:"Info"`
  436. Name string `json:"Name"`
  437. ColumnType string `json:"ColumnType"`
  438. ColIndex uint `json:"ColIndex"`
  439. IsDate string `json:"IsDate"`
  440. }
  441. type YsResult struct {
  442. Code int64 `json:"Code"`
  443. Data struct {
  444. CompanyList []interface{} `json:"CompanyList"`
  445. Content [][]string `json:"Content"`
  446. Field []struct {
  447. ColIndex int64 `json:"ColIndex"`
  448. ColumnType string `json:"ColumnType"`
  449. Info string `json:"Info"`
  450. IsDate string `json:"IsDate"`
  451. Name string `json:"Name"`
  452. Unit string `json:"Unit"`
  453. DBColName string `json:"db_col_name"`
  454. } `json:"Field"`
  455. CountPage int64 `json:"count_page"`
  456. CurrentPage int64 `json:"current_page"`
  457. Frequency string `json:"frequency"`
  458. Mindate string `json:"mindate"`
  459. PageNum int64 `json:"page_num"`
  460. Status int64 `json:"status"`
  461. TotalNum int64 `json:"total_num"`
  462. } `json:"Data"`
  463. Msg string `json:"Msg"`
  464. }
  465. /*
  466. * request data
  467. * sdatetime,edatetime ==>format:yyyy-mm-dd,
  468. * apiName ==> data.metal.com(for english)/data.smm.cn (for chinese)
  469. */
  470. func getApiData(token string, apiName string, sdatetime string, edatetime string) (item *YsResult, err error) {
  471. reqUrl := dataUrl + apiName
  472. resp, err := http.PostForm(reqUrl, url.Values{"token": {token}, "sdatetime": {sdatetime}, "edatetime": {edatetime}})
  473. if err != nil {
  474. return nil, err
  475. }
  476. defer resp.Body.Close()
  477. body, err := ioutil.ReadAll(resp.Body)
  478. if err != nil {
  479. fmt.Println("response error")
  480. return nil, err
  481. }
  482. utils.FileLog.Info("ys result:" + string(body))
  483. dataJsonContent := new(YsResult)
  484. if err = json.Unmarshal([]byte(body), &dataJsonContent); err != nil {
  485. fmt.Println(err, "data unmarshal failure")
  486. return nil, err
  487. }
  488. if dataJsonContent.Code == 200 && len(dataJsonContent.Data.Content) > 0 {
  489. return dataJsonContent, nil
  490. } else {
  491. err = errors.New("code:" + strconv.Itoa(int(dataJsonContent.Code)) + "msg:" + dataJsonContent.Msg)
  492. }
  493. return nil, nil
  494. }