ai_predict_model_index.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. package data_manage
  2. import (
  3. "eta/eta_api/global"
  4. "eta/eta_api/models/data_manage"
  5. "eta/eta_api/utils"
  6. "fmt"
  7. "github.com/rdlucklib/rdluck_tools/paging"
  8. "strconv"
  9. "strings"
  10. "time"
  11. )
  12. // AiPredictModelIndex AI预测模型标的
  13. type AiPredictModelIndex struct {
  14. AiPredictModelIndexId int `orm:"column(ai_predict_model_index_id);pk" gorm:"primaryKey"`
  15. IndexName string `description:"标的名称"`
  16. IndexCode string `description:"自生成的指标编码"`
  17. ClassifyId int `description:"分类ID"`
  18. ModelFramework string `description:"模型框架"`
  19. PredictDate time.Time `description:"预测日期"`
  20. PredictValue float64 `description:"预测值"`
  21. PredictFrequency string `description:"预测频度"`
  22. DirectionAccuracy string `description:"方向准确度"`
  23. AbsoluteDeviation string `description:"绝对偏差"`
  24. ExtraConfig string `description:"模型参数"`
  25. Sort int `description:"排序"`
  26. SysUserId int `description:"创建人ID"`
  27. SysUserRealName string `description:"创建人姓名"`
  28. LeftMin string `description:"图表左侧最小值"`
  29. LeftMax string `description:"图表左侧最大值"`
  30. CreateTime time.Time `description:"创建时间"`
  31. ModifyTime time.Time `description:"修改时间"`
  32. AiPredictModelIndexConfigId int `gorm:"column:ai_predict_model_index_config_id" description:"标的当前的配置id"`
  33. ScriptPath string `gorm:"column:script_path" description:"脚本的路径"`
  34. }
  35. func (m *AiPredictModelIndex) TableName() string {
  36. return "ai_predict_model_index"
  37. }
  38. type AiPredictModelIndexCols struct {
  39. PrimaryId string
  40. IndexName string
  41. IndexCode string
  42. ClassifyId string
  43. ModelFramework string
  44. PredictDate string
  45. PredictValue string
  46. DirectionAccuracy string
  47. AbsoluteDeviation string
  48. ExtraConfig string
  49. Sort string
  50. SysUserId string
  51. SysUserRealName string
  52. LeftMin string
  53. LeftMax string
  54. CreateTime string
  55. ModifyTime string
  56. AiPredictModelIndexConfigId string
  57. ScriptPath string
  58. }
  59. func (m *AiPredictModelIndex) Cols() AiPredictModelIndexCols {
  60. return AiPredictModelIndexCols{
  61. PrimaryId: "ai_predict_model_index_id",
  62. IndexName: "index_name",
  63. IndexCode: "index_code",
  64. ClassifyId: "classify_id",
  65. ModelFramework: "model_framework",
  66. PredictDate: "predict_date",
  67. PredictValue: "predict_value",
  68. DirectionAccuracy: "direction_accuracy",
  69. AbsoluteDeviation: "absolute_deviation",
  70. ExtraConfig: "extra_config",
  71. Sort: "sort",
  72. SysUserId: "sys_user_id",
  73. SysUserRealName: "sys_user_real_name",
  74. LeftMin: "left_min",
  75. LeftMax: "left_max",
  76. CreateTime: "create_time",
  77. ModifyTime: "modify_time",
  78. AiPredictModelIndexConfigId: "ai_predict_model_index_config_id",
  79. ScriptPath: "script_path",
  80. }
  81. }
  82. func (m *AiPredictModelIndex) Create() (err error) {
  83. o := global.DbMap[utils.DbNameIndex]
  84. err = o.Create(m).Error
  85. return
  86. }
  87. func (m *AiPredictModelIndex) CreateMulti(items []*AiPredictModelIndex) (err error) {
  88. if len(items) == 0 {
  89. return
  90. }
  91. o := global.DbMap[utils.DbNameIndex]
  92. err = o.CreateInBatches(items, utils.MultiAddNum).Error
  93. return
  94. }
  95. func (m *AiPredictModelIndex) Update(cols []string) (err error) {
  96. o := global.DbMap[utils.DbNameIndex]
  97. err = o.Select(cols).Updates(m).Error
  98. return
  99. }
  100. func (m *AiPredictModelIndex) Remove() (err error) {
  101. o := global.DbMap[utils.DbNameIndex]
  102. sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
  103. err = o.Exec(sql, m.AiPredictModelIndexId).Error
  104. return
  105. }
  106. func (m *AiPredictModelIndex) MultiRemove(ids []int) (err error) {
  107. if len(ids) == 0 {
  108. return
  109. }
  110. o := global.DbMap[utils.DbNameIndex]
  111. sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.Cols().PrimaryId, utils.GetOrmInReplace(len(ids)))
  112. err = o.Exec(sql, ids).Error
  113. return
  114. }
  115. func (m *AiPredictModelIndex) RemoveByCondition(condition string, pars []interface{}) (err error) {
  116. if condition == "" {
  117. return
  118. }
  119. o := global.DbMap[utils.DbNameIndex]
  120. sql := fmt.Sprintf(`DELETE FROM %s WHERE %s`, m.TableName(), condition)
  121. err = o.Exec(sql, pars...).Error
  122. return
  123. }
  124. func (m *AiPredictModelIndex) GetItemById(id int) (item *AiPredictModelIndex, err error) {
  125. o := global.DbMap[utils.DbNameIndex]
  126. sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
  127. err = o.Raw(sql, id).First(&item).Error
  128. return
  129. }
  130. // GetItemByConfigId
  131. // @Description: 根据配置id获取标的信息
  132. // @author: Roc
  133. // @receiver m
  134. // @datetime 2025-05-06 13:31:24
  135. // @param configId int
  136. // @return item *AiPredictModelIndex
  137. // @return err error
  138. func (m *AiPredictModelIndex) GetItemByConfigId(configId int) (item *AiPredictModelIndex, err error) {
  139. o := global.DbMap[utils.DbNameIndex]
  140. sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().AiPredictModelIndexConfigId)
  141. err = o.Raw(sql, configId).First(&item).Error
  142. return
  143. }
  144. func (m *AiPredictModelIndex) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *AiPredictModelIndex, err error) {
  145. o := global.DbMap[utils.DbNameIndex]
  146. order := ``
  147. if orderRule != "" {
  148. order = ` ORDER BY ` + orderRule
  149. }
  150. sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s LIMIT 1`, m.TableName(), condition, order)
  151. err = o.Raw(sql, pars...).First(&item).Error
  152. return
  153. }
  154. func (m *AiPredictModelIndex) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
  155. o := global.DbMap[utils.DbNameIndex]
  156. sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
  157. err = o.Raw(sql, pars...).Scan(&count).Error
  158. return
  159. }
  160. func (m *AiPredictModelIndex) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*AiPredictModelIndex, err error) {
  161. o := global.DbMap[utils.DbNameIndex]
  162. fields := strings.Join(fieldArr, ",")
  163. if len(fieldArr) == 0 {
  164. fields = `*`
  165. }
  166. order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime)
  167. if orderRule != "" {
  168. order = ` ORDER BY ` + orderRule
  169. }
  170. sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
  171. err = o.Raw(sql, pars...).Find(&items).Error
  172. return
  173. }
  174. func (m *AiPredictModelIndex) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*AiPredictModelIndex, err error) {
  175. o := global.DbMap[utils.DbNameIndex]
  176. fields := strings.Join(fieldArr, ",")
  177. if len(fieldArr) == 0 {
  178. fields = `*`
  179. }
  180. order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime)
  181. if orderRule != "" {
  182. order = ` ORDER BY ` + orderRule
  183. }
  184. sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
  185. pars = append(pars, startSize, pageSize)
  186. err = o.Raw(sql, pars...).Find(&items).Error
  187. return
  188. }
  189. // AiPredictModelIndexItem AI预测模型标的信息
  190. type AiPredictModelIndexItem struct {
  191. IndexId int `description:"标的ID"`
  192. IndexName string `description:"标的名称"`
  193. IndexCode string `description:"自生成的指标编码"`
  194. ClassifyId int `description:"分类ID"`
  195. ClassifyName string `description:"分类名称"`
  196. ModelFramework string `description:"模型框架"`
  197. PredictDate string `description:"预测日期"`
  198. PredictValue float64 `description:"预测值"`
  199. PredictFrequency string `description:"预测频度"`
  200. DirectionAccuracy string `description:"方向准确度"`
  201. AbsoluteDeviation string `description:"绝对偏差"`
  202. ExtraConfig string `description:"模型参数"`
  203. SysUserId int `description:"创建人ID"`
  204. SysUserRealName string `description:"创建人姓名"`
  205. CreateTime string `description:"创建时间"`
  206. ModifyTime string `description:"修改时间"`
  207. SearchText string `description:"搜索结果(含高亮)"`
  208. AiPredictModelIndexConfigId int `gorm:"column:ai_predict_model_index_config_id" description:"标的当前的配置id"`
  209. ScriptPath string `gorm:"column:script_path" description:"脚本的路径"`
  210. }
  211. func (m *AiPredictModelIndex) Format2Item() (item *AiPredictModelIndexItem) {
  212. item = new(AiPredictModelIndexItem)
  213. item.IndexId = m.AiPredictModelIndexId
  214. item.IndexName = m.IndexName
  215. item.IndexCode = m.IndexCode
  216. item.ClassifyId = m.ClassifyId
  217. item.ModelFramework = m.ModelFramework
  218. item.PredictDate = utils.TimeTransferString(utils.FormatDate, m.PredictDate)
  219. item.PredictValue = m.PredictValue
  220. item.PredictFrequency = m.PredictFrequency
  221. item.DirectionAccuracy = m.DirectionAccuracy
  222. item.AbsoluteDeviation = m.AbsoluteDeviation
  223. item.ExtraConfig = m.ExtraConfig
  224. item.SysUserId = m.SysUserId
  225. item.SysUserRealName = m.SysUserRealName
  226. item.AiPredictModelIndexConfigId = m.AiPredictModelIndexConfigId
  227. item.ScriptPath = m.ScriptPath
  228. item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, m.CreateTime)
  229. item.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, m.ModifyTime)
  230. return
  231. }
  232. type AiPredictModelIndexPageListResp struct {
  233. Paging *paging.PagingItem
  234. List []*AiPredictModelIndexItem `description:"列表"`
  235. }
  236. // RemoveIndexAndData 删除标的及数据
  237. func (m *AiPredictModelIndex) RemoveIndexAndData(indexId int, chartIds []int) (err error) {
  238. o := global.DbMap[utils.DbNameIndex]
  239. tx := o.Begin()
  240. defer func() {
  241. if err != nil {
  242. _ = tx.Rollback()
  243. return
  244. }
  245. _ = tx.Commit()
  246. }()
  247. sql := `DELETE FROM ai_predict_model_index WHERE ai_predict_model_index_id = ? LIMIT 1`
  248. e := tx.Exec(sql, indexId).Error
  249. if e != nil {
  250. err = fmt.Errorf("remove index err: %v", e)
  251. return
  252. }
  253. sql = ` DELETE FROM ai_predict_model_data WHERE ai_predict_model_index_id = ?`
  254. e = tx.Exec(sql, indexId).Error
  255. if e != nil {
  256. err = fmt.Errorf("remove index data err: %v", e)
  257. return
  258. }
  259. // 删除图表
  260. if len(chartIds) == 0 {
  261. return
  262. }
  263. sql = ` DELETE FROM chart_info WHERE chart_info_id IN ?`
  264. if e = tx.Exec(sql, chartIds).Error; e != nil {
  265. err = fmt.Errorf("remove charts err: %v", e)
  266. return
  267. }
  268. sql = ` DELETE FROM chart_edb_mapping WHERE chart_info_id IN ?`
  269. if e = tx.Exec(sql, chartIds).Error; e != nil {
  270. err = fmt.Errorf("remove chart mappings err: %v", e)
  271. return
  272. }
  273. return
  274. }
  275. // UpdateAiPredictModelIndexSortByClassifyId 根据分类id更新排序
  276. func UpdateAiPredictModelIndexSortByClassifyId(classifyId, nowSort int, prevEdbInfoId int, updateSort string) (err error) {
  277. o := global.DbMap[utils.DbNameIndex]
  278. sql := ` UPDATE ai_predict_model_index SET sort = ` + updateSort + ` WHERE classify_id = ?`
  279. if prevEdbInfoId > 0 {
  280. sql += ` AND ( sort > ? or ( ai_predict_model_index_id > ` + fmt.Sprint(prevEdbInfoId) + ` and sort=` + fmt.Sprint(nowSort) + ` )) `
  281. } else {
  282. sql += ` AND ( sort > ? )`
  283. }
  284. err = o.Exec(sql, classifyId, nowSort).Error
  285. return
  286. }
  287. // GetFirstAiPredictModelIndexByClassifyId 获取当前分类下,且排序数相同 的排序第一条的数据
  288. func GetFirstAiPredictModelIndexByClassifyId(classifyId int) (item *AiPredictModelIndex, err error) {
  289. o := global.DbMap[utils.DbNameIndex]
  290. sql := ` SELECT * FROM ai_predict_model_index WHERE classify_id = ? order by sort asc,ai_predict_model_index_id asc limit 1`
  291. err = o.Raw(sql, classifyId).First(&item).Error
  292. return
  293. }
  294. type AiPredictModelImportData struct {
  295. Index *AiPredictModelIndex
  296. Data []*AiPredictModelData
  297. Charts []*AiPredictModelImportCharts
  298. }
  299. type AiPredictModelImportCharts struct {
  300. ChartInfo *data_manage.ChartInfo
  301. EdbMappings []*data_manage.ChartEdbMapping
  302. }
  303. // ImportIndexAndData 导入数据
  304. func (m *AiPredictModelIndex) ImportIndexAndData(createIndexes, updateIndexes []*AiPredictModelImportData, updateCols []string) (chartIds []int, err error) {
  305. if len(createIndexes) == 0 && len(updateIndexes) == 0 {
  306. return
  307. }
  308. o := global.DbMap[utils.DbNameIndex]
  309. tx := o.Begin()
  310. defer func() {
  311. if err != nil {
  312. _ = tx.Rollback()
  313. return
  314. }
  315. _ = tx.Commit()
  316. }()
  317. if len(updateIndexes) > 0 {
  318. for _, v := range updateIndexes {
  319. // 更新指标
  320. e := tx.Select(updateCols).Updates(v.Index).Error
  321. if e != nil {
  322. err = fmt.Errorf("update index err: %v", e)
  323. return
  324. }
  325. var hasDaily, hasMonthly bool
  326. for _, d := range v.Data {
  327. d.AiPredictModelIndexId = v.Index.AiPredictModelIndexId
  328. d.IndexCode = v.Index.IndexCode
  329. d.DataTimestamp = d.DataTime.UnixNano() / 1e6
  330. if d.Source == ModelDataSourceDaily {
  331. hasDaily = true
  332. }
  333. if d.Source == ModelDataSourceMonthly {
  334. hasMonthly = true
  335. }
  336. }
  337. // 哪个有数据就先清空然后重新写入,没数据就保留旧数据, 都没就忽略
  338. if !hasDaily && !hasMonthly {
  339. continue
  340. }
  341. removeCond := ``
  342. removePars := make([]interface{}, 0)
  343. removePars = append(removePars, v.Index.AiPredictModelIndexId)
  344. if hasDaily && !hasMonthly {
  345. removeCond += ` AND source = ?`
  346. removePars = append(removePars, ModelDataSourceDaily)
  347. }
  348. if !hasDaily && hasMonthly {
  349. removeCond += ` AND source = ?`
  350. removePars = append(removePars, ModelDataSourceMonthly)
  351. }
  352. // 清空指标并新增
  353. sql := fmt.Sprintf(`DELETE FROM ai_predict_model_data WHERE ai_predict_model_index_id = ? %s`, removeCond)
  354. e = tx.Exec(sql, removePars...).Error
  355. if e != nil {
  356. err = fmt.Errorf("clear index data err: %v", e)
  357. return
  358. }
  359. e = tx.CreateInBatches(v.Data, utils.MultiAddNum).Error
  360. if e != nil {
  361. err = fmt.Errorf("insert index data err: %v", e)
  362. return
  363. }
  364. }
  365. }
  366. if len(createIndexes) > 0 {
  367. for _, v := range createIndexes {
  368. if e := tx.Create(v.Index).Error; e != nil {
  369. err = fmt.Errorf("insert index err: %v", e)
  370. return
  371. }
  372. indexId := v.Index.AiPredictModelIndexId
  373. for _, d := range v.Data {
  374. d.AiPredictModelIndexId = indexId
  375. d.IndexCode = v.Index.IndexCode
  376. d.DataTimestamp = d.DataTime.UnixNano() / 1e6
  377. }
  378. if e := tx.CreateInBatches(v.Data, utils.MultiAddNum).Error; e != nil {
  379. err = fmt.Errorf("insert index data err: %v", e)
  380. return
  381. }
  382. // 图表
  383. if len(v.Charts) == 0 {
  384. continue
  385. }
  386. for _, ct := range v.Charts {
  387. if e := tx.Create(ct.ChartInfo).Error; e != nil {
  388. err = fmt.Errorf("insert chart err: %v", e)
  389. return
  390. }
  391. for _, cm := range ct.EdbMappings {
  392. cm.ChartInfoId = ct.ChartInfo.ChartInfoId
  393. cm.EdbInfoId = indexId
  394. time.Sleep(time.Microsecond)
  395. cm.UniqueCode = utils.MD5(fmt.Sprint(utils.CHART_PREFIX, "_", indexId, "_", strconv.FormatInt(time.Now().UnixNano(), 10)))
  396. }
  397. if e := tx.CreateInBatches(ct.EdbMappings, utils.MultiAddNum).Error; e != nil {
  398. err = fmt.Errorf("insert chart mapping err: %v", e)
  399. return
  400. }
  401. chartIds = append(chartIds, ct.ChartInfo.ChartInfoId)
  402. }
  403. }
  404. }
  405. return
  406. }
  407. type AiPredictModelDetailResp struct {
  408. TableData []*AiPredictModelDataItem `description:"表格数据"`
  409. ChartView *data_manage.ChartInfoDetailResp `description:"月度预测数据图表"`
  410. DailyChartView *data_manage.ChartInfoDetailResp `description:"日度预测数据图表"`
  411. }
  412. type AiPredictModelIndexSaveReq struct {
  413. IndexId int `description:"指标ID"`
  414. MonthlyChart *AiPredictModelIndexSaveChart `description:"月度图表信息"`
  415. DailyChart *AiPredictModelIndexSaveChart `description:"日度图表信息"`
  416. }
  417. type AiPredictModelIndexSaveChart struct {
  418. LeftMin string `description:"图表左侧最小值"`
  419. LeftMax string `description:"图表左侧最大值"`
  420. Unit string `description:"单位"`
  421. }
  422. type AiPredictModelIndexExtraConfig struct {
  423. MonthlyChart MonthlyChartConfig
  424. DailyChart DailyChartConfig
  425. }
  426. type MonthlyChartConfig struct {
  427. LeftMin string `description:"图表左侧最小值"`
  428. LeftMax string `description:"图表左侧最大值"`
  429. Unit string `description:"单位"`
  430. }
  431. type DailyChartConfig struct {
  432. LeftMin string `description:"图表左侧最小值"`
  433. LeftMax string `description:"图表左侧最大值"`
  434. Unit string `description:"单位"`
  435. PredictLegendName string `description:"预测图例的名称(通常为Predicted)"`
  436. }
  437. func (m *AiPredictModelIndex) GetSortMax() (sort int, err error) {
  438. o := global.DbMap[utils.DbNameIndex]
  439. sql := `SELECT COALESCE(MAX(sort), 0) AS sort FROM ai_predict_model_index`
  440. err = o.Raw(sql).Scan(&sort).Error
  441. if err != nil {
  442. return
  443. }
  444. // 查询分类的最大排序
  445. sql = `SELECT COALESCE(MAX(sort), 0) AS sort FROM ai_predict_model_classify`
  446. var classifySort int
  447. err = o.Raw(sql).Scan(&classifySort).Error
  448. if err != nil {
  449. return
  450. }
  451. if classifySort > sort {
  452. sort = classifySort
  453. }
  454. return
  455. }