waybill.go 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037
  1. package controller
  2. import (
  3. "bufio"
  4. "cold-logistics/app/admin/model"
  5. "cold-logistics/app/admin/service"
  6. "cold-logistics/app/admin/service/dto"
  7. "cold-logistics/common/actions"
  8. "cold-logistics/common/lib"
  9. "cold-logistics/common/nats/nats_server"
  10. "cold-logistics/conf"
  11. "errors"
  12. "fmt"
  13. "github.com/beego/beego/v2/core/logs"
  14. "github.com/boombuler/barcode"
  15. "github.com/boombuler/barcode/code128"
  16. "github.com/gin-gonic/gin"
  17. "github.com/gin-gonic/gin/binding"
  18. "github.com/golang/freetype/truetype"
  19. "github.com/ser163/png2j"
  20. "github.com/signintech/gopdf"
  21. "github.com/skip2/go-qrcode"
  22. "github.com/wcharczuk/go-chart/v2"
  23. "github.com/wcharczuk/go-chart/v2/drawing"
  24. "github.com/xuri/excelize/v2"
  25. "gogs.baozhida.cn/zoie/OAuth-core/api"
  26. "gogs.baozhida.cn/zoie/OAuth-core/pkg/jwtauth/user"
  27. _ "gogs.baozhida.cn/zoie/OAuth-core/pkg/response"
  28. "gonum.org/v1/plot"
  29. "gonum.org/v1/plot/plotter"
  30. "gonum.org/v1/plot/vg"
  31. "gonum.org/v1/plot/vg/draw"
  32. "image/color"
  33. "image/jpeg"
  34. "image/png"
  35. "log"
  36. "math"
  37. "net/url"
  38. "os"
  39. "path"
  40. "sort"
  41. "strconv"
  42. "strings"
  43. "sync"
  44. "time"
  45. )
  46. type WaybillController struct {
  47. api.Api
  48. }
  49. // GetPage 获取运单列表
  50. // @Summary 获取运单列表
  51. // @Description 获取运单列表
  52. // @Tags 运单
  53. // @Param no query string false "运单号"
  54. // @Param pageSize query int false "页条数"
  55. // @Param page query int false "页码"
  56. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  57. // @Router /api/waybill [get]
  58. // @Security Bearer
  59. func (e WaybillController) GetPage(c *gin.Context) {
  60. s := service.Waybill{}
  61. req := dto.WaybillGetPageReq{}
  62. err := e.MakeContext(c).
  63. MakeOrm().
  64. Bind(&req, binding.Query).
  65. MakeService(&s.Service).
  66. Errors
  67. if err != nil {
  68. e.Logger.Error(err)
  69. e.Error(500, err, err.Error())
  70. return
  71. }
  72. //数据权限检查
  73. p := actions.GetPermissionFromContext(c)
  74. list := make([]model.Waybill, 0)
  75. var count int64
  76. err = s.GetPage(&req, &list, &count, p)
  77. if err != nil {
  78. e.Error(500, err, err.Error())
  79. return
  80. }
  81. e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
  82. }
  83. // Export 导出运单excel
  84. // @Summary 导出运单excel
  85. // @Description 导出运单excel
  86. // @Tags 运单
  87. // @Param no query string false "运单号"
  88. // @Param pageSize query int false "页条数"
  89. // @Param page query int false "页码"
  90. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  91. // @Router /api/waybill [get]
  92. // @Security Bearer
  93. func (e WaybillController) Export(c *gin.Context) {
  94. s := service.Waybill{}
  95. req := dto.WaybillGetPageReq{}
  96. err := e.MakeContext(c).
  97. MakeOrm().
  98. Bind(&req, binding.Query).
  99. MakeService(&s.Service).
  100. Errors
  101. if err != nil {
  102. e.Logger.Error(err)
  103. e.Error(500, err, err.Error())
  104. return
  105. }
  106. //数据权限检查
  107. p := actions.GetPermissionFromContext(c)
  108. list := make([]model.Waybill, 0)
  109. var count int64
  110. req.PageSize = 9999
  111. err = s.GetPage(&req, &list, &count, p)
  112. if err != nil {
  113. e.Error(500, err, err.Error())
  114. return
  115. }
  116. f := excelize.NewFile() // 设置单元格的值
  117. // 这里设置表头ÒÒ
  118. f.SetCellValue("Sheet1", "A1", "序号")
  119. f.SetCellValue("Sheet1", "B1", "状态")
  120. f.SetCellValue("Sheet1", "C1", "寄件人名称")
  121. f.SetCellValue("Sheet1", "D1", "寄件人电话")
  122. f.SetCellValue("Sheet1", "E1", "寄件人地址")
  123. f.SetCellValue("Sheet1", "F1", "收件人名称")
  124. f.SetCellValue("Sheet1", "G1", "收件人电话")
  125. f.SetCellValue("Sheet1", "H1", "收件人地址")
  126. f.SetCellValue("Sheet1", "I1", "温度要求")
  127. f.SetCellValue("Sheet1", "J1", "配送要求")
  128. f.SetCellValue("Sheet1", "K1", "货物类型")
  129. f.SetCellValue("Sheet1", "L1", "运输备注")
  130. // 设置列宽
  131. f.SetColWidth("Sheet1", "A", "A", 6)
  132. f.SetColWidth("Sheet1", "B", "B", 8)
  133. f.SetColWidth("Sheet1", "C", "C", 14)
  134. f.SetColWidth("Sheet1", "D", "D", 14)
  135. f.SetColWidth("Sheet1", "E", "E", 30)
  136. f.SetColWidth("Sheet1", "F", "F", 14)
  137. f.SetColWidth("Sheet1", "G", "G", 14)
  138. f.SetColWidth("Sheet1", "H", "H", 30)
  139. f.SetColWidth("Sheet1", "I", "K", 15)
  140. f.SetColWidth("Sheet1", "L", "L", 15)
  141. line := 1
  142. // 循环写入数据
  143. for i, v := range list {
  144. line++
  145. f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), i+1)
  146. f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), model.WaybillStatusMap[v.Status])
  147. f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.SenderAddressName)
  148. f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.SenderAddressPhone)
  149. f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.SenderAddressDetails)
  150. f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.ConsigneeAddressName)
  151. f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.ConsigneeAddressPhone)
  152. f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), v.ConsigneeAddressDetails)
  153. f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), v.TemperatureInterval)
  154. f.SetCellValue("Sheet1", fmt.Sprintf("J%d", line), v.DeliveryCondition)
  155. f.SetCellValue("Sheet1", fmt.Sprintf("K%d", line), v.CargoType)
  156. f.SetCellValue("Sheet1", fmt.Sprintf("L%d", line), v.Remark)
  157. }
  158. timeStr := time.Now().Format("20060102150405")
  159. filePath := "ofile/" + "运单" + timeStr + ".xlsx"
  160. // 保存文件
  161. if err = f.SaveAs(filePath); err != nil {
  162. logs.Error("保存运单失败:", err)
  163. }
  164. defer func() {
  165. os.Remove(filePath)
  166. }()
  167. c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
  168. // PathEscape 函数对中文做处理
  169. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape("运单"+timeStr+".xlsx"))
  170. c.Header("Content-Transfer-Encoding", "binary")
  171. c.File(filePath)
  172. }
  173. // Home 首页统计
  174. // @Summary 首页统计
  175. // @Description 首页统计
  176. // @Tags 运单
  177. // @Param no query string false "运单号"
  178. // @Param pageSize query int false "页条数"
  179. // @Param page query int false "页码"
  180. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  181. // @Router /api/waybill [get]
  182. // @Security Bearer
  183. func (e WaybillController) Home(c *gin.Context) {
  184. s := service.Waybill{}
  185. req := dto.WaybillStatsReq{}
  186. err := e.MakeContext(c).
  187. MakeOrm().
  188. Bind(&req, binding.Query).
  189. MakeService(&s.Service).
  190. Errors
  191. if err != nil {
  192. e.Logger.Error(err)
  193. e.Error(500, err, err.Error())
  194. return
  195. }
  196. //数据权限检查
  197. p := actions.GetPermissionFromContext(c)
  198. res := s.GetBasicsStats(&req, p)
  199. e.OK(res, "查询成功")
  200. }
  201. // GetAppletPage 获取运单列表
  202. // @Summary 获取运单列表
  203. // @Description 获取运单列表
  204. // @Tags 运单
  205. // @Param no query string false "运单号"
  206. // @Param pageSize query int false "页条数"
  207. // @Param page query int false "页码"
  208. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  209. // @Router /api/waybill [get]
  210. // @Security Bearer
  211. func (e WaybillController) GetAppletPage(c *gin.Context) {
  212. s := service.Waybill{}
  213. req := dto.WaybillGetAppletPageReq{}
  214. err := e.MakeContext(c).
  215. MakeOrm().
  216. Bind(&req, binding.Query).
  217. MakeService(&s.Service).
  218. Errors
  219. if err != nil {
  220. e.Logger.Error(err)
  221. e.Error(500, err, err.Error())
  222. return
  223. }
  224. //数据权限检查
  225. p := actions.GetPermissionFromContext(c)
  226. list := make([]model.Waybill, 0)
  227. var count int64
  228. err = s.GetAppletPage(&req, &list, &count, p)
  229. if err != nil {
  230. e.Error(500, err, err.Error())
  231. return
  232. }
  233. e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
  234. }
  235. // GetAppletCount 获取app运单统计数量
  236. // @Summary 获取app运单统计数量
  237. // @Description 获取app运单统计数量
  238. // @Tags 运单
  239. // @Param no query string false "运单号"
  240. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  241. // @Router /api/waybill/applet-count [get]
  242. // @Security Bearer
  243. func (e WaybillController) GetAppletCount(c *gin.Context) {
  244. s := service.Waybill{}
  245. userSvc := service.SysUser{}
  246. req := dto.WaybillGetAppletPageReq{}
  247. err := e.MakeContext(c).
  248. MakeOrm().
  249. Bind(&req, binding.Query).
  250. MakeService(&s.Service).
  251. MakeService(&userSvc.Service).
  252. Errors
  253. if err != nil {
  254. e.Logger.Error(err)
  255. e.Error(500, err, err.Error())
  256. return
  257. }
  258. //数据权限检查
  259. p := actions.GetPermissionFromContext(c)
  260. var userObj model.SysUser
  261. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  262. if err != nil {
  263. e.Error(500, err, err.Error())
  264. return
  265. }
  266. list := make([]model.Waybill, 0)
  267. var count int64
  268. if userObj.UserType == "customer" {
  269. r := dto.WaybillGetCustomerPageReq{}
  270. r.PageSize = 9999
  271. r.CustomerId = p.UserId
  272. err = s.GetCustomerPage(&r, &list, &count, p)
  273. var statusCount = make(map[int]int)
  274. statusCount[0] = int(count)
  275. for _, waybill := range list {
  276. if _, ok := statusCount[waybill.Status]; ok {
  277. statusCount[waybill.Status] += 1
  278. } else {
  279. statusCount[waybill.Status] = 1
  280. }
  281. }
  282. e.OK(statusCount, "查询成功")
  283. return
  284. }
  285. err = s.GetAppletCount(&list, &count, p)
  286. if err != nil {
  287. e.Error(500, err, err.Error())
  288. return
  289. }
  290. var statusCount = make(map[int]int)
  291. statusCount[0] = int(count)
  292. for _, waybill := range list {
  293. if _, ok := statusCount[waybill.Status]; ok {
  294. statusCount[waybill.Status] += 1
  295. } else {
  296. statusCount[waybill.Status] = 1
  297. }
  298. }
  299. e.OK(statusCount, "查询成功")
  300. }
  301. // Get 通过id获取运单
  302. // @Summary 通过id获取运单
  303. // @Description 通过id获取运单
  304. // @Tags 运单
  305. // @Param id path string true "运单id"
  306. // @Success 200 {object} response.Response{data=model.Waybill} "{"code": 200, "data": [...]}"
  307. // @Router /api/waybill/{id} [get]
  308. // @Security Bearer
  309. func (e WaybillController) Get(c *gin.Context) {
  310. s := service.Waybill{}
  311. req := dto.WaybillGetReq{}
  312. err := e.MakeContext(c).
  313. MakeOrm().
  314. Bind(&req, nil).
  315. MakeService(&s.Service).
  316. Errors
  317. if err != nil {
  318. e.Logger.Error(err)
  319. e.Error(500, err, err.Error())
  320. return
  321. }
  322. var object model.Waybill
  323. p := actions.GetPermissionFromContext(c)
  324. //数据权限检查
  325. err = s.Get(&req, &object, p)
  326. if err != nil {
  327. e.Error(500, err, err.Error())
  328. return
  329. }
  330. e.OK(object, "查询成功")
  331. }
  332. // Insert 添加运单
  333. // @Summary 添加运单
  334. // @Description 添加运单
  335. // @Tags 运单
  336. // @Accept application/json
  337. // @Product application/json
  338. // @Param data body dto.WaybillInsertReq true "data"
  339. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  340. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  341. // @Router /api/waybill [post]
  342. // @Security Bearer
  343. func (e WaybillController) Insert(c *gin.Context) {
  344. s := service.Waybill{}
  345. req := dto.WaybillInsertReq{}
  346. err := e.MakeContext(c).
  347. MakeOrm().
  348. Bind(&req, binding.JSON).
  349. MakeService(&s.Service).
  350. Errors
  351. if err != nil {
  352. e.Logger.Error(err)
  353. e.Error(500, err, err.Error())
  354. return
  355. }
  356. p := actions.GetPermissionFromContext(c)
  357. // 设置创建人
  358. req.SetCreateBy(user.GetUserId(c))
  359. req.SetDeptId(p.DeptId)
  360. err = s.Insert(&req)
  361. if err != nil {
  362. e.Error(500, err, err.Error())
  363. return
  364. }
  365. e.OK(req.GetId(), "创建成功")
  366. }
  367. // AppletInsert 添加运单app
  368. // @Summary 添加运单app
  369. // @Description 添加运单app
  370. // @Tags 运单
  371. // @Accept application/json
  372. // @Product application/json
  373. // @Param data body dto.WaybillInsertReq true "data"
  374. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  375. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  376. // @Router /api/waybill [post]
  377. // @Security Bearer
  378. func (e WaybillController) AppletInsert(c *gin.Context) {
  379. s := service.Waybill{}
  380. req := dto.WaybillInsertReq{}
  381. err := e.MakeContext(c).
  382. MakeOrm().
  383. Bind(&req, binding.JSON).
  384. MakeService(&s.Service).
  385. Errors
  386. if err != nil {
  387. e.Logger.Error(err)
  388. e.Error(500, err, err.Error())
  389. return
  390. }
  391. p := actions.GetPermissionFromContext(c)
  392. err = s.AppletInsert(&req, p)
  393. if err != nil {
  394. e.Error(500, err, err.Error())
  395. return
  396. }
  397. e.OK(req.GetId(), "添加成功")
  398. }
  399. // Update 修改运单
  400. // @Summary 修改运单
  401. // @Description 修改运单
  402. // @Tags 运单
  403. // @Accept application/json
  404. // @Product application/json
  405. // @Param data body dto.WaybillUpdateReq true "body"
  406. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  407. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  408. // @Router /api/waybill [put]
  409. // @Security Bearer
  410. func (e WaybillController) Update(c *gin.Context) {
  411. s := service.Waybill{}
  412. req := dto.WaybillUpdateReq{}
  413. err := e.MakeContext(c).
  414. MakeOrm().
  415. Bind(&req).
  416. MakeService(&s.Service).
  417. Errors
  418. if err != nil {
  419. e.Logger.Error(err)
  420. e.Error(500, err, err.Error())
  421. return
  422. }
  423. p := actions.GetPermissionFromContext(c)
  424. req.SetUpdateBy(user.GetUserId(c))
  425. err = s.Update(&req, p)
  426. if err != nil {
  427. e.Error(500, err, err.Error())
  428. return
  429. }
  430. e.OK(req.GetId(), "更新成功")
  431. }
  432. // Delivery 派单
  433. // @Summary 派单
  434. // @Description 派单
  435. // @Tags 运单
  436. // @Accept application/json
  437. // @Product application/json
  438. // @Param data body dto.WaybillDeliveryReq true "body"
  439. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  440. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  441. // @Router /api/waybill [put]
  442. // @Security Bearer
  443. func (e WaybillController) Delivery(c *gin.Context) {
  444. s := service.Waybill{}
  445. req := dto.WaybillDeliveryReq{}
  446. err := e.MakeContext(c).
  447. MakeOrm().
  448. Bind(&req).
  449. MakeService(&s.Service).
  450. Errors
  451. if err != nil {
  452. e.Logger.Error(err)
  453. e.Error(500, err, err.Error())
  454. return
  455. }
  456. p := actions.GetPermissionFromContext(c)
  457. req.SetUpdateBy(user.GetUserId(c))
  458. err = s.Delivery(&req, p)
  459. if err != nil {
  460. e.Error(500, err, err.Error())
  461. return
  462. }
  463. e.OK(req.GetId(), "派单成功")
  464. }
  465. // Delete 删除运单
  466. // @Summary 删除运单
  467. // @Description 删除运单
  468. // @Tags 运单
  469. // @Accept application/json
  470. // @Product application/json
  471. // @Param data body dto.WaybillDeleteReq true "body"
  472. // @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
  473. // @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
  474. // @Router /api/waybill [delete]
  475. // @Security Bearer
  476. func (e WaybillController) Delete(c *gin.Context) {
  477. s := service.Waybill{}
  478. req := dto.WaybillDeleteReq{}
  479. userSvc := service.SysUser{}
  480. err := e.MakeContext(c).
  481. MakeOrm().
  482. Bind(&req, binding.JSON, nil).
  483. MakeService(&s.Service).
  484. MakeService(&userSvc.Service).
  485. Errors
  486. if err != nil {
  487. e.Logger.Error(err)
  488. e.Error(500, err, err.Error())
  489. return
  490. }
  491. //数据权限检查
  492. p := actions.GetPermissionFromContext(c)
  493. err = s.Remove(&req, p)
  494. if err != nil {
  495. e.Error(500, err, err.Error())
  496. return
  497. }
  498. e.OK(req.GetId(), "删除成功")
  499. }
  500. // WarehouseIn 入库
  501. // @Summary 入库
  502. // @Description 入库
  503. // @Tags 运单
  504. // @Accept application/json
  505. // @Product application/json
  506. // @Param data body dto.WaybillInOutReq true "body"
  507. // @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
  508. // @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
  509. // @Router /api/waybill/warehouse-in [post]
  510. // @Security Bearer
  511. func (e WaybillController) WarehouseIn(c *gin.Context) {
  512. s := service.Waybill{}
  513. req := dto.WaybillInOutReq{}
  514. err := e.MakeContext(c).
  515. MakeOrm().
  516. Bind(&req, binding.JSON, nil).
  517. MakeService(&s.Service).
  518. Errors
  519. if err != nil {
  520. e.Logger.Error(err)
  521. e.Error(500, err, err.Error())
  522. return
  523. }
  524. //数据权限检查
  525. p := actions.GetPermissionFromContext(c)
  526. err = s.WarehouseIn(&req, p)
  527. if err != nil {
  528. e.Error(500, err, err.Error())
  529. return
  530. }
  531. e.OK(req.WaybillNoList, "入库成功")
  532. }
  533. // WarehouseOut 出库
  534. // @Summary 出库
  535. // @Description 出库
  536. // @Tags 运单
  537. // @Accept application/json
  538. // @Product application/json
  539. // @Param data body dto.WaybillInOutReq true "body"
  540. // @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
  541. // @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
  542. // @Router /api/waybill/warehouse-out [post]
  543. // @Security Bearer
  544. func (e WaybillController) WarehouseOut(c *gin.Context) {
  545. s := service.Waybill{}
  546. req := dto.WaybillInOutReq{}
  547. err := e.MakeContext(c).
  548. MakeOrm().
  549. Bind(&req, binding.JSON, nil).
  550. MakeService(&s.Service).
  551. Errors
  552. if err != nil {
  553. e.Logger.Error(err)
  554. e.Error(500, err, err.Error())
  555. return
  556. }
  557. //数据权限检查
  558. p := actions.GetPermissionFromContext(c)
  559. err = s.WarehouseOut(&req, p)
  560. if err != nil {
  561. e.Error(500, err, err.Error())
  562. return
  563. }
  564. e.OK(req.WaybillNoList, "出库成功")
  565. }
  566. // CarIn 上车
  567. // @Summary 上车
  568. // @Description 上车
  569. // @Tags 运单
  570. // @Accept application/json
  571. // @Product application/json
  572. // @Param data body dto.WaybillInOutReq true "body"
  573. // @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
  574. // @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
  575. // @Router /api/waybill/car-in [post]
  576. // @Security Bearer
  577. func (e WaybillController) CarIn(c *gin.Context) {
  578. s := service.Waybill{}
  579. req := dto.WaybillInOutReq{}
  580. err := e.MakeContext(c).
  581. MakeOrm().
  582. Bind(&req, binding.JSON, nil).
  583. MakeService(&s.Service).
  584. Errors
  585. if err != nil {
  586. e.Logger.Error(err)
  587. e.Error(500, err, err.Error())
  588. return
  589. }
  590. //数据权限检查
  591. p := actions.GetPermissionFromContext(c)
  592. err = s.CarIn(&req, p)
  593. if err != nil {
  594. e.Error(500, err, err.Error())
  595. return
  596. }
  597. e.OK(req.WaybillNoList, "装车成功")
  598. }
  599. // CarOut 下车
  600. // @Summary 下车
  601. // @Description 下车
  602. // @Tags 运单
  603. // @Accept application/json
  604. // @Product application/json
  605. // @Param data body dto.WaybillInOutReq true "body"
  606. // @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
  607. // @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
  608. // @Router /api/waybill/car-out [post]
  609. // @Security Bearer
  610. func (e WaybillController) CarOut(c *gin.Context) {
  611. s := service.Waybill{}
  612. req := dto.WaybillInOutReq{}
  613. err := e.MakeContext(c).
  614. MakeOrm().
  615. Bind(&req, binding.JSON, nil).
  616. MakeService(&s.Service).
  617. Errors
  618. if err != nil {
  619. e.Logger.Error(err)
  620. e.Error(500, err, err.Error())
  621. return
  622. }
  623. //数据权限检查
  624. p := actions.GetPermissionFromContext(c)
  625. err = s.CarOut(&req, p)
  626. if err != nil {
  627. e.Error(500, err, err.Error())
  628. return
  629. }
  630. e.OK(req.WaybillNoList, "下车成功")
  631. }
  632. // CoolerBoxIn 装箱
  633. // @Summary 装箱
  634. // @Description 装箱
  635. // @Tags 运单
  636. // @Accept application/json
  637. // @Product application/json
  638. // @Param data body dto.WaybillInOutReq true "body"
  639. // @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
  640. // @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
  641. // @Router /api/waybill/cooler-box-in [post]
  642. // @Security Bearer
  643. func (e WaybillController) CoolerBoxIn(c *gin.Context) {
  644. s := service.Waybill{}
  645. req := dto.WaybillInOutReq{}
  646. err := e.MakeContext(c).
  647. MakeOrm().
  648. Bind(&req, binding.JSON, nil).
  649. MakeService(&s.Service).
  650. Errors
  651. if err != nil {
  652. e.Logger.Error(err)
  653. e.Error(500, err, err.Error())
  654. return
  655. }
  656. //数据权限检查
  657. p := actions.GetPermissionFromContext(c)
  658. err = s.CoolerBoxIn(&req, p)
  659. if err != nil {
  660. e.Error(500, err, err.Error())
  661. return
  662. }
  663. e.OK(req.WaybillNoList, "装箱成功")
  664. }
  665. // Receipt 签收
  666. // @Summary 签收
  667. // @Description 签收
  668. // @Tags 运单
  669. // @Accept application/json
  670. // @Product application/json
  671. // @Param data body dto.WaybillInOutReq true "body"
  672. // @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
  673. // @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
  674. // @Router /api/waybill/car-out [post]
  675. // @Security Bearer
  676. func (e WaybillController) Receipt(c *gin.Context) {
  677. s := service.Waybill{}
  678. req := dto.WaybillReceiptReq{}
  679. err := e.MakeContext(c).
  680. MakeOrm().
  681. Bind(&req, binding.JSON, nil).
  682. MakeService(&s.Service).
  683. Errors
  684. if err != nil {
  685. e.Logger.Error(err)
  686. e.Error(500, err, err.Error())
  687. return
  688. }
  689. //数据权限检查
  690. p := actions.GetPermissionFromContext(c)
  691. err = s.Receipt(&req, p)
  692. if err != nil {
  693. e.Error(500, err, err.Error())
  694. return
  695. }
  696. e.OK(req.WaybillNo, "签收成功")
  697. }
  698. // GetCustomerPage 获取客户运单列表
  699. // @Summary 获取客户运单列表
  700. // @Description 获取客户运单列表
  701. // @Tags 运单
  702. // @Param no query string false "运单号"
  703. // @Param pageSize query int false "页条数"
  704. // @Param page query int false "页码"
  705. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  706. // @Router /api/waybill/customer [get]
  707. // @Security Bearer
  708. func (e WaybillController) GetCustomerPage(c *gin.Context) {
  709. s := service.Waybill{}
  710. req := dto.WaybillGetCustomerPageReq{}
  711. err := e.MakeContext(c).
  712. MakeOrm().
  713. Bind(&req, binding.Query).
  714. MakeService(&s.Service).
  715. Errors
  716. if err != nil {
  717. e.Logger.Error(err)
  718. e.Error(500, err, err.Error())
  719. return
  720. }
  721. //数据权限检查
  722. p := actions.GetPermissionFromContext(c)
  723. list := make([]model.Waybill, 0)
  724. var count int64
  725. req.CustomerId = p.UserId
  726. err = s.GetCustomerPage(&req, &list, &count, p)
  727. if err != nil {
  728. e.Error(500, err, err.Error())
  729. return
  730. }
  731. e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
  732. }
  733. func (e WaybillController) CustomerExport(c *gin.Context) {
  734. s := service.Waybill{}
  735. req := dto.WaybillGetCustomerPageReq{}
  736. err := e.MakeContext(c).
  737. MakeOrm().
  738. Bind(&req, binding.Query).
  739. MakeService(&s.Service).
  740. Errors
  741. if err != nil {
  742. e.Logger.Error(err)
  743. e.Error(500, err, err.Error())
  744. return
  745. }
  746. //数据权限检查
  747. p := actions.GetPermissionFromContext(c)
  748. list := make([]model.Waybill, 0)
  749. var count int64
  750. req.CustomerId = p.UserId
  751. req.PageSize = 9999
  752. err = s.GetCustomerPage(&req, &list, &count, p)
  753. if err != nil {
  754. e.Error(500, err, err.Error())
  755. return
  756. }
  757. f := excelize.NewFile() // 设置单元格的值
  758. // 这里设置表头ÒÒ
  759. f.SetCellValue("Sheet1", "A1", "序号")
  760. f.SetCellValue("Sheet1", "B1", "状态")
  761. f.SetCellValue("Sheet1", "C1", "寄件人名称")
  762. f.SetCellValue("Sheet1", "D1", "寄件人电话")
  763. f.SetCellValue("Sheet1", "E1", "寄件人地址")
  764. f.SetCellValue("Sheet1", "F1", "收件人名称")
  765. f.SetCellValue("Sheet1", "G1", "收件人电话")
  766. f.SetCellValue("Sheet1", "H1", "收件人地址")
  767. f.SetCellValue("Sheet1", "I1", "温度要求")
  768. f.SetCellValue("Sheet1", "J1", "配送要求")
  769. f.SetCellValue("Sheet1", "K1", "货物类型")
  770. f.SetCellValue("Sheet1", "L1", "运输备注")
  771. // 设置列宽
  772. f.SetColWidth("Sheet1", "A", "A", 6)
  773. f.SetColWidth("Sheet1", "B", "B", 8)
  774. f.SetColWidth("Sheet1", "C", "C", 14)
  775. f.SetColWidth("Sheet1", "D", "D", 14)
  776. f.SetColWidth("Sheet1", "E", "E", 30)
  777. f.SetColWidth("Sheet1", "F", "F", 14)
  778. f.SetColWidth("Sheet1", "G", "G", 14)
  779. f.SetColWidth("Sheet1", "H", "H", 30)
  780. f.SetColWidth("Sheet1", "I", "K", 15)
  781. f.SetColWidth("Sheet1", "L", "L", 15)
  782. line := 1
  783. // 循环写入数据
  784. for i, v := range list {
  785. line++
  786. f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), i+1)
  787. f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), model.GetCustomerWaybillStatus(v.Status))
  788. f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.SenderAddressName)
  789. f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.SenderAddressPhone)
  790. f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.SenderAddressDetails)
  791. f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.ConsigneeAddressName)
  792. f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.ConsigneeAddressPhone)
  793. f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), v.ConsigneeAddressDetails)
  794. f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), v.TemperatureInterval)
  795. f.SetCellValue("Sheet1", fmt.Sprintf("J%d", line), v.DeliveryCondition)
  796. f.SetCellValue("Sheet1", fmt.Sprintf("K%d", line), v.CargoType)
  797. f.SetCellValue("Sheet1", fmt.Sprintf("L%d", line), v.Remark)
  798. }
  799. timeStr := time.Now().Format("20060102150405")
  800. filePath := "ofile/" + "运单" + timeStr + ".xlsx"
  801. defer func() {
  802. os.Remove(filePath)
  803. }()
  804. // 保存文件
  805. if err = f.SaveAs(filePath); err != nil {
  806. logs.Error("保存运单失败:", err)
  807. }
  808. c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
  809. // PathEscape 函数对中文做处理
  810. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape("运单"+timeStr+".xlsx"))
  811. c.Header("Content-Transfer-Encoding", "binary")
  812. c.File(filePath)
  813. }
  814. // CustomerInsert 客户添加运单
  815. // @Summary 客户添加运单
  816. // @Description 客户添加运单
  817. // @Tags 运单
  818. // @Accept application/json
  819. // @Product application/json
  820. // @Param data body dto.WaybillInsertReq true "data"
  821. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  822. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  823. // @Router /api/waybill/customer [post]
  824. // @Security Bearer
  825. func (e WaybillController) CustomerInsert(c *gin.Context) {
  826. s := service.Waybill{}
  827. userSvc := service.SysUser{}
  828. req := dto.WaybillInsertReq{}
  829. err := e.MakeContext(c).
  830. MakeOrm().
  831. Bind(&req, binding.JSON).
  832. MakeService(&s.Service).
  833. MakeService(&userSvc.Service).
  834. Errors
  835. if err != nil {
  836. e.Logger.Error(err)
  837. e.Error(500, err, err.Error())
  838. return
  839. }
  840. p := actions.GetPermissionFromContext(c)
  841. var userObj model.SysUser
  842. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  843. if err != nil {
  844. e.Error(500, err, "获取用户信息失败")
  845. return
  846. }
  847. if p.DeptId == 0 && req.DeptId == 0 {
  848. e.Error(500, err, "请先选择运输公司")
  849. return
  850. }
  851. // 设置创建人
  852. req.SetCreateBy(user.GetUserId(c))
  853. req.CustomerId = p.UserId
  854. req.CustomerName = userObj.NickName
  855. if p.DeptId > 0 {
  856. req.SetDeptId(p.DeptId)
  857. }
  858. err = s.Insert(&req)
  859. if err != nil {
  860. e.Error(500, err, err.Error())
  861. return
  862. }
  863. e.OK(req.GetId(), "创建成功")
  864. }
  865. // Import 导入运单
  866. // @Summary 导入运单
  867. // @Description 导入运单
  868. // @Tags 运单
  869. // @Accept application/json
  870. // @Product application/json
  871. // @Param data body dto.WaybillInsertReq true "data"
  872. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  873. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  874. // @Router /api/waybill/import [post]
  875. // @Security Bearer
  876. func (e WaybillController) Import(c *gin.Context) {
  877. s := service.Waybill{}
  878. userSvc := service.SysUser{}
  879. req := dto.WaybillImportReq{}
  880. err := e.MakeContext(c).
  881. MakeOrm().
  882. Bind(&req, binding.Form).
  883. MakeService(&s.Service).
  884. MakeService(&userSvc.Service).
  885. Errors
  886. if err != nil {
  887. e.Logger.Error(err)
  888. e.Error(500, err, err.Error())
  889. return
  890. }
  891. //读取第一fileName的文件
  892. fileHeader, err := c.FormFile("file")
  893. if err != nil {
  894. err = errors.New("文件格式错误" + err.Error())
  895. e.Logger.Error(err)
  896. e.Error(500, err, err.Error())
  897. return
  898. }
  899. if fileHeader.Size > 1024*1024*2 {
  900. err = errors.New("文件大小超过2M")
  901. e.Logger.Error(err)
  902. e.Error(500, err, err.Error())
  903. return
  904. }
  905. file, err := fileHeader.Open()
  906. if err != nil {
  907. err = errors.New("文件格式错误" + err.Error())
  908. e.Logger.Error(err)
  909. e.Error(500, err, err.Error())
  910. return
  911. }
  912. defer file.Close()
  913. xlsx, err := excelize.OpenReader(bufio.NewReader(file))
  914. if err != nil {
  915. err = errors.New("文件格式错误" + err.Error())
  916. e.Logger.Error(err)
  917. e.Error(500, err, err.Error())
  918. return
  919. }
  920. p := actions.GetPermissionFromContext(c)
  921. if p.DeptId == 0 {
  922. e.Error(500, err, "获取用户信息失败")
  923. return
  924. }
  925. var userObj model.SysUser
  926. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  927. if err != nil {
  928. e.Error(500, err, "获取用户信息失败")
  929. return
  930. }
  931. var customerId int
  932. //customerName := req.CustomerName
  933. if userObj.UserType == model.UserTypeCustomer {
  934. customerId = userObj.Id
  935. //customerName = userObj.NickName
  936. }
  937. rows, _ := xlsx.GetRows("Sheet1")
  938. for indexRow, row := range rows {
  939. if indexRow == 0 {
  940. continue
  941. }
  942. if len(row) < 10 {
  943. for i := 0; i < 10-len(row); i++ {
  944. row = append(row, "")
  945. }
  946. }
  947. for i, colCell := range row {
  948. fmt.Println(i, ":", colCell)
  949. }
  950. quantity, _ := strconv.Atoi(row[10])
  951. obj := dto.WaybillInsertReq{
  952. Status: 1,
  953. SenderAddressName: row[0],
  954. SenderAddressPhone: row[1],
  955. SenderAddressDetails: row[2],
  956. CustomerName: row[3],
  957. ConsigneeAddressName: row[4],
  958. ConsigneeAddressPhone: row[5],
  959. ConsigneeAddressDetails: row[6],
  960. TemperatureInterval: row[7],
  961. DeliveryCondition: row[8],
  962. CargoType: row[9],
  963. Quantity: quantity,
  964. Remark: row[11],
  965. CustomerId: customerId,
  966. }
  967. obj.SetDeptId(p.DeptId)
  968. obj.SetCreateBy(user.GetUserId(c))
  969. err = s.Insert(&obj)
  970. if err != nil {
  971. e.Error(500, err, err.Error())
  972. return
  973. }
  974. }
  975. e.OK(len(rows)-1, "导入成功")
  976. }
  977. // ExportTemplate 导出运单模板
  978. // @Summary 导出运单模板
  979. // @Description 导出运单模板
  980. // @Tags 运单
  981. // @Accept application/json
  982. // @Product application/json
  983. // @Param data body dto.WaybillInsertReq true "data"
  984. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  985. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  986. // @Router /api/waybill/export-template [post]
  987. // @Security Bearer
  988. func (e WaybillController) ExportTemplate(c *gin.Context) {
  989. s := service.Waybill{}
  990. err := e.MakeContext(c).
  991. MakeOrm().
  992. MakeService(&s.Service).
  993. Errors
  994. if err != nil {
  995. e.Logger.Error(err)
  996. e.Error(500, err, err.Error())
  997. return
  998. }
  999. filePath := "./ofile/运单导入模板.xlsx"
  1000. //打开文件
  1001. fileTmp, errByOpenFile := os.Open(filePath)
  1002. defer fileTmp.Close()
  1003. //获取文件的名称
  1004. fileName := path.Base(filePath)
  1005. if errByOpenFile != nil {
  1006. e.Logger.Error(err)
  1007. e.Error(500, err, err.Error())
  1008. return
  1009. }
  1010. c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
  1011. // PathEscape 函数对中文做处理
  1012. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(fileName))
  1013. c.Header("Content-Transfer-Encoding", "binary")
  1014. c.File(filePath)
  1015. }
  1016. // TemperaturePDF 导出温度记录
  1017. // @Summary 导出温度记录
  1018. // @Description 导出温度记录
  1019. // @Tags 运单
  1020. // @Accept application/json
  1021. // @Product application/json
  1022. // @Param data body dto.WaybillInsertReq true "data"
  1023. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  1024. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  1025. // @Router /api/waybill/temperature-pdf [post]
  1026. // @Security Bearer
  1027. func (e WaybillController) TemperaturePDF1(c *gin.Context) {
  1028. s := service.Waybill{}
  1029. companySvc := service.Company{}
  1030. req := dto.WaybillGetByWaybillPdfReq{}
  1031. err := e.MakeContext(c).
  1032. MakeOrm().
  1033. Bind(&req, binding.Query).
  1034. MakeService(&s.Service).
  1035. MakeService(&companySvc.Service).
  1036. Errors
  1037. if err != nil {
  1038. e.Logger.Error(err)
  1039. e.Error(500, err, err.Error())
  1040. return
  1041. }
  1042. var waybill model.Waybill
  1043. var company model.SysDept
  1044. //err = s.GetByWaybillNo(&req, &waybill, p)
  1045. err = s.GetByWaybillNo(&req, &waybill, nil)
  1046. if err != nil {
  1047. e.Error(500, err, err.Error())
  1048. return
  1049. }
  1050. err = companySvc.Get(&dto.CompanyGetReq{Id: waybill.DeptId}, &company)
  1051. if err != nil {
  1052. e.Error(500, err, err.Error())
  1053. return
  1054. }
  1055. DeviceSensor_data, waybillPDF, err := s.GetAllData(&dto.WaybillGetByWaybillNoReq{WaybillNo: req.WaybillNo})
  1056. // 最高温度、最低温度、最高湿度、最低湿度
  1057. var maxTemp, minTemp, maxHumidity, minHumidity float32
  1058. // 最高温度时间、最低温度时间、最高湿度时间、最低湿度时间
  1059. var maxTempTime, minTempTime, maxHumidityTime, minHumidityTime string
  1060. // 总温度 总湿度
  1061. var totalTemp, totalHumidity float32
  1062. // 平均温度 平均湿度
  1063. var avgTemp, avgHumidity float32
  1064. // 温度阈值,湿度阈值
  1065. var tempThreshold, humidityThreshold string
  1066. // 记录开始时间,记录结束时间
  1067. var s_time, e_time string
  1068. var lastTime string
  1069. var isFirst, isSecond = true, false
  1070. var first_column, second_column []nats_server.DeviceData_R
  1071. if len(DeviceSensor_data) > 0 {
  1072. tempThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_tl, DeviceSensor_data[0].T_tu)
  1073. humidityThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_rhl, DeviceSensor_data[0].T_rhu)
  1074. s_time = DeviceSensor_data[0].T_time
  1075. e_time = DeviceSensor_data[len(DeviceSensor_data)-1].T_time
  1076. // 最高温度及时刻
  1077. maxTemp = DeviceSensor_data[0].T_t
  1078. maxTempTime = DeviceSensor_data[0].T_time
  1079. // 最低温度及时刻
  1080. minTemp = DeviceSensor_data[0].T_t
  1081. minTempTime = DeviceSensor_data[0].T_time
  1082. // 最高湿度及时刻
  1083. maxHumidity = DeviceSensor_data[0].T_rh
  1084. maxHumidityTime = DeviceSensor_data[0].T_time
  1085. // 获取最低湿度及时刻
  1086. minHumidity = DeviceSensor_data[0].T_rh
  1087. minHumidityTime = DeviceSensor_data[0].T_time
  1088. for i := 0; i < len(DeviceSensor_data); i++ {
  1089. data := DeviceSensor_data[i]
  1090. if data.T_t > maxTemp {
  1091. maxTemp = data.T_t
  1092. maxTempTime = data.T_time
  1093. }
  1094. if data.T_t < minTemp {
  1095. minTemp = data.T_t
  1096. minTempTime = data.T_time
  1097. }
  1098. totalTemp += data.T_t
  1099. if data.T_rh > maxHumidity {
  1100. maxHumidity = data.T_rh
  1101. maxHumidityTime = data.T_time
  1102. }
  1103. if data.T_rh < minHumidity {
  1104. minHumidity = data.T_rh
  1105. minHumidityTime = data.T_time
  1106. }
  1107. totalHumidity += data.T_rh
  1108. }
  1109. var sn string
  1110. for _, w := range waybillPDF {
  1111. for _, data := range w.Data {
  1112. if len(lastTime) > 0 {
  1113. if lastTime != data.T_time && isFirst == true {
  1114. isFirst = false
  1115. isSecond = true
  1116. } else if lastTime != data.T_time && isSecond == true {
  1117. isFirst = true
  1118. isSecond = false
  1119. }
  1120. }
  1121. if len(sn) > 0 && sn != data.T_sn && len(first_column)%2 == 1 {
  1122. isFirst, isSecond = isSecond, isFirst
  1123. }
  1124. if isFirst {
  1125. first_column = append(first_column, data)
  1126. lastTime = data.T_time
  1127. sn = data.T_sn
  1128. }
  1129. if isSecond {
  1130. second_column = append(second_column, data)
  1131. lastTime = data.T_time
  1132. sn = data.T_sn
  1133. }
  1134. }
  1135. }
  1136. // 平均温度
  1137. avgTemp = totalTemp / float32(len(DeviceSensor_data))
  1138. // 平均湿度
  1139. avgHumidity = totalHumidity / float32(len(DeviceSensor_data))
  1140. }
  1141. // -------------------获取最高温湿度、温蒂温湿度、平均温湿度结束
  1142. pdf := &gopdf.GoPdf{}
  1143. pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
  1144. err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf")
  1145. if err != nil {
  1146. return
  1147. }
  1148. err = pdf.SetFont("wts", "", 20)
  1149. if err != nil {
  1150. return
  1151. }
  1152. pdf.SetGrayFill(0.5)
  1153. pdf.SetMargins(0, 20, 0, 20)
  1154. pdf.AddPage()
  1155. if len(company.Logo) > 0 {
  1156. imgH, errImg := lib.GetImage(company.Logo)
  1157. if errImg != nil {
  1158. err = errors.New("获取图片失败")
  1159. e.Error(500, err, err.Error())
  1160. return
  1161. }
  1162. imgWidth := float64(imgH.Bounds().Dx())
  1163. imgHeight := float64(imgH.Bounds().Dy())
  1164. W := 50.
  1165. H := (imgHeight * W) / imgWidth
  1166. if strings.Contains(company.Logo, ".png") {
  1167. err = pdf.ImageFrom(imgH, 10, 5, &gopdf.Rect{W: W, H: H})
  1168. if err != nil {
  1169. err = errors.New("写入图片失败")
  1170. e.Error(500, err, err.Error())
  1171. return
  1172. }
  1173. } else {
  1174. fileName := "./ofile/" + path.Base(company.Logo)
  1175. f, _ := os.Create(fileName)
  1176. defer f.Close()
  1177. defer func() {
  1178. os.Remove(fileName)
  1179. }()
  1180. jpeg.Encode(f, imgH, &jpeg.Options{100})
  1181. err = pdf.Image(fileName, (595-W)/2, (840-H)/2, &gopdf.Rect{W: W, H: H})
  1182. if err != nil {
  1183. err = errors.New("写入图片失败")
  1184. e.Error(500, err, err.Error())
  1185. return
  1186. }
  1187. }
  1188. }
  1189. title := "运单" + req.WaybillNo + "温度记录"
  1190. if req.HumidityShow {
  1191. title = "运单" + req.WaybillNo + "温湿度记录"
  1192. }
  1193. var y float64 = 70
  1194. textw, _ := pdf.MeasureTextWidth(title)
  1195. pdf.SetX((595 / 2) - (textw / 2))
  1196. pdf.SetY(y)
  1197. pdf.Text(title)
  1198. y += 30
  1199. pdf.SetFont("wts", "", 16)
  1200. pdf.SetXY(10, y)
  1201. pdf.Text("记录概要信息")
  1202. // 线
  1203. y += 10
  1204. pdf.SetLineWidth(0.5)
  1205. pdf.SetStrokeColor(169, 169, 169)
  1206. pdf.Line(10, y, 585, y)
  1207. y += 20
  1208. pdf.SetFont("wts", "", 10)
  1209. pdf.SetXY(10, y)
  1210. pdf.Text(fmt.Sprintf("记录开始时间:%s", s_time))
  1211. pdf.SetXY(240, y)
  1212. pdf.Text(fmt.Sprintf("记录结束时间:%s", e_time))
  1213. sTime, _ := lib.TimeStrToTime(s_time)
  1214. eTime, _ := lib.TimeStrToTime(e_time)
  1215. pdf.SetXY(470, y)
  1216. minutes := int(eTime.Sub(sTime).Minutes())
  1217. hours := minutes / 60
  1218. remainingMinutes := minutes % 60
  1219. pdf.Text(fmt.Sprintf("记录总时间:%dh%dmin", hours, remainingMinutes))
  1220. // -------------最高温/湿度 最低温/湿度 平均温/湿度
  1221. y += 15
  1222. pdf.SetXY(10, y)
  1223. pdf.Text(fmt.Sprintf("最高温度:%.1f℃,%s", lib.RoundToDecimal(float64(maxTemp), 1), maxTempTime))
  1224. pdf.SetXY(240, y)
  1225. pdf.Text(fmt.Sprintf("最低温度:%.1f℃,%s", lib.RoundToDecimal(float64(minTemp), 1), minTempTime))
  1226. pdf.SetXY(470, y)
  1227. pdf.Text(fmt.Sprintf("平均温度:%.1f℃", lib.RoundToDecimal(float64(avgTemp), 1)))
  1228. if req.HumidityShow {
  1229. y += 15
  1230. pdf.SetXY(10, y)
  1231. pdf.Text(fmt.Sprintf("最高湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(maxHumidity), 1), maxHumidityTime))
  1232. pdf.SetXY(240, y)
  1233. pdf.Text(fmt.Sprintf("最低湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(minHumidity), 1), minHumidityTime))
  1234. pdf.SetXY(470, y)
  1235. pdf.Text(fmt.Sprintf("平均湿度:%.1f%%RH", lib.RoundToDecimal(float64(avgHumidity), 1)))
  1236. }
  1237. // -------------温/湿度阈值
  1238. y += 15
  1239. pdf.SetXY(10, y)
  1240. pdf.Text(fmt.Sprintf("温度阈值:%s℃", tempThreshold))
  1241. if req.HumidityShow {
  1242. pdf.SetXY(240, y)
  1243. pdf.Text(fmt.Sprintf("湿度阈值:%s%%", humidityThreshold))
  1244. }
  1245. //-------------发货单位,收货单位,备注
  1246. y += 15
  1247. pdf.SetXY(10, y)
  1248. T_forwarding_unit_temp := []rune(waybill.SenderAddressName)
  1249. if len(T_forwarding_unit_temp) > 17 {
  1250. pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp[0:17])))
  1251. pdf.SetXY(60, y+15)
  1252. pdf.Text(fmt.Sprintf("%s", string(T_forwarding_unit_temp[17:])))
  1253. } else {
  1254. pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp)))
  1255. }
  1256. pdf.SetXY(240, y)
  1257. T_consignee_unit_temp := []rune(waybill.ConsigneeAddressName)
  1258. if len(T_consignee_unit_temp) > 17 {
  1259. pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp[0:17])))
  1260. pdf.SetXY(290, y+15)
  1261. pdf.Text(fmt.Sprintf("%s", string(T_consignee_unit_temp[17:])))
  1262. } else {
  1263. pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp)))
  1264. }
  1265. // 承运方
  1266. y += 15
  1267. pdf.SetXY(10, y)
  1268. company_name := []rune(waybill.Dept.Name)
  1269. pdf.Text(fmt.Sprintf("承运方:%s", string(company_name)))
  1270. y += 15
  1271. pdf.SetXY(10, y)
  1272. T_remark_temp := []rune(waybill.Remark)
  1273. if len(waybill.Remark) > 35 {
  1274. pdf.Text(fmt.Sprintf("备注:%s", string(T_remark_temp[0:35])))
  1275. pdf.SetXY(10, y+15)
  1276. pdf.Text(fmt.Sprintf("%s", string(T_remark_temp[35:])))
  1277. } else {
  1278. pdf.Text(fmt.Sprintf("备注: %s", string(T_remark_temp)))
  1279. }
  1280. y += 15
  1281. //pdf.SetFont("wts", "", 16)
  1282. //pdf.SetXY(10, y)
  1283. //pdf.Text("记录曲线信息")
  1284. //// 线
  1285. //y += 10
  1286. //pdf.SetLineWidth(0.5)
  1287. //pdf.SetStrokeColor(169, 169, 169)
  1288. //pdf.Line(10, y, 585, y)
  1289. //y += 1
  1290. //
  1291. //var tempFilepath string
  1292. //tempFilepath, err = DeviceDataTemperatureJPG2(s_time, e_time, waybillPDF)
  1293. //if err == nil {
  1294. // imgH, _ := gopdf.ImageHolderByPath(tempFilepath)
  1295. // pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
  1296. // y += 315
  1297. //}
  1298. //
  1299. //var humidityFilepath string
  1300. //if req.HumidityShow {
  1301. // humidityFilepath, err = DeviceDataHumidityJPG2(s_time, e_time, waybillPDF)
  1302. // if err == nil {
  1303. // imgH, _ := gopdf.ImageHolderByPath(humidityFilepath)
  1304. // pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
  1305. // y += 315
  1306. // }
  1307. //}
  1308. if y > 841.89 {
  1309. // 图片结束直接分页
  1310. pdf.AddPage()
  1311. y = 20
  1312. }
  1313. y += 20
  1314. pdf.SetFont("wts", "", 16)
  1315. pdf.SetXY(10, y)
  1316. pdf.Text("记录数据信息")
  1317. // 线
  1318. y += 10
  1319. pdf.SetLineWidth(0.5)
  1320. pdf.SetStrokeColor(169, 169, 169)
  1321. pdf.Line(10, y, 585, y)
  1322. y += 10
  1323. pdf.SetFont("wts", "", 10)
  1324. var x float64 = 10
  1325. var w float64 = 112
  1326. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1327. x = x + w
  1328. w = 101
  1329. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1330. if req.HumidityShow {
  1331. x = x + w
  1332. w = 37
  1333. lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1334. x = x + w
  1335. w = 37
  1336. lib.RectFillColor(pdf, "湿度%", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1337. } else {
  1338. x = x + w
  1339. w = 37 * 2
  1340. lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1341. }
  1342. x = x + w
  1343. w = 112
  1344. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1345. x = x + w
  1346. w = 101
  1347. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1348. if req.HumidityShow {
  1349. x = x + w
  1350. w = 37
  1351. lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1352. x = x + w
  1353. w = 37
  1354. lib.RectFillColor(pdf, "湿度%", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1355. } else {
  1356. x = x + w
  1357. w = 37 * 2
  1358. lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1359. }
  1360. y += 20
  1361. var textH float64 = 25 // if text height is 25px.
  1362. for i, v := range first_column {
  1363. pdf.SetNewY(y, textH)
  1364. y = pdf.GetY()
  1365. x, w = 10, 112
  1366. lib.RectFillColor(pdf, v.T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1367. x = x + w
  1368. w = 101
  1369. lib.RectFillColor(pdf, v.T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1370. // 显示温湿度
  1371. if req.HumidityShow {
  1372. x = x + w
  1373. w = 37
  1374. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", v.T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1375. x = x + w
  1376. w = 37
  1377. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", v.T_rh), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1378. } else {
  1379. x = x + w
  1380. w = 37 * 2
  1381. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", v.T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1382. }
  1383. if i < len(second_column) {
  1384. x = x + w
  1385. w = 112
  1386. lib.RectFillColor(pdf, second_column[i].T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1387. x = x + w
  1388. w = 101
  1389. lib.RectFillColor(pdf, second_column[i].T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1390. if req.HumidityShow {
  1391. x = x + w
  1392. w = 37
  1393. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1394. x = x + w
  1395. w = 37
  1396. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_rh), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1397. } else {
  1398. x = x + w
  1399. w = 37 * 2
  1400. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1401. }
  1402. }
  1403. y += 20
  1404. }
  1405. if len(second_column) > len(first_column) {
  1406. for i := len(first_column); i < len(second_column); i++ {
  1407. pdf.SetNewY(y, textH)
  1408. y = pdf.GetY()
  1409. x, w = 297, 112
  1410. lib.RectFillColor(pdf, second_column[i].T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1411. x = x + w
  1412. w = 101
  1413. lib.RectFillColor(pdf, second_column[i].T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1414. if req.HumidityShow {
  1415. x = x + w
  1416. w = 37
  1417. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1418. x = x + w
  1419. w = 37
  1420. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_rh), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1421. } else {
  1422. x = x + w
  1423. w = 37 * 2
  1424. lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1425. }
  1426. y += 20
  1427. }
  1428. }
  1429. filename := "运单" + req.WaybillNo + "温湿度记录" + time.Now().Format("20060102150405") + ".pdf"
  1430. filePath := "ofile/" + filename
  1431. err = pdf.WritePdf(filePath)
  1432. if err != nil {
  1433. return
  1434. }
  1435. defer func() {
  1436. //os.Remove(tempFilepath)
  1437. //os.Remove(humidityFilepath)
  1438. os.Remove(filePath)
  1439. }()
  1440. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(filename))
  1441. c.Header("Content-Transfer-Encoding", "binary")
  1442. c.File(filePath)
  1443. }
  1444. func (e WaybillController) TemperaturePDF(c *gin.Context) {
  1445. s := service.Waybill{}
  1446. companySvc := service.Company{}
  1447. req := dto.WaybillGetByWaybillPdfReq{}
  1448. err := e.MakeContext(c).
  1449. MakeOrm().
  1450. Bind(&req, binding.Query).
  1451. MakeService(&s.Service).
  1452. MakeService(&companySvc.Service).
  1453. Errors
  1454. if err != nil {
  1455. e.Logger.Error(err)
  1456. e.Error(500, err, err.Error())
  1457. return
  1458. }
  1459. var waybill model.Waybill
  1460. var company model.SysDept
  1461. //err = s.GetByWaybillNo(&req, &waybill, p)
  1462. err = s.GetByWaybillNo(&req, &waybill, nil)
  1463. if err != nil {
  1464. e.Error(500, err, err.Error())
  1465. return
  1466. }
  1467. err = companySvc.Get(&dto.CompanyGetReq{Id: waybill.DeptId}, &company)
  1468. if err != nil {
  1469. e.Error(500, err, err.Error())
  1470. return
  1471. }
  1472. DeviceSensor_data, Pdf_data, waybillPDF, err := s.GetTwoDeviceSensorData(&dto.WaybillGetByWaybillNoReq{WaybillNo: req.WaybillNo})
  1473. // 最高温度、最低温度、最高湿度、最低湿度
  1474. var maxTemp, minTemp, maxHumidity, minHumidity float32
  1475. // 最高温度时间、最低温度时间、最高湿度时间、最低湿度时间
  1476. var maxTempTime, minTempTime, maxHumidityTime, minHumidityTime string
  1477. // 总温度 总湿度
  1478. var totalTemp, totalHumidity float32
  1479. // 平均温度 平均湿度
  1480. var avgTemp, avgHumidity float32
  1481. // 温度阈值,湿度阈值
  1482. var tempThreshold, humidityThreshold string
  1483. // 记录开始时间,记录结束时间
  1484. var s_time, e_time string
  1485. if len(DeviceSensor_data) > 0 {
  1486. tempThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_tl, DeviceSensor_data[0].T_tu)
  1487. humidityThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_rhl, DeviceSensor_data[0].T_rhu)
  1488. s_time = DeviceSensor_data[0].T_time
  1489. e_time = DeviceSensor_data[len(DeviceSensor_data)-1].T_time
  1490. // 最高温度及时刻
  1491. maxTemp = DeviceSensor_data[0].T_t
  1492. maxTempTime = DeviceSensor_data[0].T_time
  1493. // 最低温度及时刻
  1494. minTemp = DeviceSensor_data[0].T_t
  1495. minTempTime = DeviceSensor_data[0].T_time
  1496. // 最高湿度及时刻
  1497. maxHumidity = DeviceSensor_data[0].T_rh
  1498. maxHumidityTime = DeviceSensor_data[0].T_time
  1499. // 获取最低湿度及时刻
  1500. minHumidity = DeviceSensor_data[0].T_rh
  1501. minHumidityTime = DeviceSensor_data[0].T_time
  1502. for i := 0; i < len(DeviceSensor_data); i++ {
  1503. data := DeviceSensor_data[i]
  1504. if data.T_t > maxTemp {
  1505. maxTemp = data.T_t
  1506. maxTempTime = data.T_time
  1507. }
  1508. if data.T_t < minTemp {
  1509. minTemp = data.T_t
  1510. minTempTime = data.T_time
  1511. }
  1512. totalTemp += data.T_t
  1513. if data.T_rh > maxHumidity {
  1514. maxHumidity = data.T_rh
  1515. maxHumidityTime = data.T_time
  1516. }
  1517. if data.T_rh < minHumidity {
  1518. minHumidity = data.T_rh
  1519. minHumidityTime = data.T_time
  1520. }
  1521. totalHumidity += data.T_rh
  1522. }
  1523. // 平均温度
  1524. avgTemp = totalTemp / float32(len(DeviceSensor_data))
  1525. // 平均湿度
  1526. avgHumidity = totalHumidity / float32(len(DeviceSensor_data))
  1527. }
  1528. // -------------------获取最高温湿度、温蒂温湿度、平均温湿度结束
  1529. pdf := &gopdf.GoPdf{}
  1530. pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
  1531. err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf")
  1532. if err != nil {
  1533. return
  1534. }
  1535. err = pdf.SetFont("wts", "", 20)
  1536. if err != nil {
  1537. return
  1538. }
  1539. pdf.SetGrayFill(0.5)
  1540. pdf.SetMargins(0, 20, 0, 20)
  1541. pdf.AddPage()
  1542. if len(company.Logo) > 0 {
  1543. imgH, errImg := lib.GetImage(company.Logo)
  1544. if errImg != nil {
  1545. err = errors.New("获取图片失败")
  1546. e.Error(500, err, err.Error())
  1547. return
  1548. }
  1549. imgWidth := float64(imgH.Bounds().Dx())
  1550. imgHeight := float64(imgH.Bounds().Dy())
  1551. W := 50.
  1552. H := (imgHeight * W) / imgWidth
  1553. if strings.Contains(company.Logo, ".png") {
  1554. err = pdf.ImageFrom(imgH, 10, 5, &gopdf.Rect{W: W, H: H})
  1555. if err != nil {
  1556. err = errors.New("写入图片失败")
  1557. e.Error(500, err, err.Error())
  1558. return
  1559. }
  1560. } else {
  1561. fileName := "./ofile/" + path.Base(company.Logo)
  1562. f, _ := os.Create(fileName)
  1563. defer f.Close()
  1564. defer func() {
  1565. os.Remove(fileName)
  1566. }()
  1567. jpeg.Encode(f, imgH, &jpeg.Options{100})
  1568. err = pdf.Image(fileName, 10, 5, &gopdf.Rect{W: W, H: H})
  1569. if err != nil {
  1570. err = errors.New("写入图片失败")
  1571. e.Error(500, err, err.Error())
  1572. return
  1573. }
  1574. }
  1575. }
  1576. title := "运单" + req.WaybillNo + "温度记录"
  1577. if req.HumidityShow {
  1578. title = "运单" + req.WaybillNo + "温湿度记录"
  1579. }
  1580. var y float64 = 70
  1581. textw, _ := pdf.MeasureTextWidth(title)
  1582. pdf.SetX((595 / 2) - (textw / 2))
  1583. pdf.SetY(y)
  1584. pdf.Text(title)
  1585. y += 30
  1586. pdf.SetFont("wts", "", 16)
  1587. pdf.SetXY(10, y)
  1588. pdf.Text("记录概要信息")
  1589. // 线
  1590. y += 10
  1591. pdf.SetLineWidth(0.5)
  1592. pdf.SetStrokeColor(169, 169, 169)
  1593. pdf.Line(10, y, 585, y)
  1594. y += 20
  1595. pdf.SetFont("wts", "", 10)
  1596. pdf.SetXY(10, y)
  1597. pdf.Text(fmt.Sprintf("记录开始时间:%s", s_time))
  1598. pdf.SetXY(240, y)
  1599. pdf.Text(fmt.Sprintf("记录结束时间:%s", e_time))
  1600. sTime, _ := lib.TimeStrToTime(s_time)
  1601. eTime, _ := lib.TimeStrToTime(e_time)
  1602. pdf.SetXY(470, y)
  1603. minutes := int(eTime.Sub(sTime).Minutes())
  1604. hours := minutes / 60
  1605. remainingMinutes := minutes % 60
  1606. pdf.Text(fmt.Sprintf("记录总时间:%dh%dmin", hours, remainingMinutes))
  1607. // -------------最高温/湿度 最低温/湿度 平均温/湿度
  1608. y += 15
  1609. pdf.SetXY(10, y)
  1610. pdf.Text(fmt.Sprintf("最高温度:%.1f℃,%s", lib.RoundToDecimal(float64(maxTemp), 1), maxTempTime))
  1611. pdf.SetXY(240, y)
  1612. pdf.Text(fmt.Sprintf("最低温度:%.1f℃,%s", lib.RoundToDecimal(float64(minTemp), 1), minTempTime))
  1613. pdf.SetXY(470, y)
  1614. pdf.Text(fmt.Sprintf("平均温度:%.1f℃", lib.RoundToDecimal(float64(avgTemp), 1)))
  1615. if req.HumidityShow {
  1616. y += 15
  1617. pdf.SetXY(10, y)
  1618. pdf.Text(fmt.Sprintf("最高湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(maxHumidity), 1), maxHumidityTime))
  1619. pdf.SetXY(240, y)
  1620. pdf.Text(fmt.Sprintf("最低湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(minHumidity), 1), minHumidityTime))
  1621. pdf.SetXY(470, y)
  1622. pdf.Text(fmt.Sprintf("平均湿度:%.1f%%RH", lib.RoundToDecimal(float64(avgHumidity), 1)))
  1623. }
  1624. // -------------温/湿度阈值
  1625. y += 15
  1626. pdf.SetXY(10, y)
  1627. pdf.Text(fmt.Sprintf("温度阈值:%s℃", tempThreshold))
  1628. if req.HumidityShow {
  1629. pdf.SetXY(240, y)
  1630. pdf.Text(fmt.Sprintf("温度阈值:%s%%", humidityThreshold))
  1631. }
  1632. //-------------发货单位,收货单位,备注
  1633. y += 15
  1634. pdf.SetXY(10, y)
  1635. T_forwarding_unit_temp := []rune(waybill.SenderAddressName)
  1636. if len(T_forwarding_unit_temp) > 17 {
  1637. pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp[0:17])))
  1638. pdf.SetXY(60, y+15)
  1639. pdf.Text(fmt.Sprintf("%s", string(T_forwarding_unit_temp[17:])))
  1640. } else {
  1641. pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp)))
  1642. }
  1643. pdf.SetXY(240, y)
  1644. T_consignee_unit_temp := []rune(waybill.ConsigneeAddressName)
  1645. if len(T_consignee_unit_temp) > 17 {
  1646. pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp[0:17])))
  1647. pdf.SetXY(290, y+15)
  1648. pdf.Text(fmt.Sprintf("%s", string(T_consignee_unit_temp[17:])))
  1649. } else {
  1650. pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp)))
  1651. }
  1652. // 承运方
  1653. y += 15
  1654. pdf.SetXY(10, y)
  1655. company_name := []rune(waybill.Dept.Name)
  1656. pdf.Text(fmt.Sprintf("承运方:%s", string(company_name)))
  1657. y += 15
  1658. pdf.SetXY(10, y)
  1659. T_remark_temp := []rune(waybill.Remark)
  1660. if len(waybill.Remark) > 35 {
  1661. pdf.Text(fmt.Sprintf("备注:%s", string(T_remark_temp[0:35])))
  1662. pdf.SetXY(10, y+15)
  1663. pdf.Text(fmt.Sprintf("%s", string(T_remark_temp[35:])))
  1664. } else {
  1665. pdf.Text(fmt.Sprintf("备注: %s", string(T_remark_temp)))
  1666. }
  1667. y += 35
  1668. pdf.SetFont("wts", "", 16)
  1669. pdf.SetXY(10, y)
  1670. pdf.Text("记录曲线信息")
  1671. // 线
  1672. y += 10
  1673. pdf.SetLineWidth(0.5)
  1674. pdf.SetStrokeColor(169, 169, 169)
  1675. pdf.Line(10, y, 585, y)
  1676. y += 1
  1677. var tempFilepath string
  1678. tempFilepath, err = DeviceDataTemperatureJPG3(s_time, e_time, waybillPDF)
  1679. if err == nil {
  1680. imgH, _ := gopdf.ImageHolderByPath(tempFilepath)
  1681. pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
  1682. y += 315
  1683. }
  1684. //var humidityFilepath string
  1685. //if req.HumidityShow {
  1686. // humidityFilepath, err = DeviceDataHumidityJPG2(s_time, e_time, waybillPDF)
  1687. // if err == nil {
  1688. // imgH, _ := gopdf.ImageHolderByPath(humidityFilepath)
  1689. // pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
  1690. // y += 315
  1691. // }
  1692. //}
  1693. if y > 841.89 {
  1694. // 图片结束直接分页
  1695. pdf.AddPage()
  1696. y = 20
  1697. }
  1698. y += 20
  1699. pdf.SetFont("wts", "", 16)
  1700. pdf.SetXY(10, y)
  1701. pdf.Text("记录数据信息")
  1702. // 线
  1703. y += 10
  1704. pdf.SetLineWidth(0.5)
  1705. pdf.SetStrokeColor(169, 169, 169)
  1706. pdf.Line(10, y, 585, y)
  1707. y += 10
  1708. pdf.SetFont("wts", "", 10)
  1709. var x float64 = 19
  1710. var w float64 = 112
  1711. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1712. x = x + w
  1713. w = 37
  1714. lib.RectFillColor(pdf, "T1", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1715. x = x + w
  1716. lib.RectFillColor(pdf, "T2", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1717. x = x + w
  1718. w = 112
  1719. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1720. x = x + w
  1721. w = 37
  1722. lib.RectFillColor(pdf, "T1", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1723. x = x + w
  1724. lib.RectFillColor(pdf, "T2", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1725. x = x + w
  1726. w = 112
  1727. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1728. x = x + w
  1729. w = 37
  1730. lib.RectFillColor(pdf, "T1", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1731. x = x + w
  1732. lib.RectFillColor(pdf, "T2", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1733. for i, v := range Pdf_data {
  1734. if i%3 == 0 {
  1735. y += 20
  1736. var textH float64 = 25 // if text height is 25px.
  1737. pdf.SetNewY(y, textH)
  1738. y = pdf.GetY()
  1739. x, w = 19, 112
  1740. lib.RectFillColor(pdf, v.T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1741. x = x + w
  1742. w = 37
  1743. lib.RectFillColor(pdf, lib.Float32_to_string(&v.T_id1), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1744. x = x + w
  1745. lib.RectFillColor(pdf, lib.Float32_to_string(&v.T_id2), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1746. }
  1747. if i%3 == 1 {
  1748. x = x + w
  1749. w = 112
  1750. lib.RectFillColor(pdf, v.T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1751. x = x + w
  1752. w = 37
  1753. lib.RectFillColor(pdf, lib.Float32_to_string(&v.T_id1), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1754. x = x + w
  1755. lib.RectFillColor(pdf, lib.Float32_to_string(&v.T_id2), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1756. }
  1757. if i%3 == 2 {
  1758. x = x + w
  1759. w = 112
  1760. lib.RectFillColor(pdf, v.T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1761. x = x + w
  1762. w = 37
  1763. lib.RectFillColor(pdf, lib.Float32_to_string(&v.T_id1), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1764. x = x + w
  1765. lib.RectFillColor(pdf, lib.Float32_to_string(&v.T_id2), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1766. }
  1767. }
  1768. filename := "运单" + req.WaybillNo + "温湿度记录" + time.Now().Format("20060102150405") + ".pdf"
  1769. filePath := "ofile/" + filename
  1770. err = pdf.WritePdf(filePath)
  1771. if err != nil {
  1772. return
  1773. }
  1774. defer func() {
  1775. os.Remove(tempFilepath)
  1776. //os.Remove(humidityFilepath)
  1777. os.Remove(filePath)
  1778. }()
  1779. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(filename))
  1780. c.Header("Content-Transfer-Encoding", "binary")
  1781. c.File(filePath)
  1782. }
  1783. // WaybillPdf 导出运单pdf
  1784. // // @Summary 导出运单pdf
  1785. // @Description 导出运单pdf
  1786. // @Tags 运单
  1787. // @Param no query string false "运单号"
  1788. // @Param pageSize query int false "页条数"
  1789. // @Param page query int false "页码"
  1790. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  1791. // @Router /api/waybill [get]
  1792. // @Security Bearer
  1793. func (e WaybillController) WaybillPDF(c *gin.Context) {
  1794. s := service.Waybill{}
  1795. companySvc := service.Company{}
  1796. req := dto.WaybillGetByWaybillPdfReq{}
  1797. err := e.MakeContext(c).
  1798. MakeOrm().
  1799. Bind(&req, binding.Query).
  1800. MakeService(&s.Service).
  1801. MakeService(&companySvc.Service).
  1802. Errors
  1803. if err != nil {
  1804. e.Logger.Error(err)
  1805. e.Error(500, err, err.Error())
  1806. return
  1807. }
  1808. var waybill model.Waybill
  1809. var company model.SysDept
  1810. //err = s.GetByWaybillNo(&req, &waybill, p)
  1811. err = s.GetByWaybillNo(&req, &waybill, nil)
  1812. if err != nil {
  1813. e.Error(500, err, err.Error())
  1814. return
  1815. }
  1816. err = companySvc.Get(&dto.CompanyGetReq{Id: waybill.DeptId}, &company)
  1817. if err != nil {
  1818. e.Error(500, err, err.Error())
  1819. return
  1820. }
  1821. // -------------------生成运单条码
  1822. // 运单条码
  1823. cs, _ := code128.Encode(waybill.WaybillNo)
  1824. // 创建一个要输出数据的文件
  1825. imgPath := "ofile/img/" + waybill.WaybillNo + ".png"
  1826. file, _ := os.Create(imgPath)
  1827. defer file.Close()
  1828. // 设置图片像素大小
  1829. barCode, _ := barcode.Scale(cs, 205, 50)
  1830. // 将code128的条形码编码为png图片
  1831. png.Encode(file, barCode)
  1832. imgPath2 := "ofile/img/" + waybill.WaybillNo + ".jpg"
  1833. png2j.Con2jpg(imgPath, imgPath2)
  1834. qrcode, err := qrcode.Encode(fmt.Sprintf("%s/WaybillInquiry?waybillNo=%s", conf.ExtConfig.Service.Domain, waybill.WaybillNo),
  1835. qrcode.Medium, 70)
  1836. if err != nil {
  1837. e.Error(500, err, err.Error())
  1838. return
  1839. }
  1840. qrCodeImgH, err := gopdf.ImageHolderByBytes(qrcode)
  1841. if err != nil {
  1842. e.Error(500, err, err.Error())
  1843. return
  1844. }
  1845. pdf := &gopdf.GoPdf{}
  1846. pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 283.46, H: 283.46}}) //595.28, 841.89 = A4
  1847. //pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
  1848. err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf")
  1849. if err != nil {
  1850. return
  1851. }
  1852. pdf.SetGrayFill(0.5)
  1853. pdf.SetMargins(0, 10, 0, 10)
  1854. for i := 0; i < waybill.Quantity; i++ {
  1855. pdf.AddPage()
  1856. var y float64 = 20
  1857. pdf.SetFont("wts", "", 10)
  1858. if len(company.Logo) > 0 {
  1859. imgH, errImg := lib.GetImage(company.Logo)
  1860. if errImg != nil {
  1861. err = errors.New("获取图片失败")
  1862. e.Error(500, err, err.Error())
  1863. return
  1864. }
  1865. imgWidth := float64(imgH.Bounds().Dx())
  1866. imgHeight := float64(imgH.Bounds().Dy())
  1867. W := 30.
  1868. H := (imgHeight * W) / imgWidth
  1869. if strings.Contains(company.Logo, ".png") {
  1870. err = pdf.ImageFrom(imgH, 10, 0, &gopdf.Rect{W: W, H: H})
  1871. if err != nil {
  1872. err = errors.New("写入图片失败")
  1873. e.Error(500, err, err.Error())
  1874. return
  1875. }
  1876. } else {
  1877. fileName := "./ofile/" + path.Base(company.Logo)
  1878. f, _ := os.Create(fileName)
  1879. defer f.Close()
  1880. defer func() {
  1881. os.Remove(fileName)
  1882. }()
  1883. jpeg.Encode(f, imgH, &jpeg.Options{100})
  1884. err = pdf.Image(fileName, 10, 0, &gopdf.Rect{W: W, H: H})
  1885. if err != nil {
  1886. err = errors.New("写入图片失败")
  1887. e.Error(500, err, err.Error())
  1888. return
  1889. }
  1890. }
  1891. } else {
  1892. title := "#" + company.Name
  1893. pdf.SetXY(10, y)
  1894. pdf.Text(title)
  1895. }
  1896. //y += 12
  1897. pdf.SetXY(250, 20)
  1898. pdf.SetFont("wts", "", 13)
  1899. pdf.Text(fmt.Sprintf("%d/%d", i+1, waybill.Quantity))
  1900. pdf.SetFont("wts", "", 10)
  1901. y += 10
  1902. pdf.Image(imgPath2, 20, y, &gopdf.Rect{W: 240, H: 30})
  1903. y += 43
  1904. textw, _ := pdf.MeasureTextWidth(waybill.WaybillNo)
  1905. pdf.SetX((283.46 / 2) - (textw / 2))
  1906. pdf.SetY(y)
  1907. pdf.Text(waybill.WaybillNo)
  1908. // 线
  1909. y += 6
  1910. pdf.SetLineWidth(0.5)
  1911. pdf.SetLineType("dotted")
  1912. pdf.Line(10, y, 273, y)
  1913. y += 28
  1914. pdf.SetFont("wts", "", 18)
  1915. pdf.SetXY(12, y+3)
  1916. pdf.Text("收")
  1917. pdf.SetFont("wts", "", 10)
  1918. y -= 5
  1919. pdf.SetXY(40, y)
  1920. pdf.Text(fmt.Sprintf("%s %s", lib.MaskStr(waybill.ConsigneeAddressName), lib.MaskPhoneNumber(waybill.ConsigneeAddressPhone)))
  1921. y += 15
  1922. pdf.SetXY(40, y)
  1923. pdf.Text(waybill.ConsigneeAddressDetails)
  1924. // 线
  1925. y += 8
  1926. pdf.SetLineWidth(0.5)
  1927. pdf.SetLineType("dotted")
  1928. pdf.Line(10, y, 273, y)
  1929. y += 22
  1930. pdf.SetFont("wts", "", 13)
  1931. pdf.SetXY(14, y+3)
  1932. pdf.Text("寄")
  1933. pdf.SetFont("wts", "", 10)
  1934. y -= 5
  1935. pdf.SetXY(40, y)
  1936. pdf.Text(fmt.Sprintf("%s %s", lib.MaskStr(waybill.SenderAddressName), lib.MaskPhoneNumber(waybill.SenderAddressPhone)))
  1937. y += 15
  1938. pdf.SetXY(40, y)
  1939. pdf.Text(waybill.SenderAddressDetails)
  1940. // 线
  1941. y += 10
  1942. pdf.SetLineWidth(0.5)
  1943. //pdf.SetLineType("dashed")
  1944. pdf.SetLineType("dotted")
  1945. pdf.Line(10, y, 273, y)
  1946. y += 12
  1947. pdf.SetXY(10, y)
  1948. pdf.SetFont("wts", "", 8)
  1949. pdf.Text("下单时间:" + waybill.OrderTime.String())
  1950. // 线
  1951. y += 6
  1952. pdf.SetLineWidth(0.5)
  1953. pdf.SetLineType("dotted")
  1954. pdf.Line(10, y, 273, y)
  1955. pdf.SetFont("wts", "", 10)
  1956. y += 20
  1957. pdf.SetXY(10, y)
  1958. pdf.Text("备注:")
  1959. pdf.SetFont("wts", "", 8)
  1960. y += 15
  1961. pdf.SetXY(30, y)
  1962. pdf.Text("货物类型:" + waybill.CargoType)
  1963. y += 15
  1964. pdf.SetXY(30, y)
  1965. pdf.Text("温度要求:" + waybill.TemperatureInterval)
  1966. y += 15
  1967. pdf.SetXY(30, y)
  1968. pdf.Text("配送要求:" + waybill.DeliveryCondition)
  1969. x := 170.
  1970. //pdf.Image(qrcodeImgPath2, x, y-55, &gopdf.Rect{W: 70, H: 70})
  1971. pdf.ImageByHolder(qrCodeImgH, x, y-63, &gopdf.Rect{W: 70, H: 70})
  1972. pdf.SetFont("wts", "", 8)
  1973. y += 10
  1974. textw, _ = pdf.MeasureTextWidth("扫码查询")
  1975. pdf.SetX(x + 35 - (textw / 2))
  1976. pdf.SetY(y)
  1977. pdf.Text("扫码查询")
  1978. y += 10
  1979. textw, _ = pdf.MeasureTextWidth("物流温湿度信息")
  1980. pdf.SetX(x + 35 - (textw / 2))
  1981. pdf.SetY(y)
  1982. pdf.Text("物流温湿度信息")
  1983. }
  1984. filename := "运单" + req.WaybillNo + "温湿度记录" + time.Now().Format("20060102150405") + ".pdf"
  1985. filePath := "ofile/" + filename
  1986. err = pdf.WritePdf(filePath)
  1987. if err != nil {
  1988. return
  1989. }
  1990. defer func() {
  1991. os.Remove(filePath)
  1992. os.Remove(imgPath)
  1993. os.Remove(imgPath2)
  1994. }()
  1995. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(filename))
  1996. c.Header("Content-Transfer-Encoding", "binary")
  1997. c.File(filePath)
  1998. }
  1999. // 获取温度图片
  2000. func DeviceDataTemperatureJPG(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  2001. if len(waybillPDF) == 0 {
  2002. return "", errors.New("暂无数据可生成图片")
  2003. }
  2004. // 创建一个新的绘图
  2005. p := plot.New()
  2006. // 设置绘图标题和标签
  2007. p.Title.Text = "temperature"
  2008. //p.Legend.ThumbnailWidth = 20
  2009. deviceSensorList := []nats_server.DeviceSensor_R{}
  2010. dataList := []nats_server.DeviceData_R{}
  2011. for _, w := range waybillPDF {
  2012. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  2013. dataList = append(dataList, w.Data...)
  2014. }
  2015. TemperatureMin := deviceSensorList[0].T_DeviceSensorParameter.T_Tlower
  2016. TemperatureMax := deviceSensorList[0].T_DeviceSensorParameter.T_Tupper
  2017. var ymin, ymax float32
  2018. for i, r := range dataList {
  2019. if i == 0 {
  2020. ymin = r.T_t
  2021. ymax = r.T_t
  2022. }
  2023. if ymin > r.T_t {
  2024. ymin = r.T_t
  2025. }
  2026. if ymax < r.T_t {
  2027. ymax = r.T_t
  2028. }
  2029. }
  2030. var chData = make(chan int, 10)
  2031. var jobGroup sync.WaitGroup
  2032. // 创建温度线
  2033. for i := 0; i < len(deviceSensorList); i++ {
  2034. chData <- 1
  2035. jobGroup.Add(1)
  2036. go func(index int) {
  2037. defer func() {
  2038. <-chData // 完成时chan取出1个
  2039. jobGroup.Done() // 完成时将等待组值减1
  2040. }()
  2041. sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
  2042. r_maps := []nats_server.DeviceData_R{}
  2043. for _, data := range dataList {
  2044. if data.T_sn == sn && data.T_id == id {
  2045. r_maps = append(r_maps, data)
  2046. }
  2047. }
  2048. fmt.Println(r_maps)
  2049. if len(r_maps) == 0 {
  2050. return
  2051. }
  2052. sort.Slice(r_maps, func(i, j int) bool {
  2053. return r_maps[i].T_time < r_maps[j].T_time
  2054. })
  2055. pts := make(plotter.XYs, len(r_maps))
  2056. for j, d := range r_maps {
  2057. t, _ := lib.TimeStrToTime(d.T_time)
  2058. pts[j].X = float64(t.Unix())
  2059. pts[j].Y = float64(d.T_t)
  2060. }
  2061. line, err := plotter.NewLine(pts)
  2062. if err != nil {
  2063. return
  2064. }
  2065. line.Color = randomColor(index)
  2066. p.Add(line)
  2067. }(i)
  2068. }
  2069. jobGroup.Wait()
  2070. st, _ := lib.TimeStrToTime(startTime)
  2071. et, _ := lib.TimeStrToTime(endTime)
  2072. xmin, xmax := float64(st.Unix()), float64(et.Unix())
  2073. // 添加最高,最低标准线 用红色虚线标识
  2074. p.Add(horizontalLine(xmin, xmax, float64(TemperatureMin)))
  2075. p.Add(horizontalLine(xmin, xmax, float64(TemperatureMax)))
  2076. if ymax < TemperatureMax {
  2077. ymax = TemperatureMax
  2078. }
  2079. if ymin > 0 {
  2080. ymin = 0
  2081. }
  2082. p.Y.Min, p.Y.Max = float64(ymin), float64(ymax)
  2083. p.X.Min, p.X.Max = xmin, xmax
  2084. p.Y.Tick.Marker = commaTicks{}
  2085. p.X.Tick.Marker = timeTicks{}
  2086. p.X.Tick.Label.Rotation = math.Pi / 5
  2087. p.X.Tick.Label.YAlign = draw.YCenter
  2088. p.X.Tick.Label.XAlign = draw.XRight
  2089. filepath := "ofile/" + "temperature" + deviceSensorList[0].T_sn + ".jpg"
  2090. // 保存文件
  2091. if err := p.Save(10*vg.Inch, 4*vg.Inch, filepath); err != nil {
  2092. logs.Error(lib.FuncName(), "生成图片失败", err)
  2093. return "", err
  2094. }
  2095. return filepath, nil
  2096. }
  2097. func DeviceDataTemperatureJPG2(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  2098. if len(waybillPDF) == 0 {
  2099. return "", errors.New("暂无数据可生成图片")
  2100. }
  2101. deviceSensorList := []nats_server.DeviceSensor_R{}
  2102. dataList := []nats_server.DeviceData_R{}
  2103. for _, w := range waybillPDF {
  2104. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  2105. dataList = append(dataList, w.Data...)
  2106. }
  2107. TemperatureMin := deviceSensorList[0].T_DeviceSensorParameter.T_Tlower
  2108. TemperatureMax := deviceSensorList[0].T_DeviceSensorParameter.T_Tupper
  2109. var ymin, ymax float32
  2110. for i, r := range dataList {
  2111. if i == 0 {
  2112. ymin = r.T_t
  2113. ymax = r.T_t
  2114. }
  2115. if ymin > r.T_t {
  2116. ymin = r.T_t
  2117. }
  2118. if ymax < r.T_t {
  2119. ymax = r.T_t
  2120. }
  2121. }
  2122. series := make([]chart.Series, 0)
  2123. var chData = make(chan int, 10)
  2124. var jobGroup sync.WaitGroup
  2125. // 创建温度线
  2126. for i := 0; i < len(deviceSensorList); i++ {
  2127. chData <- 1
  2128. jobGroup.Add(1)
  2129. go func(index int) {
  2130. defer func() {
  2131. <-chData // 完成时chan取出1个
  2132. jobGroup.Done() // 完成时将等待组值减1
  2133. }()
  2134. sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
  2135. r_maps := []nats_server.DeviceData_R{}
  2136. for _, data := range dataList {
  2137. if data.T_sn == sn && data.T_id == id {
  2138. r_maps = append(r_maps, data)
  2139. }
  2140. }
  2141. fmt.Println(r_maps)
  2142. if len(r_maps) == 0 {
  2143. return
  2144. }
  2145. sort.Slice(r_maps, func(i, j int) bool {
  2146. return r_maps[i].T_time < r_maps[j].T_time
  2147. })
  2148. xValues := make([]time.Time, len(r_maps))
  2149. yValues := make([]float64, len(r_maps))
  2150. for j := 0; j < len(r_maps); j++ {
  2151. t, _ := lib.TimeStrToTime(r_maps[j].T_time)
  2152. xValues[j] = t
  2153. yValues[j] = float64(r_maps[j].T_t)
  2154. }
  2155. series = append(series, chart.TimeSeries{
  2156. Name: fmt.Sprintf("%s-%d", sn, id),
  2157. XValues: xValues,
  2158. YValues: yValues,
  2159. })
  2160. }(i)
  2161. }
  2162. jobGroup.Wait()
  2163. if ymax < TemperatureMax {
  2164. ymax = TemperatureMax
  2165. }
  2166. if ymin > 0 {
  2167. ymin = 0
  2168. }
  2169. if ymin > TemperatureMin {
  2170. ymin = TemperatureMin
  2171. }
  2172. st, _ := lib.TimeStrToTime(startTime)
  2173. et, _ := lib.TimeStrToTime(endTime)
  2174. series = append(series, chart.TimeSeries{
  2175. Style: chart.Style{
  2176. StrokeColor: drawing.ColorRed,
  2177. StrokeDashArray: []float64{5.0, 5.0},
  2178. },
  2179. XValues: []time.Time{st, et},
  2180. YValues: []float64{float64(TemperatureMin), float64(TemperatureMin)},
  2181. })
  2182. series = append(series, chart.TimeSeries{
  2183. Style: chart.Style{
  2184. StrokeColor: drawing.ColorRed,
  2185. StrokeDashArray: []float64{5.0, 5.0},
  2186. },
  2187. XValues: []time.Time{st, et},
  2188. YValues: []float64{float64(TemperatureMax), float64(TemperatureMax)},
  2189. })
  2190. font := getZWFont()
  2191. graph := chart.Chart{
  2192. Title: "温度记录",
  2193. TitleStyle: chart.Style{
  2194. FontSize: 15,
  2195. },
  2196. Background: chart.Style{
  2197. Padding: chart.Box{
  2198. Top: 20,
  2199. },
  2200. },
  2201. Font: font,
  2202. XAxis: chart.XAxis{
  2203. Name: "时间",
  2204. ValueFormatter: chart.TimeValueFormatterWithFormat("2006-01-02 15:04"),
  2205. },
  2206. YAxis: chart.YAxis{
  2207. Name: "温度",
  2208. Range: &chart.ContinuousRange{
  2209. Min: float64(ymin),
  2210. Max: float64(ymax + 2),
  2211. },
  2212. },
  2213. Series: series,
  2214. }
  2215. //graph.Elements = []chart.Renderable{
  2216. // chart.Legend(&graph),
  2217. //}
  2218. filepath := "ofile/" + "temperature" + deviceSensorList[0].T_sn + ".jpg"
  2219. f, _ := os.Create(filepath)
  2220. defer f.Close()
  2221. graph.Render(chart.PNG, f)
  2222. return filepath, nil
  2223. }
  2224. func DeviceDataTemperatureJPG3(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  2225. if len(waybillPDF) == 0 {
  2226. return "", errors.New("暂无数据可生成图片")
  2227. }
  2228. deviceSensorList := []nats_server.DeviceSensor_R{}
  2229. dataList := []nats_server.DeviceData_R{}
  2230. deviceDataPdfList := []service.DeviceDataPdf{}
  2231. for _, w := range waybillPDF {
  2232. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  2233. dataList = append(dataList, w.Data...)
  2234. deviceDataPdfList = append(deviceDataPdfList, w.DeviceDataPdf...)
  2235. }
  2236. TemperatureMin := deviceSensorList[0].T_DeviceSensorParameter.T_Tlower
  2237. TemperatureMax := deviceSensorList[0].T_DeviceSensorParameter.T_Tupper
  2238. var ymin, ymax float32
  2239. for i, r := range dataList {
  2240. if i == 0 {
  2241. ymin = r.T_t
  2242. ymax = r.T_t
  2243. }
  2244. if ymin > r.T_t {
  2245. ymin = r.T_t
  2246. }
  2247. if ymax < r.T_t {
  2248. ymax = r.T_t
  2249. }
  2250. }
  2251. sort.Slice(deviceDataPdfList, func(i, j int) bool {
  2252. return deviceDataPdfList[i].T_time < deviceDataPdfList[j].T_time
  2253. })
  2254. series := make([]chart.Series, 0)
  2255. // 创建温度线
  2256. xValues := make([]time.Time, len(deviceDataPdfList))
  2257. yValues1 := make([]float64, len(deviceDataPdfList))
  2258. yValues2 := make([]float64, len(deviceDataPdfList))
  2259. for i := 0; i < len(deviceDataPdfList); i++ {
  2260. t, _ := lib.TimeStrToTime(deviceDataPdfList[i].T_time)
  2261. xValues[i] = t
  2262. yValues1[i] = float64(deviceDataPdfList[i].T_id1)
  2263. yValues2[i] = float64(deviceDataPdfList[i].T_id2)
  2264. }
  2265. series = append(series, chart.TimeSeries{
  2266. Name: "T1",
  2267. XValues: xValues,
  2268. YValues: yValues1,
  2269. })
  2270. series = append(series, chart.TimeSeries{
  2271. Name: "T2",
  2272. XValues: xValues,
  2273. YValues: yValues2,
  2274. })
  2275. if ymax < TemperatureMax {
  2276. ymax = TemperatureMax
  2277. }
  2278. if ymin > 0 {
  2279. ymin = 0
  2280. }
  2281. if ymin > TemperatureMin {
  2282. ymin = TemperatureMin
  2283. }
  2284. st, _ := lib.TimeStrToTime(startTime)
  2285. et, _ := lib.TimeStrToTime(endTime)
  2286. series = append(series, chart.TimeSeries{
  2287. Style: chart.Style{
  2288. StrokeColor: drawing.ColorRed,
  2289. StrokeDashArray: []float64{5.0, 5.0},
  2290. },
  2291. XValues: []time.Time{st, et},
  2292. YValues: []float64{float64(TemperatureMin), float64(TemperatureMin)},
  2293. })
  2294. series = append(series, chart.TimeSeries{
  2295. Style: chart.Style{
  2296. StrokeColor: drawing.ColorRed,
  2297. StrokeDashArray: []float64{5.0, 5.0},
  2298. },
  2299. XValues: []time.Time{st, et},
  2300. YValues: []float64{float64(TemperatureMax), float64(TemperatureMax)},
  2301. })
  2302. font := getZWFont()
  2303. graph := chart.Chart{
  2304. Title: "温度记录",
  2305. TitleStyle: chart.Style{
  2306. FontSize: 14,
  2307. },
  2308. Background: chart.Style{
  2309. Padding: chart.Box{
  2310. Top: 20,
  2311. },
  2312. },
  2313. Font: font,
  2314. XAxis: chart.XAxis{
  2315. Name: "时间",
  2316. ValueFormatter: chart.TimeValueFormatterWithFormat("2006-01-02 15:04"),
  2317. },
  2318. YAxis: chart.YAxis{
  2319. Name: "温度",
  2320. Range: &chart.ContinuousRange{
  2321. Min: float64(ymin),
  2322. Max: float64(ymax + 2),
  2323. },
  2324. },
  2325. Series: series,
  2326. }
  2327. //graph.Elements = []chart.Renderable{
  2328. // chart.Legend(&graph),
  2329. //}
  2330. filepath := "ofile/" + "temperature" + deviceSensorList[0].T_sn + ".jpg"
  2331. f, _ := os.Create(filepath)
  2332. defer f.Close()
  2333. graph.Render(chart.PNG, f)
  2334. return filepath, nil
  2335. }
  2336. // 获取湿度图片
  2337. func DeviceDataHumidityJPG(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  2338. if len(waybillPDF) == 0 {
  2339. return "", errors.New("暂无数据可生成图片")
  2340. }
  2341. // 创建一个新的绘图
  2342. p := plot.New()
  2343. // 设置绘图标题和标签
  2344. p.Title.Text = "humidity"
  2345. deviceSensorList := []nats_server.DeviceSensor_R{}
  2346. dataList := []nats_server.DeviceData_R{}
  2347. for _, w := range waybillPDF {
  2348. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  2349. dataList = append(dataList, w.Data...)
  2350. }
  2351. humidityMin := deviceSensorList[0].T_DeviceSensorParameter.T_RHlower
  2352. humidityMax := deviceSensorList[0].T_DeviceSensorParameter.T_RHupper
  2353. var ymin, ymax float32
  2354. for i, r := range dataList {
  2355. if i == 0 {
  2356. ymin = r.T_rh
  2357. ymax = r.T_rh
  2358. }
  2359. if ymin > r.T_rh {
  2360. ymin = r.T_rh
  2361. }
  2362. if ymax < r.T_rh {
  2363. ymax = r.T_rh
  2364. }
  2365. }
  2366. var chData = make(chan int, 10)
  2367. var jobGroup sync.WaitGroup
  2368. // 创建温度线
  2369. for i := 0; i < len(deviceSensorList); i++ {
  2370. chData <- 1
  2371. jobGroup.Add(1)
  2372. go func(index int) {
  2373. defer func() {
  2374. <-chData // 完成时chan取出1个
  2375. jobGroup.Done() // 完成时将等待组值减1
  2376. }()
  2377. sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
  2378. r_maps := []nats_server.DeviceData_R{}
  2379. for _, data := range dataList {
  2380. if data.T_sn == sn && data.T_id == id {
  2381. r_maps = append(r_maps, data)
  2382. }
  2383. }
  2384. if len(r_maps) == 0 {
  2385. return
  2386. }
  2387. sort.Slice(r_maps, func(i, j int) bool {
  2388. return r_maps[i].T_time < r_maps[j].T_time
  2389. })
  2390. pts := make(plotter.XYs, len(r_maps))
  2391. for j, d := range r_maps {
  2392. t, _ := lib.TimeStrToTime(d.T_time)
  2393. pts[j].X = float64(t.Unix())
  2394. pts[j].Y = float64(d.T_rh)
  2395. }
  2396. line, err := plotter.NewLine(pts)
  2397. if err != nil {
  2398. return
  2399. }
  2400. line.Color = randomColor(index)
  2401. p.Add(line)
  2402. }(i)
  2403. }
  2404. jobGroup.Wait()
  2405. st, _ := lib.TimeStrToTime(startTime)
  2406. et, _ := lib.TimeStrToTime(endTime)
  2407. xmin, xmax := float64(st.Unix()), float64(et.Unix())
  2408. // 添加最高,最低标准线 用红色虚线标识
  2409. p.Add(horizontalLine(xmin, xmax, float64(humidityMin)))
  2410. p.Add(horizontalLine(xmin, xmax, float64(humidityMax)))
  2411. if ymax < humidityMax {
  2412. ymax = humidityMax
  2413. }
  2414. if ymin > 0 {
  2415. ymin = 0
  2416. }
  2417. p.Y.Min, p.Y.Max = float64(ymin), float64(ymax)
  2418. p.X.Min, p.X.Max = xmin, xmax
  2419. p.Y.Tick.Marker = commaTicks{}
  2420. //p.X.Tick.Marker = plot.TimeTicks{Format: "2006-01-02 15:04:05"}
  2421. p.X.Tick.Marker = timeTicks{}
  2422. p.X.Tick.Label.Rotation = math.Pi / 5
  2423. p.X.Tick.Label.YAlign = draw.YCenter
  2424. p.X.Tick.Label.XAlign = draw.XRight
  2425. filepath := "ofile/" + "humidity" + deviceSensorList[0].T_sn + ".jpg"
  2426. // 保存文件
  2427. if err := p.Save(10*vg.Inch, 4*vg.Inch, filepath); err != nil {
  2428. logs.Error(lib.FuncName(), "生成图片失败", err)
  2429. return "", err
  2430. }
  2431. return filepath, nil
  2432. }
  2433. func DeviceDataHumidityJPG2(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  2434. if len(waybillPDF) == 0 {
  2435. return "", errors.New("暂无数据可生成图片")
  2436. }
  2437. deviceSensorList := []nats_server.DeviceSensor_R{}
  2438. dataList := []nats_server.DeviceData_R{}
  2439. for _, w := range waybillPDF {
  2440. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  2441. dataList = append(dataList, w.Data...)
  2442. }
  2443. humidityMin := deviceSensorList[0].T_DeviceSensorParameter.T_RHlower
  2444. humidityMax := deviceSensorList[0].T_DeviceSensorParameter.T_RHupper
  2445. var ymin, ymax float32
  2446. for i, r := range dataList {
  2447. if i == 0 {
  2448. ymin = r.T_t
  2449. ymax = r.T_t
  2450. }
  2451. if ymin > r.T_t {
  2452. ymin = r.T_t
  2453. }
  2454. if ymax < r.T_t {
  2455. ymax = r.T_t
  2456. }
  2457. }
  2458. series := make([]chart.Series, 0)
  2459. var chData = make(chan int, 10)
  2460. var jobGroup sync.WaitGroup
  2461. // 创建温度线
  2462. for i := 0; i < len(deviceSensorList); i++ {
  2463. chData <- 1
  2464. jobGroup.Add(1)
  2465. go func(index int) {
  2466. defer func() {
  2467. <-chData // 完成时chan取出1个
  2468. jobGroup.Done() // 完成时将等待组值减1
  2469. }()
  2470. sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
  2471. r_maps := []nats_server.DeviceData_R{}
  2472. for _, data := range dataList {
  2473. if data.T_sn == sn && data.T_id == id {
  2474. r_maps = append(r_maps, data)
  2475. }
  2476. }
  2477. if len(r_maps) == 0 {
  2478. return
  2479. }
  2480. sort.Slice(r_maps, func(i, j int) bool {
  2481. return r_maps[i].T_time < r_maps[j].T_time
  2482. })
  2483. xValues := make([]time.Time, len(r_maps))
  2484. yValues := make([]float64, len(r_maps))
  2485. for j := 0; j < len(r_maps); j++ {
  2486. t, _ := lib.TimeStrToTime(r_maps[j].T_time)
  2487. xValues[j] = t
  2488. yValues[j] = float64(r_maps[j].T_rh)
  2489. }
  2490. series = append(series, chart.TimeSeries{
  2491. Name: fmt.Sprintf("%s-%d", sn, id),
  2492. XValues: xValues,
  2493. YValues: yValues,
  2494. })
  2495. }(i)
  2496. }
  2497. jobGroup.Wait()
  2498. if ymax < humidityMax {
  2499. ymax = humidityMax
  2500. }
  2501. if ymin > 0 {
  2502. ymin = 0
  2503. }
  2504. if ymin > humidityMin {
  2505. ymin = humidityMin
  2506. }
  2507. st, _ := lib.TimeStrToTime(startTime)
  2508. et, _ := lib.TimeStrToTime(endTime)
  2509. series = append(series, chart.TimeSeries{
  2510. Style: chart.Style{
  2511. StrokeColor: drawing.ColorRed,
  2512. StrokeDashArray: []float64{5.0, 5.0},
  2513. },
  2514. XValues: []time.Time{st, et},
  2515. YValues: []float64{float64(humidityMin), float64(humidityMin)},
  2516. })
  2517. series = append(series, chart.TimeSeries{
  2518. Style: chart.Style{
  2519. StrokeColor: drawing.ColorRed,
  2520. StrokeDashArray: []float64{5.0, 5.0},
  2521. },
  2522. XValues: []time.Time{st, et},
  2523. YValues: []float64{float64(humidityMax), float64(humidityMax)},
  2524. })
  2525. font := getZWFont()
  2526. graph := chart.Chart{
  2527. Title: "湿度记录",
  2528. TitleStyle: chart.Style{
  2529. FontSize: 15,
  2530. },
  2531. Background: chart.Style{
  2532. Padding: chart.Box{
  2533. Top: 20,
  2534. },
  2535. },
  2536. Font: font,
  2537. XAxis: chart.XAxis{
  2538. Name: "时间",
  2539. ValueFormatter: chart.TimeValueFormatterWithFormat("2006-01-02 15:04"),
  2540. },
  2541. YAxis: chart.YAxis{
  2542. Name: "湿度",
  2543. Range: &chart.ContinuousRange{
  2544. Min: float64(ymin),
  2545. Max: float64(ymax + 2),
  2546. },
  2547. },
  2548. Series: series,
  2549. }
  2550. //graph.Elements = []chart.Renderable{
  2551. // chart.Legend(&graph),
  2552. //}
  2553. filepath := "ofile/" + "humidity" + deviceSensorList[0].T_sn + ".jpg"
  2554. f, _ := os.Create(filepath)
  2555. defer f.Close()
  2556. graph.Render(chart.PNG, f)
  2557. return filepath, nil
  2558. }
  2559. func DeviceDataHumidityJPG3(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  2560. if len(waybillPDF) == 0 {
  2561. return "", errors.New("暂无数据可生成图片")
  2562. }
  2563. deviceSensorList := []nats_server.DeviceSensor_R{}
  2564. dataList := []nats_server.DeviceData_R{}
  2565. deviceDataPdfList := []service.DeviceDataPdf{}
  2566. for _, w := range waybillPDF {
  2567. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  2568. dataList = append(dataList, w.Data...)
  2569. deviceDataPdfList = append(deviceDataPdfList, w.DeviceDataPdf...)
  2570. }
  2571. TemperatureMin := deviceSensorList[0].T_DeviceSensorParameter.T_Tlower
  2572. TemperatureMax := deviceSensorList[0].T_DeviceSensorParameter.T_Tupper
  2573. var ymin, ymax float32
  2574. for i, r := range dataList {
  2575. if i == 0 {
  2576. ymin = r.T_rh
  2577. ymax = r.T_rh
  2578. }
  2579. if ymin > r.T_rh {
  2580. ymin = r.T_rh
  2581. }
  2582. if ymax < r.T_rh {
  2583. ymax = r.T_rh
  2584. }
  2585. }
  2586. series := make([]chart.Series, 0)
  2587. // 创建温度线
  2588. xValues1 := make([]time.Time, len(deviceDataPdfList))
  2589. yValues1 := make([]float64, len(deviceDataPdfList))
  2590. xValues2 := make([]time.Time, len(deviceDataPdfList))
  2591. yValues2 := make([]float64, len(deviceDataPdfList))
  2592. for i := 0; i < len(deviceDataPdfList); i++ {
  2593. t, _ := lib.TimeStrToTime(deviceDataPdfList[i].T_time)
  2594. xValues1[i] = t
  2595. yValues1[i] = float64(deviceDataPdfList[i].T_id1)
  2596. xValues2[i] = t
  2597. yValues2[i] = float64(deviceDataPdfList[i].T_id2)
  2598. }
  2599. series = append(series, chart.TimeSeries{
  2600. Name: "T1",
  2601. XValues: xValues1,
  2602. YValues: yValues1,
  2603. })
  2604. series = append(series, chart.TimeSeries{
  2605. Name: "T2",
  2606. XValues: xValues2,
  2607. YValues: yValues2,
  2608. })
  2609. if ymax < TemperatureMax {
  2610. ymax = TemperatureMax
  2611. }
  2612. if ymin > 0 {
  2613. ymin = 0
  2614. }
  2615. if ymin > TemperatureMin {
  2616. ymin = TemperatureMin
  2617. }
  2618. st, _ := lib.TimeStrToTime(startTime)
  2619. et, _ := lib.TimeStrToTime(endTime)
  2620. series = append(series, chart.TimeSeries{
  2621. Style: chart.Style{
  2622. StrokeColor: drawing.ColorRed,
  2623. StrokeDashArray: []float64{5.0, 5.0},
  2624. },
  2625. XValues: []time.Time{st, et},
  2626. YValues: []float64{float64(TemperatureMin), float64(TemperatureMin)},
  2627. })
  2628. series = append(series, chart.TimeSeries{
  2629. Style: chart.Style{
  2630. StrokeColor: drawing.ColorRed,
  2631. StrokeDashArray: []float64{5.0, 5.0},
  2632. },
  2633. XValues: []time.Time{st, et},
  2634. YValues: []float64{float64(TemperatureMax), float64(TemperatureMax)},
  2635. })
  2636. font := getZWFont()
  2637. graph := chart.Chart{
  2638. Title: "温度记录",
  2639. TitleStyle: chart.Style{
  2640. FontSize: 15,
  2641. },
  2642. Background: chart.Style{
  2643. Padding: chart.Box{
  2644. Top: 20,
  2645. },
  2646. },
  2647. Font: font,
  2648. XAxis: chart.XAxis{
  2649. Name: "时间",
  2650. ValueFormatter: chart.TimeValueFormatterWithFormat("2006-01-02 15:04"),
  2651. },
  2652. YAxis: chart.YAxis{
  2653. Name: "温度",
  2654. Range: &chart.ContinuousRange{
  2655. Min: float64(ymin),
  2656. Max: float64(ymax + 2),
  2657. },
  2658. },
  2659. Series: series,
  2660. }
  2661. //graph.Elements = []chart.Renderable{
  2662. // chart.Legend(&graph),
  2663. //}
  2664. filepath := "ofile/" + "temperature" + deviceSensorList[0].T_sn + ".jpg"
  2665. f, _ := os.Create(filepath)
  2666. defer f.Close()
  2667. graph.Render(chart.PNG, f)
  2668. return filepath, nil
  2669. }
  2670. func horizontalLine(xmin, xmax, y float64) *plotter.Line {
  2671. pts := make(plotter.XYs, 2)
  2672. pts[0].X = xmin
  2673. pts[0].Y = y
  2674. pts[1].X = xmax
  2675. pts[1].Y = y
  2676. line, err := plotter.NewLine(pts)
  2677. if err != nil {
  2678. panic(err)
  2679. }
  2680. line.LineStyle.Dashes = []vg.Length{vg.Points(8), vg.Points(5), vg.Points(1), vg.Points(5)}
  2681. line.Color = color.RGBA{R: 255, A: 255}
  2682. return line
  2683. }
  2684. type timeTicks struct{}
  2685. func (timeTicks) Ticks(min, max float64) []plot.Tick {
  2686. tks := plot.TimeTicks{}.Ticks(min, max)
  2687. for i, t := range tks {
  2688. //if t.Label == "" { // Skip minor ticks, they are fine.
  2689. // continue
  2690. //}
  2691. tks[i].Label = time.Unix(int64(t.Value), 0).Format("2006-01-02 15:04:05")
  2692. }
  2693. return tks
  2694. }
  2695. type commaTicks struct{}
  2696. // Ticks computes the default tick marks, but inserts commas
  2697. // into the labels for the major tick marks.
  2698. func (commaTicks) Ticks(min, max float64) []plot.Tick {
  2699. tks := plot.DefaultTicks{}.Ticks(min, max)
  2700. for i, t := range tks {
  2701. //if t.Label == "" { // Skip minor ticks, they are fine.
  2702. // continue
  2703. //}
  2704. tks[i].Label = fmt.Sprintf("%.0f", t.Value)
  2705. }
  2706. return tks
  2707. }
  2708. // 生成随机颜色的辅助函数
  2709. func randomColor(i int) color.RGBA {
  2710. var colors []color.RGBA
  2711. colors = append(colors,
  2712. color.RGBA{R: 52, G: 152, B: 219, A: 255},
  2713. color.RGBA{R: 230, G: 126, B: 34, A: 255},
  2714. color.RGBA{R: 142, G: 68, B: 173, A: 255},
  2715. color.RGBA{R: 211, G: 84, B: 0, A: 255},
  2716. color.RGBA{R: 231, G: 76, B: 60, A: 255},
  2717. color.RGBA{R: 26, G: 188, B: 156, A: 255},
  2718. color.RGBA{R: 243, G: 156, B: 18, A: 255},
  2719. color.RGBA{R: 22, G: 160, B: 133, A: 255},
  2720. color.RGBA{R: 46, G: 204, B: 113, A: 255},
  2721. color.RGBA{R: 39, G: 174, B: 96, A: 255},
  2722. color.RGBA{R: 41, G: 128, B: 185, A: 255},
  2723. color.RGBA{R: 155, G: 89, B: 182, A: 255},
  2724. color.RGBA{R: 192, G: 57, B: 43, A: 255},
  2725. color.RGBA{R: 241, G: 196, B: 15, A: 255},
  2726. )
  2727. return colors[i%len(colors)]
  2728. }
  2729. func randomColor2(i int) drawing.Color {
  2730. var colors []drawing.Color
  2731. colors = append(colors,
  2732. drawing.Color{R: 52, G: 152, B: 219, A: 255},
  2733. drawing.Color{R: 230, G: 126, B: 34, A: 255},
  2734. drawing.Color{R: 142, G: 68, B: 173, A: 255},
  2735. drawing.Color{R: 211, G: 84, B: 0, A: 255},
  2736. drawing.Color{R: 231, G: 76, B: 60, A: 255},
  2737. drawing.Color{R: 26, G: 188, B: 156, A: 255},
  2738. drawing.Color{R: 243, G: 156, B: 18, A: 255},
  2739. drawing.Color{R: 22, G: 160, B: 133, A: 255},
  2740. drawing.Color{R: 46, G: 204, B: 113, A: 255},
  2741. drawing.Color{R: 39, G: 174, B: 96, A: 255},
  2742. drawing.Color{R: 41, G: 128, B: 185, A: 255},
  2743. drawing.Color{R: 155, G: 89, B: 182, A: 255},
  2744. drawing.Color{R: 192, G: 57, B: 43, A: 255},
  2745. drawing.Color{R: 241, G: 196, B: 15, A: 255},
  2746. )
  2747. return colors[i%len(colors)]
  2748. }
  2749. // getZWFont 加载字体
  2750. func getZWFont() *truetype.Font {
  2751. fontFile := "./static/fonts/MiSans-Medium.ttf"
  2752. fontBytes, err := os.ReadFile(fontFile)
  2753. if err != nil {
  2754. log.Println(err)
  2755. return nil
  2756. }
  2757. font, err := truetype.Parse(fontBytes)
  2758. if err != nil {
  2759. log.Println(err)
  2760. return nil
  2761. }
  2762. return font
  2763. }