Warning.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. package controllers
  2. import (
  3. "Cold_Api/Nats/NatsServer"
  4. "Cold_Api/conf"
  5. "Cold_Api/controllers/lib"
  6. "Cold_Api/logs"
  7. "Cold_Api/models/Account"
  8. "Cold_Api/models/Device"
  9. "Cold_Api/models/System"
  10. "Cold_Api/models/Warning"
  11. "fmt"
  12. "github.com/robfig/cron/v3"
  13. "github.com/xuri/excelize/v2"
  14. "math"
  15. "os"
  16. "strconv"
  17. "time"
  18. )
  19. // 设备告警 ------------------------------------------
  20. // 告警列表
  21. func (c *DeviceController) DeviceWarning_List() {
  22. type R_JSONS struct {
  23. //必须的大写开头
  24. Data []Warning.Warning_R
  25. Num int64
  26. Page int
  27. Page_size int
  28. }
  29. var r_jsons R_JSONS
  30. page, _ := c.GetInt("page")
  31. if page < 1 {
  32. page = 1
  33. }
  34. page_z, _ := c.GetInt("page_z")
  35. if page_z < 1 {
  36. page_z = conf.Page_size
  37. }
  38. T_name := c.GetString("T_name")
  39. T_tp := c.GetString("T_tp")
  40. Time_start := c.GetString("Time_start")
  41. Time_end := c.GetString("Time_end")
  42. T_handle, _ := c.GetInt("T_handle")
  43. T_admin, _ := c.GetInt("T_admin")
  44. T_history, _ := c.GetInt("T_history")
  45. var tpList []string
  46. if len(T_tp) > 0 {
  47. tpList = lib.SplitStringIds(T_tp, "T")
  48. } else {
  49. power, _ := Account.Read_Power_ById(c.Admin_r.T_power)
  50. tpList = lib.SplitStringIds(power.T_warning, "W")
  51. }
  52. var T_year, T_month string
  53. if T_history == 1 {
  54. date, err := time.Parse("2006-01-02 15:04:05", Time_start)
  55. if err != nil {
  56. c.Data["json"] = lib.JSONS{Code: 202, Msg: "时间格式错误"}
  57. c.ServeJSON()
  58. return
  59. }
  60. T_year, T_month = date.Format("2006"), date.Format("01")
  61. }
  62. if T_admin == 1 {
  63. if T_history == 1 {
  64. // 获取备份
  65. r_jsons.Data, r_jsons.Num = Warning.Read_Admin_Warning_Backups(c.Admin_r.T_pids, T_year, T_month, tpList, T_name, T_handle, Time_start, Time_end, page, page_z)
  66. } else {
  67. // 获取最新
  68. r_jsons.Data, r_jsons.Num = Warning.Read_Admin_Warning_List(c.Admin_r.T_pids, tpList, T_name, T_handle, Time_start, Time_end, page, page_z)
  69. }
  70. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  71. c.ServeJSON()
  72. return
  73. }
  74. if T_history == 1 {
  75. r_jsons.Data, r_jsons.Num = Warning.Read_Warning_Backups(c.T_pid, T_year, T_month, tpList, T_name, T_handle, Time_start, Time_end, page, page_z)
  76. } else {
  77. // 获取最新
  78. r_jsons.Data, r_jsons.Num = Warning.Read_Warning_List(c.T_pid, tpList, T_name, T_handle, Time_start, Time_end, page, page_z)
  79. }
  80. r_jsons.Page = page
  81. r_jsons.Page_size = int(math.Ceil(float64(r_jsons.Num) / float64(page_z)))
  82. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  83. c.ServeJSON()
  84. return
  85. }
  86. // 查询告警
  87. func (c *DeviceController) DeviceWarning_Get() {
  88. id, _ := c.GetInt("T_id")
  89. T_history, _ := c.GetInt("T_history")
  90. T := Warning.Read_Warning_ById(int64(id))
  91. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Warning.WarningToWarning_R(T_history, T)}
  92. c.ServeJSON()
  93. return
  94. }
  95. // 编辑告警(处理告警)
  96. func (c *DeviceController) DeviceWarning_Post() {
  97. id, _ := c.GetInt("T_id")
  98. T_Text := c.GetString("T_Text")
  99. T_time := c.GetString("T_time")
  100. T_history, _ := c.GetInt("T_history")
  101. var T_year, T_month string
  102. var warning Warning.Warning
  103. Wtab := "warning"
  104. if T_history == 1 {
  105. date, err := time.Parse("2006-01-02 15:04:05", T_time)
  106. if err != nil {
  107. c.Data["json"] = lib.JSONS{Code: 202, Msg: "时间格式错误"}
  108. c.ServeJSON()
  109. return
  110. }
  111. T_year, T_month = date.Format("2006"), date.Format("01")
  112. Wtab += "_" + T_year + "_" + T_month
  113. warning, err = Warning.Read_Warning_ById_Backups(id, T_year, T_month)
  114. if err != nil {
  115. c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_id Err!"}
  116. c.ServeJSON()
  117. return
  118. }
  119. warning.T_Text = T_Text
  120. warning.T_State = 2
  121. if is := Warning.Update_Warning_Backups(warning, T_year, T_month); !is {
  122. c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改失败!"}
  123. c.ServeJSON()
  124. return
  125. }
  126. } else {
  127. warning = Warning.Read_Warning_ById(int64(id))
  128. if warning.Id == 0 {
  129. c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_id Err!"}
  130. c.ServeJSON()
  131. return
  132. }
  133. warning.T_Text = T_Text
  134. warning.T_State = 2
  135. if is := Warning.Update_Warning(warning, "T_Text", "T_State"); !is {
  136. c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改失败!"}
  137. c.ServeJSON()
  138. return
  139. }
  140. }
  141. System.Add_UserLogs(c.Admin_r.T_uuid, "设备管理", "报警处理操作", Wtab+":"+strconv.Itoa(id)+"->"+T_Text)
  142. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
  143. c.ServeJSON()
  144. return
  145. }
  146. // 删除告警
  147. func (c *DeviceController) DeviceWarning_Del() {
  148. id, _ := c.GetInt("T_id")
  149. T_time := c.GetString("T_time")
  150. T_history, _ := c.GetInt("T_history")
  151. var T_year, T_month string
  152. var warning Warning.Warning
  153. Wtab := "warning"
  154. if T_history == 1 {
  155. date, err := time.Parse("2006-01-02 15:04:05", T_time)
  156. if err != nil {
  157. c.Data["json"] = lib.JSONS{Code: 202, Msg: "时间格式错误"}
  158. c.ServeJSON()
  159. return
  160. }
  161. T_year, T_month = date.Format("2006"), date.Format("01")
  162. Wtab += "_" + T_year + "_" + T_month
  163. warning, err = Warning.Read_Warning_ById_Backups(id, T_year, T_month)
  164. if err != nil {
  165. c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_id Err!"}
  166. c.ServeJSON()
  167. return
  168. }
  169. warning.T_State = 0
  170. if is := Warning.Update_Warning_Backups(warning, T_year, T_month); !is {
  171. c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"}
  172. c.ServeJSON()
  173. return
  174. }
  175. } else {
  176. warning = Warning.Read_Warning_ById(int64(id))
  177. if warning.Id == 0 {
  178. c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_id Err!"}
  179. c.ServeJSON()
  180. return
  181. }
  182. warning.T_State = 0
  183. if is := Warning.Update_Warning(warning, "T_Text", "T_State"); !is {
  184. c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"}
  185. c.ServeJSON()
  186. return
  187. }
  188. }
  189. System.Add_UserLogs(c.Admin_r.T_uuid, "设备管理", "报警删除操作", Wtab+":"+strconv.Itoa(id))
  190. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
  191. c.ServeJSON()
  192. return
  193. }
  194. // 导出告警
  195. func (c *DeviceController) DeviceWarning_Data_Excel() {
  196. T_name := c.GetString("T_name")
  197. T_tp := c.GetString("T_tp")
  198. Time_start := c.GetString("Time_start")
  199. Time_end := c.GetString("Time_end")
  200. T_handle, _ := c.GetInt("T_handle")
  201. T_history, _ := c.GetInt("T_history")
  202. var tpList []string
  203. if len(T_tp) > 0 {
  204. tpList = lib.SplitStringIds(T_tp, "T")
  205. } else {
  206. power, _ := Account.Read_Power_ById(c.Admin_r.T_power)
  207. tpList = lib.SplitStringIds(power.T_warning, "W")
  208. }
  209. var T_year, T_month string
  210. if T_history == 1 {
  211. date, err := time.Parse("2006-01-02 15:04:05", Time_start)
  212. if err != nil {
  213. c.Data["json"] = lib.JSONS{Code: 202, Msg: "时间格式错误"}
  214. c.ServeJSON()
  215. return
  216. }
  217. T_year, T_month = date.Format("2006"), date.Format("01")
  218. }
  219. var Device_data []Warning.Warning_R
  220. if T_history == 1 {
  221. // 获取备份
  222. Device_data, _ = Warning.Read_Warning_Backups(c.T_pid, T_year, T_month, tpList, T_name, T_handle, Time_start, Time_end, 0, 9999)
  223. } else {
  224. // 获取最新
  225. Device_data, _ = Warning.Read_Warning_List(c.T_pid, tpList, T_name, T_handle, Time_start, Time_end, 0, 9999)
  226. }
  227. f := excelize.NewFile() // 设置单元格的值
  228. // 这里设置表头
  229. f.SetCellValue("Sheet1", "A1", "报警类型")
  230. f.SetCellValue("Sheet1", "B1", "Sn")
  231. f.SetCellValue("Sheet1", "C1", "设备名称")
  232. f.SetCellValue("Sheet1", "D1", "传感器")
  233. f.SetCellValue("Sheet1", "E1", "报警内容")
  234. f.SetCellValue("Sheet1", "F1", "记录时间")
  235. f.SetCellValue("Sheet1", "G1", "处理")
  236. f.SetCellValue("Sheet1", "H1", "处理时间")
  237. // 设置列宽
  238. f.SetColWidth("Sheet1", "A", "A", 20)
  239. f.SetColWidth("Sheet1", "B", "B", 25)
  240. f.SetColWidth("Sheet1", "C", "C", 30)
  241. f.SetColWidth("Sheet1", "D", "D", 30)
  242. f.SetColWidth("Sheet1", "G", "E", 30)
  243. f.SetColWidth("Sheet1", "H", "F", 15)
  244. f.SetColWidth("Sheet1", "I", "G", 30)
  245. f.SetColWidth("Sheet1", "J", "H", 15)
  246. line := 1
  247. // 循环写入数据
  248. for _, v := range Device_data {
  249. line++
  250. f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), Warning.Read_WarningType_Get(v.T_tp))
  251. f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), fmt.Sprintf("%s[%d]", v.T_sn, v.Id))
  252. f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.T_D_name)
  253. f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.T_DS_name)
  254. f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.T_Remark)
  255. f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.T_Ut)
  256. f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.T_Text)
  257. f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), v.CreateTime)
  258. }
  259. timeStr := time.Now().Format("20060102150405")
  260. // 保存文件
  261. if err := f.SaveAs("ofile/" + timeStr + ".xlsx"); err != nil {
  262. fmt.Println(err)
  263. }
  264. url, is := NatsServer.Qiniu_UploadFile(lib.GetCurrentDirectory()+"/ofile/"+timeStr+".xlsx", "ofile/"+timeStr+".xlsx")
  265. if !is {
  266. c.Data["json"] = lib.JSONS{Code: 202, Msg: "oss!"}
  267. c.ServeJSON()
  268. return
  269. }
  270. //删除文件
  271. err := os.Remove("ofile/" + timeStr + ".xlsx")
  272. if err != nil {
  273. fmt.Println(err)
  274. }
  275. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: url}
  276. c.ServeJSON()
  277. return
  278. }
  279. // 告警提示列表
  280. func (c *DeviceController) DeviceWarningList_T_Tips() {
  281. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Warning.Read_WarningType_All_T_Notice_mechanism()}
  282. c.ServeJSON()
  283. return
  284. }
  285. // 告警类型列表
  286. func (c *DeviceController) WarningType_List_All() {
  287. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Warning.Read_WarningType_All()}
  288. c.ServeJSON()
  289. return
  290. }
  291. // 告警类型列表 - 权限关联列表
  292. func (c *DeviceController) WarningType_Power_List_All() {
  293. power, err := Account.Read_Power_ById(c.Admin_r.T_power)
  294. if err != nil {
  295. c.Data["json"] = lib.JSONS{Code: 200, Msg: "获取菜单失败"}
  296. c.ServeJSON()
  297. return
  298. }
  299. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Warning.Read_WarningType_Power_All(power.T_warning)}
  300. c.ServeJSON()
  301. return
  302. }
  303. // 通过传感器类型获取报警列表
  304. func (c *DeviceController) Read_Warning_List_By_DS_T_type() {
  305. var r_jsons lib.R_JSONS
  306. page, _ := c.GetInt("page")
  307. if page < 1 {
  308. page = 1
  309. }
  310. page_z, _ := c.GetInt("page_z")
  311. if page_z < 1 {
  312. page_z = conf.Page_size
  313. }
  314. T_type, _ := c.GetInt("T_type")
  315. T_name := c.GetString("T_name")
  316. r_jsons.Data, r_jsons.Num = Warning.Read_Warning_List_By_DS_T_type(c.T_pid, T_type, T_name, page, page_z)
  317. r_jsons.Page = page
  318. r_jsons.Page_size = int(math.Ceil(float64(r_jsons.Num) / float64(page_z)))
  319. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  320. c.ServeJSON()
  321. return
  322. }
  323. func (c *DeviceController) Read_WarningSend_List() {
  324. var r_jsons lib.R_JSONS
  325. page, _ := c.GetInt("page")
  326. if page < 1 {
  327. page = 1
  328. }
  329. page_z, _ := c.GetInt("page_z")
  330. if page_z < 1 {
  331. page_z = conf.Page_size
  332. }
  333. T_ntype, _ := c.GetInt("T_ntype")
  334. r_jsons.Data, r_jsons.Num = Warning.Read_WarningSand_List(c.T_pid, T_ntype, page, page_z)
  335. r_jsons.Page = page
  336. r_jsons.Page_size = int(math.Ceil(float64(r_jsons.Num) / float64(page_z)))
  337. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  338. c.ServeJSON()
  339. return
  340. }
  341. func (c *DeviceController) Read_WarningRate_List() {
  342. page, _ := c.GetInt("page")
  343. if page < 1 {
  344. page = 1
  345. }
  346. page_z, _ := c.GetInt("page_z")
  347. if page_z < 1 {
  348. page_z = conf.Page_size
  349. }
  350. T_type := c.GetString("T_type")
  351. T_uuid := c.GetString("T_uuid")
  352. T_year, _ := c.GetInt("T_year")
  353. T_month, _ := c.GetInt("T_month")
  354. var startTime, endTime string
  355. now := time.Now()
  356. var month time.Month
  357. // 默认本月
  358. if T_year == 0 {
  359. T_year = now.Year()
  360. }
  361. if T_month == 0 {
  362. month = now.Month()
  363. } else {
  364. month = time.Month(T_month)
  365. }
  366. if T_type == Warning.WarningRateDay {
  367. startTime = time.Date(T_year, month, 1, 0, 0, 0, 0, time.Local).Format("2006-01-02")
  368. endTime = time.Date(T_year, month+1, -1, 0, 0, 0, 0, time.Local).Format("2006-01-02")
  369. }
  370. // 默认本年
  371. if T_type == Warning.WarningRateMonth {
  372. startTime = time.Date(T_year, 1, 0, 0, 0, 0, 0, time.Local).Format("2006-01")
  373. endTime = time.Date(T_year, 12, 0, 0, 0, 0, 0, time.Local).Format("2006-01")
  374. }
  375. if len(T_uuid) == 0 {
  376. T_uuid = c.Admin_r.T_uuid
  377. }
  378. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Warning.Read_WarningRate_List(T_uuid, T_type, startTime, endTime)}
  379. c.ServeJSON()
  380. return
  381. }
  382. func Cron_WarningRate() {
  383. //创建一个定时任务对象
  384. c := cron.New(cron.WithSeconds())
  385. //给对象增加定时任务
  386. // @daily 每日运行一次
  387. //c.AddFunc("0 */1 * * * ?", Cron_WarningRateDay_Add)
  388. //c.AddFunc("0 */1 * * * ?", Cron_WarningRateMonth_Add)
  389. c.AddFunc("@daily", Cron_WarningRateDay_Add)
  390. c.AddFunc("@monthly", Cron_WarningRateMonth_Add)
  391. //启动定时任务
  392. c.Start()
  393. defer c.Stop()
  394. //查询语句,阻塞,让main函数不退出,保持程序运行
  395. select {}
  396. }
  397. // 保存每天的设备报警率
  398. func Cron_WarningRateDay_Add() {
  399. T_date := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
  400. logs.Info("开始统计" + T_date + "设备报警率")
  401. // 获取管理员用户列表
  402. adminList := Account.Read_Admin_List_All()
  403. // 获取排除的pid及其子id
  404. //Exclude_Pids := Get_Exclude_Pids()
  405. // 获取内部用户关联的pid
  406. for _, admin := range adminList {
  407. // 内部用户已绑定公司,* 绑定所有公司
  408. if len(admin.T_pids) == 0 || admin.T_pids == "*" {
  409. continue
  410. }
  411. // 获取排除后的pid
  412. T_pids := lib.SplitStringToIntIds(admin.T_pids, "P")
  413. if len(T_pids) == 0 {
  414. continue
  415. }
  416. pids := Account.ReadCompanyWarningIds_T_pids(T_pids)
  417. if len(pids) == 0 {
  418. continue
  419. }
  420. // 获取探头数量
  421. dsCnt := Device.Read_DeviceSensorCount_ByT_pids(pids)
  422. // 获取当天报警数量
  423. warningCount := Warning.Read_WarningCount_byDay(pids)
  424. T_rate, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", float64(warningCount)/float64(dsCnt)), 64) // 保留2位小数
  425. // 保存设备报警率
  426. warningRate := Warning.WarningRate{
  427. T_uuid: admin.T_uuid,
  428. T_date: T_date,
  429. T_type: Warning.WarningRateDay,
  430. T_device_num: dsCnt,
  431. T_warning_num: warningCount,
  432. T_rate: float32(T_rate),
  433. }
  434. Warning.Add_WarningRate(warningRate)
  435. }
  436. }
  437. // 保存每月的设备报警率
  438. func Cron_WarningRateMonth_Add() {
  439. now := time.Now()
  440. // fixme 测试
  441. //now := time.Now().AddDate(0, 1, 0)
  442. T_date := now.AddDate(0, -1, 0).Format("2006-01")
  443. firstOfMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.Local)
  444. startTime := firstOfMonth.AddDate(0, -1, 0).Format("2006-01-02") // 上月第一天
  445. endTime := firstOfMonth.AddDate(0, 0, -1).Format("2006-01-02") // 上月最后一天
  446. logs.Info("开始统计" + T_date + "设备报警率")
  447. logs.Info("开始时间" + startTime)
  448. logs.Info("结束时间" + endTime)
  449. rateAvgList := Warning.Read_WarningRateAvg_Month(startTime, endTime)
  450. // 获取内部用户关联的pid
  451. for _, rate := range rateAvgList {
  452. T_rate, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", float64(rate.T_warning_num)/float64(rate.T_device_num)), 64) // 保留2位小数
  453. // 保存设备报警率
  454. warningRate := Warning.WarningRate{
  455. T_uuid: rate.T_uuid,
  456. T_date: T_date,
  457. T_type: Warning.WarningRateMonth,
  458. T_device_num: rate.T_device_num,
  459. T_warning_num: rate.T_warning_num,
  460. T_rate: float32(T_rate),
  461. }
  462. Warning.Add_WarningRate(warningRate)
  463. }
  464. }
  465. // 获取排除的pids
  466. func Get_Exclude_Pids() map[int]struct{} {
  467. ColdExcludePidList := lib.SplitStringToIntIds(conf.WarningRateExcludePid, ",")
  468. // 获取排除的pid
  469. ExcludeList := Account.ReadCompanyIds_T_pids(ColdExcludePidList)
  470. ExcludeListMap := make(map[int]struct{})
  471. for _, v := range ExcludeList {
  472. ExcludeListMap[v] = struct{}{}
  473. }
  474. return ExcludeListMap
  475. }
  476. // 获取用户排除后的pids
  477. func Get_AfterExclude_Pids(excludePids map[int]struct{}, adminPids string) []int {
  478. var list []int
  479. T_pids := lib.SplitStringToIntIds(adminPids, "P")
  480. userPids := Account.ReadCompanyIds_T_pids(T_pids)
  481. if len(T_pids) == 0 {
  482. return userPids
  483. }
  484. for _, v := range userPids {
  485. if _, ok := excludePids[v]; ok {
  486. continue
  487. }
  488. list = append(list, v)
  489. }
  490. return list
  491. }