base_from_ths_hf.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. package controllers
  2. import (
  3. "encoding/json"
  4. "eta/eta_index_lib/logic"
  5. "eta/eta_index_lib/models"
  6. "eta/eta_index_lib/models/mgo"
  7. "eta/eta_index_lib/services"
  8. "eta/eta_index_lib/utils"
  9. "fmt"
  10. "strconv"
  11. "strings"
  12. "time"
  13. )
  14. // ThsHfController 同花顺高频数据
  15. type ThsHfController struct {
  16. BaseAuthController
  17. }
  18. // GetData
  19. // @Title 同花顺高频数据-获取数据
  20. // @Description 同花顺高频数据-获取数据
  21. // @Success 200 {object} models.ThsHfSearchEdbReq
  22. // @router /hf/edb_data [post]
  23. func (this *ThsHfController) GetData() {
  24. br := new(models.BaseResponse).Init()
  25. defer func() {
  26. if br.ErrMsg == "" {
  27. br.IsSendEmail = false
  28. }
  29. this.Data["json"] = br
  30. this.ServeJSON()
  31. }()
  32. var params models.ThsHfSearchEdbReq
  33. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &params); e != nil {
  34. br.Msg = "参数解析异常"
  35. br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
  36. return
  37. }
  38. params.StockCode = strings.TrimSpace(params.StockCode)
  39. if params.StockCode == "" {
  40. br.Msg = "请输入证券代码"
  41. return
  42. }
  43. stockCodes := strings.Split(params.StockCode, ",")
  44. if len(stockCodes) == 0 {
  45. br.Msg = "请输入证券代码"
  46. return
  47. }
  48. if len(stockCodes) > 10 {
  49. br.Msg = "最多输入10个证券代码"
  50. return
  51. }
  52. params.EdbCode = strings.TrimSpace(params.EdbCode)
  53. if params.EdbCode == "" {
  54. br.Msg = "请输入指标代码"
  55. return
  56. }
  57. edbCodes := strings.Split(params.EdbCode, ",")
  58. if len(edbCodes) == 0 {
  59. br.Msg = "请输入指标代码"
  60. return
  61. }
  62. if len(edbCodes) > 20 {
  63. br.Msg = "最多选择/输入20个指标代码"
  64. return
  65. }
  66. if params.StartTime == "" {
  67. br.Msg = "请选择起始时间"
  68. return
  69. }
  70. _, e := time.ParseInLocation(utils.FormatDateTime, params.StartTime, time.Local)
  71. if e != nil {
  72. br.Msg = "起始时间格式有误"
  73. br.ErrMsg = fmt.Sprintf("起始时间格式有误, %v", e)
  74. return
  75. }
  76. // 结束时间选填, 不填则为当前时间
  77. if params.EndTime != "" {
  78. _, e := time.ParseInLocation(utils.FormatDateTime, params.EndTime, time.Local)
  79. if e != nil {
  80. br.Msg = "截止时间格式有误"
  81. br.ErrMsg = fmt.Sprintf("截止时间格式有误, %v", e)
  82. return
  83. }
  84. }
  85. if params.EndTime == "" {
  86. params.EndTime = time.Now().Local().Format(utils.FormatDateTime)
  87. }
  88. if !utils.InArrayByInt(models.ThsHfPeriodArr, params.Interval) {
  89. br.Msg = "时间周期有误"
  90. br.ErrMsg = fmt.Sprintf("时间周期有误, Interval: %d", params.Interval)
  91. return
  92. }
  93. if params.CPS != "" && !utils.InArrayByStr(models.ThsHfCPSArr, params.CPS) {
  94. br.Msg = "复权方式有误"
  95. br.ErrMsg = fmt.Sprintf("复权方式有误, CPS: %s", params.CPS)
  96. return
  97. }
  98. if params.BaseDate != "" {
  99. _, e = time.ParseInLocation(utils.FormatDate, params.BaseDate, time.Local)
  100. if e != nil {
  101. br.Msg = "复权基点格式有误"
  102. br.ErrMsg = fmt.Sprintf("复权基点格式有误, %v", e)
  103. return
  104. }
  105. }
  106. if params.Fill != "" && !utils.InArrayByStr(models.ThsHfFillArr, params.Fill) {
  107. br.Msg = "非交易间隔处理有误"
  108. br.ErrMsg = fmt.Sprintf("非交易间隔处理有误, Fill: %s", params.Fill)
  109. return
  110. }
  111. // 根据配置获取指标数据
  112. indexes, e := services.GetEdbDataFromThsHf(params, "")
  113. if e != nil {
  114. br.Msg = "获取失败"
  115. br.ErrMsg = fmt.Sprintf("获取同花顺高频指标失败, %v", e)
  116. return
  117. }
  118. br.Data = indexes
  119. br.Ret = 200
  120. br.Success = true
  121. br.Msg = "获取成功"
  122. }
  123. // BaseAdd
  124. // @Title 同花顺高频数据-新增至数据源
  125. // @Description 同花顺高频数据-新增至数据源
  126. // @Success 200 {object} models.ThsHfBaseAddReq
  127. // @router /hf/base/add [post]
  128. func (this *ThsHfController) BaseAdd() {
  129. br := new(models.BaseResponse).Init()
  130. defer func() {
  131. if br.ErrMsg == "" {
  132. br.IsSendEmail = false
  133. }
  134. this.Data["json"] = br
  135. this.ServeJSON()
  136. }()
  137. var params models.ThsHfBaseAddReq
  138. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &params); e != nil {
  139. br.Msg = "参数解析异常"
  140. br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
  141. return
  142. }
  143. params.StockCode = strings.TrimSpace(params.StockCode)
  144. if params.StockCode == "" {
  145. br.Msg = "请输入证券代码"
  146. return
  147. }
  148. params.EdbCode = strings.TrimSpace(params.EdbCode)
  149. if params.EdbCode == "" {
  150. br.Msg = "请输入指标代码"
  151. return
  152. }
  153. if params.StartTime == "" {
  154. br.Msg = "请选择起始时间"
  155. return
  156. }
  157. startTime, e := time.ParseInLocation(utils.FormatDateTime, params.StartTime, time.Local)
  158. if e != nil {
  159. br.Msg = "起始时间格式有误"
  160. br.ErrMsg = fmt.Sprintf("起始时间格式有误, %v", e)
  161. return
  162. }
  163. var endTime time.Time
  164. if params.EndTime != "" {
  165. ed, e := time.ParseInLocation(utils.FormatDateTime, params.EndTime, time.Local)
  166. if e != nil {
  167. br.Msg = "截止时间格式有误"
  168. br.ErrMsg = fmt.Sprintf("截止时间格式有误, %v", e)
  169. return
  170. }
  171. endTime = ed
  172. }
  173. if !utils.InArrayByInt(models.ThsHfPeriodArr, params.Interval) {
  174. br.Msg = "时间周期有误"
  175. br.ErrMsg = fmt.Sprintf("时间周期有误, Interval: %d", params.Interval)
  176. return
  177. }
  178. if params.CPS != "" && !utils.InArrayByStr(models.ThsHfCPSArr, params.CPS) {
  179. br.Msg = "复权方式有误"
  180. br.ErrMsg = fmt.Sprintf("复权方式有误, CPS: %s", params.CPS)
  181. return
  182. }
  183. if params.BaseDate != "" {
  184. _, e = time.ParseInLocation(utils.FormatDate, params.BaseDate, time.Local)
  185. if e != nil {
  186. br.Msg = "复权基点格式有误"
  187. br.ErrMsg = fmt.Sprintf("复权基点格式有误, %v", e)
  188. return
  189. }
  190. }
  191. if params.Fill != "" && !utils.InArrayByStr(models.ThsHfFillArr, params.Fill) {
  192. br.Msg = "非交易间隔处理有误"
  193. br.ErrMsg = fmt.Sprintf("非交易间隔处理有误, Fill: %s", params.Fill)
  194. return
  195. }
  196. if params.ClassifyId <= 0 {
  197. br.Msg = "请选择分类"
  198. return
  199. }
  200. params.IndexName = strings.TrimSpace(params.IndexName)
  201. if params.IndexName == "" {
  202. br.Msg = "请输入指标名称"
  203. return
  204. }
  205. if params.Frequency == "" {
  206. br.Msg = "请输入频度"
  207. return
  208. }
  209. // 缓存
  210. source := utils.DATA_SOURCE_THS
  211. subSource := utils.DATA_SUB_SOURCE_HIGH_FREQUENCY
  212. cacheKey := fmt.Sprintf("%s_%d_%d_%s_%s", utils.CACHE_BASE_EDB_ADD, source, subSource, params.StockCode, params.EdbCode)
  213. defer func() {
  214. _ = utils.Rc.Delete(cacheKey)
  215. }()
  216. if utils.Rc.IsExist(cacheKey) {
  217. br.Ret = 501
  218. br.Success = true
  219. br.Msg = "系统处理中,请稍后重试"
  220. return
  221. }
  222. utils.Rc.SetNX(cacheKey, 1, 3*time.Minute)
  223. // 已添加则忽略
  224. indexOb := new(models.BaseFromThsHfIndex)
  225. {
  226. cond := fmt.Sprintf(" AND %s = ? AND %s = ?", indexOb.Cols().StockCode, indexOb.Cols().Indicator)
  227. pars := make([]interface{}, 0)
  228. pars = append(pars, params.StockCode, params.EdbCode)
  229. item, e := indexOb.GetItemByCondition(cond, pars, "")
  230. if e != nil && e.Error() != utils.ErrNoRow() {
  231. br.Msg = "操作失败"
  232. br.ErrMsg = fmt.Sprintf("获取原始指标失败, %v", e)
  233. return
  234. }
  235. if item != nil {
  236. br.Ret = 200
  237. br.Success = true
  238. br.Msg = "操作成功"
  239. return
  240. }
  241. }
  242. // 获取指标数据
  243. var apiPars models.ThsHfSearchEdbReq
  244. apiPars.StockCode = params.StockCode
  245. apiPars.EdbCode = params.EdbCode
  246. apiPars.StartTime = params.StartTime
  247. apiPars.EndTime = params.EndTime
  248. apiPars.Interval = params.Interval
  249. apiPars.Fill = params.Fill
  250. apiPars.CPS = params.CPS
  251. apiPars.BaseDate = params.BaseDate
  252. indexes, e := services.GetEdbDataFromThsHf(apiPars, "")
  253. if e != nil {
  254. br.Msg = "操作失败"
  255. br.ErrMsg = fmt.Sprintf("获取同花顺高频指标失败, %v", e)
  256. return
  257. }
  258. if len(indexes) == 0 {
  259. br.Msg = "未搜索到指标"
  260. br.ErrMsg = "未搜索到指标"
  261. return
  262. }
  263. indexWithData := indexes[0]
  264. indexItem := new(models.BaseFromThsHfIndex)
  265. indexItem.BaseFromThsHfClassifyId = params.ClassifyId
  266. indexItem.IndexCode = fmt.Sprintf("%s%s%s%s", utils.ThsHf, params.StockCode, params.EdbCode, params.Frequency)
  267. indexItem.IndexName = params.IndexName
  268. indexItem.Unit = params.Unit
  269. indexItem.Frequency = params.Frequency
  270. indexItem.StartDate = startTime
  271. indexItem.EndDate = endTime
  272. indexItem.SysUserId = params.SysAdminId
  273. indexItem.SysUserRealName = params.SysAdminName
  274. terminal, e := services.GetFirstTerminal(utils.DATA_SOURCE_THS, "")
  275. if e != nil {
  276. br.Msg = "终端未配置"
  277. br.ErrMsg = fmt.Sprintf("终端未配置, %v", e)
  278. return
  279. }
  280. indexItem.TerminalCode = terminal.TerminalCode
  281. indexItem.StockCode = params.StockCode
  282. indexItem.Indicator = params.EdbCode
  283. b, e := json.Marshal(apiPars)
  284. if e != nil {
  285. br.Msg = "操作失败"
  286. br.ErrMsg = fmt.Sprintf("API入参JSON格式化失败, %v", e)
  287. return
  288. }
  289. indexItem.ApiPars = string(b)
  290. if len(indexWithData.IndexData) > 0 {
  291. indexItem.StartDate = indexWithData.IndexData[0].DataTime
  292. indexItem.EndDate = indexWithData.IndexData[len(indexWithData.IndexData)-1].DataTime
  293. lastVal, e := utils.FormatFloatPlaces(indexWithData.IndexData[0].Value, 4)
  294. if e != nil {
  295. br.Msg = "操作失败"
  296. br.ErrMsg = fmt.Sprintf("格式化最新值失败, val: %v, err: %v", indexWithData.IndexData[0].Value, e)
  297. return
  298. }
  299. indexItem.LatestValue = lastVal
  300. }
  301. indexItem.CreateTime = time.Now().Local()
  302. indexItem.ModifyTime = time.Now().Local()
  303. // 新增指标
  304. if e := indexItem.Create(); e != nil {
  305. br.Msg = "操作失败"
  306. br.ErrMsg = fmt.Sprintf("新增指标失败, %v", e)
  307. return
  308. }
  309. // 新增数据
  310. if utils.UseMongo {
  311. dataList := make([]interface{}, 0)
  312. for _, v := range indexWithData.IndexData {
  313. newVal, e := utils.FormatFloatPlaces(v.Value, 4)
  314. if e != nil {
  315. utils.FileLog.Info(fmt.Sprintf("FormatFloatPlaces err: %v", e))
  316. continue
  317. }
  318. dataList = append(dataList, &mgo.BaseFromThsHfData{
  319. BaseFromThsHfIndexId: int64(indexItem.BaseFromThsHfIndexId),
  320. IndexCode: indexItem.IndexCode,
  321. DataTime: v.DataTime,
  322. Value: newVal,
  323. UniqueCode: utils.MD5(fmt.Sprint(indexItem.IndexCode, v.DataTime.Format(utils.FormatDateTimeMinute))),
  324. CreateTime: time.Now().Local(),
  325. ModifyTime: time.Now().Local(),
  326. DataTimestamp: v.DataTime.UnixNano() / 1e6,
  327. })
  328. }
  329. dataOb := new(mgo.BaseFromThsHfData)
  330. if e = dataOb.BatchInsertData(500, dataList); e != nil {
  331. br.Msg = "操作失败"
  332. br.ErrMsg = fmt.Sprintf("批量新增数据失败-Mongo, %v", e)
  333. return
  334. }
  335. } else {
  336. dataOb := new(models.BaseFromThsHfData)
  337. itemData := make([]*models.BaseFromThsHfData, 0)
  338. for _, v := range indexWithData.IndexData {
  339. newVal, e := utils.FormatFloatPlaces(v.Value, 4)
  340. if e != nil {
  341. utils.FileLog.Info(fmt.Sprintf("FormatFloatPlaces err: %v", e))
  342. continue
  343. }
  344. t := new(models.BaseFromThsHfData)
  345. t.BaseFromThsHfIndexId = indexItem.BaseFromThsHfIndexId
  346. t.IndexCode = indexItem.IndexCode
  347. t.DataTime = v.DataTime
  348. t.Value = newVal
  349. t.UniqueCode = utils.MD5(fmt.Sprint(indexItem.IndexCode, v.DataTime.Format(utils.FormatDateTimeMinute)))
  350. t.CreateTime = time.Now().Local()
  351. t.ModifyTime = time.Now().Local()
  352. t.DataTimestamp = v.DataTime.UnixNano() / 1e6
  353. itemData = append(itemData, t)
  354. }
  355. if e = dataOb.CreateMulti(itemData); e != nil {
  356. br.Msg = "操作失败"
  357. br.ErrMsg = fmt.Sprintf("批量新增数据失败-MySQL, %v", e)
  358. return
  359. }
  360. }
  361. br.Ret = 200
  362. br.Success = true
  363. br.Msg = "操作成功"
  364. }
  365. // BaseRefresh
  366. // @Title 同花顺高频数据-数据源刷新
  367. // @Description 同花顺高频数据-数据源刷新
  368. // @Success 200 {object} models.ThsHfBaseRefreshReq
  369. // @router /hf/base/refresh [post]
  370. func (this *ThsHfController) BaseRefresh() {
  371. br := new(models.BaseResponse).Init()
  372. defer func() {
  373. if br.ErrMsg == "" {
  374. br.IsSendEmail = false
  375. }
  376. this.Data["json"] = br
  377. this.ServeJSON()
  378. }()
  379. var params models.ThsHfBaseRefreshReq
  380. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &params); e != nil {
  381. br.Msg = "参数解析异常"
  382. br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
  383. return
  384. }
  385. params.BaseIndexCode = strings.TrimSpace(params.BaseIndexCode)
  386. if params.BaseIndexCode == "" {
  387. br.Msg = "参数异常"
  388. br.ErrMsg = fmt.Sprintf("参数异常, BaseIndexCode: %s", params.BaseIndexCode)
  389. return
  390. }
  391. if params.RefreshType <= 0 {
  392. params.RefreshType = 1
  393. }
  394. indexItem := new(models.BaseFromThsHfIndex)
  395. {
  396. ob := new(models.BaseFromThsHfIndex)
  397. cond := fmt.Sprintf(" AND %s = ?", ob.Cols().IndexCode)
  398. pars := make([]interface{}, 0)
  399. pars = append(pars, params.BaseIndexCode)
  400. item, e := ob.GetItemByCondition(cond, pars, "")
  401. if e != nil {
  402. if e.Error() == utils.ErrNoRow() {
  403. br.Msg = "指标不存在"
  404. return
  405. }
  406. br.Msg = "操作失败"
  407. br.ErrMsg = fmt.Sprintf("获取源指标失败, %v", e)
  408. return
  409. }
  410. indexItem = item
  411. }
  412. source := utils.DATA_SOURCE_THS
  413. subSource := utils.DATA_SUB_SOURCE_HIGH_FREQUENCY
  414. cacheKey := fmt.Sprintf("%s_%d_%d_%s_%s", utils.CACHE_BASE_EDB_REFRESH, source, subSource, indexItem.StockCode, indexItem.Indicator)
  415. defer func() {
  416. _ = utils.Rc.Delete(cacheKey)
  417. }()
  418. if utils.Rc.IsExist(cacheKey) {
  419. br.Ret = 501
  420. br.Success = true
  421. br.Msg = "系统处理中,请稍后重试"
  422. return
  423. }
  424. utils.Rc.SetNX(cacheKey, 1, 3*time.Minute)
  425. // API参数
  426. var apiPars models.ThsHfSearchEdbReq
  427. if e := json.Unmarshal([]byte(indexItem.ApiPars), &apiPars); e != nil {
  428. br.Msg = "操作失败"
  429. br.ErrMsg = fmt.Sprintf("源指标API参数异常, %v", e)
  430. return
  431. }
  432. // 刷新6小时: 指标开始时间前推6小时; 全部: API参数中的开始时间
  433. if params.RefreshType == 1 {
  434. apiPars.StartTime = indexItem.StartDate.Add(-6 * time.Hour).Format(utils.FormatDateTime)
  435. }
  436. // 若API参数中的结束时间不为空, 且不在EndDate之后, 那么不再刷新该指标
  437. if apiPars.EndTime != "" {
  438. apiEnd, e := time.ParseInLocation(utils.FormatDateTime, apiPars.EndTime, time.Local)
  439. if e != nil {
  440. br.Msg = "操作失败"
  441. br.ErrMsg = fmt.Sprintf("API参数结束时间有误, %v", e)
  442. return
  443. }
  444. if !apiEnd.After(indexItem.EndDate) {
  445. br.Ret = 200
  446. br.Success = true
  447. br.Msg = "该指标无需刷新"
  448. return
  449. }
  450. }
  451. // API-获取指标数据
  452. indexes, e := services.GetEdbDataFromThsHf(apiPars, indexItem.TerminalCode)
  453. if e != nil {
  454. br.Msg = "操作失败"
  455. br.ErrMsg = fmt.Sprintf("获取同花顺高频指标失败, %v", e)
  456. return
  457. }
  458. if len(indexes) == 0 {
  459. br.Msg = "未搜索到指标"
  460. br.ErrMsg = fmt.Sprintf("未搜索到指标, StockCode: %s, Indicator: %s", indexItem.StockCode, indexItem.Indicator)
  461. return
  462. }
  463. indexWithData := indexes[0]
  464. // 写入指标数据
  465. if utils.UseMongo {
  466. if e = services.RefreshThsHfBaseIndexMgo(indexItem, indexWithData, apiPars.StartTime); e != nil {
  467. br.Msg = "操作失败"
  468. br.ErrMsg = fmt.Sprintf("写入源指标数据失败-Mongo, %v", e)
  469. return
  470. }
  471. } else {
  472. if e = services.RefreshThsHfBaseIndex(indexItem, indexWithData, apiPars.StartTime); e != nil {
  473. br.Msg = "操作失败"
  474. br.ErrMsg = fmt.Sprintf("写入源指标数据失败, %v", e)
  475. return
  476. }
  477. }
  478. br.Ret = 200
  479. br.Success = true
  480. br.Msg = "操作成功"
  481. }
  482. // EdbAdd
  483. // @Title 同花顺高频数据-新增至指标库
  484. // @Description 同花顺高频数据-新增至指标库
  485. // @Success 200 {object} models.ThsHfEdbAddReq
  486. // @router /hf/edb/add [post]
  487. func (this *ThsHfController) EdbAdd() {
  488. br := new(models.BaseResponse).Init()
  489. defer func() {
  490. if br.ErrMsg == "" {
  491. br.IsSendEmail = false
  492. }
  493. this.Data["json"] = br
  494. this.ServeJSON()
  495. }()
  496. var params models.ThsHfEdbAddReq
  497. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &params); e != nil {
  498. br.Msg = "参数解析异常"
  499. br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
  500. return
  501. }
  502. if params.NewIndex == nil {
  503. br.Msg = "参数有误"
  504. br.ErrMsg = "参数有误, 指标信息有误"
  505. return
  506. }
  507. params.NewIndex.NewIndexName = strings.TrimSpace(params.NewIndex.NewIndexName)
  508. if params.NewIndex.NewIndexName == "" {
  509. br.Msg = "请输入指标名称"
  510. return
  511. }
  512. if params.NewIndex.ClassifyId <= 0 {
  513. br.Msg = "请选择分类"
  514. return
  515. }
  516. if params.NewIndex.Unit == "" {
  517. params.NewIndex.Unit = "无"
  518. }
  519. if params.NewIndex.NewFrequency == "" {
  520. br.Msg = "请输入频度"
  521. return
  522. }
  523. // 校验转换规则
  524. convertRule := params.ConvertRule
  525. if convertRule.ConvertType != 1 && convertRule.ConvertType != 2 {
  526. br.Msg = "请选择数据转换方式"
  527. return
  528. }
  529. if convertRule.ConvertType == 1 {
  530. if convertRule.ConvertFixed.FixedDay != 1 && convertRule.ConvertFixed.FixedDay != 2 {
  531. br.Msg = "请选择指定时间"
  532. return
  533. }
  534. if convertRule.ConvertFixed.FixedTime == "" {
  535. br.Msg = "请选择指定时间"
  536. return
  537. }
  538. timePrefix := time.Now().Local().Format(utils.FormatDate)
  539. st := fmt.Sprintf("%s %s", timePrefix, convertRule.ConvertFixed.FixedTime)
  540. _, e := time.Parse(utils.FormatDateTime, st)
  541. if e != nil {
  542. br.Msg = "指定时间格式有误"
  543. return
  544. }
  545. }
  546. if convertRule.ConvertType == 2 {
  547. if convertRule.ConvertArea.StartDay != 1 && convertRule.ConvertArea.StartDay != 2 {
  548. br.Msg = "请选择起始时间"
  549. return
  550. }
  551. if convertRule.ConvertArea.StartTime == "" {
  552. br.Msg = "请选择起始时间"
  553. return
  554. }
  555. var startTimePre string
  556. if convertRule.ConvertArea.StartDay == 1 {
  557. startTimePre = time.Now().Local().Format(utils.FormatDate)
  558. }
  559. if convertRule.ConvertArea.StartDay == 2 {
  560. startTimePre = time.Now().Local().AddDate(0, 0, -1).Format(utils.FormatDate)
  561. }
  562. st := fmt.Sprintf("%s %s", startTimePre, convertRule.ConvertArea.StartTime)
  563. startTime, e := time.Parse(utils.FormatDateTime, st)
  564. if e != nil {
  565. br.Msg = "起始时间格式有误"
  566. return
  567. }
  568. if convertRule.ConvertArea.EndDay != 1 && convertRule.ConvertArea.EndDay != 2 {
  569. br.Msg = "请选择截止时间"
  570. return
  571. }
  572. if convertRule.ConvertArea.EndTime == "" {
  573. br.Msg = "请选择截止时间"
  574. return
  575. }
  576. var endTimePre string
  577. if convertRule.ConvertArea.EndDay == 1 {
  578. endTimePre = time.Now().Local().Format(utils.FormatDate)
  579. }
  580. if convertRule.ConvertArea.EndDay == 2 {
  581. endTimePre = time.Now().Local().AddDate(0, 0, -1).Format(utils.FormatDate)
  582. }
  583. ed := fmt.Sprintf("%s %s", endTimePre, convertRule.ConvertArea.EndTime)
  584. endTime, e := time.Parse(utils.FormatDateTime, ed)
  585. if e != nil {
  586. br.Msg = "截止时间格式有误"
  587. return
  588. }
  589. if startTime.After(endTime) {
  590. br.Msg = "起始日期不可早于截止日期"
  591. return
  592. }
  593. }
  594. convertRuleByte, e := json.Marshal(params.ConvertRule)
  595. if e != nil {
  596. br.Msg = "操作失败"
  597. br.ErrMsg = fmt.Sprintf("转换规则JSON格式化失败, %v", e)
  598. return
  599. }
  600. // 缓存
  601. source := utils.DATA_SOURCE_THS
  602. subSource := utils.DATA_SUB_SOURCE_HIGH_FREQUENCY
  603. cacheKey := fmt.Sprintf("%s_%d_%d_%s_%s_%s", utils.CACHE_EDB_DATA_ADD, source, subSource, params.NewIndex.StockCode, params.NewIndex.EdbCode, params.NewIndex.NewFrequency)
  604. defer func() {
  605. _ = utils.Rc.Delete(cacheKey)
  606. }()
  607. if utils.Rc.IsExist(cacheKey) {
  608. br.Ret = 501
  609. br.Success = true
  610. br.Msg = "系统处理中,请稍后重试"
  611. return
  612. }
  613. utils.Rc.SetNX(cacheKey, 1, 3*time.Minute)
  614. // 校验指标/分类
  615. baseIndexOb := new(models.BaseFromThsHfIndex)
  616. baseIndex, e := baseIndexOb.GetItemById(params.NewIndex.IndexId)
  617. if e != nil {
  618. br.Msg = "原指标不存在"
  619. br.ErrMsg = fmt.Sprintf("原指标不存在, %v", e)
  620. return
  621. }
  622. _, e = models.GetEdbClassifyById(params.NewIndex.ClassifyId)
  623. if e != nil {
  624. br.Msg = "分类信息有误"
  625. br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
  626. return
  627. }
  628. // 判断指标名称是否已存在
  629. {
  630. var cond string
  631. var pars []interface{}
  632. if this.Lang == utils.EnLangVersion {
  633. cond += " AND edb_name_en = ? "
  634. } else {
  635. cond += " AND edb_name = ?"
  636. }
  637. pars = append(pars, params.NewIndex.NewIndexName)
  638. count, e := models.GetEdbInfoCountByCondition(cond, pars)
  639. if e != nil {
  640. br.Msg = "操作失败"
  641. br.ErrMsg = fmt.Sprintf("获取重名指标失败, %v", e)
  642. return
  643. }
  644. if count > 0 {
  645. br.Msg = "指标名称已存在"
  646. return
  647. }
  648. }
  649. // 排序/指标编码
  650. sortMax, e := models.GetEdbClassifyMaxSort(params.NewIndex.ClassifyId, 0)
  651. if e != nil {
  652. br.Msg = "操作失败"
  653. br.ErrMsg = fmt.Sprintf("获取最大排序失败, %v", e)
  654. return
  655. }
  656. edbCode, e := utils.GenerateEdbCode(1, "")
  657. if e != nil {
  658. br.Msg = "操作失败"
  659. br.ErrMsg = fmt.Sprintf("生成指标编码失败, %v", e)
  660. return
  661. }
  662. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  663. uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
  664. thsOb := new(models.EdbThsHf)
  665. var addPars models.ThsHfAddBaseParams
  666. addPars.EdbCode = edbCode
  667. addPars.EdbName = params.NewIndex.NewIndexName
  668. addPars.Unit = params.NewIndex.Unit
  669. addPars.Frequency = params.NewIndex.NewFrequency
  670. addPars.Sort = sortMax + 1
  671. addPars.ClassifyId = params.NewIndex.ClassifyId
  672. addPars.SysUserId = params.NewIndex.SysAdminId
  673. addPars.SysUserRealName = params.NewIndex.SysAdminName
  674. addPars.UniqueCode = uniqueCode
  675. addPars.ConvertRule = string(convertRuleByte)
  676. edbInfo, e := thsOb.Add(addPars, baseIndex)
  677. if e != nil {
  678. br.Msg = "新增失败"
  679. br.ErrMsg = fmt.Sprintf("新增指标失败, %v", e)
  680. return
  681. }
  682. // 更新指标最值
  683. if e = thsOb.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo); e != nil {
  684. br.Msg = "刷新指标失败"
  685. br.ErrMsg = fmt.Sprintf("更新指标最值失败, %v", e)
  686. return
  687. }
  688. // 添加到es
  689. go logic.UpdateEs(edbInfo.EdbInfoId)
  690. br.Ret = 200
  691. br.Success = true
  692. br.Msg = "操作成功"
  693. }
  694. // EdbRefresh
  695. // @Title 同花顺高频数据-指标库刷新
  696. // @Description 同花顺高频数据-指标库刷新
  697. // @Success 200 {object} models.RefreshEdbInfoReq
  698. // @router /hf/edb/refresh [post]
  699. func (this *ThsHfController) EdbRefresh() {
  700. br := new(models.BaseResponse).Init()
  701. defer func() {
  702. if br.ErrMsg == "" {
  703. br.IsSendEmail = false
  704. }
  705. this.Data["json"] = br
  706. this.ServeJSON()
  707. }()
  708. var req models.RefreshEdbInfoReq
  709. err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
  710. if err != nil {
  711. br.Msg = "参数解析异常!"
  712. br.ErrMsg = "参数解析失败,Err:" + err.Error()
  713. return
  714. }
  715. if req.EdbCode == "" {
  716. br.Msg = "请输入指标编码!"
  717. br.ErrMsg = "请输入指标编码,指标编码为空"
  718. return
  719. }
  720. if req.EdbInfoId < 0 {
  721. br.Msg = "请输入指标ID!"
  722. br.ErrMsg = "请输入指标ID"
  723. return
  724. }
  725. thsOb := new(models.EdbThsHf)
  726. source := thsOb.GetSource()
  727. subSource := thsOb.GetSubSource()
  728. cacheKey := fmt.Sprintf("%s_%d_%d_%s", utils.CACHE_EDB_DATA_REFRESH, source, subSource, req.EdbCode)
  729. if utils.Rc.IsExist(cacheKey) {
  730. br.Ret = 501
  731. br.Success = true
  732. br.Msg = "系统处理中,请稍后重试"
  733. return
  734. }
  735. utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
  736. defer func() {
  737. _ = utils.Rc.Delete(cacheKey)
  738. }()
  739. // 获取指标详情
  740. edbInfo, e := models.GetEdbInfoByEdbCode(source, req.EdbCode)
  741. if e != nil {
  742. br.Msg = "指标不存在"
  743. br.ErrMsg = fmt.Sprintf("指标不存在, %v", e)
  744. return
  745. }
  746. // 获取指标关联信息
  747. baseMapping := new(models.BaseFromEdbMapping)
  748. {
  749. ob := new(models.BaseFromEdbMapping)
  750. cond := fmt.Sprintf(" AND %s = ? AND %s = ? AND %s = ?", ob.Cols().EdbCode, ob.Cols().Source, ob.Cols().SubSource)
  751. pars := make([]interface{}, 0)
  752. pars = append(pars, req.EdbCode, thsOb.GetSource(), thsOb.GetSubSource())
  753. mapping, e := ob.GetItemByCondition(cond, pars, "")
  754. if e != nil {
  755. br.Msg = "刷新失败"
  756. br.ErrMsg = fmt.Sprintf("指标关联信息有误, %v", e)
  757. return
  758. }
  759. baseMapping = mapping
  760. }
  761. // 刷新指标
  762. if e = thsOb.Refresh(edbInfo, baseMapping, req.StartDate); e != nil {
  763. br.Msg = "刷新指标失败"
  764. br.ErrMsg = fmt.Sprintf("刷新指标失败, %v", e)
  765. return
  766. }
  767. // 更新指标最值
  768. if e = thsOb.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo); e != nil {
  769. br.Msg = "刷新指标失败"
  770. br.ErrMsg = fmt.Sprintf("更新指标最值失败, %v", e)
  771. return
  772. }
  773. // 更新ES
  774. go logic.UpdateEs(edbInfo.EdbInfoId)
  775. br.Ret = 200
  776. br.Success = true
  777. br.Msg = "操作成功"
  778. }