base_from_ths_hf.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  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. if params.EndTime == "" {
  275. indexItem.EndDate = time.Now().Local()
  276. }
  277. terminal, e := services.GetFirstTerminal(utils.DATA_SOURCE_THS, "")
  278. if e != nil {
  279. br.Msg = "终端未配置"
  280. br.ErrMsg = fmt.Sprintf("终端未配置, %v", e)
  281. return
  282. }
  283. indexItem.TerminalCode = terminal.TerminalCode
  284. indexItem.StockCode = params.StockCode
  285. indexItem.Indicator = params.EdbCode
  286. b, e := json.Marshal(apiPars)
  287. if e != nil {
  288. br.Msg = "操作失败"
  289. br.ErrMsg = fmt.Sprintf("API入参JSON格式化失败, %v", e)
  290. return
  291. }
  292. indexItem.ApiPars = string(b)
  293. if len(indexWithData.IndexData) > 0 {
  294. indexItem.LatestValue = indexWithData.IndexData[0].Value
  295. }
  296. indexItem.CreateTime = time.Now().Local()
  297. indexItem.ModifyTime = time.Now().Local()
  298. // 新增指标
  299. if e := indexItem.Create(); e != nil {
  300. br.Msg = "操作失败"
  301. br.ErrMsg = fmt.Sprintf("新增指标失败, %v", e)
  302. return
  303. }
  304. // 新增数据
  305. if utils.UseMongo {
  306. dataList := make([]interface{}, 0)
  307. for _, v := range indexWithData.IndexData {
  308. dataList = append(dataList, &mgo.BaseFromThsHfData{
  309. BaseFromThsHfIndexId: int64(indexItem.BaseFromThsHfIndexId),
  310. IndexCode: indexItem.IndexCode,
  311. DataTime: v.DataTime,
  312. Value: v.Value,
  313. UniqueCode: utils.MD5(fmt.Sprint(indexItem.IndexCode, v.DataTime.Format(utils.FormatDateTimeMinute))),
  314. CreateTime: time.Now().Local(),
  315. ModifyTime: time.Now().Local(),
  316. DataTimestamp: v.DataTime.UnixNano() / 1e6,
  317. })
  318. }
  319. dataOb := new(mgo.BaseFromThsHfData)
  320. if e = dataOb.BatchInsertData(500, dataList); e != nil {
  321. br.Msg = "操作失败"
  322. br.ErrMsg = fmt.Sprintf("批量新增数据失败-Mongo, %v", e)
  323. return
  324. }
  325. } else {
  326. dataOb := new(models.BaseFromThsHfData)
  327. itemData := make([]*models.BaseFromThsHfData, 0)
  328. for _, v := range indexWithData.IndexData {
  329. t := new(models.BaseFromThsHfData)
  330. t.BaseFromThsHfIndexId = indexItem.BaseFromThsHfIndexId
  331. t.IndexCode = indexItem.IndexCode
  332. t.DataTime = v.DataTime
  333. t.Value = v.Value
  334. t.UniqueCode = utils.MD5(fmt.Sprint(indexItem.IndexCode, v.DataTime.Format(utils.FormatDateTimeMinute)))
  335. t.CreateTime = time.Now().Local()
  336. t.ModifyTime = time.Now().Local()
  337. t.DataTimestamp = v.DataTime.UnixNano() / 1e6
  338. itemData = append(itemData, t)
  339. }
  340. if e = dataOb.CreateMulti(itemData); e != nil {
  341. br.Msg = "操作失败"
  342. br.ErrMsg = fmt.Sprintf("批量新增数据失败-MySQL, %v", e)
  343. return
  344. }
  345. }
  346. br.Ret = 200
  347. br.Success = true
  348. br.Msg = "操作成功"
  349. }
  350. // BaseRefresh
  351. // @Title 同花顺高频数据-数据源刷新
  352. // @Description 同花顺高频数据-数据源刷新
  353. // @Success 200 {object} models.ThsHfBaseRefreshReq
  354. // @router /hf/base/refresh [post]
  355. func (this *ThsHfController) BaseRefresh() {
  356. br := new(models.BaseResponse).Init()
  357. defer func() {
  358. if br.ErrMsg == "" {
  359. br.IsSendEmail = false
  360. }
  361. this.Data["json"] = br
  362. this.ServeJSON()
  363. }()
  364. var params models.ThsHfBaseRefreshReq
  365. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &params); e != nil {
  366. br.Msg = "参数解析异常"
  367. br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
  368. return
  369. }
  370. params.BaseIndexCode = strings.TrimSpace(params.BaseIndexCode)
  371. if params.BaseIndexCode == "" {
  372. br.Msg = "参数异常"
  373. br.ErrMsg = fmt.Sprintf("参数异常, BaseIndexCode: %s", params.BaseIndexCode)
  374. return
  375. }
  376. if params.RefreshType <= 0 {
  377. params.RefreshType = 1
  378. }
  379. indexItem := new(models.BaseFromThsHfIndex)
  380. {
  381. ob := new(models.BaseFromThsHfIndex)
  382. cond := fmt.Sprintf(" AND %s = ?", ob.Cols().IndexCode)
  383. pars := make([]interface{}, 0)
  384. pars = append(pars, params.BaseIndexCode)
  385. item, e := ob.GetItemByCondition(cond, pars, "")
  386. if e != nil {
  387. if e.Error() == utils.ErrNoRow() {
  388. br.Msg = "指标不存在"
  389. return
  390. }
  391. br.Msg = "操作失败"
  392. br.ErrMsg = fmt.Sprintf("获取源指标失败, %v", e)
  393. return
  394. }
  395. indexItem = item
  396. }
  397. source := utils.DATA_SOURCE_THS
  398. subSource := utils.DATA_SUB_SOURCE_HIGH_FREQUENCY
  399. cacheKey := fmt.Sprintf("%s_%d_%d_%s_%s", utils.CACHE_BASE_EDB_REFRESH, source, subSource, indexItem.StockCode, indexItem.Indicator)
  400. defer func() {
  401. _ = utils.Rc.Delete(cacheKey)
  402. }()
  403. if utils.Rc.IsExist(cacheKey) {
  404. br.Ret = 501
  405. br.Success = true
  406. br.Msg = "系统处理中,请稍后重试"
  407. return
  408. }
  409. utils.Rc.SetNX(cacheKey, 1, 3*time.Minute)
  410. // API参数
  411. var apiPars models.ThsHfSearchEdbReq
  412. if e := json.Unmarshal([]byte(indexItem.ApiPars), &apiPars); e != nil {
  413. br.Msg = "操作失败"
  414. br.ErrMsg = fmt.Sprintf("源指标API参数异常, %v", e)
  415. return
  416. }
  417. // 刷新6小时: 指标开始时间前推6小时; 全部: API参数中的开始时间
  418. if params.RefreshType == 1 {
  419. apiPars.StartTime = indexItem.StartDate.Add(-6 * time.Hour).Format(utils.FormatDateTime)
  420. }
  421. // 若API参数中的结束时间不为空, 且不在EndDate之后, 那么不再刷新该指标
  422. if apiPars.EndTime != "" {
  423. apiEnd, e := time.ParseInLocation(utils.FormatDateTime, apiPars.EndTime, time.Local)
  424. if e != nil {
  425. br.Msg = "操作失败"
  426. br.ErrMsg = fmt.Sprintf("API参数结束时间有误, %v", e)
  427. return
  428. }
  429. if !apiEnd.After(indexItem.EndDate) {
  430. br.Ret = 200
  431. br.Success = true
  432. br.Msg = "该指标无需刷新"
  433. return
  434. }
  435. }
  436. // API-获取指标数据
  437. indexes, e := services.GetEdbDataFromThsHf(apiPars, indexItem.TerminalCode)
  438. if e != nil {
  439. br.Msg = "操作失败"
  440. br.ErrMsg = fmt.Sprintf("获取同花顺高频指标失败, %v", e)
  441. return
  442. }
  443. if len(indexes) == 0 {
  444. br.Msg = "未搜索到指标"
  445. br.ErrMsg = fmt.Sprintf("未搜索到指标, StockCode: %s, Indicator: %s", indexItem.StockCode, indexItem.Indicator)
  446. return
  447. }
  448. indexWithData := indexes[0]
  449. // 写入指标数据
  450. if utils.UseMongo {
  451. if e = services.RefreshThsHfBaseIndexMgo(indexItem, indexWithData, apiPars.StartTime); e != nil {
  452. br.Msg = "操作失败"
  453. br.ErrMsg = fmt.Sprintf("写入源指标数据失败-Mongo, %v", e)
  454. return
  455. }
  456. } else {
  457. if e = services.RefreshThsHfBaseIndex(indexItem, indexWithData, apiPars.StartTime); e != nil {
  458. br.Msg = "操作失败"
  459. br.ErrMsg = fmt.Sprintf("写入源指标数据失败, %v", e)
  460. return
  461. }
  462. }
  463. br.Ret = 200
  464. br.Success = true
  465. br.Msg = "操作成功"
  466. }
  467. // EdbAdd
  468. // @Title 同花顺高频数据-新增至指标库
  469. // @Description 同花顺高频数据-新增至指标库
  470. // @Success 200 {object} models.ThsHfEdbAddReq
  471. // @router /hf/edb/add [post]
  472. func (this *ThsHfController) EdbAdd() {
  473. br := new(models.BaseResponse).Init()
  474. defer func() {
  475. if br.ErrMsg == "" {
  476. br.IsSendEmail = false
  477. }
  478. this.Data["json"] = br
  479. this.ServeJSON()
  480. }()
  481. var params models.ThsHfEdbAddReq
  482. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &params); e != nil {
  483. br.Msg = "参数解析异常"
  484. br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
  485. return
  486. }
  487. if params.NewIndex == nil {
  488. br.Msg = "参数有误"
  489. br.ErrMsg = "参数有误, 指标信息有误"
  490. return
  491. }
  492. params.NewIndex.NewIndexName = strings.TrimSpace(params.NewIndex.NewIndexName)
  493. if params.NewIndex.NewIndexName == "" {
  494. br.Msg = "请输入指标名称"
  495. return
  496. }
  497. if params.NewIndex.ClassifyId <= 0 {
  498. br.Msg = "请选择分类"
  499. return
  500. }
  501. if params.NewIndex.Unit == "" {
  502. params.NewIndex.Unit = "无"
  503. }
  504. if params.NewIndex.NewFrequency == "" {
  505. br.Msg = "请输入频度"
  506. return
  507. }
  508. // 校验转换规则
  509. convertRule := params.ConvertRule
  510. if convertRule.ConvertType != 1 && convertRule.ConvertType != 2 {
  511. br.Msg = "请选择数据转换方式"
  512. return
  513. }
  514. if convertRule.ConvertType == 1 {
  515. if convertRule.ConvertFixed.FixedDay != 1 && convertRule.ConvertFixed.FixedDay != 2 {
  516. br.Msg = "请选择指定时间"
  517. return
  518. }
  519. if convertRule.ConvertFixed.FixedTime == "" {
  520. br.Msg = "请选择指定时间"
  521. return
  522. }
  523. timePrefix := time.Now().Local().Format(utils.FormatDate)
  524. st := fmt.Sprintf("%s %s", timePrefix, convertRule.ConvertFixed.FixedTime)
  525. _, e := time.Parse(utils.FormatDateTime, st)
  526. if e != nil {
  527. br.Msg = "指定时间格式有误"
  528. return
  529. }
  530. }
  531. if convertRule.ConvertType == 2 {
  532. if convertRule.ConvertArea.StartDay != 1 && convertRule.ConvertArea.StartDay != 2 {
  533. br.Msg = "请选择起始时间"
  534. return
  535. }
  536. if convertRule.ConvertArea.StartTime == "" {
  537. br.Msg = "请选择起始时间"
  538. return
  539. }
  540. var startTimePre string
  541. if convertRule.ConvertArea.StartDay == 1 {
  542. startTimePre = time.Now().Local().Format(utils.FormatDate)
  543. }
  544. if convertRule.ConvertArea.StartDay == 2 {
  545. startTimePre = time.Now().Local().AddDate(0, 0, -1).Format(utils.FormatDate)
  546. }
  547. st := fmt.Sprintf("%s %s", startTimePre, convertRule.ConvertArea.StartTime)
  548. startTime, e := time.Parse(utils.FormatDateTime, st)
  549. if e != nil {
  550. br.Msg = "起始时间格式有误"
  551. return
  552. }
  553. if convertRule.ConvertArea.EndDay != 1 && convertRule.ConvertArea.EndDay != 2 {
  554. br.Msg = "请选择截止时间"
  555. return
  556. }
  557. if convertRule.ConvertArea.EndTime == "" {
  558. br.Msg = "请选择截止时间"
  559. return
  560. }
  561. var endTimePre string
  562. if convertRule.ConvertArea.EndDay == 1 {
  563. endTimePre = time.Now().Local().Format(utils.FormatDate)
  564. }
  565. if convertRule.ConvertArea.EndDay == 2 {
  566. endTimePre = time.Now().Local().AddDate(0, 0, -1).Format(utils.FormatDate)
  567. }
  568. ed := fmt.Sprintf("%s %s", endTimePre, convertRule.ConvertArea.EndTime)
  569. endTime, e := time.Parse(utils.FormatDateTime, ed)
  570. if e != nil {
  571. br.Msg = "截止时间格式有误"
  572. return
  573. }
  574. if startTime.After(endTime) {
  575. br.Msg = "起始日期不可早于截止日期"
  576. return
  577. }
  578. }
  579. convertRuleByte, e := json.Marshal(params.ConvertRule)
  580. if e != nil {
  581. br.Msg = "操作失败"
  582. br.ErrMsg = fmt.Sprintf("转换规则JSON格式化失败, %v", e)
  583. return
  584. }
  585. // 缓存
  586. source := utils.DATA_SOURCE_THS
  587. subSource := utils.DATA_SUB_SOURCE_HIGH_FREQUENCY
  588. 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)
  589. defer func() {
  590. _ = utils.Rc.Delete(cacheKey)
  591. }()
  592. if utils.Rc.IsExist(cacheKey) {
  593. br.Ret = 501
  594. br.Success = true
  595. br.Msg = "系统处理中,请稍后重试"
  596. return
  597. }
  598. utils.Rc.SetNX(cacheKey, 1, 3*time.Minute)
  599. // 校验指标/分类
  600. baseIndexOb := new(models.BaseFromThsHfIndex)
  601. baseIndex, e := baseIndexOb.GetItemById(params.NewIndex.IndexId)
  602. if e != nil {
  603. br.Msg = "原指标不存在"
  604. br.ErrMsg = fmt.Sprintf("原指标不存在, %v", e)
  605. return
  606. }
  607. _, e = models.GetEdbClassifyById(params.NewIndex.ClassifyId)
  608. if e != nil {
  609. br.Msg = "分类信息有误"
  610. br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
  611. return
  612. }
  613. // 判断指标名称是否已存在
  614. {
  615. var cond string
  616. var pars []interface{}
  617. if this.Lang == utils.EnLangVersion {
  618. cond += " AND edb_name_en = ? "
  619. } else {
  620. cond += " AND edb_name = ?"
  621. }
  622. pars = append(pars, params.NewIndex.NewIndexName)
  623. count, e := models.GetEdbInfoCountByCondition(cond, pars)
  624. if e != nil {
  625. br.Msg = "操作失败"
  626. br.ErrMsg = fmt.Sprintf("获取重名指标失败, %v", e)
  627. return
  628. }
  629. if count > 0 {
  630. br.Msg = "指标名称已存在"
  631. return
  632. }
  633. }
  634. // 排序/指标编码
  635. sortMax, e := models.GetEdbClassifyMaxSort(params.NewIndex.ClassifyId, 0)
  636. if e != nil {
  637. br.Msg = "操作失败"
  638. br.ErrMsg = fmt.Sprintf("获取最大排序失败, %v", e)
  639. return
  640. }
  641. edbCode, e := utils.GenerateEdbCode(1, "")
  642. if e != nil {
  643. br.Msg = "操作失败"
  644. br.ErrMsg = fmt.Sprintf("生成指标编码失败, %v", e)
  645. return
  646. }
  647. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  648. uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
  649. thsOb := new(models.EdbThsHf)
  650. var addPars models.ThsHfAddBaseParams
  651. addPars.EdbCode = edbCode
  652. addPars.EdbName = params.NewIndex.NewIndexName
  653. addPars.Unit = params.NewIndex.Unit
  654. addPars.Frequency = params.NewIndex.NewFrequency
  655. addPars.Sort = sortMax + 1
  656. addPars.ClassifyId = params.NewIndex.ClassifyId
  657. addPars.SysUserId = params.NewIndex.SysAdminId
  658. addPars.SysUserRealName = params.NewIndex.SysAdminName
  659. addPars.UniqueCode = uniqueCode
  660. addPars.ConvertRule = string(convertRuleByte)
  661. edbInfo, e := thsOb.Add(addPars, baseIndex)
  662. if e != nil {
  663. br.Msg = "新增失败"
  664. br.ErrMsg = fmt.Sprintf("新增指标失败, %v", e)
  665. return
  666. }
  667. // 更新指标最值
  668. e, _ = models.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo)
  669. if e != nil {
  670. br.Msg = "刷新指标失败"
  671. br.ErrMsg = fmt.Sprintf("更新指标最值失败, %v", e)
  672. return
  673. }
  674. // 添加到es
  675. go logic.UpdateEs(edbInfo.EdbInfoId)
  676. br.Ret = 200
  677. br.Success = true
  678. br.Msg = "操作成功"
  679. }
  680. // EdbRefresh
  681. // @Title 同花顺高频数据-指标库刷新
  682. // @Description 同花顺高频数据-指标库刷新
  683. // @Success 200 {object} models.RefreshEdbInfoReq
  684. // @router /hf/edb/refresh [post]
  685. func (this *ThsHfController) EdbRefresh() {
  686. br := new(models.BaseResponse).Init()
  687. defer func() {
  688. if br.ErrMsg == "" {
  689. br.IsSendEmail = false
  690. }
  691. this.Data["json"] = br
  692. this.ServeJSON()
  693. }()
  694. var req models.RefreshEdbInfoReq
  695. err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
  696. if err != nil {
  697. br.Msg = "参数解析异常!"
  698. br.ErrMsg = "参数解析失败,Err:" + err.Error()
  699. return
  700. }
  701. if req.EdbCode == "" {
  702. br.Msg = "请输入指标编码!"
  703. br.ErrMsg = "请输入指标编码,指标编码为空"
  704. return
  705. }
  706. if req.EdbInfoId < 0 {
  707. br.Msg = "请输入指标ID!"
  708. br.ErrMsg = "请输入指标ID"
  709. return
  710. }
  711. thsOb := new(models.EdbThsHf)
  712. source := thsOb.GetSource()
  713. subSource := thsOb.GetSubSource()
  714. cacheKey := fmt.Sprintf("%s_%d_%d_%s", utils.CACHE_EDB_DATA_REFRESH, source, subSource, req.EdbCode)
  715. if utils.Rc.IsExist(cacheKey) {
  716. br.Ret = 501
  717. br.Success = true
  718. br.Msg = "系统处理中,请稍后重试"
  719. return
  720. }
  721. utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
  722. defer func() {
  723. _ = utils.Rc.Delete(cacheKey)
  724. }()
  725. // 获取指标详情
  726. edbInfo, e := models.GetEdbInfoByEdbCode(source, req.EdbCode)
  727. if e != nil {
  728. br.Msg = "指标不存在"
  729. br.ErrMsg = fmt.Sprintf("指标不存在, %v", e)
  730. return
  731. }
  732. // 获取指标关联信息
  733. baseMapping := new(models.BaseFromEdbMapping)
  734. {
  735. ob := new(models.BaseFromEdbMapping)
  736. cond := fmt.Sprintf(" AND %s = ? AND %s = ? AND %s = ?", ob.Cols().EdbCode, ob.Cols().Source, ob.Cols().SubSource)
  737. pars := make([]interface{}, 0)
  738. pars = append(pars, req.EdbCode, thsOb.GetSource(), thsOb.GetSubSource())
  739. mapping, e := ob.GetItemByCondition(cond, pars, "")
  740. if e != nil {
  741. br.Msg = "刷新失败"
  742. br.ErrMsg = fmt.Sprintf("指标关联信息有误, %v", e)
  743. return
  744. }
  745. baseMapping = mapping
  746. }
  747. // 刷新指标
  748. if e = thsOb.Refresh(edbInfo, baseMapping, req.StartDate); e != nil {
  749. br.Msg = "刷新指标失败"
  750. br.ErrMsg = fmt.Sprintf("刷新指标失败, %v", e)
  751. return
  752. }
  753. // 更新指标最值
  754. e, _ = models.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo)
  755. if e != nil {
  756. br.Msg = "刷新指标失败"
  757. br.ErrMsg = fmt.Sprintf("更新指标最值失败, %v", e)
  758. return
  759. }
  760. // 更新ES
  761. go logic.UpdateEs(edbInfo.EdbInfoId)
  762. br.Ret = 200
  763. br.Success = true
  764. br.Msg = "操作成功"
  765. }