dcitemhistorydatamodel.go 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. package model
  2. import (
  3. "GtDataStore/app/cmd/organization/pb"
  4. "context"
  5. "database/sql"
  6. "fmt"
  7. "github.com/zeromicro/go-zero/core/stores/sqlc"
  8. "github.com/zeromicro/go-zero/core/stores/sqlx"
  9. "strings"
  10. "time"
  11. )
  12. var _ DcItemHistoryDataModel = (*customDcItemHistoryDataModel)(nil)
  13. type (
  14. // DcItemHistoryDataModel is an interface to be customized, add more methods here,
  15. // and implement the added methods in customDcItemHistoryDataModel.
  16. DcItemHistoryDataModel interface {
  17. dcItemHistoryDataModel
  18. MultiInsert(ctx context.Context, projectId int64, datas []*pb.ItemHistoryData) (int64, error)
  19. QueryHistoryDataByTime(ctx context.Context, in *pb.ItemHistoryDataByTimeReq) ([]ItemHistoryData, error)
  20. QueryHistoryDataMaxMinByTime(ctx context.Context, in *pb.ItemHistoryDataByTimeReq) (*MaxMinData, error)
  21. }
  22. customDcItemHistoryDataModel struct {
  23. *defaultDcItemHistoryDataModel
  24. }
  25. MaxMinData struct {
  26. MaxVal sql.NullFloat64 `db:"max_val"` // 最大值
  27. MinVal sql.NullFloat64 `db:"min_val"` // 最小值
  28. }
  29. ItemHistoryData struct {
  30. ItemName string `db:"item_name"` // 点位名
  31. Val float64 `db:"val"` // 值
  32. HTime time.Time `db:"h_time"` // 采集数据时间
  33. }
  34. )
  35. // NewDcItemHistoryDataModel returns a model for the database table.
  36. func NewDcItemHistoryDataModel(conn sqlx.SqlConn) DcItemHistoryDataModel {
  37. return &customDcItemHistoryDataModel{
  38. defaultDcItemHistoryDataModel: newDcItemHistoryDataModel(conn),
  39. }
  40. }
  41. func (m *defaultDcItemHistoryDataModel) MultiInsert(ctx context.Context, projectId int64, datas []*pb.ItemHistoryData) (int64, error) {
  42. query := fmt.Sprintf("insert ignore into %s (`item_name`,`val`,`h_time`) values (?, ?, ?)", m.getTableName(projectId))
  43. if bulk, err := sqlx.NewBulkInserter(m.conn, query); err == nil {
  44. for _, data := range datas {
  45. if err = bulk.Insert(data.ItemName, data.Val, data.HTime); err != nil {
  46. return 0, err
  47. }
  48. }
  49. bulk.Flush()
  50. return int64(len(datas)), nil
  51. } else {
  52. return 0, err
  53. }
  54. }
  55. func (m *defaultDcItemHistoryDataModel) QueryHistoryDataByTime(ctx context.Context, in *pb.ItemHistoryDataByTimeReq) ([]ItemHistoryData, error) {
  56. resp := make([]ItemHistoryData, 0)
  57. var err error
  58. query := fmt.Sprintf("SELECT * FROM %s AS hd "+
  59. " LEFT JOIN dc_item_config as ic ON hd.item_name = ic.item_name "+
  60. " WHERE hd.val > ic.min_val AND hd.val < ic.max_val AND hd.item_name in (?) AND h_time BETWEEN ? AND ?", m.getTableName(in.ProjectId))
  61. if strings.Index(in.ItemName, ",") > 0 {
  62. err = m.conn.QueryRowsCtx(ctx, &resp, query, strings.Split(in.ItemName, ","), in.Stime, in.Etime)
  63. } else {
  64. err = m.conn.QueryRowsCtx(ctx, &resp, query, in.ItemName, in.Stime, in.Etime)
  65. }
  66. switch err {
  67. case nil:
  68. return resp, nil
  69. case sqlc.ErrNotFound:
  70. return nil, ErrNotFound
  71. default:
  72. return nil, err
  73. }
  74. }
  75. func (m *defaultDcItemHistoryDataModel) QueryHistoryDataMaxMinByTime(ctx context.Context, in *pb.ItemHistoryDataByTimeReq) (*MaxMinData, error) {
  76. resp := &MaxMinData{}
  77. var err error
  78. query := fmt.Sprintf("SELECT max(val) as max_val, min(val) as min_val FROM %s AS hd "+
  79. " LEFT JOIN dc_item_config as ic ON hd.item_name = ic.item_name "+
  80. " WHERE hd.val > ic.min_val AND hd.val < ic.max_val AND hd.item_name = ? AND h_time BETWEEN ? AND ?", m.getTableName(in.ProjectId))
  81. err = m.conn.QueryRowCtx(ctx, resp, query, in.ItemName, in.Stime, in.Etime)
  82. switch err {
  83. case nil:
  84. if !resp.MaxVal.Valid {
  85. resp.MaxVal.Float64 = 0
  86. }
  87. if !resp.MinVal.Valid {
  88. resp.MinVal.Float64 = 0
  89. }
  90. return resp, nil
  91. case sqlc.ErrNotFound:
  92. return nil, ErrNotFound
  93. default:
  94. return nil, err
  95. }
  96. }
  97. func (m *defaultDcItemHistoryDataModel) getTableName(projectId int64) string {
  98. return fmt.Sprintf("dc_item_history_data_%d", projectId)
  99. }
  100. /*
  101. func (m *defaultDcItemHistoryDataModel) QueryHistoryData(ctx context.Context, in *pb.ItemHistoryDataListReq) ([]DcItemHistoryData, error) {
  102. resp := make([]DcItemHistoryData, 0)
  103. var err error
  104. var query string
  105. if in.Aggregator == "realtime" {
  106. query = fmt.Sprintf("SELECT project_id,item_name,val,DATE_FORMAT(c_time, '%%Y-%%m-%%d %%H:00:00') as c_time FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY DATE_FORMAT(c_time, '%%Y-%%m-%%d %%H:00:00') ORDER BY TIME_TO_SEC(c_time) ASC) AS row_num FROM %s WHERE project_id = ? AND item_name = ? AND c_time >= ? AND c_time < ? AND val <> 0) subquery WHERE row_num = 1;", m.table)
  107. } else if in.Aggregator == "new" {
  108. groupSql := ""
  109. timeSql := ""
  110. if in.Interval == "minute" {
  111. query = fmt.Sprintf(`
  112. SELECT val, DATE_ADD(DATE_FORMAT(min_c_time, '%%Y-%%m-%%d %%H:%%i'), INTERVAL (FLOOR(TIME_TO_SEC(min_c_time)/600)*%d) MINUTE) as c_time
  113. FROM (
  114. SELECT MAX(val) AS val,
  115. MIN(c_time) AS min_c_time
  116. FROM %s
  117. WHERE project_id = ? AND item_name = ?
  118. AND c_time >= ? AND c_time < ?
  119. GROUP BY DATE_FORMAT(c_time, '%%Y-%%m-%%d %%H:%%i'), FLOOR(TIME_TO_SEC(c_time) / 600)
  120. ) AS subquery
  121. ORDER BY min_c_time ASC;`, in.Size, m.table)
  122. } else if in.Interval == "h" {
  123. timeSql = fmt.Sprintf("DATE_ADD(concat(DATE_FORMAT(ts,'%%Y-%%m-%%d '),LPAD(FLOOR(DATE_FORMAT(ts, '%%H')/%d)*%d,2,0),':00:00'), INTERVAL %d hour)", in.Size, in.Size, in.Size)
  124. groupSql = fmt.Sprintf("DATE_FORMAT(ts, '%%Y-%%m-%%d' ),FLOOR(DATE_FORMAT(ts, '%%H' )/%d)", in.Size)
  125. } else {
  126. // day
  127. timeSql = fmt.Sprintf("DATE_ADD(concat(DATE_FORMAT(ts,'%%Y-%%m-'),LPAD(FLOOR(DATE_FORMAT(ts, '%%d')/%d)*%d,2,0),' 00:00:00'), INTERVAL %d day)", in.Size, in.Size, in.Size)
  128. groupSql = fmt.Sprintf("DATE_FORMAT(ts, '%%Y-%%m' ),FLOOR(DATE_FORMAT(ts, '%%d' )/%d)", in.Size)
  129. }
  130. tableName := "ws_scada." + TableName(itemId)
  131. table := fmt.Sprintf(`(select *
  132. from %s
  133. where item_name = "%s" and project_id = %s
  134. and ts >= "%s" and ts < "%s"
  135. order by ts desc
  136. limit 99999999) A `, tableName, itemId, projectId, sTime, eTime)
  137. rows, err = DB.New().Table(table).
  138. Select(fmt.Sprintf("cast(item_value as DECIMAL(11,4)) as val, %s as htime", timeSql)).
  139. Group(groupSql).
  140. Order("htime asc").
  141. Rows()
  142. }
  143. err = m.conn.QueryRowCtx(ctx, &resp, query, in.ProjectId, in.ItemName, in.Stime, in.Etime)
  144. switch err {
  145. case nil:
  146. return resp, nil
  147. case sqlc.ErrNotFound:
  148. return nil, ErrNotFound
  149. default:
  150. return nil, err
  151. }
  152. var rows *sql.Rows
  153. if aggregator == "realtime" {
  154. rows, err = DB.New().Table("ws_scada."+TableName(itemId)).
  155. Select("item_value as val,CASE WHEN MINUTE(ts) >= 30 THEN DATE_FORMAT(DATE_ADD(ts, INTERVAL 1 HOUR), '%Y-%m-%d %H:00:00') ELSE DATE_FORMAT(ts, '%Y-%m-%d %H:00:00') END AS htime").
  156. Where("item_name = ? ", itemId).
  157. Where("ts >= ? and ts < ?", sTime, eTime).
  158. Where("project_id = ?", projectId).
  159. Group("htime").
  160. Rows()
  161. } else if aggregator == "new" {
  162. groupSql := ""
  163. timeSql := ""
  164. if interval == "minute" {
  165. timeSql = fmt.Sprintf("DATE_ADD(concat(DATE_FORMAT(ts,'%%Y-%%m-%%d %%H:'),LPAD(FLOOR(DATE_FORMAT(ts, '%%i')/%d)*%d,2,0),':00'), INTERVAL %d minute)", sizeInt, sizeInt, sizeInt)
  166. groupSql = fmt.Sprintf("DATE_FORMAT(ts, '%%Y-%%m-%%d %%H' ),FLOOR(DATE_FORMAT(ts, '%%i' )/%d)", sizeInt)
  167. } else if interval == "h" {
  168. timeSql = fmt.Sprintf("DATE_ADD(concat(DATE_FORMAT(ts,'%%Y-%%m-%%d '),LPAD(FLOOR(DATE_FORMAT(ts, '%%H')/%d)*%d,2,0),':00:00'), INTERVAL %d hour)", sizeInt, sizeInt, sizeInt)
  169. groupSql = fmt.Sprintf("DATE_FORMAT(ts, '%%Y-%%m-%%d' ),FLOOR(DATE_FORMAT(ts, '%%H' )/%d)", sizeInt)
  170. } else {
  171. // day
  172. timeSql = fmt.Sprintf("DATE_ADD(concat(DATE_FORMAT(ts,'%%Y-%%m-'),LPAD(FLOOR(DATE_FORMAT(ts, '%%d')/%d)*%d,2,0),' 00:00:00'), INTERVAL %d day)", sizeInt, sizeInt, sizeInt)
  173. groupSql = fmt.Sprintf("DATE_FORMAT(ts, '%%Y-%%m' ),FLOOR(DATE_FORMAT(ts, '%%d' )/%d)", sizeInt)
  174. }
  175. tableName := "ws_scada." + TableName(itemId)
  176. table := fmt.Sprintf(`(select *
  177. from %s
  178. where item_name = "%s" and project_id = %s
  179. and ts >= "%s" and ts < "%s"
  180. order by ts desc
  181. limit 99999999) A `, tableName, itemId, projectId, sTime, eTime)
  182. rows, err = DB.New().Table(table).
  183. Select(fmt.Sprintf("cast(item_value as DECIMAL(11,4)) as val, %s as htime", timeSql)).
  184. Group(groupSql).
  185. Order("htime asc").
  186. Rows()
  187. } else {
  188. groupSql := ""
  189. timeSql := ""
  190. if interval == "minute" {
  191. timeSql = fmt.Sprintf("concat(DATE_FORMAT(ts,'%%Y-%%m-%%d %%H:'),LPAD(FLOOR(DATE_FORMAT(ts, '%%i')/%d)*%d,2,0),':00')", sizeInt, sizeInt)
  192. groupSql = fmt.Sprintf("DATE_FORMAT(ts, '%%Y-%%m-%%d %%H' ),FLOOR(DATE_FORMAT(ts, '%%i' )/%d)", sizeInt)
  193. } else if interval == "h" {
  194. timeSql = fmt.Sprintf("concat(DATE_FORMAT(ts, '%%Y-%%m-%%d ' ),LPAD(FLOOR(DATE_FORMAT(ts, '%%H' )/%d)*%d,2,0),':00:00')", sizeInt, sizeInt)
  195. groupSql = fmt.Sprintf("DATE_FORMAT(ts, '%%Y-%%m-%%d' ),FLOOR(DATE_FORMAT(ts, '%%H' )/%d)", sizeInt)
  196. } else {
  197. //day
  198. timeSql = fmt.Sprintf("concat(DATE_FORMAT(ts, '%%Y-%%m-' ),LPAD(FLOOR(DATE_FORMAT(ts, '%%d' )/%d)*%d,2,0),' 00:00:00')", sizeInt, sizeInt)
  199. groupSql = fmt.Sprintf("DATE_FORMAT(ts, '%%Y-%%m' ),FLOOR(DATE_FORMAT(ts, '%%d' )/%d)", sizeInt)
  200. }
  201. rows, err = DB.New().Table("ws_scada."+TableName(itemId)).
  202. Select(fmt.Sprintf("%s(cast(item_value as DECIMAL(11,4))) as val, %s as htime", aggregator, timeSql)).
  203. Where("item_name = ? ", itemId).
  204. Where("ts >= ? and ts < ?", sTime, eTime).
  205. Where("project_id = ?", projectId).
  206. Group(groupSql).
  207. Rows()
  208. }
  209. defer rows.Close()
  210. if err != nil {
  211. log.Error(err)
  212. return nil, err
  213. }
  214. // 查询点位信息 导出表格需要
  215. configMap, err := GetDrdcByItemNameAndDeviceId(itemId, fmt.Sprintf("%d", deviceId))
  216. if err != nil {
  217. log.Error(err)
  218. return nil, err
  219. }
  220. for rows.Next() {
  221. di := postgres.JinkeHistoryData{}
  222. var val sql.NullString
  223. err := rows.Scan(&val, &di.Htime)
  224. di.Val = NullStringConverse(val)
  225. if err != nil { // 获得的都是字符串
  226. log.Error("Some amazing wrong happens in the process of queryAll.", err)
  227. return nil, err
  228. }
  229. di.Name = configMap.ItemAlias
  230. //判断小数点
  231. if configMap.IsBool == false {
  232. di.Val = processPrecise(di.Val, configMap.ItemPrecise)
  233. }
  234. resp = append(resp, di)
  235. }
  236. return resp, nil
  237. }
  238. */