Task.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. package controllers
  2. import (
  3. "ColdVerify_server/Nats/NatsServer"
  4. "ColdVerify_server/conf"
  5. "ColdVerify_server/lib"
  6. "ColdVerify_server/logs"
  7. "ColdVerify_server/models/Account"
  8. "ColdVerify_server/models/Device"
  9. "ColdVerify_server/models/System"
  10. "ColdVerify_server/models/Task"
  11. "fmt"
  12. beego "github.com/beego/beego/v2/server/web"
  13. "gonum.org/v1/plot"
  14. "gonum.org/v1/plot/plotter"
  15. "gonum.org/v1/plot/vg"
  16. "gonum.org/v1/plot/vg/draw"
  17. "image/color"
  18. "math"
  19. "sync"
  20. "time"
  21. )
  22. type TaskController struct {
  23. beego.Controller
  24. }
  25. // 列表 -
  26. func (c *TaskController) List() {
  27. // 验证登录 User_is, User_r
  28. User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
  29. if !User_is {
  30. c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
  31. c.ServeJSON()
  32. return
  33. }
  34. var r_jsons lib.R_JSONS
  35. page, _ := c.GetInt("page")
  36. if page < 1 {
  37. page = 1
  38. }
  39. page_z, _ := c.GetInt("page_z")
  40. if page_z < 1 {
  41. page_z = conf.Page_size
  42. }
  43. T_name := c.GetString("T_name")
  44. T_uuid := c.GetString("T_uuid")
  45. UserMap := Account.UserListToMap(Account.Read_User_List_ALL_1())
  46. AdminMap := Account.AdminListToMap(Account.Read_Admin_List_ALL_1())
  47. var T_admin string
  48. if User_r.T_power > 2 {
  49. T_admin = User_r.T_uuid
  50. }
  51. var cnt int
  52. List, cnt := Task.Read_Task_List(T_uuid, T_admin, T_name, UserMap, AdminMap, page, page_z)
  53. page_size := math.Ceil(float64(cnt) / float64(page_z))
  54. r_jsons.List = List
  55. r_jsons.Page = page
  56. r_jsons.Page_size = int(page_size)
  57. r_jsons.Pages = lib.Func_page(int64(page), int64(page_size))
  58. r_jsons.Num = cnt
  59. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  60. c.ServeJSON()
  61. return
  62. }
  63. // 列表 -
  64. func (c *TaskController) UserTaskList() {
  65. // 验证登录 User_is, User_r
  66. User_r, User_is := Account.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
  67. if !User_is {
  68. c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
  69. c.ServeJSON()
  70. return
  71. }
  72. var r_jsons lib.R_JSONS
  73. page, _ := c.GetInt("page")
  74. if page < 1 {
  75. page = 1
  76. }
  77. page_z, _ := c.GetInt("page_z")
  78. if page_z < 1 {
  79. page_z = conf.Page_size
  80. }
  81. T_name := c.GetString("T_name")
  82. UserMap := Account.UserListToMap(Account.Read_User_List_ALL_1())
  83. AdminMap := Account.AdminListToMap(Account.Read_Admin_List_ALL_1())
  84. var cnt int
  85. List, cnt := Task.Read_UserTask_List(User_r.T_uuid, T_name, UserMap, AdminMap, page, page_z)
  86. page_size := math.Ceil(float64(cnt) / float64(page_z))
  87. r_jsons.List = List
  88. r_jsons.Page = page
  89. r_jsons.Page_size = int(page_size)
  90. r_jsons.Pages = lib.Func_page(int64(page), int64(page_size))
  91. r_jsons.Num = cnt
  92. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  93. c.ServeJSON()
  94. return
  95. }
  96. // 获取-
  97. func (c *TaskController) Get() {
  98. // 验证登录 User_is, User_r
  99. _, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
  100. if !User_is {
  101. c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
  102. c.ServeJSON()
  103. return
  104. }
  105. T_task_id := c.GetString("T_task_id")
  106. r, is := Task.Read_Task(T_task_id)
  107. if !is {
  108. c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
  109. c.ServeJSON()
  110. return
  111. }
  112. // 添加浏览量
  113. _ = Task.Add_Task_Visit(r)
  114. r.T_Visit += 1
  115. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Task.TaskToTask_R(r)}
  116. c.ServeJSON()
  117. return
  118. }
  119. // 添加-
  120. func (c *TaskController) Add() {
  121. // 验证登录 User_is, User_r
  122. User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
  123. if !User_is {
  124. c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
  125. c.ServeJSON()
  126. return
  127. }
  128. dc := Device.DeviceClass{
  129. T_uuid: User_r.T_uuid,
  130. T_State: 1,
  131. }
  132. T_class_id, is := Device.Add_DeviceClass(dc)
  133. if !is {
  134. c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加分类失败!"}
  135. c.ServeJSON()
  136. return
  137. }
  138. System.Add_UserLogs_T(User_r.T_uuid, "分类管理", "添加", dc)
  139. T_name := c.GetString("T_name")
  140. T_uuid := c.GetString("T_uuid") // 用户uuid
  141. T_VerifyTemplate_class := c.GetString("T_VerifyTemplate_class")
  142. T_VerifyTemplate_id := c.GetString("T_VerifyTemplate_id")
  143. T_deadline := c.GetString("T_deadline")
  144. T_scheme := c.GetString("T_scheme")
  145. T_collection := c.GetString("T_collection")
  146. T_reporting := c.GetString("T_reporting")
  147. T_delivery := c.GetString("T_delivery")
  148. var_ := Task.Task{
  149. T_class: int(T_class_id),
  150. T_uuid: T_uuid,
  151. T_name: T_name,
  152. T_VerifyTemplate_class: T_VerifyTemplate_class,
  153. T_VerifyTemplate_id: T_VerifyTemplate_id,
  154. T_deadline: T_deadline,
  155. T_scheme: T_scheme,
  156. T_collection: T_collection,
  157. T_reporting: T_reporting,
  158. T_delivery: T_delivery,
  159. T_Show: 1,
  160. T_State: 1,
  161. }
  162. T_task_id, is := Task.Add_Task(var_)
  163. if !is {
  164. c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加失败!"}
  165. c.ServeJSON()
  166. return
  167. }
  168. NatsServer.Create_Local_Table(T_task_id)
  169. // 添加任务操作日志
  170. Task.Add_TaskLogs_T(User_r.T_uuid, T_task_id, "任务管理", "添加", var_)
  171. System.Add_UserLogs_T(User_r.T_uuid, "任务管理", "添加", var_)
  172. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_task_id}
  173. c.ServeJSON()
  174. return
  175. }
  176. // 添加-
  177. func (c *TaskController) AddData_Tool() {
  178. T_uuid := "3e84dda9-9eec-42b9-9350-0894262fc8a1" // 用户uuid
  179. T_name := c.GetString("T_name")
  180. T_task_id := c.GetString("T_task_id")
  181. r, _ := Task.Read_Task(T_task_id)
  182. if r.T_collection_state == 2 {
  183. c.Data["json"] = lib.JSONS{Code: 200, Msg: "数据采集中..."}
  184. c.ServeJSON()
  185. return
  186. }
  187. if r.Id > 0 {
  188. // 同步1.0数据
  189. NatsServer.Sync1_TaskData(T_task_id)
  190. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_task_id}
  191. c.ServeJSON()
  192. return
  193. }
  194. dc := Device.DeviceClass{
  195. T_uuid: T_uuid,
  196. T_State: 1,
  197. }
  198. T_class_id, is := Device.Add_DeviceClass(dc)
  199. if !is {
  200. c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加分类失败!"}
  201. c.ServeJSON()
  202. return
  203. }
  204. var_ := Task.Task{
  205. T_task_id: T_task_id,
  206. T_class: int(T_class_id),
  207. T_uuid: T_uuid,
  208. T_name: T_name,
  209. T_Show: 1,
  210. T_State: 1,
  211. T_collection_state: 2,
  212. }
  213. _, is = Task.Add_Task_Tool(var_)
  214. if !is {
  215. c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加失败!"}
  216. c.ServeJSON()
  217. return
  218. }
  219. // 创建本地表
  220. NatsServer.Create_Local_Table(T_task_id)
  221. // 同步1.0数据
  222. NatsServer.Sync1_TaskData(T_task_id)
  223. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_task_id}
  224. c.ServeJSON()
  225. return
  226. }
  227. // 修改采集状态-
  228. func (c *TaskController) UpCollectionState() {
  229. // 验证登录 User_is, User_r
  230. User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
  231. if !User_is {
  232. c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
  233. c.ServeJSON()
  234. return
  235. }
  236. T_collection_state, _ := c.GetInt("T_collection_state")
  237. T_task_id := c.GetString("T_task_id")
  238. r, is := Task.Read_Task(T_task_id)
  239. if !is {
  240. c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
  241. c.ServeJSON()
  242. return
  243. }
  244. r.T_collection_state = T_collection_state
  245. if !Task.Update_Task(r, "T_collection_state") {
  246. c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改失败!"}
  247. c.ServeJSON()
  248. return
  249. }
  250. // 添加任务操作日志
  251. Task.Add_TaskLogs_T(User_r.T_uuid, T_task_id, "任务管理", "修改采集状态", r)
  252. System.Add_UserLogs_T(User_r.T_uuid, "任务管理", "修改采集状态", r)
  253. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
  254. c.ServeJSON()
  255. return
  256. }
  257. // 修改-
  258. func (c *TaskController) Up() {
  259. // 验证登录 User_is, User_r
  260. User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
  261. if !User_is {
  262. c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
  263. c.ServeJSON()
  264. return
  265. }
  266. T_name := c.GetString("T_name")
  267. T_Show, T_Show_err := c.GetInt("T_Show")
  268. T_VerifyTemplate_class := c.GetString("T_VerifyTemplate_class")
  269. T_VerifyTemplate_id := c.GetString("T_VerifyTemplate_id")
  270. T_deadline := c.GetString("T_deadline")
  271. T_scheme := c.GetString("T_scheme")
  272. T_collection := c.GetString("T_collection")
  273. T_collection_state, _ := c.GetInt("T_collection_state")
  274. T_reporting := c.GetString("T_reporting")
  275. T_delivery := c.GetString("T_delivery")
  276. T_doc1 := c.GetString("T_doc1")
  277. T_pdf1 := c.GetString("T_pdf1")
  278. T_doc2 := c.GetString("T_doc2")
  279. T_pdf2 := c.GetString("T_pdf2")
  280. T_doc3 := c.GetString("T_doc3")
  281. T_pdf3 := c.GetString("T_pdf3")
  282. T_task_id := c.GetString("T_task_id")
  283. r, is := Task.Read_Task(T_task_id)
  284. if !is {
  285. c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
  286. c.ServeJSON()
  287. return
  288. }
  289. // .......
  290. clos := make([]string, 0)
  291. if len(T_name) > 0 {
  292. r.T_name = T_name
  293. clos = append(clos, "T_name")
  294. }
  295. if T_Show_err == nil {
  296. r.T_Show = T_Show
  297. clos = append(clos, "T_Show")
  298. }
  299. if len(T_VerifyTemplate_class) > 0 {
  300. r.T_VerifyTemplate_class = T_VerifyTemplate_class
  301. clos = append(clos, "T_VerifyTemplate_class")
  302. }
  303. if len(T_VerifyTemplate_id) > 0 {
  304. r.T_VerifyTemplate_id = T_VerifyTemplate_id
  305. clos = append(clos, "T_VerifyTemplate_id")
  306. }
  307. if len(T_deadline) > 0 {
  308. r.T_deadline = T_deadline
  309. clos = append(clos, "T_deadline")
  310. }
  311. if len(T_scheme) > 0 {
  312. r.T_scheme = T_scheme
  313. clos = append(clos, "T_scheme")
  314. }
  315. if len(T_collection) > 0 {
  316. r.T_collection = T_collection
  317. clos = append(clos, "T_collection")
  318. }
  319. if len(T_reporting) > 0 {
  320. r.T_reporting = T_reporting
  321. clos = append(clos, "T_reporting")
  322. }
  323. if len(T_delivery) > 0 {
  324. r.T_delivery = T_delivery
  325. clos = append(clos, "T_delivery")
  326. }
  327. if T_collection_state == 4 {
  328. r.T_collection_state = T_collection_state
  329. clos = append(clos, "T_collection_state")
  330. }
  331. if len(T_doc1) > 0 {
  332. r.T_doc1 = T_doc1
  333. clos = append(clos, "T_doc1")
  334. }
  335. // 验证报告内容T_pdf1 ,上传后将 当前任务 实施方案 标志 为 1
  336. if len(T_pdf1) > 0 {
  337. r.T_pdf1 = T_pdf1
  338. clos = append(clos, "T_pdf1")
  339. r.T_scheme_state = 1
  340. clos = append(clos, "T_scheme_state")
  341. }
  342. if len(T_doc2) > 0 {
  343. r.T_doc2 = T_doc2
  344. clos = append(clos, "T_doc2")
  345. }
  346. // 验证报告内容T_pdf2 ,上传后将 当前任务 报告编写 标志 为 1
  347. if len(T_pdf2) > 0 {
  348. r.T_pdf2 = T_pdf2
  349. clos = append(clos, "T_pdf2")
  350. r.T_reporting_state = 1
  351. clos = append(clos, "T_reporting_state")
  352. }
  353. if len(T_doc3) > 0 {
  354. r.T_doc3 = T_doc3
  355. clos = append(clos, "T_doc3")
  356. }
  357. if len(T_pdf3) > 0 {
  358. r.T_pdf3 = T_pdf3
  359. clos = append(clos, "T_pdf3")
  360. }
  361. // .......
  362. // "T_name", "T_Show", "T_VerifyTemplate_id", "T_deadline",
  363. // "T_collection", "T_reporting", "T_delivery",
  364. // "T_collection_state", "T_reporting_state", "T_delivery_state",
  365. // "T_doc1", "T_pdf1", "T_doc2", "T_pdf2", "T_doc3", "T_pdf3"
  366. if !Task.Update_Task(r, clos...) {
  367. c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改失败!"}
  368. c.ServeJSON()
  369. return
  370. }
  371. // 添加任务操作日志
  372. Task.Add_TaskLogs_T(User_r.T_uuid, T_task_id, "任务管理", "修改", r)
  373. System.Add_UserLogs_T(User_r.T_uuid, "任务管理", "修改", r)
  374. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
  375. c.ServeJSON()
  376. return
  377. }
  378. // 删除-
  379. func (c *TaskController) Del() {
  380. // 验证登录 User_is, User_r
  381. User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
  382. if !User_is {
  383. c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
  384. c.ServeJSON()
  385. return
  386. }
  387. T_task_id := c.GetString("T_task_id")
  388. if r, is := Task.Read_Task(T_task_id); is {
  389. if !Task.Delete_Task(r) {
  390. c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"}
  391. c.ServeJSON()
  392. return
  393. }
  394. // 添加任务操作日志
  395. Task.Add_TaskLogs_T(User_r.T_uuid, T_task_id, "任务管理", "删除", r)
  396. System.Add_UserLogs_T(User_r.T_uuid, "任务管理", "删除", r)
  397. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
  398. c.ServeJSON()
  399. return
  400. }
  401. c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
  402. c.ServeJSON()
  403. return
  404. }
  405. // 列表 -
  406. func (c *TaskController) Logs_List() {
  407. // 验证登录 User_is, User_r
  408. _, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
  409. if !User_is {
  410. c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
  411. c.ServeJSON()
  412. return
  413. }
  414. var r_jsons lib.R_JSONS
  415. page, _ := c.GetInt("page")
  416. if page < 1 {
  417. page = 1
  418. }
  419. page_z, _ := c.GetInt("page_z")
  420. if page_z < 1 {
  421. page_z = conf.Page_size
  422. }
  423. T_task_id := c.GetString("T_task_id")
  424. AdminMap := Account.AdminListToMap(Account.Read_Admin_List_ALL_1())
  425. var cnt int
  426. List, cnt := Task.Read_TaskLogs_List(T_task_id, AdminMap, page, page_z)
  427. page_size := math.Ceil(float64(cnt) / float64(page_z))
  428. r_jsons.List = List
  429. r_jsons.Page = page
  430. r_jsons.Page_size = int(page_size)
  431. r_jsons.Pages = lib.Func_page(int64(page), int64(page_size))
  432. r_jsons.Num = cnt
  433. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  434. c.ServeJSON()
  435. return
  436. }
  437. // 查询图片生成状态
  438. func (c *TaskController) DeviceData_JPGState() {
  439. T_task_id := c.GetString("T_task_id")
  440. T_remark := c.GetString("T_remark")
  441. jpg, is := Device.Redis_DeviceDataJPG_Get(T_task_id + T_remark)
  442. if !is {
  443. c.Data["json"] = lib.JSONS{Code: 202, Msg: "暂无图片正在生成"}
  444. c.ServeJSON()
  445. return
  446. }
  447. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: jpg}
  448. c.ServeJSON()
  449. return
  450. }
  451. func (c *TaskController) DeviceData_JPG() {
  452. StartTime := c.GetString("StartTime")
  453. if len(StartTime) > 0 {
  454. _, ok := lib.TimeStrToTime(StartTime)
  455. if !ok {
  456. c.Data["json"] = lib.JSONS{Code: 202, Msg: "时间格式错误!"}
  457. c.ServeJSON()
  458. return
  459. }
  460. }
  461. EndTime := c.GetString("EndTime")
  462. if len(EndTime) > 0 {
  463. _, ok := lib.TimeStrToTime(EndTime)
  464. if !ok {
  465. c.Data["json"] = lib.JSONS{Code: 202, Msg: "时间格式错误!"}
  466. c.ServeJSON()
  467. return
  468. }
  469. }
  470. T_remark := c.GetString("T_remark")
  471. TemperatureMin, _ := c.GetFloat("TemperatureMin") // 最低温度
  472. TemperatureMax, _ := c.GetFloat("TemperatureMax") // 最高温度
  473. if TemperatureMin == 0 {
  474. TemperatureMin = 2
  475. }
  476. if TemperatureMax == 0 {
  477. TemperatureMax = 8
  478. }
  479. T_task_id := c.GetString("T_task_id")
  480. Task_r, is := Task.Read_Task(T_task_id)
  481. if !is {
  482. c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"}
  483. c.ServeJSON()
  484. return
  485. }
  486. if Task_r.T_collection_state == 2 {
  487. c.Data["json"] = lib.JSONS{Code: 202, Msg: "数据采集中,请稍后!"}
  488. c.ServeJSON()
  489. return
  490. }
  491. deviceClassList, _ := Device.Read_DeviceClassList_OrderList(Task_r.T_class, "", T_remark, 0, 9999)
  492. if !is {
  493. c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_class 错误!"}
  494. c.ServeJSON()
  495. return
  496. }
  497. Device.Redis_DeviceDataJPG_Del(T_task_id + T_remark)
  498. // 生成图片
  499. go DeviceDataJPG(StartTime, EndTime, T_task_id, T_remark, deviceClassList, TemperatureMin, TemperatureMax)
  500. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
  501. c.ServeJSON()
  502. return
  503. }
  504. // 存档生成图片
  505. func DeviceDataJPG(StartTime, EndTime, T_task_id, T_remark string, deviceList []Device.DeviceClassList, TemperatureMin, TemperatureMax float64) {
  506. Device.Redis_DeviceDataJPG_Set(T_task_id+T_remark, Device.DeviceDataJPG{
  507. State: 1,
  508. Msg: "图片生成中",
  509. Url: "",
  510. })
  511. msg := ""
  512. state := 2
  513. url := ""
  514. if TemperatureMin == 0 {
  515. TemperatureMin = 2
  516. }
  517. if TemperatureMax == 0 {
  518. TemperatureMax = 8
  519. }
  520. var ymin, ymax float64
  521. var xminT, xmaxT time.Time
  522. if len(deviceList) > 0 {
  523. ymin, ymax, xminT, xmaxT = Device.Read_DeviceData_T_Min_Max_Time_Min_Max(deviceList[0].T_sn, StartTime, EndTime)
  524. }
  525. // 创建一个新的绘图
  526. p := plot.New()
  527. // 设置绘图标题和标签
  528. p.Title.Text = "温度折线图"
  529. //p.Legend.ThumbnailWidth = 5 * vg.Inch
  530. p.X.Label.Text = "时间"
  531. p.Y.Label.Text = "温度"
  532. var chData = make(chan int, 10)
  533. var jobGroup sync.WaitGroup
  534. var device = make([]Device.DeviceCount, len(deviceList))
  535. // 创建温度线
  536. for i := 0; i < len(deviceList); i++ {
  537. chData <- 1
  538. jobGroup.Add(1)
  539. go func(index int) {
  540. //go func(index int, wg *sync.WaitGroup, p *plot.Plot) {
  541. defer func() {
  542. <-chData // 完成时chan取出1个
  543. jobGroup.Done() // 完成时将等待组值减1
  544. }()
  545. sn, id := deviceList[index].T_sn, deviceList[index].T_id
  546. ymin_, ymax_, minTime_, maxTime_ := Device.Read_DeviceData_T_Min_Max_Time_Min_Max(sn, StartTime, EndTime)
  547. if ymin > ymin_ {
  548. ymin = ymin_
  549. }
  550. if ymax < ymax_ {
  551. ymax = ymax_
  552. }
  553. if xminT.After(minTime_) && !minTime_.IsZero() {
  554. xminT = minTime_
  555. }
  556. if xmaxT.Before(maxTime_) && !maxTime_.IsZero() {
  557. xmaxT = maxTime_
  558. }
  559. r_maps, r_maps_num := Device.Read_DeviceSensorData_ById_List(sn, StartTime, EndTime, 0, 9999)
  560. device[index] = Device.DeviceCount{
  561. T_id: id,
  562. Num: r_maps_num,
  563. }
  564. if r_maps_num == 0 {
  565. return
  566. }
  567. pts := make(plotter.XYs, len(r_maps))
  568. for j, d := range r_maps {
  569. t, _ := lib.TimeStrToTime(d.T_time)
  570. pts[j].X = float64(t.Unix())
  571. pts[j].Y = float64(d.T_t)
  572. }
  573. line, err := plotter.NewLine(pts)
  574. if err != nil {
  575. return
  576. }
  577. line.Color = randomColor(index)
  578. p.Add(line)
  579. }(i)
  580. }
  581. jobGroup.Wait()
  582. xmin, xmax := float64(xminT.Unix()), float64(xmaxT.Unix())
  583. // 添加最高,最低标准线 用红色虚线标识
  584. p.Add(horizontalLine(xmin, xmax, TemperatureMin))
  585. p.Add(horizontalLine(xmin, xmax, TemperatureMax))
  586. if ymax < 8 {
  587. ymax = 8
  588. }
  589. if ymin > 0 {
  590. ymin = 0
  591. }
  592. p.Y.Min, p.Y.Max = ymin, ymax
  593. p.X.Min, p.X.Max = xmin, xmax
  594. p.Y.Tick.Marker = commaTicks{}
  595. //p.X.Tick.Marker = plot.TimeTicks{Format: "2006-01-02 15:04:05"}
  596. p.X.Tick.Marker = timeTicks{}
  597. p.X.Tick.Label.Rotation = math.Pi / 5
  598. p.X.Tick.Label.YAlign = draw.YCenter
  599. p.X.Tick.Label.XAlign = draw.XRight
  600. filename := "jpg" + time.Now().Format("20060102150405")
  601. // 保存文件
  602. if err := p.Save(10*vg.Inch, 4*vg.Inch, "ofile/"+filename+".jpg"); err != nil {
  603. Device.Redis_DeviceDataJPG_Set(T_task_id+T_remark, Device.DeviceDataJPG{
  604. State: 3,
  605. Msg: "图片生成失败",
  606. Url: url,
  607. })
  608. logs.Error(lib.FuncName(), "生成图片失败", err)
  609. return
  610. }
  611. if !lib.Pload_qiniu("ofile/"+filename+".jpg", "ofile/"+filename+".jpg") {
  612. Device.Redis_DeviceDataJPG_Set(T_task_id+T_remark, Device.DeviceDataJPG{
  613. State: 3,
  614. Msg: "图片上传七牛云失败",
  615. Url: url,
  616. })
  617. logs.Error(lib.FuncName(), "上传七牛云失败")
  618. return
  619. }
  620. //删除目录
  621. //os.Remove("ofile/" + filename + ".jpg")
  622. msg = "图片生成成功"
  623. url = "https://bzdcoldverifyoss.baozhida.cn/" + "ofile/" + filename + ".jpg"
  624. Device.Redis_DeviceDataJPG_Set(T_task_id+T_remark, Device.DeviceDataJPG{
  625. State: state,
  626. Msg: msg,
  627. Url: url,
  628. Device: device,
  629. })
  630. return
  631. }
  632. func horizontalLine(xmin, xmax, y float64) *plotter.Line {
  633. pts := make(plotter.XYs, 2)
  634. pts[0].X = xmin
  635. pts[0].Y = y
  636. pts[1].X = xmax
  637. pts[1].Y = y
  638. line, err := plotter.NewLine(pts)
  639. if err != nil {
  640. panic(err)
  641. }
  642. line.LineStyle.Dashes = []vg.Length{vg.Points(8), vg.Points(5), vg.Points(1), vg.Points(5)}
  643. line.Color = color.RGBA{R: 255, A: 255}
  644. return line
  645. }
  646. type timeTicks struct{}
  647. func (timeTicks) Ticks(min, max float64) []plot.Tick {
  648. tks := plot.TimeTicks{}.Ticks(min, max)
  649. for i, t := range tks {
  650. //if t.Label == "" { // Skip minor ticks, they are fine.
  651. // continue
  652. //}
  653. tks[i].Label = time.Unix(int64(t.Value), 0).Format("2006-01-02 15:04:05")
  654. }
  655. return tks
  656. }
  657. type commaTicks struct{}
  658. // Ticks computes the default tick marks, but inserts commas
  659. // into the labels for the major tick marks.
  660. func (commaTicks) Ticks(min, max float64) []plot.Tick {
  661. tks := plot.DefaultTicks{}.Ticks(min, max)
  662. for i, t := range tks {
  663. //if t.Label == "" { // Skip minor ticks, they are fine.
  664. // continue
  665. //}
  666. tks[i].Label = fmt.Sprintf("%.0f", t.Value)
  667. }
  668. return tks
  669. }
  670. // 生成随机颜色的辅助函数
  671. func randomColor(i int) color.RGBA {
  672. var colors []color.RGBA
  673. colors = append(colors,
  674. color.RGBA{R: 52, G: 152, B: 219, A: 255},
  675. color.RGBA{R: 230, G: 126, B: 34, A: 255},
  676. color.RGBA{R: 142, G: 68, B: 173, A: 255},
  677. color.RGBA{R: 211, G: 84, B: 0, A: 255},
  678. color.RGBA{R: 231, G: 76, B: 60, A: 255},
  679. color.RGBA{R: 26, G: 188, B: 156, A: 255},
  680. color.RGBA{R: 243, G: 156, B: 18, A: 255},
  681. color.RGBA{R: 22, G: 160, B: 133, A: 255},
  682. color.RGBA{R: 46, G: 204, B: 113, A: 255},
  683. color.RGBA{R: 39, G: 174, B: 96, A: 255},
  684. color.RGBA{R: 41, G: 128, B: 185, A: 255},
  685. color.RGBA{R: 155, G: 89, B: 182, A: 255},
  686. color.RGBA{R: 192, G: 57, B: 43, A: 255},
  687. color.RGBA{R: 241, G: 196, B: 15, A: 255},
  688. )
  689. return colors[i%len(colors)]
  690. }