waybill.go 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389
  1. package controller
  2. import (
  3. "bufio"
  4. "cold-delivery/app/admin/model"
  5. "cold-delivery/app/admin/service"
  6. "cold-delivery/app/admin/service/dto"
  7. "cold-delivery/common/actions"
  8. "cold-delivery/common/lib"
  9. "cold-delivery/common/nats/nats_server"
  10. "errors"
  11. "fmt"
  12. "github.com/beego/beego/v2/core/logs"
  13. "github.com/gin-gonic/gin"
  14. "github.com/gin-gonic/gin/binding"
  15. "github.com/golang/freetype/truetype"
  16. "github.com/pborman/uuid"
  17. "github.com/signintech/gopdf"
  18. "github.com/wcharczuk/go-chart/v2"
  19. "github.com/wcharczuk/go-chart/v2/drawing"
  20. "github.com/xuri/excelize/v2"
  21. "gogs.baozhida.cn/zoie/OAuth-core/api"
  22. "gogs.baozhida.cn/zoie/OAuth-core/pkg/jwtauth/user"
  23. _ "gogs.baozhida.cn/zoie/OAuth-core/pkg/response"
  24. "gonum.org/v1/plot"
  25. "gonum.org/v1/plot/plotter"
  26. "gonum.org/v1/plot/vg"
  27. "gonum.org/v1/plot/vg/draw"
  28. "image/color"
  29. "log"
  30. "math"
  31. "net/url"
  32. "os"
  33. "path"
  34. "sort"
  35. "sync"
  36. "time"
  37. )
  38. type WaybillController struct {
  39. api.Api
  40. }
  41. // GetPage 获取运单列表
  42. // @Summary 获取运单列表
  43. // @Description 获取运单列表
  44. // @Tags 运单
  45. // @Param waybillNo query string false "运单号"
  46. // @Param orderNo query string false "订单号"
  47. // @Param status query int false "状态"
  48. // @Param orderStartTime query string false "下单开始时间"
  49. // @Param orderEndTime query string false "下单结束时间"
  50. // @Param pageSize query int false "页条数"
  51. // @Param page query int false "页码"
  52. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  53. // @Router /api/waybill [get]
  54. // @Security Bearer
  55. func (e WaybillController) GetPage(c *gin.Context) {
  56. s := service.Waybill{}
  57. userSvc := service.SysUser{}
  58. req := dto.WaybillGetPageReq{}
  59. err := e.MakeContext(c).
  60. MakeOrm().
  61. Bind(&req, binding.Query).
  62. MakeService(&s.Service).
  63. MakeService(&userSvc.Service).
  64. Errors
  65. if err != nil {
  66. e.Logger.Error(err)
  67. e.Error(500, err, err.Error())
  68. return
  69. }
  70. //数据权限检查
  71. p := actions.GetPermissionFromContext(c)
  72. var userObj model.SysUser
  73. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  74. if err != nil {
  75. e.Error(500, err, err.Error())
  76. return
  77. }
  78. list := make([]model.Waybill, 0)
  79. var count int64
  80. if userObj.HasPost() {
  81. err = s.GetPage(&req, &list, &count, p)
  82. } else {
  83. err = s.GetUserPage(&req, &list, &count, p)
  84. }
  85. if err != nil {
  86. e.Error(500, err, err.Error())
  87. return
  88. }
  89. //for i, _ := range list {
  90. // var ReCheckuser model.SysUser
  91. // err = userSvc.GetUser(list[i].ReCheckId, &ReCheckuser)
  92. // if err != nil {
  93. // e.Error(500, err, err.Error())
  94. // return
  95. // }
  96. // list[i].ReCheck.Id = list[i].ReCheckId
  97. // list[i].ReCheck.NickName = ReCheckuser.NickName
  98. // list[i].ReCheck.Phone = ReCheckuser.Phone
  99. //}
  100. for i, _ := range list {
  101. if list[i].ReCheckId != 0 {
  102. var ReCheckuser model.SysUser
  103. err = userSvc.GetUser(list[i].ReCheckId, &ReCheckuser)
  104. if err != nil {
  105. e.Logger.Error("获取复核人信息失败", "ReCheckId", list[i].ReCheckId, "err", err)
  106. continue
  107. }
  108. list[i].ReCheck.Id = list[i].ReCheckId
  109. list[i].ReCheck.NickName = ReCheckuser.NickName
  110. list[i].ReCheck.Phone = ReCheckuser.Phone
  111. }
  112. }
  113. e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
  114. }
  115. // Export 导出运单列表
  116. // @Summary 导出运单列表
  117. // @Description 导出运单列表
  118. // @Tags 运单
  119. // @Param waybillNo query string false "运单号"
  120. // @Param pageSize query int false "页条数"
  121. // @Param page query int false "页码"
  122. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  123. // @Router /api/waybill/export [get]
  124. // @Security Bearer
  125. func (e WaybillController) Export(c *gin.Context) {
  126. s := service.Waybill{}
  127. req := dto.WaybillGetPageReq{}
  128. err := e.MakeContext(c).
  129. MakeOrm().
  130. Bind(&req, binding.Query).
  131. MakeService(&s.Service).
  132. Errors
  133. if err != nil {
  134. e.Logger.Error(err)
  135. e.Error(500, err, err.Error())
  136. return
  137. }
  138. //数据权限检查
  139. p := actions.GetPermissionFromContext(c)
  140. list := make([]model.Waybill, 0)
  141. var count int64
  142. req.PageSize = 9999
  143. err = s.GetPage(&req, &list, &count, p)
  144. if err != nil {
  145. e.Error(500, err, err.Error())
  146. return
  147. }
  148. f := excelize.NewFile() // 设置单元格的值
  149. // 这里设置表头ÒÒ
  150. f.SetCellValue("Sheet1", "A1", "序号")
  151. f.SetCellValue("Sheet1", "B1", "状态")
  152. f.SetCellValue("Sheet1", "C1", "寄件人名称")
  153. f.SetCellValue("Sheet1", "D1", "寄件人电话")
  154. f.SetCellValue("Sheet1", "E1", "寄件人地址")
  155. f.SetCellValue("Sheet1", "F1", "收件人名称")
  156. f.SetCellValue("Sheet1", "G1", "收件人电话")
  157. f.SetCellValue("Sheet1", "H1", "收件人地址")
  158. f.SetCellValue("Sheet1", "I1", "防拆标签码")
  159. f.SetCellValue("Sheet1", "J1", "运输备注")
  160. // 设置列宽
  161. f.SetColWidth("Sheet1", "A", "A", 6)
  162. f.SetColWidth("Sheet1", "B", "B", 8)
  163. f.SetColWidth("Sheet1", "C", "C", 14)
  164. f.SetColWidth("Sheet1", "D", "D", 14)
  165. f.SetColWidth("Sheet1", "E", "E", 30)
  166. f.SetColWidth("Sheet1", "F", "F", 14)
  167. f.SetColWidth("Sheet1", "G", "G", 14)
  168. f.SetColWidth("Sheet1", "H", "H", 30)
  169. f.SetColWidth("Sheet1", "I", "J", 15)
  170. f.SetColWidth("Sheet1", "K", "K", 30)
  171. line := 1
  172. // 循环写入数据
  173. for i, v := range list {
  174. line++
  175. f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), i+1)
  176. f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), model.WaybillStatusMap[v.Status])
  177. f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.SenderAddressName)
  178. f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.SenderAddressPhone)
  179. f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.SenderAddressDetails)
  180. f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.ConsigneeAddressName)
  181. f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.ConsigneeAddressPhone)
  182. f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), v.ConsigneeAddressDetails)
  183. f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), v.DeliveryName)
  184. f.SetCellValue("Sheet1", fmt.Sprintf("J%d", line), v.DeliveryPhone)
  185. f.SetCellValue("Sheet1", fmt.Sprintf("K%d", line), v.Remark)
  186. }
  187. timeStr := time.Now().Format("20060102150405")
  188. filePath := "ofile/" + "运单" + timeStr + ".xlsx"
  189. // 保存文件
  190. if err = f.SaveAs(filePath); err != nil {
  191. logs.Error("保存运单失败:", err)
  192. }
  193. defer func() {
  194. os.Remove(filePath)
  195. }()
  196. c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
  197. // PathEscape 函数对中文做处理
  198. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape("运单"+timeStr+".xlsx"))
  199. c.Header("Content-Transfer-Encoding", "binary")
  200. c.File(filePath)
  201. }
  202. // Home 首页统计
  203. // @Summary 首页统计
  204. // @Description 首页统计
  205. // @Tags 运单
  206. // @Param data body dto.WaybillStatsReq true "data"
  207. // @Param date query string true "日期"
  208. // @Param type query string true "类型 month-月 year-年"
  209. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  210. // @Router /api/waybill/home [get]
  211. // @Security Bearer
  212. func (e WaybillController) Home(c *gin.Context) {
  213. s := service.Waybill{}
  214. userSvc := service.SysUser{}
  215. req := dto.WaybillStatsReq{}
  216. err := e.MakeContext(c).
  217. MakeOrm().
  218. Bind(&req, binding.Query).
  219. MakeService(&s.Service).
  220. MakeService(&userSvc.Service).
  221. Errors
  222. if err != nil {
  223. e.Logger.Error(err)
  224. e.Error(500, err, err.Error())
  225. return
  226. }
  227. //数据权限检查
  228. p := actions.GetPermissionFromContext(c)
  229. var userObj model.SysUser
  230. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  231. if err != nil {
  232. e.Error(500, err, err.Error())
  233. return
  234. }
  235. var res dto.WaybillStatsRes
  236. if userObj.HasPost() {
  237. res = s.GetBasicsStats(&req, p)
  238. } else {
  239. res = s.GetUserBasicsStats(&req, p, service.GetUserBasicsStatsScopes(p.UserId))
  240. }
  241. e.OK(res, "查询成功")
  242. }
  243. // UserStats 用户运单数量统计
  244. // @Summary 首页统计
  245. // @Description 首页统计
  246. // @Tags 运单
  247. // @Param data body dto.WaybillUserStatsReq true "data"
  248. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  249. // @Router /api/waybill/user-stats [post]
  250. // @Security Bearer
  251. func (e WaybillController) UserStats(c *gin.Context) {
  252. s := service.Waybill{}
  253. userSvc := service.SysUser{}
  254. req := dto.WaybillUserStatsReq{}
  255. err := e.MakeContext(c).
  256. MakeOrm().
  257. Bind(&req, binding.JSON).
  258. MakeService(&s.Service).
  259. MakeService(&userSvc.Service).
  260. Errors
  261. if err != nil {
  262. e.Logger.Error(err)
  263. e.Error(500, err, err.Error())
  264. return
  265. }
  266. //数据权限检查
  267. p := actions.GetPermissionFromContext(c)
  268. var userObj model.SysUser
  269. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  270. if err != nil {
  271. e.Error(500, err, err.Error())
  272. return
  273. }
  274. var res []dto.WaybillUserStats
  275. if req.UserType == "delivery" {
  276. if userObj.HasPost() {
  277. res = s.GetDeliveryStats(&req, p)
  278. } else {
  279. req.UserIds = []int{p.UserId}
  280. res = s.GetDeliveryStats(&req, p)
  281. }
  282. }
  283. if req.UserType == "reCheck" {
  284. if userObj.HasPost() {
  285. res = s.GetReCheckStats(&req, p)
  286. } else {
  287. req.UserIds = []int{p.UserId}
  288. res = s.GetReCheckStats(&req, p)
  289. }
  290. }
  291. e.OK(res, "查询成功")
  292. }
  293. // GetAppletPage 获取运单列表
  294. // @Summary 获取运单列表
  295. // @Description 获取运单列表
  296. // @Tags 运单
  297. // @Param waybillNo query string false "运单号"
  298. // @Param status query int false "状态"
  299. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  300. // @Router /api/waybill/applet [get]
  301. // @Security Bearer
  302. func (e WaybillController) GetAppletPage(c *gin.Context) {
  303. s := service.Waybill{}
  304. req := dto.WaybillGetAppletPageReq{}
  305. err := e.MakeContext(c).
  306. MakeOrm().
  307. Bind(&req, binding.Query).
  308. MakeService(&s.Service).
  309. Errors
  310. if err != nil {
  311. e.Logger.Error(err)
  312. e.Error(500, err, err.Error())
  313. return
  314. }
  315. //数据权限检查
  316. p := actions.GetPermissionFromContext(c)
  317. list := make([]model.Waybill, 0)
  318. var count int64
  319. err = s.GetAppletPage(&req, &list, &count, p)
  320. if err != nil {
  321. e.Error(500, err, err.Error())
  322. return
  323. }
  324. e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
  325. }
  326. // GetAppletCount 获取app运单统计数量
  327. // @Summary 获取app运单统计数量
  328. // @Description 获取app运单统计数量
  329. // @Tags 运单
  330. // @Param waybillNo query string false "运单号"
  331. // @Param status query int false "状态"
  332. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  333. // @Router /api/waybill/applet-count [get]
  334. // @Security Bearer
  335. func (e WaybillController) GetAppletCount(c *gin.Context) {
  336. s := service.Waybill{}
  337. userSvc := service.SysUser{}
  338. req := dto.WaybillGetAppletPageReq{}
  339. err := e.MakeContext(c).
  340. MakeOrm().
  341. Bind(&req, binding.Query).
  342. MakeService(&s.Service).
  343. MakeService(&userSvc.Service).
  344. Errors
  345. if err != nil {
  346. e.Logger.Error(err)
  347. e.Error(500, err, err.Error())
  348. return
  349. }
  350. //数据权限检查
  351. p := actions.GetPermissionFromContext(c)
  352. var userObj model.SysUser
  353. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  354. if err != nil {
  355. e.Error(500, err, err.Error())
  356. return
  357. }
  358. list := make([]model.Waybill, 0)
  359. var count int64
  360. if userObj.UserType == "customer" {
  361. r := dto.WaybillGetCustomerPageReq{}
  362. r.PageSize = 9999
  363. r.CustomerId = p.UserId
  364. err = s.GetCustomerPage(&r, &list, &count, p)
  365. var statusCount = make(map[int]int)
  366. statusCount[0] = int(count)
  367. for _, waybill := range list {
  368. if _, ok := statusCount[waybill.Status]; ok {
  369. statusCount[waybill.Status] += 1
  370. } else {
  371. statusCount[waybill.Status] = 1
  372. }
  373. }
  374. e.OK(statusCount, "查询成功")
  375. return
  376. }
  377. err = s.GetAppletCount(&list, &count, p)
  378. if err != nil {
  379. e.Error(500, err, err.Error())
  380. return
  381. }
  382. var statusCount = make(map[int]int)
  383. statusCount[0] = int(count)
  384. for _, waybill := range list {
  385. if _, ok := statusCount[waybill.Status]; ok {
  386. statusCount[waybill.Status] += 1
  387. } else {
  388. statusCount[waybill.Status] = 1
  389. }
  390. }
  391. e.OK(statusCount, "查询成功")
  392. }
  393. // Get 通过id获取运单
  394. // @Summary 通过id获取运单
  395. // @Description 通过id获取运单
  396. // @Tags 运单
  397. // @Param id path string true "运单id"
  398. // @Success 200 {object} response.Response{data=model.Waybill} "{"code": 200, "data": [...]}"
  399. // @Router /api/waybill/{id} [get]
  400. // @Security Bearer
  401. func (e WaybillController) Get(c *gin.Context) {
  402. s := service.Waybill{}
  403. req := dto.WaybillGetReq{}
  404. err := e.MakeContext(c).
  405. MakeOrm().
  406. Bind(&req, nil).
  407. MakeService(&s.Service).
  408. Errors
  409. if err != nil {
  410. e.Logger.Error(err)
  411. e.Error(500, err, err.Error())
  412. return
  413. }
  414. var object model.Waybill
  415. p := actions.GetPermissionFromContext(c)
  416. //数据权限检查
  417. err = s.Get(&req, &object, p)
  418. if err != nil {
  419. e.Error(500, err, err.Error())
  420. return
  421. }
  422. e.OK(object, "查询成功")
  423. }
  424. // GetByWaybillNo 通过id获取运单
  425. // @Summary 通过id获取运单
  426. // @Description 通过id获取运单
  427. // @Tags 运单
  428. // @Param waybillNo path string true "运单编号-必填"
  429. // @Success 200 {object} response.Response{data=model.Waybill} "{"code": 200, "data": [...]}"
  430. // @Router /api/waybill/no [get]
  431. // @Security Bearer
  432. func (e WaybillController) GetByWaybillNo(c *gin.Context) {
  433. s := service.Waybill{}
  434. req := dto.WaybillGetByWaybillPdfReq{}
  435. err := e.MakeContext(c).
  436. MakeOrm().
  437. Bind(&req, binding.Query).
  438. MakeService(&s.Service).
  439. Errors
  440. if err != nil {
  441. e.Logger.Error(err)
  442. e.Error(500, err, err.Error())
  443. return
  444. }
  445. var object model.Waybill
  446. //数据权限检查
  447. err = s.GetByWaybillNo(&req, &object, nil)
  448. if err != nil {
  449. e.Error(500, err, err.Error())
  450. return
  451. }
  452. e.OK(object, "查询成功")
  453. }
  454. // Insert 添加运单
  455. // @Summary 添加运单
  456. // @Description 添加运单
  457. // @Tags 运单
  458. // @Accept application/json
  459. // @Product application/json
  460. // @Param data body dto.WaybillInsertReq true "data"
  461. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  462. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  463. // @Router /api/waybill [post]
  464. // @Security Bearer
  465. func (e WaybillController) Insert(c *gin.Context) {
  466. s := service.Waybill{}
  467. req := dto.WaybillInsertReq{}
  468. err := e.MakeContext(c).
  469. MakeOrm().
  470. Bind(&req, binding.JSON).
  471. MakeService(&s.Service).
  472. Errors
  473. if err != nil {
  474. e.Logger.Error(err)
  475. e.Error(500, err, err.Error())
  476. return
  477. }
  478. p := actions.GetPermissionFromContext(c)
  479. // 设置创建人
  480. req.SetCreateBy(user.GetUserId(c))
  481. req.SetDeptId(p.DeptId)
  482. err = s.Insert(&req)
  483. if err != nil {
  484. e.Error(500, err, err.Error())
  485. return
  486. }
  487. e.OK(req.GetId(), "添加成功")
  488. }
  489. // UpdateStatus 修改运单状态
  490. // @Summary 修改运单状态
  491. // @Description 修改运单状态
  492. // @Tags 运单
  493. // @Accept application/json
  494. // @Product application/json
  495. // @Param data body dto.WaybillUpdateStatusReq true "body"
  496. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  497. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  498. // @Router /api/waybill/update-status [put]
  499. // @Security Bearer
  500. func (e WaybillController) UpdateStatus(c *gin.Context) {
  501. s := service.Waybill{}
  502. req := dto.UpdateStatusReq{}
  503. err := e.MakeContext(c).
  504. MakeOrm().
  505. Bind(&req).
  506. MakeService(&s.Service).
  507. Errors
  508. if err != nil {
  509. e.Logger.Error(err)
  510. e.Error(500, err, err.Error())
  511. return
  512. }
  513. p := actions.GetPermissionFromContext(c)
  514. req.SetUpdateBy(user.GetUserId(c))
  515. err = s.UpdateStatus(&req, p)
  516. if err != nil {
  517. e.Error(500, err, err.Error())
  518. return
  519. }
  520. e.OK(req.GetId(), "修改成功")
  521. }
  522. // Update 修改运单
  523. // @Summary 修改运单
  524. // @Description 修改运单
  525. // @Tags 运单
  526. // @Accept application/json
  527. // @Product application/json
  528. // @Param data body dto.WaybillUpdateReq true "body"
  529. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  530. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  531. // @Router /api/waybill [put]
  532. // @Security Bearer
  533. func (e WaybillController) Update(c *gin.Context) {
  534. s := service.Waybill{}
  535. req := dto.WaybillUpdateReq{}
  536. err := e.MakeContext(c).
  537. MakeOrm().
  538. Bind(&req).
  539. MakeService(&s.Service).
  540. Errors
  541. if err != nil {
  542. e.Logger.Error(err)
  543. e.Error(500, err, err.Error())
  544. return
  545. }
  546. p := actions.GetPermissionFromContext(c)
  547. req.SetUpdateBy(user.GetUserId(c))
  548. err = s.Update(&req, p)
  549. if err != nil {
  550. e.Error(500, err, err.Error())
  551. return
  552. }
  553. e.OK(req.GetId(), "修改成功")
  554. }
  555. // Audit 审核订单
  556. // @Summary 审核订单
  557. // @Description 审核订单
  558. // @Tags 运单
  559. // @Accept application/json
  560. // @Product application/json
  561. // @Param data body dto.WaybillUpdateReq true "body"
  562. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  563. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  564. // @Router /api/waybill/audit [put]
  565. // @Security Bearer
  566. func (e WaybillController) Audit(c *gin.Context) {
  567. s := service.Waybill{}
  568. req := dto.WaybillUpdateReqaudit{}
  569. err := e.MakeContext(c).
  570. MakeOrm().
  571. Bind(&req).
  572. MakeService(&s.Service).
  573. Errors
  574. if err != nil {
  575. e.Logger.Error(err)
  576. e.Error(500, err, err.Error())
  577. return
  578. }
  579. p := actions.GetPermissionFromContext(c)
  580. req.SetUpdateBy(user.GetUserId(c))
  581. err = s.Audit(&req, p)
  582. if err != nil {
  583. e.Error(500, err, err.Error())
  584. return
  585. }
  586. e.OK(req.GetId(), "审核成功")
  587. }
  588. // AdminAudit 管理员审核订单
  589. // @Summary 管理员审核订单
  590. // @Description 审核订单
  591. // @Tags 运单
  592. // @Accept application/json
  593. // @Product application/json
  594. // @Param data body dto.WaybillAdmin true "body"
  595. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  596. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  597. // @Router /api/waybill/adminaudit [put]
  598. // @Security Bearer
  599. func (e WaybillController) AdminAudit(c *gin.Context) {
  600. s := service.Waybill{}
  601. req := dto.WaybillAdmin{}
  602. err := e.MakeContext(c).
  603. MakeOrm().
  604. Bind(&req).
  605. MakeService(&s.Service).
  606. Errors
  607. if err != nil {
  608. e.Logger.Error(err)
  609. e.Error(500, err, err.Error())
  610. return
  611. }
  612. p := actions.GetPermissionFromContext(c)
  613. err, userObj := service.GetUserProfile(e.Orm, p.UserId)
  614. if err != nil {
  615. e.Error(500, err, "获取用户信息失败")
  616. return
  617. }
  618. if !userObj.HasPost() && userObj.Id != 1 {
  619. e.Error(500, err, err.Error())
  620. return
  621. }
  622. req.SetUpdateBy(user.GetUserId(c))
  623. err = s.AdminAudit(&req, p)
  624. if err != nil {
  625. e.Error(500, err, err.Error())
  626. return
  627. }
  628. e.OK(req.GetId(), "审核成功")
  629. }
  630. // Packing 待取药装箱
  631. // @Summary 待取药装箱
  632. // @Description 待取药装箱(分配保温箱、冰排、防伪标签)
  633. // @Tags 运单
  634. // @Accept application/json
  635. // @Product application/json
  636. // @Param data body dto.WaybillPackingReq true "body"
  637. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  638. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  639. // @Router /api/waybill/packing [post]
  640. // @Security Bearer
  641. func (e WaybillController) Packing(c *gin.Context) {
  642. s := service.Waybill{}
  643. IceRaftSvc := service.IceRaft{}
  644. req := dto.WaybillPackingReq{}
  645. err := e.MakeContext(c).
  646. MakeOrm().
  647. Bind(&req).
  648. MakeService(&s.Service).
  649. MakeService(&IceRaftSvc.Service).
  650. Errors
  651. if err != nil {
  652. e.Logger.Error(err)
  653. e.Error(500, err, err.Error())
  654. return
  655. }
  656. p := actions.GetPermissionFromContext(c)
  657. if len(req.WaybillIds) == 0 {
  658. e.Error(500, err, "运单ID不能为空")
  659. return
  660. }
  661. oldIceRaftCode := make([]string, 0)
  662. if req.CoolerBoxId != 0 {
  663. err = IceRaftSvc.GetPageByCoolerBoxId(req.CoolerBoxId, &oldIceRaftCode, p)
  664. if err != nil {
  665. e.Error(500, err, err.Error())
  666. return
  667. }
  668. }
  669. req.SetUpdateBy(user.GetUserId(c))
  670. req.OldIceRaftCode = oldIceRaftCode
  671. err = s.Packing(&req, p)
  672. if err != nil {
  673. e.Error(500, err, err.Error())
  674. return
  675. }
  676. e.OK(req.GetId(), "装箱成功")
  677. }
  678. // Delivery 派单
  679. // @Summary 派单
  680. // @Description 派单
  681. // @Tags 运单
  682. // @Accept application/json
  683. // @Product application/json
  684. // @Param data body dto.WaybillDeliveryReq true "body"
  685. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  686. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  687. // @Router /api/waybill/delivery [put]
  688. // @Security Bearer
  689. func (e WaybillController) Delivery(c *gin.Context) {
  690. s := service.Waybill{}
  691. IceRaftSvc := service.IceRaft{}
  692. req := dto.WaybillDeliveryReq{}
  693. err := e.MakeContext(c).
  694. MakeOrm().
  695. Bind(&req).
  696. MakeService(&s.Service).
  697. MakeService(&IceRaftSvc.Service).
  698. Errors
  699. if err != nil {
  700. e.Logger.Error(err)
  701. e.Error(500, err, err.Error())
  702. return
  703. }
  704. p := actions.GetPermissionFromContext(c)
  705. if len(req.WaybillIds) == 0 {
  706. e.Error(500, err, "配送员不能为空")
  707. return
  708. }
  709. oldIceRaftCode := make([]string, 0)
  710. missingIceRaftCode := make([]string, 0)
  711. if req.CoolerBoxId != 0 {
  712. err = IceRaftSvc.GetPageByCoolerBoxId(req.CoolerBoxId, &oldIceRaftCode, p)
  713. if err != nil {
  714. e.Error(500, err, err.Error())
  715. return
  716. }
  717. }
  718. req.SetUpdateBy(user.GetUserId(c))
  719. req.OldIceRaftCode = oldIceRaftCode
  720. err = s.Delivery(&req, p)
  721. if err != nil {
  722. e.Error(500, err, err.Error())
  723. return
  724. }
  725. missingIceRaftCode = lib.FindStrListMissingData(oldIceRaftCode, req.IceRaftCode)
  726. if len(missingIceRaftCode) > 0 {
  727. c.JSON(200, map[string]interface{}{
  728. "requestId": uuid.NewUUID(),
  729. "code": 2000,
  730. "msg": "派单成功",
  731. "status": "success",
  732. "data": missingIceRaftCode,
  733. })
  734. return
  735. }
  736. e.OK(req.GetId(), "派单成功")
  737. }
  738. // Delete 删除运单
  739. // @Summary 删除运单
  740. // @Description 删除运单
  741. // @Tags 运单
  742. // @Accept application/json
  743. // @Product application/json
  744. // @Param data body dto.WaybillDeleteReq true "body"
  745. // @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
  746. // @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
  747. // @Router /api/waybill [delete]
  748. // @Security Bearer
  749. func (e WaybillController) Delete(c *gin.Context) {
  750. s := service.Waybill{}
  751. req := dto.WaybillDeleteReq{}
  752. userSvc := service.SysUser{}
  753. err := e.MakeContext(c).
  754. MakeOrm().
  755. Bind(&req, binding.JSON, nil).
  756. MakeService(&s.Service).
  757. MakeService(&userSvc.Service).
  758. Errors
  759. if err != nil {
  760. e.Logger.Error(err)
  761. e.Error(500, err, err.Error())
  762. return
  763. }
  764. //数据权限检查
  765. p := actions.GetPermissionFromContext(c)
  766. err = s.Remove(&req, p)
  767. if err != nil {
  768. e.Error(500, err, err.Error())
  769. return
  770. }
  771. e.OK(req.GetId(), "删除成功")
  772. }
  773. // Receipt 签收
  774. // @Summary 签收
  775. // @Description 签收
  776. // @Tags 运单
  777. // @Accept application/json
  778. // @Product application/json
  779. // @Param data body dto.WaybillInOutReq true "body"
  780. // @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
  781. // @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
  782. // @Router /api/waybill/receipt [post]
  783. // @Security Bearer
  784. func (e WaybillController) Receipt(c *gin.Context) {
  785. s := service.Waybill{}
  786. req := dto.WaybillReceiptReq{}
  787. err := e.MakeContext(c).
  788. MakeOrm().
  789. Bind(&req, binding.JSON, nil).
  790. MakeService(&s.Service).
  791. Errors
  792. if err != nil {
  793. e.Logger.Error(err)
  794. e.Error(500, err, err.Error())
  795. return
  796. }
  797. //数据权限检查
  798. p := actions.GetPermissionFromContext(c)
  799. err = s.Receipt(&req, p)
  800. if err != nil {
  801. e.Error(500, err, err.Error())
  802. return
  803. }
  804. e.OK(req.WaybillNo, "提交成功")
  805. }
  806. // CustomerReceipt 客户签收
  807. // @Summary 客户签收
  808. // @Description 客户签收
  809. // @Tags 运单
  810. // @Accept application/json
  811. // @Product application/json
  812. // @Param data body dto.WaybillReceiptReq true "body"
  813. // @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
  814. // @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
  815. // @Router /api/waybill/customer/receipt [post]
  816. // @Security Bearer
  817. func (e WaybillController) CustomerReceipt(c *gin.Context) {
  818. s := service.Waybill{}
  819. req := dto.WaybillReceiptReq{}
  820. err := e.MakeContext(c).
  821. MakeOrm().
  822. Bind(&req, binding.JSON, nil).
  823. MakeService(&s.Service).
  824. Errors
  825. if err != nil {
  826. e.Logger.Error(err)
  827. e.Error(500, err, err.Error())
  828. return
  829. }
  830. p := actions.GetPermissionFromContext(c)
  831. //req.WaybillNo = lib.AesDecryptCBC(req.WaybillNo, lib.AesKey)
  832. //数据权限检查
  833. err = s.Receipt(&req, p)
  834. if err != nil {
  835. e.Error(500, err, err.Error())
  836. return
  837. }
  838. e.OK(req.WaybillNo, "签收成功")
  839. }
  840. // CreateSole 生成唯一订单号
  841. // @Summary 生成唯一订单号
  842. // @Description 生成唯一订单号
  843. // @Tags 运单
  844. // @Accept application/json
  845. // @Product application/json
  846. // @Param data body dto.WaybillReceiptReq true "body"
  847. // @Success 200 {string} string "{"code": 200, "message": "生成成功"}"
  848. // @Success 200 {string} string "{"code": -1, "message": "生成成功"}"
  849. // @Router /api/waybill/createsole [get]
  850. // @Security Bearer
  851. func (e WaybillController) CreateSole(c *gin.Context) {
  852. s := service.Waybill{}
  853. err := e.MakeContext(c).
  854. MakeOrm().
  855. MakeService(&s.Service).
  856. Errors
  857. if err != nil {
  858. e.Logger.Error(err)
  859. e.Error(500, err, err.Error())
  860. return
  861. }
  862. sole, err := s.CreateSole()
  863. if err != nil {
  864. e.Error(500, err, err.Error())
  865. return
  866. }
  867. e.OK(sole, "生成成功")
  868. }
  869. // Turnarounds 订单转门店
  870. // @Summary 订单转门店
  871. // @Description 订单转门店
  872. // @Tags 运单
  873. // @Accept application/json
  874. // @Product application/json
  875. // @Param data body dto.WaybillReceiptReq true "body"
  876. // @Success 200 {string} string "{"code": 200, "message": "生成成功"}"
  877. // @Success 200 {string} string "{"code": -1, "message": "生成成功"}"
  878. // @Router /api/waybill/turnarounds [put]
  879. // @Security Bearer
  880. func (e WaybillController) Turnarounds(c *gin.Context) {
  881. s := service.Waybill{}
  882. req := dto.WaybillTurnarounds{}
  883. err := e.MakeContext(c).
  884. MakeOrm().
  885. Bind(&req, binding.JSON).
  886. MakeService(&s.Service).
  887. Errors
  888. if err != nil {
  889. e.Logger.Error(err)
  890. e.Error(500, err, err.Error())
  891. return
  892. }
  893. //数据权限检查
  894. p := actions.GetPermissionFromContext(c)
  895. err = s.WaybillTurnarounds(&req, p)
  896. if err != nil {
  897. e.Error(500, err, err.Error())
  898. return
  899. }
  900. e.OK(req, "转门店成功")
  901. }
  902. // SecondaryDistribution 二次分配订单
  903. // @Summary 二次分配订单
  904. // @Description 二次分配订单
  905. // @Tags 运单
  906. // @Accept application/json
  907. // @Product application/json
  908. // @Param data body dto.WaybillReceiptReq true "body"
  909. // @Success 200 {string} string "{"code": 200, "message": "生成成功"}"
  910. // @Success 200 {string} string "{"code": -1, "message": "生成成功"}"
  911. // @Router /api/waybill/SecondaryDistribution [put]
  912. // @Security Bearer
  913. func (e WaybillController) SecondaryDistribution(c *gin.Context) {
  914. s := service.Waybill{}
  915. req := dto.WaybillAssignment{}
  916. err := e.MakeContext(c).
  917. MakeOrm().
  918. Bind(&req, binding.JSON).
  919. MakeService(&s.Service).
  920. Errors
  921. if err != nil {
  922. e.Logger.Error(err)
  923. e.Error(500, err, err.Error())
  924. return
  925. }
  926. //数据权限检查
  927. p := actions.GetPermissionFromContext(c)
  928. err = s.SecondaryDistribution(&req, p)
  929. if err != nil {
  930. e.Error(500, err, err.Error())
  931. return
  932. }
  933. e.OK(req.WaybillNo, "分配成功")
  934. }
  935. // GetCustomerPage 获取客户运单列表
  936. // @Summary 获取客户运单列表
  937. // @Description 获取客户运单列表
  938. // @Tags 运单
  939. // @Param waybillNo query string false "运单号"
  940. // @Param orderNo query string false "订单号"
  941. // @Param status query int false "状态"
  942. // @Param orderStartTime query string false "下单开始时间"
  943. // @Param orderEndTime query string false "下单结束时间"
  944. // @Param pageSize query int false "页条数"
  945. // @Param page query int false "页码"
  946. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  947. // @Router /api/waybill/customer [get]
  948. // @Security Bearer
  949. func (e WaybillController) GetCustomerPage(c *gin.Context) {
  950. s := service.Waybill{}
  951. req := dto.WaybillGetCustomerPageReq{}
  952. err := e.MakeContext(c).
  953. MakeOrm().
  954. Bind(&req, binding.Query).
  955. MakeService(&s.Service).
  956. Errors
  957. if err != nil {
  958. e.Logger.Error(err)
  959. e.Error(500, err, err.Error())
  960. return
  961. }
  962. //数据权限检查
  963. p := actions.GetPermissionFromContext(c)
  964. list := make([]model.Waybill, 0)
  965. var count int64
  966. req.CustomerId = p.UserId
  967. err = s.GetCustomerPage(&req, &list, &count, p)
  968. if err != nil {
  969. e.Error(500, err, err.Error())
  970. return
  971. }
  972. e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
  973. }
  974. // CustomerExport 导出客户运单列表
  975. // @Summary 导出客户运单列表
  976. // @Description 导出客户运单列表
  977. // @Tags 运单
  978. // @Param waybillNo query string false "运单号"
  979. // @Param orderNo query string false "订单号"
  980. // @Param status query int false "状态"
  981. // @Param orderStartTime query string false "下单开始时间"
  982. // @Param orderEndTime query string false "下单结束时间"
  983. // @Param pageSize query int false "页条数"
  984. // @Param page query int false "页码"
  985. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  986. // @Router /api/waybill/customer/export [get]
  987. // @Security Bearer
  988. func (e WaybillController) CustomerExport(c *gin.Context) {
  989. s := service.Waybill{}
  990. req := dto.WaybillGetCustomerPageReq{}
  991. err := e.MakeContext(c).
  992. MakeOrm().
  993. Bind(&req, binding.Query).
  994. MakeService(&s.Service).
  995. Errors
  996. if err != nil {
  997. e.Logger.Error(err)
  998. e.Error(500, err, err.Error())
  999. return
  1000. }
  1001. //数据权限检查
  1002. p := actions.GetPermissionFromContext(c)
  1003. list := make([]model.Waybill, 0)
  1004. var count int64
  1005. req.CustomerId = p.UserId
  1006. req.PageSize = 9999
  1007. err = s.GetCustomerPage(&req, &list, &count, p)
  1008. if err != nil {
  1009. e.Error(500, err, err.Error())
  1010. return
  1011. }
  1012. f := excelize.NewFile() // 设置单元格的值
  1013. // 这里设置表头ÒÒ
  1014. f.SetCellValue("Sheet1", "A1", "序号")
  1015. f.SetCellValue("Sheet1", "B1", "状态")
  1016. f.SetCellValue("Sheet1", "C1", "寄件人名称")
  1017. f.SetCellValue("Sheet1", "D1", "寄件人电话")
  1018. f.SetCellValue("Sheet1", "E1", "寄件人地址")
  1019. f.SetCellValue("Sheet1", "F1", "收件人名称")
  1020. f.SetCellValue("Sheet1", "G1", "收件人电话")
  1021. f.SetCellValue("Sheet1", "H1", "收件人地址")
  1022. f.SetCellValue("Sheet1", "I1", "配送人姓名")
  1023. f.SetCellValue("Sheet1", "J1", "配送人电话")
  1024. f.SetCellValue("Sheet1", "K1", "运输备注")
  1025. // 设置列宽
  1026. f.SetColWidth("Sheet1", "A", "A", 6)
  1027. f.SetColWidth("Sheet1", "B", "B", 8)
  1028. f.SetColWidth("Sheet1", "C", "C", 14)
  1029. f.SetColWidth("Sheet1", "D", "D", 14)
  1030. f.SetColWidth("Sheet1", "E", "E", 30)
  1031. f.SetColWidth("Sheet1", "F", "F", 14)
  1032. f.SetColWidth("Sheet1", "G", "G", 14)
  1033. f.SetColWidth("Sheet1", "H", "H", 30)
  1034. f.SetColWidth("Sheet1", "I", "I", 15)
  1035. f.SetColWidth("Sheet1", "J", "J", 15)
  1036. f.SetColWidth("Sheet1", "K", "K", 15)
  1037. line := 1
  1038. // 循环写入数据
  1039. for i, v := range list {
  1040. line++
  1041. f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), i+1)
  1042. f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), model.WaybillStatusMap[v.Status])
  1043. f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.SenderAddressName)
  1044. f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.SenderAddressPhone)
  1045. f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.SenderAddressDetails)
  1046. f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.ConsigneeAddressName)
  1047. f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.ConsigneeAddressPhone)
  1048. f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), v.ConsigneeAddressDetails)
  1049. f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), v.DeliveryName)
  1050. f.SetCellValue("Sheet1", fmt.Sprintf("J%d", line), v.DeliveryPhone)
  1051. f.SetCellValue("Sheet1", fmt.Sprintf("K%d", line), v.Remark)
  1052. }
  1053. timeStr := time.Now().Format("20060102150405")
  1054. filePath := "ofile/" + "运单" + timeStr + ".xlsx"
  1055. defer func() {
  1056. os.Remove(filePath)
  1057. }()
  1058. // 保存文件
  1059. if err = f.SaveAs(filePath); err != nil {
  1060. logs.Error("保存运单失败:", err)
  1061. }
  1062. c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
  1063. // PathEscape 函数对中文做处理
  1064. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape("运单"+timeStr+".xlsx"))
  1065. c.Header("Content-Transfer-Encoding", "binary")
  1066. c.File(filePath)
  1067. }
  1068. // CustomerInsert 客户添加运单
  1069. // @Summary 客户添加运单
  1070. // @Description 客户添加运单
  1071. // @Tags 运单
  1072. // @Accept application/json
  1073. // @Product application/json
  1074. // @Param data body dto.WaybillInsertReq true "data"
  1075. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  1076. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  1077. // @Router /api/waybill/customer [post]
  1078. // @Security Bearer
  1079. func (e WaybillController) CustomerInsert(c *gin.Context) {
  1080. s := service.Waybill{}
  1081. userSvc := service.SysUser{}
  1082. req := dto.WaybillInsertReq{}
  1083. err := e.MakeContext(c).
  1084. MakeOrm().
  1085. Bind(&req, binding.JSON).
  1086. MakeService(&s.Service).
  1087. MakeService(&userSvc.Service).
  1088. Errors
  1089. if err != nil {
  1090. e.Logger.Error(err)
  1091. e.Error(500, err, err.Error())
  1092. return
  1093. }
  1094. p := actions.GetPermissionFromContext(c)
  1095. var userObj model.SysUser
  1096. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  1097. if err != nil {
  1098. e.Error(500, err, "获取用户信息失败")
  1099. return
  1100. }
  1101. if p.DeptId == 0 && req.DeptId == 0 {
  1102. e.Error(500, err, "请先选择运输公司")
  1103. return
  1104. }
  1105. // 设置创建人
  1106. req.SetCreateBy(user.GetUserId(c))
  1107. if p.DeptId > 0 {
  1108. req.SetDeptId(p.DeptId)
  1109. }
  1110. err = s.Insert(&req)
  1111. if err != nil {
  1112. e.Error(500, err, err.Error())
  1113. return
  1114. }
  1115. e.OK(req.GetId(), "添加成功")
  1116. }
  1117. // Import 导入运单
  1118. // @Summary 导入运单
  1119. // @Description 导入运单
  1120. // @Tags 运单
  1121. // @Accept application/json
  1122. // @Product application/json
  1123. // @Param data body dto.WaybillImportReq true "data"
  1124. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  1125. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  1126. // @Router /api/waybill/import [post]
  1127. // @Security Bearer
  1128. func (e WaybillController) Import(c *gin.Context) {
  1129. s := service.Waybill{}
  1130. userSvc := service.SysUser{}
  1131. req := dto.WaybillImportReq{}
  1132. err := e.MakeContext(c).
  1133. MakeOrm().
  1134. Bind(&req, binding.Form).
  1135. MakeService(&s.Service).
  1136. MakeService(&userSvc.Service).
  1137. Errors
  1138. if err != nil {
  1139. e.Logger.Error(err)
  1140. e.Error(500, err, err.Error())
  1141. return
  1142. }
  1143. //读取第一fileName的文件
  1144. fileHeader, err := c.FormFile("file")
  1145. if err != nil {
  1146. err = errors.New("文件格式错误" + err.Error())
  1147. e.Logger.Error(err)
  1148. e.Error(500, err, err.Error())
  1149. return
  1150. }
  1151. if fileHeader.Size > 1024*1024*2 {
  1152. err = errors.New("文件大小超过2M")
  1153. e.Logger.Error(err)
  1154. e.Error(500, err, err.Error())
  1155. return
  1156. }
  1157. file, err := fileHeader.Open()
  1158. if err != nil {
  1159. err = errors.New("文件格式错误" + err.Error())
  1160. e.Logger.Error(err)
  1161. e.Error(500, err, err.Error())
  1162. return
  1163. }
  1164. defer file.Close()
  1165. xlsx, err := excelize.OpenReader(bufio.NewReader(file))
  1166. if err != nil {
  1167. err = errors.New("文件格式错误" + err.Error())
  1168. e.Logger.Error(err)
  1169. e.Error(500, err, err.Error())
  1170. return
  1171. }
  1172. p := actions.GetPermissionFromContext(c)
  1173. if p.DeptId == 0 {
  1174. e.Error(500, err, "获取用户信息失败")
  1175. return
  1176. }
  1177. var userObj model.SysUser
  1178. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  1179. if err != nil {
  1180. e.Error(500, err, "获取用户信息失败")
  1181. return
  1182. }
  1183. rows, _ := xlsx.GetRows("Sheet1")
  1184. for indexRow, row := range rows {
  1185. if indexRow == 0 {
  1186. continue
  1187. }
  1188. if len(row) < 10 {
  1189. for i := 0; i < 10-len(row); i++ {
  1190. row = append(row, "")
  1191. }
  1192. }
  1193. for i, colCell := range row {
  1194. fmt.Println(i, ":", colCell)
  1195. }
  1196. //quantity, _ := strconv.Atoi(row[8])
  1197. obj := dto.WaybillInsertReq{
  1198. Status: 1,
  1199. ConsigneeAddressName: row[0],
  1200. ConsigneeAddressPhone: row[1],
  1201. ConsigneeAddressDetails: row[2],
  1202. TamperProofLabel: row[3], // 防拆标签
  1203. Remark: row[4],
  1204. ReCheckId: p.UserId,
  1205. DeliveryId: p.UserId,
  1206. }
  1207. obj.SetDeptId(p.DeptId)
  1208. obj.SetCreateBy(user.GetUserId(c))
  1209. err = s.Insert(&obj)
  1210. if err != nil {
  1211. e.Error(500, err, err.Error())
  1212. return
  1213. }
  1214. }
  1215. e.OK(len(rows)-1, "导入成功")
  1216. }
  1217. // ExportTemplate 导出运单模板
  1218. // @Summary 导出运单模板
  1219. // @Description 导出运单模板
  1220. // @Tags 运单
  1221. // @Accept application/json
  1222. // @Product application/json
  1223. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  1224. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  1225. // @Router /api/waybill/export-template [get]
  1226. // @Security Bearer
  1227. func (e WaybillController) ExportTemplate(c *gin.Context) {
  1228. s := service.Waybill{}
  1229. err := e.MakeContext(c).
  1230. MakeOrm().
  1231. MakeService(&s.Service).
  1232. Errors
  1233. if err != nil {
  1234. e.Logger.Error(err)
  1235. e.Error(500, err, err.Error())
  1236. return
  1237. }
  1238. filePath := "./ofile/运单导入模板.xlsx"
  1239. //打开文件
  1240. fileTmp, errByOpenFile := os.Open(filePath)
  1241. defer fileTmp.Close()
  1242. //获取文件的名称
  1243. fileName := path.Base(filePath)
  1244. if errByOpenFile != nil {
  1245. e.Logger.Error(err)
  1246. e.Error(500, err, err.Error())
  1247. return
  1248. }
  1249. c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
  1250. // PathEscape 函数对中文做处理
  1251. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(fileName))
  1252. c.Header("Content-Transfer-Encoding", "binary")
  1253. c.File(filePath)
  1254. }
  1255. // TemperaturePDF 导出温度记录
  1256. // @Summary 导出温度记录
  1257. // @Description 导出温度记录
  1258. // @Tags 运单
  1259. // @Accept application/json
  1260. // @Product application/json
  1261. // @Param data body dto.WaybillGetByWaybillPdfReq true "data"
  1262. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  1263. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  1264. // @Router /api/waybill/temperature-pdf [get]
  1265. // @Security Bearer
  1266. func (e WaybillController) TemperaturePDF(c *gin.Context) {
  1267. s := service.Waybill{}
  1268. req := dto.WaybillGetByWaybillPdfReq{}
  1269. err := e.MakeContext(c).
  1270. MakeOrm().
  1271. Bind(&req, binding.Query).
  1272. MakeService(&s.Service).
  1273. Errors
  1274. if err != nil {
  1275. e.Logger.Error(err)
  1276. e.Error(500, err, err.Error())
  1277. return
  1278. }
  1279. var waybill model.Waybill
  1280. //p := actions.GetPermissionFromContext(c)
  1281. //err = s.GetByWaybillNo(&req, &waybill, p)
  1282. err = s.GetByWaybillNo(&req, &waybill, nil)
  1283. if err != nil {
  1284. e.Error(500, err, err.Error())
  1285. return
  1286. }
  1287. DeviceSensor_data, waybillPDF, err := s.GetAllData(&dto.WaybillGetByWaybillNoReq{WaybillNo: req.WaybillNo})
  1288. // 最高温度、最低温度、最高湿度、最低湿度
  1289. var maxTemp, minTemp, maxHumidity, minHumidity float32
  1290. // 最高温度时间、最低温度时间、最高湿度时间、最低湿度时间
  1291. var maxTempTime, minTempTime, maxHumidityTime, minHumidityTime string
  1292. // 总温度 总湿度
  1293. var totalTemp, totalHumidity float32
  1294. // 平均温度 平均湿度
  1295. var avgTemp, avgHumidity float32
  1296. // 温度阈值,湿度阈值
  1297. var tempThreshold, humidityThreshold string
  1298. // 记录开始时间,记录结束时间
  1299. var s_time, e_time string
  1300. var lastTime string
  1301. var isFirst, isSecond = true, false
  1302. var first_column, second_column []nats_server.DeviceData_R
  1303. if len(DeviceSensor_data) > 0 {
  1304. tempThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_tl, DeviceSensor_data[0].T_tu)
  1305. humidityThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_rhl, DeviceSensor_data[0].T_rhu)
  1306. s_time = DeviceSensor_data[0].T_time
  1307. e_time = DeviceSensor_data[len(DeviceSensor_data)-1].T_time
  1308. // 最高温度及时刻
  1309. maxTemp = DeviceSensor_data[0].T_t
  1310. maxTempTime = DeviceSensor_data[0].T_time
  1311. // 最低温度及时刻
  1312. minTemp = DeviceSensor_data[0].T_t
  1313. minTempTime = DeviceSensor_data[0].T_time
  1314. // 最高湿度及时刻
  1315. maxHumidity = DeviceSensor_data[0].T_rh
  1316. maxHumidityTime = DeviceSensor_data[0].T_time
  1317. // 获取最低湿度及时刻
  1318. minHumidity = DeviceSensor_data[0].T_rh
  1319. minHumidityTime = DeviceSensor_data[0].T_time
  1320. for i := 0; i < len(DeviceSensor_data); i++ {
  1321. data := DeviceSensor_data[i]
  1322. if data.T_t > maxTemp {
  1323. maxTemp = data.T_t
  1324. maxTempTime = data.T_time
  1325. }
  1326. if data.T_t < minTemp {
  1327. minTemp = data.T_t
  1328. minTempTime = data.T_time
  1329. }
  1330. totalTemp += data.T_t
  1331. if data.T_rh > maxHumidity {
  1332. maxHumidity = data.T_rh
  1333. maxHumidityTime = data.T_time
  1334. }
  1335. if data.T_rh < minHumidity {
  1336. minHumidity = data.T_rh
  1337. minHumidityTime = data.T_time
  1338. }
  1339. totalHumidity += data.T_rh
  1340. }
  1341. var sn string
  1342. for _, w := range waybillPDF {
  1343. for _, data := range w.Data {
  1344. if len(lastTime) > 0 {
  1345. if lastTime != data.T_time && isFirst == true {
  1346. isFirst = false
  1347. isSecond = true
  1348. } else if lastTime != data.T_time && isSecond == true {
  1349. isFirst = true
  1350. isSecond = false
  1351. }
  1352. }
  1353. if len(sn) > 0 && sn != data.T_sn && len(first_column)%2 == 1 {
  1354. isFirst, isSecond = isSecond, isFirst
  1355. }
  1356. if isFirst {
  1357. first_column = append(first_column, data)
  1358. lastTime = data.T_time
  1359. sn = data.T_sn
  1360. }
  1361. if isSecond {
  1362. second_column = append(second_column, data)
  1363. lastTime = data.T_time
  1364. sn = data.T_sn
  1365. }
  1366. }
  1367. }
  1368. // 平均温度
  1369. avgTemp = totalTemp / float32(len(DeviceSensor_data))
  1370. // 平均湿度
  1371. avgHumidity = totalHumidity / float32(len(DeviceSensor_data))
  1372. }
  1373. // -------------------获取最高温湿度、温蒂温湿度、平均温湿度结束
  1374. pdf := &gopdf.GoPdf{}
  1375. pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
  1376. err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf")
  1377. if err != nil {
  1378. return
  1379. }
  1380. err = pdf.SetFont("wts", "", 20)
  1381. if err != nil {
  1382. return
  1383. }
  1384. pdf.SetGrayFill(0.5)
  1385. pdf.SetMargins(0, 20, 0, 20)
  1386. pdf.AddPage()
  1387. title := "运单" + req.WaybillNo + "温度记录"
  1388. if req.HumidityShow {
  1389. title = "运单" + req.WaybillNo + "温湿度记录"
  1390. }
  1391. var y float64 = 40
  1392. textw, _ := pdf.MeasureTextWidth(title)
  1393. pdf.SetX((595 / 2) - (textw / 2))
  1394. pdf.SetY(y)
  1395. pdf.Text(title)
  1396. //y += 30
  1397. //pdf.SetFont("wts", "", 16)
  1398. //pdf.SetXY(10, y)
  1399. //pdf.Text("实施设备信息")
  1400. //// 线
  1401. //y += 10
  1402. //pdf.SetLineWidth(0.5)
  1403. //pdf.SetStrokeColor(169, 169, 169)
  1404. //pdf.Line(10, y, 585, y)
  1405. //pdf.SetFont("wts", "", 10)
  1406. //y += 20
  1407. //pdf.SetXY(10, y)
  1408. //pdf.Text(fmt.Sprintf("主机名称:%s", device.T_devName))
  1409. //pdf.SetXY(300, y)
  1410. //pdf.Text(fmt.Sprintf("主机编号:%s", device.T_sn))
  1411. y += 25
  1412. pdf.SetFont("wts", "", 16)
  1413. pdf.SetXY(10, y)
  1414. pdf.Text("记录概要信息")
  1415. // 线
  1416. y += 10
  1417. pdf.SetLineWidth(0.5)
  1418. pdf.SetStrokeColor(169, 169, 169)
  1419. pdf.Line(10, y, 585, y)
  1420. y += 20
  1421. pdf.SetFont("wts", "", 10)
  1422. pdf.SetXY(10, y)
  1423. pdf.Text(fmt.Sprintf("记录开始时间:%s", s_time))
  1424. pdf.SetXY(240, y)
  1425. pdf.Text(fmt.Sprintf("记录结束时间:%s", e_time))
  1426. sTime, _ := lib.TimeStrToTime(s_time)
  1427. eTime, _ := lib.TimeStrToTime(e_time)
  1428. pdf.SetXY(470, y)
  1429. minutes := int(eTime.Sub(sTime).Minutes())
  1430. hours := minutes / 60
  1431. remainingMinutes := minutes % 60
  1432. pdf.Text(fmt.Sprintf("记录总时间:%dh%dmin", hours, remainingMinutes))
  1433. // -------------最高温/湿度 最低温/湿度 平均温/湿度
  1434. y += 15
  1435. pdf.SetXY(10, y)
  1436. pdf.Text(fmt.Sprintf("最高温度:%.1f℃,%s", lib.RoundToDecimal(float64(maxTemp), 1), maxTempTime))
  1437. pdf.SetXY(240, y)
  1438. pdf.Text(fmt.Sprintf("最低温度:%.1f℃,%s", lib.RoundToDecimal(float64(minTemp), 1), minTempTime))
  1439. pdf.SetXY(470, y)
  1440. pdf.Text(fmt.Sprintf("平均温度:%.1f℃", lib.RoundToDecimal(float64(avgTemp), 1)))
  1441. if req.HumidityShow {
  1442. y += 15
  1443. pdf.SetXY(10, y)
  1444. pdf.Text(fmt.Sprintf("最高湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(maxHumidity), 1), maxHumidityTime))
  1445. pdf.SetXY(240, y)
  1446. pdf.Text(fmt.Sprintf("最低湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(minHumidity), 1), minHumidityTime))
  1447. pdf.SetXY(470, y)
  1448. pdf.Text(fmt.Sprintf("平均湿度:%.1f%%RH", lib.RoundToDecimal(float64(avgHumidity), 1)))
  1449. }
  1450. // -------------温/湿度阈值
  1451. y += 15
  1452. pdf.SetXY(10, y)
  1453. pdf.Text(fmt.Sprintf("温度阈值:%s℃", tempThreshold))
  1454. if req.HumidityShow {
  1455. pdf.SetXY(240, y)
  1456. pdf.Text(fmt.Sprintf("温度阈值:%s%%", humidityThreshold))
  1457. }
  1458. //-------------发货单位,收货单位,备注
  1459. y += 15
  1460. pdf.SetXY(10, y)
  1461. T_forwarding_unit_temp := []rune(waybill.SenderAddressName)
  1462. if len(T_forwarding_unit_temp) > 17 {
  1463. pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp[0:17])))
  1464. pdf.SetXY(60, y+15)
  1465. pdf.Text(fmt.Sprintf("%s", string(T_forwarding_unit_temp[17:])))
  1466. } else {
  1467. pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp)))
  1468. }
  1469. pdf.SetXY(240, y)
  1470. T_consignee_unit_temp := []rune(waybill.ConsigneeAddressName)
  1471. if len(T_consignee_unit_temp) > 17 {
  1472. pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp[0:17])))
  1473. pdf.SetXY(290, y+15)
  1474. pdf.Text(fmt.Sprintf("%s", string(T_consignee_unit_temp[17:])))
  1475. } else {
  1476. pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp)))
  1477. }
  1478. // 承运方
  1479. y += 15
  1480. pdf.SetXY(10, y)
  1481. company_name := []rune(waybill.Dept.Name)
  1482. pdf.Text(fmt.Sprintf("承运方:%s", string(company_name)))
  1483. y += 15
  1484. pdf.SetXY(10, y)
  1485. T_remark_temp := []rune(waybill.Remark)
  1486. if len(waybill.Remark) > 35 {
  1487. pdf.Text(fmt.Sprintf("备注:%s", string(T_remark_temp[0:35])))
  1488. pdf.SetXY(10, y+15)
  1489. pdf.Text(fmt.Sprintf("%s", string(T_remark_temp[35:])))
  1490. } else {
  1491. pdf.Text(fmt.Sprintf("备注: %s", string(T_remark_temp)))
  1492. }
  1493. y += 15
  1494. //pdf.SetFont("wts", "", 16)
  1495. //pdf.SetXY(10, y)
  1496. //pdf.Text("记录曲线信息")
  1497. //// 线
  1498. //y += 10
  1499. //pdf.SetLineWidth(0.5)
  1500. //pdf.SetStrokeColor(169, 169, 169)
  1501. //pdf.Line(10, y, 585, y)
  1502. //y += 1
  1503. //
  1504. //var tempFilepath string
  1505. //tempFilepath, err = DeviceDataTemperatureJPG2(s_time, e_time, waybillPDF)
  1506. //if err == nil {
  1507. // imgH, _ := gopdf.ImageHolderByPath(tempFilepath)
  1508. // pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
  1509. // y += 315
  1510. //}
  1511. //
  1512. //var humidityFilepath string
  1513. //if req.HumidityShow {
  1514. // humidityFilepath, err = DeviceDataHumidityJPG2(s_time, e_time, waybillPDF)
  1515. // if err == nil {
  1516. // imgH, _ := gopdf.ImageHolderByPath(humidityFilepath)
  1517. // pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
  1518. // y += 315
  1519. // }
  1520. //}
  1521. if y > 841.89 {
  1522. // 图片结束直接分页
  1523. pdf.AddPage()
  1524. y = 20
  1525. }
  1526. y += 20
  1527. pdf.SetFont("wts", "", 16)
  1528. pdf.SetXY(10, y)
  1529. pdf.Text("记录数据信息")
  1530. // 线
  1531. y += 10
  1532. pdf.SetLineWidth(0.5)
  1533. pdf.SetStrokeColor(169, 169, 169)
  1534. pdf.Line(10, y, 585, y)
  1535. y += 10
  1536. pdf.SetFont("wts", "", 10)
  1537. var x float64 = 10
  1538. var w float64 = 112
  1539. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1540. x = x + w
  1541. w = 101
  1542. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1543. if req.HumidityShow {
  1544. x = x + w
  1545. w = 37
  1546. lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1547. x = x + w
  1548. w = 37
  1549. lib.RectFillColor(pdf, "湿度%", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1550. } else {
  1551. x = x + w
  1552. w = 37 * 2
  1553. lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1554. }
  1555. x = x + w
  1556. w = 112
  1557. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1558. x = x + w
  1559. w = 101
  1560. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1561. if req.HumidityShow {
  1562. x = x + w
  1563. w = 37
  1564. lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1565. x = x + w
  1566. w = 37
  1567. lib.RectFillColor(pdf, "湿度%", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1568. } else {
  1569. x = x + w
  1570. w = 37 * 2
  1571. lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1572. }
  1573. y += 20
  1574. var textH float64 = 25 // if text height is 25px.
  1575. for i, v := range first_column {
  1576. pdf.SetNewY(y, textH)
  1577. y = pdf.GetY()
  1578. x, w = 10, 112
  1579. lib.RectFillColor(pdf, v.T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1580. x = x + w
  1581. w = 101
  1582. lib.RectFillColor(pdf, v.T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1583. // 显示温湿度
  1584. if req.HumidityShow {
  1585. x = x + w
  1586. w = 37
  1587. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", v.T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1588. x = x + w
  1589. w = 37
  1590. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", v.T_rh), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1591. } else {
  1592. x = x + w
  1593. w = 37 * 2
  1594. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", v.T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1595. }
  1596. if i < len(second_column) {
  1597. x = x + w
  1598. w = 112
  1599. lib.RectFillColor(pdf, second_column[i].T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1600. x = x + w
  1601. w = 101
  1602. lib.RectFillColor(pdf, second_column[i].T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1603. if req.HumidityShow {
  1604. x = x + w
  1605. w = 37
  1606. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1607. x = x + w
  1608. w = 37
  1609. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_rh), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1610. } else {
  1611. x = x + w
  1612. w = 37 * 2
  1613. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1614. }
  1615. }
  1616. y += 20
  1617. }
  1618. if len(second_column) > len(first_column) {
  1619. for i := len(first_column); i < len(second_column); i++ {
  1620. pdf.SetNewY(y, textH)
  1621. y = pdf.GetY()
  1622. x, w = 297, 112
  1623. lib.RectFillColor(pdf, second_column[i].T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1624. x = x + w
  1625. w = 101
  1626. lib.RectFillColor(pdf, second_column[i].T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1627. if req.HumidityShow {
  1628. x = x + w
  1629. w = 37
  1630. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1631. x = x + w
  1632. w = 37
  1633. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_rh), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1634. } else {
  1635. x = x + w
  1636. w = 37 * 2
  1637. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1638. }
  1639. y += 20
  1640. }
  1641. }
  1642. filename := "运单" + req.WaybillNo + "温湿度记录" + time.Now().Format("20060102150405") + ".pdf"
  1643. filePath := "ofile/" + filename
  1644. err = pdf.WritePdf(filePath)
  1645. if err != nil {
  1646. return
  1647. }
  1648. defer func() {
  1649. //os.Remove(tempFilepath)
  1650. //os.Remove(humidityFilepath)
  1651. os.Remove(filePath)
  1652. }()
  1653. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(filename))
  1654. c.Header("Content-Transfer-Encoding", "binary")
  1655. c.File(filePath)
  1656. }
  1657. // 获取温度图片
  1658. func DeviceDataTemperatureJPG(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  1659. if len(waybillPDF) == 0 {
  1660. return "", errors.New("暂无数据可生成图片")
  1661. }
  1662. // 创建一个新的绘图
  1663. p := plot.New()
  1664. // 设置绘图标题和标签
  1665. p.Title.Text = "temperature"
  1666. //p.Legend.ThumbnailWidth = 20
  1667. deviceSensorList := []nats_server.DeviceSensor_R{}
  1668. dataList := []nats_server.DeviceData_R{}
  1669. for _, w := range waybillPDF {
  1670. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  1671. dataList = append(dataList, w.Data...)
  1672. }
  1673. TemperatureMin := deviceSensorList[0].T_DeviceSensorParameter.T_Tlower
  1674. TemperatureMax := deviceSensorList[0].T_DeviceSensorParameter.T_Tupper
  1675. var ymin, ymax float32
  1676. for i, r := range dataList {
  1677. if i == 0 {
  1678. ymin = r.T_t
  1679. ymax = r.T_t
  1680. }
  1681. if ymin > r.T_t {
  1682. ymin = r.T_t
  1683. }
  1684. if ymax < r.T_t {
  1685. ymax = r.T_t
  1686. }
  1687. }
  1688. var chData = make(chan int, 10)
  1689. var jobGroup sync.WaitGroup
  1690. // 创建温度线
  1691. for i := 0; i < len(deviceSensorList); i++ {
  1692. chData <- 1
  1693. jobGroup.Add(1)
  1694. go func(index int) {
  1695. defer func() {
  1696. <-chData // 完成时chan取出1个
  1697. jobGroup.Done() // 完成时将等待组值减1
  1698. }()
  1699. sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
  1700. r_maps := []nats_server.DeviceData_R{}
  1701. for _, data := range dataList {
  1702. if data.T_sn == sn && data.T_id == id {
  1703. r_maps = append(r_maps, data)
  1704. }
  1705. }
  1706. fmt.Println(r_maps)
  1707. if len(r_maps) == 0 {
  1708. return
  1709. }
  1710. sort.Slice(r_maps, func(i, j int) bool {
  1711. return r_maps[i].T_time < r_maps[j].T_time
  1712. })
  1713. pts := make(plotter.XYs, len(r_maps))
  1714. for j, d := range r_maps {
  1715. t, _ := lib.TimeStrToTime(d.T_time)
  1716. pts[j].X = float64(t.Unix())
  1717. pts[j].Y = float64(d.T_t)
  1718. }
  1719. line, err := plotter.NewLine(pts)
  1720. if err != nil {
  1721. return
  1722. }
  1723. line.Color = randomColor(index)
  1724. p.Add(line)
  1725. }(i)
  1726. }
  1727. jobGroup.Wait()
  1728. st, _ := lib.TimeStrToTime(startTime)
  1729. et, _ := lib.TimeStrToTime(endTime)
  1730. xmin, xmax := float64(st.Unix()), float64(et.Unix())
  1731. // 添加最高,最低标准线 用红色虚线标识
  1732. p.Add(horizontalLine(xmin, xmax, float64(TemperatureMin)))
  1733. p.Add(horizontalLine(xmin, xmax, float64(TemperatureMax)))
  1734. if ymax < TemperatureMax {
  1735. ymax = TemperatureMax
  1736. }
  1737. if ymin > 0 {
  1738. ymin = 0
  1739. }
  1740. p.Y.Min, p.Y.Max = float64(ymin), float64(ymax)
  1741. p.X.Min, p.X.Max = xmin, xmax
  1742. p.Y.Tick.Marker = commaTicks{}
  1743. p.X.Tick.Marker = timeTicks{}
  1744. p.X.Tick.Label.Rotation = math.Pi / 5
  1745. p.X.Tick.Label.YAlign = draw.YCenter
  1746. p.X.Tick.Label.XAlign = draw.XRight
  1747. filepath := "ofile/" + "temperature" + deviceSensorList[0].T_sn + ".jpg"
  1748. // 保存文件
  1749. if err := p.Save(10*vg.Inch, 4*vg.Inch, filepath); err != nil {
  1750. logs.Error(lib.FuncName(), "生成图片失败", err)
  1751. return "", err
  1752. }
  1753. return filepath, nil
  1754. }
  1755. func DeviceDataTemperatureJPG2(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  1756. if len(waybillPDF) == 0 {
  1757. return "", errors.New("暂无数据可生成图片")
  1758. }
  1759. deviceSensorList := []nats_server.DeviceSensor_R{}
  1760. dataList := []nats_server.DeviceData_R{}
  1761. for _, w := range waybillPDF {
  1762. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  1763. dataList = append(dataList, w.Data...)
  1764. }
  1765. TemperatureMin := deviceSensorList[0].T_DeviceSensorParameter.T_Tlower
  1766. TemperatureMax := deviceSensorList[0].T_DeviceSensorParameter.T_Tupper
  1767. var ymin, ymax float32
  1768. for i, r := range dataList {
  1769. if i == 0 {
  1770. ymin = r.T_t
  1771. ymax = r.T_t
  1772. }
  1773. if ymin > r.T_t {
  1774. ymin = r.T_t
  1775. }
  1776. if ymax < r.T_t {
  1777. ymax = r.T_t
  1778. }
  1779. }
  1780. series := make([]chart.Series, 0)
  1781. var chData = make(chan int, 10)
  1782. var jobGroup sync.WaitGroup
  1783. // 创建温度线
  1784. for i := 0; i < len(deviceSensorList); i++ {
  1785. chData <- 1
  1786. jobGroup.Add(1)
  1787. go func(index int) {
  1788. defer func() {
  1789. <-chData // 完成时chan取出1个
  1790. jobGroup.Done() // 完成时将等待组值减1
  1791. }()
  1792. sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
  1793. r_maps := []nats_server.DeviceData_R{}
  1794. for _, data := range dataList {
  1795. if data.T_sn == sn && data.T_id == id {
  1796. r_maps = append(r_maps, data)
  1797. }
  1798. }
  1799. fmt.Println(r_maps)
  1800. if len(r_maps) == 0 {
  1801. return
  1802. }
  1803. sort.Slice(r_maps, func(i, j int) bool {
  1804. return r_maps[i].T_time < r_maps[j].T_time
  1805. })
  1806. xValues := make([]time.Time, len(r_maps))
  1807. yValues := make([]float64, len(r_maps))
  1808. for j := 0; j < len(r_maps); j++ {
  1809. t, _ := lib.TimeStrToTime(r_maps[j].T_time)
  1810. xValues[j] = t
  1811. yValues[j] = float64(r_maps[j].T_t)
  1812. }
  1813. series = append(series, chart.TimeSeries{
  1814. Name: fmt.Sprintf("%s-%d", sn, id),
  1815. XValues: xValues,
  1816. YValues: yValues,
  1817. })
  1818. }(i)
  1819. }
  1820. jobGroup.Wait()
  1821. if ymax < TemperatureMax {
  1822. ymax = TemperatureMax
  1823. }
  1824. if ymin > 0 {
  1825. ymin = 0
  1826. }
  1827. if ymin > TemperatureMin {
  1828. ymin = TemperatureMin
  1829. }
  1830. st, _ := lib.TimeStrToTime(startTime)
  1831. et, _ := lib.TimeStrToTime(endTime)
  1832. series = append(series, chart.TimeSeries{
  1833. Style: chart.Style{
  1834. StrokeColor: drawing.ColorRed,
  1835. StrokeDashArray: []float64{5.0, 5.0},
  1836. },
  1837. XValues: []time.Time{st, et},
  1838. YValues: []float64{float64(TemperatureMin), float64(TemperatureMin)},
  1839. })
  1840. series = append(series, chart.TimeSeries{
  1841. Style: chart.Style{
  1842. StrokeColor: drawing.ColorRed,
  1843. StrokeDashArray: []float64{5.0, 5.0},
  1844. },
  1845. XValues: []time.Time{st, et},
  1846. YValues: []float64{float64(TemperatureMax), float64(TemperatureMax)},
  1847. })
  1848. font := getZWFont()
  1849. graph := chart.Chart{
  1850. Title: "温度记录",
  1851. TitleStyle: chart.Style{
  1852. FontSize: 15,
  1853. },
  1854. Background: chart.Style{
  1855. Padding: chart.Box{
  1856. Top: 20,
  1857. },
  1858. },
  1859. Font: font,
  1860. XAxis: chart.XAxis{
  1861. Name: "时间",
  1862. ValueFormatter: chart.TimeValueFormatterWithFormat("2006-01-02 15:04"),
  1863. },
  1864. YAxis: chart.YAxis{
  1865. Name: "温度",
  1866. Range: &chart.ContinuousRange{
  1867. Min: float64(ymin),
  1868. Max: float64(ymax + 2),
  1869. },
  1870. },
  1871. Series: series,
  1872. }
  1873. //graph.Elements = []chart.Renderable{
  1874. // chart.Legend(&graph),
  1875. //}
  1876. filepath := "ofile/" + "temperature" + deviceSensorList[0].T_sn + ".jpg"
  1877. f, _ := os.Create(filepath)
  1878. defer f.Close()
  1879. graph.Render(chart.PNG, f)
  1880. return filepath, nil
  1881. }
  1882. // 获取湿度图片
  1883. func DeviceDataHumidityJPG(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  1884. if len(waybillPDF) == 0 {
  1885. return "", errors.New("暂无数据可生成图片")
  1886. }
  1887. // 创建一个新的绘图
  1888. p := plot.New()
  1889. // 设置绘图标题和标签
  1890. p.Title.Text = "humidity"
  1891. deviceSensorList := []nats_server.DeviceSensor_R{}
  1892. dataList := []nats_server.DeviceData_R{}
  1893. for _, w := range waybillPDF {
  1894. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  1895. dataList = append(dataList, w.Data...)
  1896. }
  1897. humidityMin := deviceSensorList[0].T_DeviceSensorParameter.T_RHlower
  1898. humidityMax := deviceSensorList[0].T_DeviceSensorParameter.T_RHupper
  1899. var ymin, ymax float32
  1900. for i, r := range dataList {
  1901. if i == 0 {
  1902. ymin = r.T_rh
  1903. ymax = r.T_rh
  1904. }
  1905. if ymin > r.T_rh {
  1906. ymin = r.T_rh
  1907. }
  1908. if ymax < r.T_rh {
  1909. ymax = r.T_rh
  1910. }
  1911. }
  1912. var chData = make(chan int, 10)
  1913. var jobGroup sync.WaitGroup
  1914. // 创建温度线
  1915. for i := 0; i < len(deviceSensorList); i++ {
  1916. chData <- 1
  1917. jobGroup.Add(1)
  1918. go func(index int) {
  1919. defer func() {
  1920. <-chData // 完成时chan取出1个
  1921. jobGroup.Done() // 完成时将等待组值减1
  1922. }()
  1923. sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
  1924. r_maps := []nats_server.DeviceData_R{}
  1925. for _, data := range dataList {
  1926. if data.T_sn == sn && data.T_id == id {
  1927. r_maps = append(r_maps, data)
  1928. }
  1929. }
  1930. if len(r_maps) == 0 {
  1931. return
  1932. }
  1933. sort.Slice(r_maps, func(i, j int) bool {
  1934. return r_maps[i].T_time < r_maps[j].T_time
  1935. })
  1936. pts := make(plotter.XYs, len(r_maps))
  1937. for j, d := range r_maps {
  1938. t, _ := lib.TimeStrToTime(d.T_time)
  1939. pts[j].X = float64(t.Unix())
  1940. pts[j].Y = float64(d.T_rh)
  1941. }
  1942. line, err := plotter.NewLine(pts)
  1943. if err != nil {
  1944. return
  1945. }
  1946. line.Color = randomColor(index)
  1947. p.Add(line)
  1948. }(i)
  1949. }
  1950. jobGroup.Wait()
  1951. st, _ := lib.TimeStrToTime(startTime)
  1952. et, _ := lib.TimeStrToTime(endTime)
  1953. xmin, xmax := float64(st.Unix()), float64(et.Unix())
  1954. // 添加最高,最低标准线 用红色虚线标识
  1955. p.Add(horizontalLine(xmin, xmax, float64(humidityMin)))
  1956. p.Add(horizontalLine(xmin, xmax, float64(humidityMax)))
  1957. if ymax < humidityMax {
  1958. ymax = humidityMax
  1959. }
  1960. if ymin > 0 {
  1961. ymin = 0
  1962. }
  1963. p.Y.Min, p.Y.Max = float64(ymin), float64(ymax)
  1964. p.X.Min, p.X.Max = xmin, xmax
  1965. p.Y.Tick.Marker = commaTicks{}
  1966. //p.X.Tick.Marker = plot.TimeTicks{Format: "2006-01-02 15:04:05"}
  1967. p.X.Tick.Marker = timeTicks{}
  1968. p.X.Tick.Label.Rotation = math.Pi / 5
  1969. p.X.Tick.Label.YAlign = draw.YCenter
  1970. p.X.Tick.Label.XAlign = draw.XRight
  1971. filepath := "ofile/" + "humidity" + deviceSensorList[0].T_sn + ".jpg"
  1972. // 保存文件
  1973. if err := p.Save(10*vg.Inch, 4*vg.Inch, filepath); err != nil {
  1974. logs.Error(lib.FuncName(), "生成图片失败", err)
  1975. return "", err
  1976. }
  1977. return filepath, nil
  1978. }
  1979. func DeviceDataHumidityJPG2(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  1980. if len(waybillPDF) == 0 {
  1981. return "", errors.New("暂无数据可生成图片")
  1982. }
  1983. deviceSensorList := []nats_server.DeviceSensor_R{}
  1984. dataList := []nats_server.DeviceData_R{}
  1985. for _, w := range waybillPDF {
  1986. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  1987. dataList = append(dataList, w.Data...)
  1988. }
  1989. humidityMin := deviceSensorList[0].T_DeviceSensorParameter.T_RHlower
  1990. humidityMax := deviceSensorList[0].T_DeviceSensorParameter.T_RHupper
  1991. var ymin, ymax float32
  1992. for i, r := range dataList {
  1993. if i == 0 {
  1994. ymin = r.T_t
  1995. ymax = r.T_t
  1996. }
  1997. if ymin > r.T_t {
  1998. ymin = r.T_t
  1999. }
  2000. if ymax < r.T_t {
  2001. ymax = r.T_t
  2002. }
  2003. }
  2004. series := make([]chart.Series, 0)
  2005. var chData = make(chan int, 10)
  2006. var jobGroup sync.WaitGroup
  2007. // 创建温度线
  2008. for i := 0; i < len(deviceSensorList); i++ {
  2009. chData <- 1
  2010. jobGroup.Add(1)
  2011. go func(index int) {
  2012. defer func() {
  2013. <-chData // 完成时chan取出1个
  2014. jobGroup.Done() // 完成时将等待组值减1
  2015. }()
  2016. sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
  2017. r_maps := []nats_server.DeviceData_R{}
  2018. for _, data := range dataList {
  2019. if data.T_sn == sn && data.T_id == id {
  2020. r_maps = append(r_maps, data)
  2021. }
  2022. }
  2023. if len(r_maps) == 0 {
  2024. return
  2025. }
  2026. sort.Slice(r_maps, func(i, j int) bool {
  2027. return r_maps[i].T_time < r_maps[j].T_time
  2028. })
  2029. xValues := make([]time.Time, len(r_maps))
  2030. yValues := make([]float64, len(r_maps))
  2031. for j := 0; j < len(r_maps); j++ {
  2032. t, _ := lib.TimeStrToTime(r_maps[j].T_time)
  2033. xValues[j] = t
  2034. yValues[j] = float64(r_maps[j].T_rh)
  2035. }
  2036. series = append(series, chart.TimeSeries{
  2037. Name: fmt.Sprintf("%s-%d", sn, id),
  2038. XValues: xValues,
  2039. YValues: yValues,
  2040. })
  2041. }(i)
  2042. }
  2043. jobGroup.Wait()
  2044. if ymax < humidityMax {
  2045. ymax = humidityMax
  2046. }
  2047. if ymin > 0 {
  2048. ymin = 0
  2049. }
  2050. if ymin > humidityMin {
  2051. ymin = humidityMin
  2052. }
  2053. st, _ := lib.TimeStrToTime(startTime)
  2054. et, _ := lib.TimeStrToTime(endTime)
  2055. series = append(series, chart.TimeSeries{
  2056. Style: chart.Style{
  2057. StrokeColor: drawing.ColorRed,
  2058. StrokeDashArray: []float64{5.0, 5.0},
  2059. },
  2060. XValues: []time.Time{st, et},
  2061. YValues: []float64{float64(humidityMin), float64(humidityMin)},
  2062. })
  2063. series = append(series, chart.TimeSeries{
  2064. Style: chart.Style{
  2065. StrokeColor: drawing.ColorRed,
  2066. StrokeDashArray: []float64{5.0, 5.0},
  2067. },
  2068. XValues: []time.Time{st, et},
  2069. YValues: []float64{float64(humidityMax), float64(humidityMax)},
  2070. })
  2071. font := getZWFont()
  2072. graph := chart.Chart{
  2073. Title: "湿度记录",
  2074. TitleStyle: chart.Style{
  2075. FontSize: 15,
  2076. },
  2077. Background: chart.Style{
  2078. Padding: chart.Box{
  2079. Top: 20,
  2080. },
  2081. },
  2082. Font: font,
  2083. XAxis: chart.XAxis{
  2084. Name: "时间",
  2085. ValueFormatter: chart.TimeValueFormatterWithFormat("2006-01-02 15:04"),
  2086. },
  2087. YAxis: chart.YAxis{
  2088. Name: "湿度",
  2089. Range: &chart.ContinuousRange{
  2090. Min: float64(ymin),
  2091. Max: float64(ymax + 2),
  2092. },
  2093. },
  2094. Series: series,
  2095. }
  2096. //graph.Elements = []chart.Renderable{
  2097. // chart.Legend(&graph),
  2098. //}
  2099. filepath := "ofile/" + "humidity" + deviceSensorList[0].T_sn + ".jpg"
  2100. f, _ := os.Create(filepath)
  2101. defer f.Close()
  2102. graph.Render(chart.PNG, f)
  2103. return filepath, nil
  2104. }
  2105. func horizontalLine(xmin, xmax, y float64) *plotter.Line {
  2106. pts := make(plotter.XYs, 2)
  2107. pts[0].X = xmin
  2108. pts[0].Y = y
  2109. pts[1].X = xmax
  2110. pts[1].Y = y
  2111. line, err := plotter.NewLine(pts)
  2112. if err != nil {
  2113. panic(err)
  2114. }
  2115. line.LineStyle.Dashes = []vg.Length{vg.Points(8), vg.Points(5), vg.Points(1), vg.Points(5)}
  2116. line.Color = color.RGBA{R: 255, A: 255}
  2117. return line
  2118. }
  2119. type timeTicks struct{}
  2120. func (timeTicks) Ticks(min, max float64) []plot.Tick {
  2121. tks := plot.TimeTicks{}.Ticks(min, max)
  2122. for i, t := range tks {
  2123. //if t.Label == "" { // Skip minor ticks, they are fine.
  2124. // continue
  2125. //}
  2126. tks[i].Label = time.Unix(int64(t.Value), 0).Format("2006-01-02 15:04:05")
  2127. }
  2128. return tks
  2129. }
  2130. type commaTicks struct{}
  2131. // Ticks computes the default tick marks, but inserts commas
  2132. // into the labels for the major tick marks.
  2133. func (commaTicks) Ticks(min, max float64) []plot.Tick {
  2134. tks := plot.DefaultTicks{}.Ticks(min, max)
  2135. for i, t := range tks {
  2136. //if t.Label == "" { // Skip minor ticks, they are fine.
  2137. // continue
  2138. //}
  2139. tks[i].Label = fmt.Sprintf("%.0f", t.Value)
  2140. }
  2141. return tks
  2142. }
  2143. // 生成随机颜色的辅助函数
  2144. func randomColor(i int) color.RGBA {
  2145. var colors []color.RGBA
  2146. colors = append(colors,
  2147. color.RGBA{R: 52, G: 152, B: 219, A: 255},
  2148. color.RGBA{R: 230, G: 126, B: 34, A: 255},
  2149. color.RGBA{R: 142, G: 68, B: 173, A: 255},
  2150. color.RGBA{R: 211, G: 84, B: 0, A: 255},
  2151. color.RGBA{R: 231, G: 76, B: 60, A: 255},
  2152. color.RGBA{R: 26, G: 188, B: 156, A: 255},
  2153. color.RGBA{R: 243, G: 156, B: 18, A: 255},
  2154. color.RGBA{R: 22, G: 160, B: 133, A: 255},
  2155. color.RGBA{R: 46, G: 204, B: 113, A: 255},
  2156. color.RGBA{R: 39, G: 174, B: 96, A: 255},
  2157. color.RGBA{R: 41, G: 128, B: 185, A: 255},
  2158. color.RGBA{R: 155, G: 89, B: 182, A: 255},
  2159. color.RGBA{R: 192, G: 57, B: 43, A: 255},
  2160. color.RGBA{R: 241, G: 196, B: 15, A: 255},
  2161. )
  2162. return colors[i%len(colors)]
  2163. }
  2164. func randomColor2(i int) drawing.Color {
  2165. var colors []drawing.Color
  2166. colors = append(colors,
  2167. drawing.Color{R: 52, G: 152, B: 219, A: 255},
  2168. drawing.Color{R: 230, G: 126, B: 34, A: 255},
  2169. drawing.Color{R: 142, G: 68, B: 173, A: 255},
  2170. drawing.Color{R: 211, G: 84, B: 0, A: 255},
  2171. drawing.Color{R: 231, G: 76, B: 60, A: 255},
  2172. drawing.Color{R: 26, G: 188, B: 156, A: 255},
  2173. drawing.Color{R: 243, G: 156, B: 18, A: 255},
  2174. drawing.Color{R: 22, G: 160, B: 133, A: 255},
  2175. drawing.Color{R: 46, G: 204, B: 113, A: 255},
  2176. drawing.Color{R: 39, G: 174, B: 96, A: 255},
  2177. drawing.Color{R: 41, G: 128, B: 185, A: 255},
  2178. drawing.Color{R: 155, G: 89, B: 182, A: 255},
  2179. drawing.Color{R: 192, G: 57, B: 43, A: 255},
  2180. drawing.Color{R: 241, G: 196, B: 15, A: 255},
  2181. )
  2182. return colors[i%len(colors)]
  2183. }
  2184. // getZWFont 加载字体
  2185. func getZWFont() *truetype.Font {
  2186. fontFile := "./static/fonts/MiSans-Medium.ttf"
  2187. fontBytes, err := os.ReadFile(fontFile)
  2188. if err != nil {
  2189. log.Println(err)
  2190. return nil
  2191. }
  2192. font, err := truetype.Parse(fontBytes)
  2193. if err != nil {
  2194. log.Println(err)
  2195. return nil
  2196. }
  2197. return font
  2198. }