base_from_ths_hf.go 21 KB

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