waybill.go 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127
  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/file_store"
  9. "cold-logistics/common/lib"
  10. "cold-logistics/common/nats/nats_server"
  11. "cold-logistics/conf"
  12. "errors"
  13. "fmt"
  14. "github.com/beego/beego/v2/core/logs"
  15. "github.com/boombuler/barcode"
  16. "github.com/boombuler/barcode/code128"
  17. "github.com/gin-gonic/gin"
  18. "github.com/gin-gonic/gin/binding"
  19. "github.com/golang/freetype/truetype"
  20. "github.com/jordan-wright/email"
  21. "github.com/ser163/png2j"
  22. "github.com/signintech/gopdf"
  23. "github.com/skip2/go-qrcode"
  24. "github.com/wcharczuk/go-chart/v2"
  25. "github.com/wcharczuk/go-chart/v2/drawing"
  26. "github.com/xuri/excelize/v2"
  27. "gogs.baozhida.cn/zoie/OAuth-core/api"
  28. "gogs.baozhida.cn/zoie/OAuth-core/pkg/jwtauth/user"
  29. _ "gogs.baozhida.cn/zoie/OAuth-core/pkg/response"
  30. "image"
  31. "image/jpeg"
  32. "image/png"
  33. "log"
  34. "net/smtp"
  35. "net/url"
  36. "os"
  37. "path"
  38. "sort"
  39. "strconv"
  40. "strings"
  41. "time"
  42. )
  43. type WaybillController struct {
  44. api.Api
  45. }
  46. // GetPage 获取运单列表
  47. // @Summary 获取运单列表
  48. // @Description 获取运单列表
  49. // @Tags 运单
  50. // @Param waybillNo query string false "运单号"
  51. // @Param status query string false "状态:1待派单 2待装车 3待入库 4已装车 5已入库 6已下车 7已出库 8已签收 9待装箱 10已装箱 11已出箱"
  52. // @Param orderStartTime query string false "下单开始时间"
  53. // @Param orderEndTime 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 waybillNo query string false "运单号"
  88. // @Param status query string false "状态:1待派单 2待装车 3待入库 4已装车 5已入库 6已下车 7已出库 8已签收 9待装箱 10已装箱 11已出箱"
  89. // @Param orderStartTime query string false "下单开始时间"
  90. // @Param orderEndTime query string false "下单结束时间"
  91. // @Param pageSize query int false "页条数"
  92. // @Param page query int false "页码"
  93. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  94. // @Router /api/waybill [get]
  95. // @Security Bearer
  96. func (e WaybillController) Export(c *gin.Context) {
  97. s := service.Waybill{}
  98. req := dto.WaybillGetPageReq{}
  99. err := e.MakeContext(c).
  100. MakeOrm().
  101. Bind(&req, binding.Query).
  102. MakeService(&s.Service).
  103. Errors
  104. if err != nil {
  105. e.Logger.Error(err)
  106. e.Error(500, err, err.Error())
  107. return
  108. }
  109. //数据权限检查
  110. p := actions.GetPermissionFromContext(c)
  111. list := make([]model.Waybill, 0)
  112. var count int64
  113. req.PageSize = 9999
  114. err = s.GetPage(&req, &list, &count, p)
  115. if err != nil {
  116. e.Error(500, err, err.Error())
  117. return
  118. }
  119. f := excelize.NewFile() // 设置单元格的值
  120. // 这里设置表头ÒÒ
  121. f.SetCellValue("Sheet1", "A1", "序号")
  122. f.SetCellValue("Sheet1", "B1", "状态")
  123. f.SetCellValue("Sheet1", "C1", "寄件人名称")
  124. f.SetCellValue("Sheet1", "D1", "寄件人电话")
  125. f.SetCellValue("Sheet1", "E1", "寄件人地址")
  126. f.SetCellValue("Sheet1", "F1", "收件人名称")
  127. f.SetCellValue("Sheet1", "G1", "收件人电话")
  128. f.SetCellValue("Sheet1", "H1", "收件人地址")
  129. f.SetCellValue("Sheet1", "I1", "温度要求")
  130. f.SetCellValue("Sheet1", "J1", "配送要求")
  131. f.SetCellValue("Sheet1", "K1", "货物类型")
  132. f.SetCellValue("Sheet1", "L1", "运输备注")
  133. // 设置列宽
  134. f.SetColWidth("Sheet1", "A", "A", 6)
  135. f.SetColWidth("Sheet1", "B", "B", 8)
  136. f.SetColWidth("Sheet1", "C", "C", 14)
  137. f.SetColWidth("Sheet1", "D", "D", 14)
  138. f.SetColWidth("Sheet1", "E", "E", 30)
  139. f.SetColWidth("Sheet1", "F", "F", 14)
  140. f.SetColWidth("Sheet1", "G", "G", 14)
  141. f.SetColWidth("Sheet1", "H", "H", 30)
  142. f.SetColWidth("Sheet1", "I", "K", 15)
  143. f.SetColWidth("Sheet1", "L", "L", 15)
  144. line := 1
  145. // 循环写入数据
  146. for i, v := range list {
  147. line++
  148. f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), i+1)
  149. f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), model.WaybillStatusMap[v.Status])
  150. f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.SenderAddressName)
  151. f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.SenderAddressPhone)
  152. f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.SenderAddressDetails)
  153. f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.ConsigneeAddressName)
  154. f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.ConsigneeAddressPhone)
  155. f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), v.ConsigneeAddressDetails)
  156. f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), v.TemperatureInterval)
  157. f.SetCellValue("Sheet1", fmt.Sprintf("J%d", line), v.DeliveryCondition)
  158. f.SetCellValue("Sheet1", fmt.Sprintf("K%d", line), v.CargoType)
  159. f.SetCellValue("Sheet1", fmt.Sprintf("L%d", line), v.Remark)
  160. }
  161. timeStr := time.Now().Format("20060102150405")
  162. filePath := "ofile/" + "运单" + timeStr + ".xlsx"
  163. // 保存文件
  164. if err = f.SaveAs(filePath); err != nil {
  165. logs.Error("保存运单失败:", err)
  166. }
  167. defer func() {
  168. os.Remove(filePath)
  169. }()
  170. c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
  171. // PathEscape 函数对中文做处理
  172. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape("运单"+timeStr+".xlsx"))
  173. c.Header("Content-Transfer-Encoding", "binary")
  174. c.File(filePath)
  175. }
  176. // Home 首页统计
  177. // @Summary 首页统计
  178. // @Description 首页统计
  179. // @Tags 运单
  180. // @Param date query string false "日期"
  181. // @Param type query string false "类型 month-月 year-年"
  182. // @Param pageSize query int false "页条数"
  183. // @Param page query int false "页码"
  184. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  185. // @Router /api/waybill [get]
  186. // @Security Bearer
  187. func (e WaybillController) Home(c *gin.Context) {
  188. s := service.Waybill{}
  189. req := dto.WaybillStatsReq{}
  190. err := e.MakeContext(c).
  191. MakeOrm().
  192. Bind(&req, binding.Query).
  193. MakeService(&s.Service).
  194. Errors
  195. if err != nil {
  196. e.Logger.Error(err)
  197. e.Error(500, err, err.Error())
  198. return
  199. }
  200. //数据权限检查
  201. p := actions.GetPermissionFromContext(c)
  202. res := s.GetBasicsStats(&req, p)
  203. e.OK(res, "查询成功")
  204. }
  205. // GetAppletPage 获取运单列表
  206. // @Summary 获取运单列表
  207. // @Description 获取运单列表
  208. // @Tags 运单
  209. // @Param waybillNo query string false "运单号"
  210. // @Param status query string false "状态:1待派单 2待装车 3待入库 4已装车 5已入库 6已下车 7已出库 8已签收 9待装箱 10已装箱 11已出箱"
  211. // @Param pageSize query int false "页条数"
  212. // @Param page query int false "页码"
  213. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  214. // @Router /api/waybill [get]
  215. // @Security Bearer
  216. func (e WaybillController) GetAppletPage(c *gin.Context) {
  217. s := service.Waybill{}
  218. req := dto.WaybillGetAppletPageReq{}
  219. err := e.MakeContext(c).
  220. MakeOrm().
  221. Bind(&req, binding.Query).
  222. MakeService(&s.Service).
  223. Errors
  224. if err != nil {
  225. e.Logger.Error(err)
  226. e.Error(500, err, err.Error())
  227. return
  228. }
  229. //数据权限检查
  230. p := actions.GetPermissionFromContext(c)
  231. list := make([]model.Waybill, 0)
  232. var count int64
  233. err = s.GetAppletPage(&req, &list, &count, p)
  234. if err != nil {
  235. e.Error(500, err, err.Error())
  236. return
  237. }
  238. e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
  239. }
  240. // GetAppletCount 获取app运单统计数量
  241. // @Summary 获取app运单统计数量
  242. // @Description 获取app运单统计数量
  243. // @Tags 运单
  244. // @Param waybillNo query string false "运单号"
  245. // @Param status query string false "状态:1待派单 2待装车 3待入库 4已装车 5已入库 6已下车 7已出库 8已签收 9待装箱 10已装箱 11已出箱"
  246. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  247. // @Router /api/waybill/applet-count [get]
  248. // @Security Bearer
  249. func (e WaybillController) GetAppletCount(c *gin.Context) {
  250. s := service.Waybill{}
  251. userSvc := service.SysUser{}
  252. req := dto.WaybillGetAppletPageReq{}
  253. err := e.MakeContext(c).
  254. MakeOrm().
  255. Bind(&req, binding.Query).
  256. MakeService(&s.Service).
  257. MakeService(&userSvc.Service).
  258. Errors
  259. if err != nil {
  260. e.Logger.Error(err)
  261. e.Error(500, err, err.Error())
  262. return
  263. }
  264. //数据权限检查
  265. p := actions.GetPermissionFromContext(c)
  266. var userObj model.SysUser
  267. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  268. if err != nil {
  269. e.Error(500, err, err.Error())
  270. return
  271. }
  272. list := make([]model.Waybill, 0)
  273. var count int64
  274. if userObj.UserType == "customer" {
  275. r := dto.WaybillGetCustomerPageReq{}
  276. r.PageSize = 9999
  277. r.CustomerId = p.UserId
  278. err = s.GetCustomerPage(&r, &list, &count, p)
  279. var statusCount = make(map[int]int)
  280. statusCount[0] = int(count)
  281. for _, waybill := range list {
  282. if _, ok := statusCount[waybill.Status]; ok {
  283. statusCount[waybill.Status] += 1
  284. } else {
  285. statusCount[waybill.Status] = 1
  286. }
  287. }
  288. e.OK(statusCount, "查询成功")
  289. return
  290. }
  291. err = s.GetAppletCount(&list, &count, p)
  292. if err != nil {
  293. e.Error(500, err, err.Error())
  294. return
  295. }
  296. var statusCount = make(map[int]int)
  297. statusCount[0] = int(count)
  298. for _, waybill := range list {
  299. if _, ok := statusCount[waybill.Status]; ok {
  300. statusCount[waybill.Status] += 1
  301. } else {
  302. statusCount[waybill.Status] = 1
  303. }
  304. }
  305. e.OK(statusCount, "查询成功")
  306. }
  307. // Get 通过id获取运单
  308. // @Summary 通过id获取运单
  309. // @Description 通过id获取运单
  310. // @Tags 运单
  311. // @Param id path string true "运单id"
  312. // @Success 200 {object} response.Response{data=model.Waybill} "{"code": 200, "data": [...]}"
  313. // @Router /api/waybill/{id} [get]
  314. // @Security Bearer
  315. func (e WaybillController) Get(c *gin.Context) {
  316. s := service.Waybill{}
  317. req := dto.WaybillGetReq{}
  318. err := e.MakeContext(c).
  319. MakeOrm().
  320. Bind(&req, nil).
  321. MakeService(&s.Service).
  322. Errors
  323. if err != nil {
  324. e.Logger.Error(err)
  325. e.Error(500, err, err.Error())
  326. return
  327. }
  328. var object model.Waybill
  329. p := actions.GetPermissionFromContext(c)
  330. //数据权限检查
  331. err = s.Get(&req, &object, p)
  332. if err != nil {
  333. e.Error(500, err, err.Error())
  334. return
  335. }
  336. e.OK(object, "查询成功")
  337. }
  338. // Insert 添加运单
  339. // @Summary 添加运单
  340. // @Description 添加运单
  341. // @Tags 运单
  342. // @Accept application/json
  343. // @Product application/json
  344. // @Param data body dto.WaybillInsertReq true "data"
  345. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  346. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  347. // @Router /api/waybill [post]
  348. // @Security Bearer
  349. func (e WaybillController) Insert(c *gin.Context) {
  350. s := service.Waybill{}
  351. req := dto.WaybillInsertReq{}
  352. err := e.MakeContext(c).
  353. MakeOrm().
  354. Bind(&req, binding.JSON).
  355. MakeService(&s.Service).
  356. Errors
  357. if err != nil {
  358. e.Logger.Error(err)
  359. e.Error(500, err, err.Error())
  360. return
  361. }
  362. p := actions.GetPermissionFromContext(c)
  363. // 设置创建人
  364. req.SetCreateBy(user.GetUserId(c))
  365. req.SetDeptId(p.DeptId)
  366. err = s.Insert(&req)
  367. if err != nil {
  368. e.Error(500, err, err.Error())
  369. return
  370. }
  371. e.OK(req.GetId(), "添加成功")
  372. }
  373. // AppletInsert 添加运单app
  374. // @Summary 添加运单app
  375. // @Description 添加运单app
  376. // @Tags 运单
  377. // @Accept application/json
  378. // @Product application/json
  379. // @Param data body dto.WaybillInsertReq true "data"
  380. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  381. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  382. // @Router /api/waybill [post]
  383. // @Security Bearer
  384. func (e WaybillController) AppletInsert(c *gin.Context) {
  385. s := service.Waybill{}
  386. req := dto.WaybillInsertReq{}
  387. err := e.MakeContext(c).
  388. MakeOrm().
  389. Bind(&req, binding.JSON).
  390. MakeService(&s.Service).
  391. Errors
  392. if err != nil {
  393. e.Logger.Error(err)
  394. e.Error(500, err, err.Error())
  395. return
  396. }
  397. p := actions.GetPermissionFromContext(c)
  398. err = s.AppletInsert(&req, p)
  399. if err != nil {
  400. e.Error(500, err, err.Error())
  401. return
  402. }
  403. e.OK(req.GetId(), "添加成功")
  404. }
  405. // Update 修改运单
  406. // @Summary 修改运单
  407. // @Description 修改运单
  408. // @Tags 运单
  409. // @Accept application/json
  410. // @Product application/json
  411. // @Param data body dto.WaybillUpdateReq true "body"
  412. // @Success 200 {string} string "{"code": 200, "message": "修改成功"}"
  413. // @Success 200 {string} string "{"code": -1, "message": "修改失败"}"
  414. // @Router /api/waybill [put]
  415. // @Security Bearer
  416. func (e WaybillController) Update(c *gin.Context) {
  417. s := service.Waybill{}
  418. req := dto.WaybillUpdateReq{}
  419. err := e.MakeContext(c).
  420. MakeOrm().
  421. Bind(&req).
  422. MakeService(&s.Service).
  423. Errors
  424. if err != nil {
  425. e.Logger.Error(err)
  426. e.Error(500, err, err.Error())
  427. return
  428. }
  429. p := actions.GetPermissionFromContext(c)
  430. req.SetUpdateBy(user.GetUserId(c))
  431. err = s.Update(&req, p)
  432. if err != nil {
  433. e.Error(500, err, err.Error())
  434. return
  435. }
  436. e.OK(req.GetId(), "修改成功")
  437. }
  438. // Delivery 派单
  439. // @Summary 派单
  440. // @Description 派单
  441. // @Tags 运单
  442. // @Accept application/json
  443. // @Product application/json
  444. // @Param data body dto.WaybillDeliveryReq true "body"
  445. // @Success 200 {string} string "{"code": 200, "message": "派单成功"}"
  446. // @Success 200 {string} string "{"code": -1, "message": "派单失败"}"
  447. // @Router /api/waybill [put]
  448. // @Security Bearer
  449. func (e WaybillController) Delivery(c *gin.Context) {
  450. s := service.Waybill{}
  451. req := dto.WaybillDeliveryReq{}
  452. err := e.MakeContext(c).
  453. MakeOrm().
  454. Bind(&req).
  455. MakeService(&s.Service).
  456. Errors
  457. if err != nil {
  458. e.Logger.Error(err)
  459. e.Error(500, err, err.Error())
  460. return
  461. }
  462. p := actions.GetPermissionFromContext(c)
  463. req.SetUpdateBy(user.GetUserId(c))
  464. err = s.Delivery(&req, p)
  465. if err != nil {
  466. e.Error(500, err, err.Error())
  467. return
  468. }
  469. e.OK(req.GetId(), "派单成功")
  470. }
  471. // Delete 删除运单
  472. // @Summary 删除运单
  473. // @Description 删除运单
  474. // @Tags 运单
  475. // @Accept application/json
  476. // @Product application/json
  477. // @Param data body dto.WaybillDeleteReq true "body"
  478. // @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
  479. // @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
  480. // @Router /api/waybill [delete]
  481. // @Security Bearer
  482. func (e WaybillController) Delete(c *gin.Context) {
  483. s := service.Waybill{}
  484. req := dto.WaybillDeleteReq{}
  485. userSvc := service.SysUser{}
  486. err := e.MakeContext(c).
  487. MakeOrm().
  488. Bind(&req, binding.JSON, nil).
  489. MakeService(&s.Service).
  490. MakeService(&userSvc.Service).
  491. Errors
  492. if err != nil {
  493. e.Logger.Error(err)
  494. e.Error(500, err, err.Error())
  495. return
  496. }
  497. //数据权限检查
  498. p := actions.GetPermissionFromContext(c)
  499. err = s.Remove(&req, p)
  500. if err != nil {
  501. e.Error(500, err, err.Error())
  502. return
  503. }
  504. e.OK(req.GetId(), "删除成功")
  505. }
  506. // WarehouseIn 入库
  507. // @Summary 入库
  508. // @Description 入库
  509. // @Tags 运单
  510. // @Accept application/json
  511. // @Product application/json
  512. // @Param data body dto.WaybillInOutReq true "body"
  513. // @Success 200 {string} string "{"code": 200, "message": "入库成功"}"
  514. // @Success 200 {string} string "{"code": -1, "message": "入库失败"}"
  515. // @Router /api/waybill/warehouse-in [post]
  516. // @Security Bearer
  517. func (e WaybillController) WarehouseIn(c *gin.Context) {
  518. s := service.Waybill{}
  519. req := dto.WaybillInOutReq{}
  520. err := e.MakeContext(c).
  521. MakeOrm().
  522. Bind(&req, binding.JSON, nil).
  523. MakeService(&s.Service).
  524. Errors
  525. if err != nil {
  526. e.Logger.Error(err)
  527. e.Error(500, err, err.Error())
  528. return
  529. }
  530. //数据权限检查
  531. p := actions.GetPermissionFromContext(c)
  532. err = s.WarehouseIn(&req, p)
  533. if err != nil {
  534. e.Error(500, err, err.Error())
  535. return
  536. }
  537. e.OK(req.WaybillNoList, "入库成功")
  538. }
  539. // WarehouseOut 出库
  540. // @Summary 出库
  541. // @Description 出库
  542. // @Tags 运单
  543. // @Accept application/json
  544. // @Product application/json
  545. // @Param data body dto.WaybillInOutReq true "body"
  546. // @Success 200 {string} string "{"code": 200, "message": "出库成功"}"
  547. // @Success 200 {string} string "{"code": -1, "message": "出库失败"}"
  548. // @Router /api/waybill/warehouse-out [post]
  549. // @Security Bearer
  550. func (e WaybillController) WarehouseOut(c *gin.Context) {
  551. s := service.Waybill{}
  552. req := dto.WaybillInOutReq{}
  553. err := e.MakeContext(c).
  554. MakeOrm().
  555. Bind(&req, binding.JSON, nil).
  556. MakeService(&s.Service).
  557. Errors
  558. if err != nil {
  559. e.Logger.Error(err)
  560. e.Error(500, err, err.Error())
  561. return
  562. }
  563. //数据权限检查
  564. p := actions.GetPermissionFromContext(c)
  565. err = s.WarehouseOut(&req, p)
  566. if err != nil {
  567. e.Error(500, err, err.Error())
  568. return
  569. }
  570. e.OK(req.WaybillNoList, "出库成功")
  571. }
  572. // CarIn 装车
  573. // @Summary 装车
  574. // @Description 装车
  575. // @Tags 运单
  576. // @Accept application/json
  577. // @Product application/json
  578. // @Param data body dto.WaybillInOutReq true "body"
  579. // @Success 200 {string} string "{"code": 200, "message": "装车成功"}"
  580. // @Success 200 {string} string "{"code": -1, "message": "装车失败"}"
  581. // @Router /api/waybill/car-in [post]
  582. // @Security Bearer
  583. func (e WaybillController) CarIn(c *gin.Context) {
  584. s := service.Waybill{}
  585. req := dto.WaybillInOutReq{}
  586. err := e.MakeContext(c).
  587. MakeOrm().
  588. Bind(&req, binding.JSON, nil).
  589. MakeService(&s.Service).
  590. Errors
  591. if err != nil {
  592. e.Logger.Error(err)
  593. e.Error(500, err, err.Error())
  594. return
  595. }
  596. //数据权限检查
  597. p := actions.GetPermissionFromContext(c)
  598. err = s.CarIn(&req, p)
  599. if err != nil {
  600. e.Error(500, err, err.Error())
  601. return
  602. }
  603. e.OK(req.WaybillNoList, "装车成功")
  604. }
  605. // CarOut 下车
  606. // @Summary 下车
  607. // @Description 下车
  608. // @Tags 运单
  609. // @Accept application/json
  610. // @Product application/json
  611. // @Param data body dto.WaybillInOutReq true "body"
  612. // @Success 200 {string} string "{"code": 200, "message": "下车成功"}"
  613. // @Success 200 {string} string "{"code": -1, "message": "下车失败"}"
  614. // @Router /api/waybill/car-out [post]
  615. // @Security Bearer
  616. func (e WaybillController) CarOut(c *gin.Context) {
  617. s := service.Waybill{}
  618. req := dto.WaybillInOutReq{}
  619. err := e.MakeContext(c).
  620. MakeOrm().
  621. Bind(&req, binding.JSON, nil).
  622. MakeService(&s.Service).
  623. Errors
  624. if err != nil {
  625. e.Logger.Error(err)
  626. e.Error(500, err, err.Error())
  627. return
  628. }
  629. //数据权限检查
  630. p := actions.GetPermissionFromContext(c)
  631. err = s.CarOut(&req, p)
  632. if err != nil {
  633. e.Error(500, err, err.Error())
  634. return
  635. }
  636. e.OK(req.WaybillNoList, "下车成功")
  637. }
  638. // CoolerBoxIn 装箱
  639. // @Summary 装箱
  640. // @Description 装箱
  641. // @Tags 运单
  642. // @Accept application/json
  643. // @Product application/json
  644. // @Param data body dto.WaybillCoolerBoxInReq true "body"
  645. // @Success 200 {string} string "{"code": 200, "message": "装箱成功"}"
  646. // @Success 200 {string} string "{"code": -1, "message": "装箱失败"}"
  647. // @Router /api/waybill/cooler-box-in [post]
  648. // @Security Bearer
  649. func (e WaybillController) CoolerBoxIn(c *gin.Context) {
  650. s := service.Waybill{}
  651. req := dto.WaybillCoolerBoxInReq{}
  652. err := e.MakeContext(c).
  653. MakeOrm().
  654. Bind(&req, binding.JSON, nil).
  655. MakeService(&s.Service).
  656. Errors
  657. if err != nil {
  658. e.Logger.Error(err)
  659. e.Error(500, err, err.Error())
  660. return
  661. }
  662. //数据权限检查
  663. p := actions.GetPermissionFromContext(c)
  664. err = s.CoolerBoxIn(&req, p)
  665. if err != nil {
  666. e.Error(500, err, err.Error())
  667. return
  668. }
  669. e.OK(req.WaybillNoList, "装箱成功")
  670. }
  671. // StopRecord 停止记录
  672. // @Summary 停止记录
  673. // @Description 停止记录
  674. // @Tags 运单
  675. // @Accept application/json
  676. // @Product application/json
  677. // @Param data body dto.WaybillStopRecordReq true "body"
  678. // @Success 200 {string} string "{"code": 200, "message": "停止记录成功"}"
  679. // @Success 200 {string} string "{"code": -1, "message": "停止记录失败"}"
  680. // @Router /api/waybill/stop-record [post]
  681. // @Security Bearer
  682. func (e WaybillController) StopRecord(c *gin.Context) {
  683. s := service.Waybill{}
  684. req := dto.WaybillStopRecordReq{}
  685. err := e.MakeContext(c).
  686. MakeOrm().
  687. Bind(&req, binding.JSON, nil).
  688. MakeService(&s.Service).
  689. Errors
  690. if err != nil {
  691. e.Logger.Error(err)
  692. e.Error(500, err, err.Error())
  693. return
  694. }
  695. //数据权限检查
  696. p := actions.GetPermissionFromContext(c)
  697. err = s.StopRecord(&req, p)
  698. if err != nil {
  699. e.Error(500, err, err.Error())
  700. return
  701. }
  702. e.OK(req.WaybillNo, "停止记录成功")
  703. }
  704. // Receipt 签收
  705. // @Summary 签收
  706. // @Description 签收
  707. // @Tags 运单
  708. // @Accept application/json
  709. // @Product application/json
  710. // @Param data body dto.WaybillReceiptReq true "body"
  711. // @Success 200 {string} string "{"code": 200, "message": "签收成功"}"
  712. // @Success 200 {string} string "{"code": -1, "message": "签收失败"}"
  713. // @Router /api/waybill/car-out [post]
  714. // @Security Bearer
  715. func (e WaybillController) Receipt(c *gin.Context) {
  716. s := service.Waybill{}
  717. req := dto.WaybillReceiptReq{}
  718. err := e.MakeContext(c).
  719. MakeOrm().
  720. Bind(&req, binding.JSON, nil).
  721. MakeService(&s.Service).
  722. Errors
  723. if err != nil {
  724. e.Logger.Error(err)
  725. e.Error(500, err, err.Error())
  726. return
  727. }
  728. //数据权限检查
  729. p := actions.GetPermissionFromContext(c)
  730. err = s.Receipt(&req, p)
  731. if err != nil {
  732. e.Error(500, err, err.Error())
  733. return
  734. }
  735. e.OK(req.WaybillNo, "签收成功")
  736. }
  737. // GetCustomerPage 获取客户运单列表
  738. // @Summary 获取客户运单列表
  739. // @Description 获取客户运单列表
  740. // @Tags 运单
  741. // @Param waybillNo query string false "运单号"
  742. // @Param status query int false "状态:1未发货 2已发货 3已签收 4已处理"
  743. // @Param orderStartTime query string false "下单开始时间"
  744. // @Param orderEndTime query string false "下单开始时间"
  745. // @Param pageSize query int false "页条数"
  746. // @Param page query int false "页码"
  747. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  748. // @Router /api/waybill/customer [get]
  749. // @Security Bearer
  750. func (e WaybillController) GetCustomerPage(c *gin.Context) {
  751. s := service.Waybill{}
  752. req := dto.WaybillGetCustomerPageReq{}
  753. err := e.MakeContext(c).
  754. MakeOrm().
  755. Bind(&req, binding.Query).
  756. MakeService(&s.Service).
  757. Errors
  758. if err != nil {
  759. e.Logger.Error(err)
  760. e.Error(500, err, err.Error())
  761. return
  762. }
  763. //数据权限检查
  764. p := actions.GetPermissionFromContext(c)
  765. list := make([]model.Waybill, 0)
  766. var count int64
  767. req.CustomerId = p.UserId
  768. err = s.GetCustomerPage(&req, &list, &count, p)
  769. if err != nil {
  770. e.Error(500, err, err.Error())
  771. return
  772. }
  773. e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
  774. }
  775. // CustomerExport 运单管理-客户导出
  776. // @Summary 运单管理-客户导出
  777. // @Description 运单管理-客户导出
  778. // @Tags 运单
  779. // @Param waybillNo query string false "运单号"
  780. // @Param status query int false "状态:1未发货 2已发货 3已签收 4已处理"
  781. // @Param orderStartTime query string false "下单开始时间"
  782. // @Param orderEndTime query string false "下单开始时间"
  783. // @Param pageSize query int false "页条数"
  784. // @Param page query int false "页码"
  785. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  786. // @Router /api/waybill/customer/export [get]
  787. // @Security Bearer
  788. func (e WaybillController) CustomerExport(c *gin.Context) {
  789. s := service.Waybill{}
  790. req := dto.WaybillGetCustomerPageReq{}
  791. err := e.MakeContext(c).
  792. MakeOrm().
  793. Bind(&req, binding.Query).
  794. MakeService(&s.Service).
  795. Errors
  796. if err != nil {
  797. e.Logger.Error(err)
  798. e.Error(500, err, err.Error())
  799. return
  800. }
  801. //数据权限检查
  802. p := actions.GetPermissionFromContext(c)
  803. list := make([]model.Waybill, 0)
  804. var count int64
  805. req.CustomerId = p.UserId
  806. req.PageSize = 9999
  807. err = s.GetCustomerPage(&req, &list, &count, p)
  808. if err != nil {
  809. e.Error(500, err, err.Error())
  810. return
  811. }
  812. f := excelize.NewFile() // 设置单元格的值
  813. // 这里设置表头ÒÒ
  814. f.SetCellValue("Sheet1", "A1", "序号")
  815. f.SetCellValue("Sheet1", "B1", "状态")
  816. f.SetCellValue("Sheet1", "C1", "寄件人名称")
  817. f.SetCellValue("Sheet1", "D1", "寄件人电话")
  818. f.SetCellValue("Sheet1", "E1", "寄件人地址")
  819. f.SetCellValue("Sheet1", "F1", "收件人名称")
  820. f.SetCellValue("Sheet1", "G1", "收件人电话")
  821. f.SetCellValue("Sheet1", "H1", "收件人地址")
  822. f.SetCellValue("Sheet1", "I1", "温度要求")
  823. f.SetCellValue("Sheet1", "J1", "配送要求")
  824. f.SetCellValue("Sheet1", "K1", "货物类型")
  825. f.SetCellValue("Sheet1", "L1", "运输备注")
  826. // 设置列宽
  827. f.SetColWidth("Sheet1", "A", "A", 6)
  828. f.SetColWidth("Sheet1", "B", "B", 8)
  829. f.SetColWidth("Sheet1", "C", "C", 14)
  830. f.SetColWidth("Sheet1", "D", "D", 14)
  831. f.SetColWidth("Sheet1", "E", "E", 30)
  832. f.SetColWidth("Sheet1", "F", "F", 14)
  833. f.SetColWidth("Sheet1", "G", "G", 14)
  834. f.SetColWidth("Sheet1", "H", "H", 30)
  835. f.SetColWidth("Sheet1", "I", "K", 15)
  836. f.SetColWidth("Sheet1", "L", "L", 15)
  837. line := 1
  838. // 循环写入数据
  839. for i, v := range list {
  840. line++
  841. f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), i+1)
  842. f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), model.GetCustomerWaybillStatus(v.Status))
  843. f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.SenderAddressName)
  844. f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.SenderAddressPhone)
  845. f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.SenderAddressDetails)
  846. f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.ConsigneeAddressName)
  847. f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.ConsigneeAddressPhone)
  848. f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), v.ConsigneeAddressDetails)
  849. f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), v.TemperatureInterval)
  850. f.SetCellValue("Sheet1", fmt.Sprintf("J%d", line), v.DeliveryCondition)
  851. f.SetCellValue("Sheet1", fmt.Sprintf("K%d", line), v.CargoType)
  852. f.SetCellValue("Sheet1", fmt.Sprintf("L%d", line), v.Remark)
  853. }
  854. timeStr := time.Now().Format("20060102150405")
  855. filePath := "ofile/" + "运单" + timeStr + ".xlsx"
  856. defer func() {
  857. os.Remove(filePath)
  858. }()
  859. // 保存文件
  860. if err = f.SaveAs(filePath); err != nil {
  861. logs.Error("保存运单失败:", err)
  862. }
  863. c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
  864. // PathEscape 函数对中文做处理
  865. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape("运单"+timeStr+".xlsx"))
  866. c.Header("Content-Transfer-Encoding", "binary")
  867. c.File(filePath)
  868. }
  869. // CustomerInsert 客户添加运单
  870. // @Summary 客户添加运单
  871. // @Description 客户添加运单
  872. // @Tags 运单
  873. // @Accept application/json
  874. // @Product application/json
  875. // @Param data body dto.WaybillInsertReq true "data"
  876. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  877. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  878. // @Router /api/waybill/customer [post]
  879. // @Security Bearer
  880. func (e WaybillController) CustomerInsert(c *gin.Context) {
  881. s := service.Waybill{}
  882. userSvc := service.SysUser{}
  883. req := dto.WaybillInsertReq{}
  884. err := e.MakeContext(c).
  885. MakeOrm().
  886. Bind(&req, binding.JSON).
  887. MakeService(&s.Service).
  888. MakeService(&userSvc.Service).
  889. Errors
  890. if err != nil {
  891. e.Logger.Error(err)
  892. e.Error(500, err, err.Error())
  893. return
  894. }
  895. p := actions.GetPermissionFromContext(c)
  896. var userObj model.SysUser
  897. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  898. if err != nil {
  899. e.Error(500, err, "获取用户信息失败")
  900. return
  901. }
  902. if p.DeptId == 0 && req.DeptId == 0 {
  903. e.Error(500, err, "请先选择运输公司")
  904. return
  905. }
  906. // 设置创建人
  907. req.SetCreateBy(user.GetUserId(c))
  908. req.CustomerId = p.UserId
  909. req.CustomerName = userObj.NickName
  910. if p.DeptId > 0 {
  911. req.SetDeptId(p.DeptId)
  912. }
  913. err = s.Insert(&req)
  914. if err != nil {
  915. e.Error(500, err, err.Error())
  916. return
  917. }
  918. e.OK(req.GetId(), "添加成功")
  919. }
  920. // Import 导入运单
  921. // @Summary 导入运单
  922. // @Description 导入运单
  923. // @Tags 运单
  924. // @Accept application/json
  925. // @Product application/json
  926. // @Param data body dto.WaybillImportReq true "data"
  927. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  928. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  929. // @Router /api/waybill/import [post]
  930. // @Security Bearer
  931. func (e WaybillController) Import(c *gin.Context) {
  932. s := service.Waybill{}
  933. userSvc := service.SysUser{}
  934. req := dto.WaybillImportReq{}
  935. err := e.MakeContext(c).
  936. MakeOrm().
  937. Bind(&req, binding.Form).
  938. MakeService(&s.Service).
  939. MakeService(&userSvc.Service).
  940. Errors
  941. if err != nil {
  942. e.Logger.Error(err)
  943. e.Error(500, err, err.Error())
  944. return
  945. }
  946. //读取第一fileName的文件
  947. fileHeader, err := c.FormFile("file")
  948. if err != nil {
  949. err = errors.New("文件格式错误" + err.Error())
  950. e.Logger.Error(err)
  951. e.Error(500, err, err.Error())
  952. return
  953. }
  954. if fileHeader.Size > 1024*1024*2 {
  955. err = errors.New("文件大小超过2M")
  956. e.Logger.Error(err)
  957. e.Error(500, err, err.Error())
  958. return
  959. }
  960. file, err := fileHeader.Open()
  961. if err != nil {
  962. err = errors.New("文件格式错误" + err.Error())
  963. e.Logger.Error(err)
  964. e.Error(500, err, err.Error())
  965. return
  966. }
  967. defer file.Close()
  968. xlsx, err := excelize.OpenReader(bufio.NewReader(file))
  969. if err != nil {
  970. err = errors.New("文件格式错误" + err.Error())
  971. e.Logger.Error(err)
  972. e.Error(500, err, err.Error())
  973. return
  974. }
  975. p := actions.GetPermissionFromContext(c)
  976. if p.DeptId == 0 {
  977. e.Error(500, err, "获取用户信息失败")
  978. return
  979. }
  980. var userObj model.SysUser
  981. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  982. if err != nil {
  983. e.Error(500, err, "获取用户信息失败")
  984. return
  985. }
  986. var customerId int
  987. //customerName := req.CustomerName
  988. if userObj.UserType == model.UserTypeCustomer {
  989. customerId = userObj.Id
  990. //customerName = userObj.NickName
  991. }
  992. rows, _ := xlsx.GetRows("Sheet1")
  993. for indexRow, row := range rows {
  994. if indexRow == 0 {
  995. continue
  996. }
  997. if len(row) < 12 {
  998. for i := 0; i < 12-len(row); i++ {
  999. row = append(row, "")
  1000. }
  1001. }
  1002. for i, colCell := range row {
  1003. fmt.Println(i, ":", colCell)
  1004. }
  1005. quantity, _ := strconv.Atoi(row[10])
  1006. obj := dto.WaybillInsertReq{
  1007. Status: 1,
  1008. SenderAddressName: row[0],
  1009. SenderAddressPhone: row[1],
  1010. SenderAddressDetails: row[2],
  1011. CustomerName: row[3],
  1012. ConsigneeAddressName: row[4],
  1013. ConsigneeAddressPhone: row[5],
  1014. ConsigneeAddressDetails: row[6],
  1015. TemperatureInterval: row[7],
  1016. DeliveryCondition: row[8],
  1017. CargoType: row[9],
  1018. Quantity: quantity,
  1019. Remark: row[11],
  1020. CustomerId: customerId,
  1021. }
  1022. obj.SetDeptId(p.DeptId)
  1023. obj.SetCreateBy(user.GetUserId(c))
  1024. err = s.Insert(&obj)
  1025. if err != nil {
  1026. e.Error(500, err, err.Error())
  1027. return
  1028. }
  1029. }
  1030. e.OK(len(rows)-1, "导入成功")
  1031. }
  1032. // ExportTemplate 导出运单模板
  1033. // @Summary 导出运单模板
  1034. // @Description 导出运单模板
  1035. // @Tags 运单
  1036. // @Accept application/json
  1037. // @Product application/json
  1038. // @Router /api/waybill/export-template [post]
  1039. // @Security Bearer
  1040. func (e WaybillController) ExportTemplate(c *gin.Context) {
  1041. s := service.Waybill{}
  1042. err := e.MakeContext(c).
  1043. MakeOrm().
  1044. MakeService(&s.Service).
  1045. Errors
  1046. if err != nil {
  1047. e.Logger.Error(err)
  1048. e.Error(500, err, err.Error())
  1049. return
  1050. }
  1051. filePath := "./ofile/运单导入模板.xlsx"
  1052. //打开文件
  1053. fileTmp, errByOpenFile := os.Open(filePath)
  1054. defer fileTmp.Close()
  1055. //获取文件的名称
  1056. fileName := path.Base(filePath)
  1057. if errByOpenFile != nil {
  1058. e.Logger.Error(err)
  1059. e.Error(500, err, err.Error())
  1060. return
  1061. }
  1062. c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
  1063. // PathEscape 函数对中文做处理
  1064. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(fileName))
  1065. c.Header("Content-Transfer-Encoding", "binary")
  1066. c.File(filePath)
  1067. }
  1068. // TemperaturePDF 导出温度记录pdf
  1069. // @Summary 导出温度记录pdf
  1070. // @Description 导出温度记录pdf
  1071. // @Tags 运单
  1072. // @Accept application/json
  1073. // @Product application/json
  1074. // @Param data body dto.WaybillGetByWaybillPdfReq true "data"
  1075. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  1076. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  1077. // @Router /api/waybill/temperature-pdf [post]
  1078. // @Security Bearer
  1079. func (e WaybillController) TemperaturePDF(c *gin.Context) {
  1080. s := service.Waybill{}
  1081. companySvc := service.Company{}
  1082. req := dto.WaybillGetByWaybillPdfReq{}
  1083. err := e.MakeContext(c).
  1084. MakeOrm().
  1085. Bind(&req, binding.JSON, nil).
  1086. MakeService(&s.Service).
  1087. MakeService(&companySvc.Service).
  1088. Errors
  1089. if err != nil {
  1090. e.Logger.Error(err)
  1091. e.Error(500, err, err.Error())
  1092. return
  1093. }
  1094. var waybill model.Waybill
  1095. err = s.GetByWaybillNo(&req, &waybill, nil)
  1096. if err != nil {
  1097. e.Error(500, err, err.Error())
  1098. return
  1099. }
  1100. var company model.SysDept
  1101. err = companySvc.Get(&dto.CompanyGetReq{Id: waybill.DeptId}, &company)
  1102. if err != nil {
  1103. e.Error(500, err, err.Error())
  1104. return
  1105. }
  1106. filename, filePath, err := PDF(s, waybill, company, req.WaybillTaskIds, req.HumidityShow)
  1107. defer func() {
  1108. os.Remove(filePath)
  1109. }()
  1110. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(filename))
  1111. c.Header("Content-Transfer-Encoding", "binary")
  1112. c.File(filePath)
  1113. }
  1114. // TemperaturePDFUrl 导出温度记录pdf链接
  1115. // @Summary 导出温度记录pdf链接
  1116. // @Description 导出温度记录pdf链接
  1117. // @Tags 运单
  1118. // @Accept application/json
  1119. // @Product application/json
  1120. // @Param data body dto.WaybillGetByWaybillPdfReq true "data"
  1121. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  1122. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  1123. // @Router /api/waybill/temperature-pdf [post]
  1124. // @Security Bearer
  1125. func (e WaybillController) TemperaturePDFUrl(c *gin.Context) {
  1126. s := service.Waybill{}
  1127. companySvc := service.Company{}
  1128. req := dto.WaybillGetByWaybillPdfReq{}
  1129. err := e.MakeContext(c).
  1130. MakeOrm().
  1131. Bind(&req, binding.JSON, nil).
  1132. MakeService(&s.Service).
  1133. MakeService(&companySvc.Service).
  1134. Errors
  1135. if err != nil {
  1136. e.Logger.Error(err)
  1137. e.Error(500, err, err.Error())
  1138. return
  1139. }
  1140. var waybill model.Waybill
  1141. err = s.GetByWaybillNo(&req, &waybill, nil)
  1142. if err != nil {
  1143. e.Error(500, err, err.Error())
  1144. return
  1145. }
  1146. var company model.SysDept
  1147. err = companySvc.Get(&dto.CompanyGetReq{Id: waybill.DeptId}, &company)
  1148. if err != nil {
  1149. e.Error(500, err, err.Error())
  1150. return
  1151. }
  1152. filename, filePath, err := PDF(s, waybill, company, req.WaybillTaskIds, req.HumidityShow)
  1153. defer func() {
  1154. os.Remove(filePath)
  1155. }()
  1156. err = file_store.QiniuFileStore.UpLoad(filename, filePath)
  1157. if err != nil {
  1158. c.JSON(400, gin.H{"error": "文件上传失败"})
  1159. return
  1160. }
  1161. e.Custom(gin.H{
  1162. "code": 200,
  1163. "data": conf.ExtConfig.Qiniu.Endpoint + filename,
  1164. "msg": "success",
  1165. })
  1166. }
  1167. func PDF(s service.Waybill, waybill model.Waybill, company model.SysDept, waybillTaskIds []int, humidityShow bool) (filename, filePath string, err error) {
  1168. DeviceSensor_data, Pdf_data, waybillPDF, err := s.GetTwoDeviceSensorData(&dto.WaybillPdfReq{WaybillNo: waybill.WaybillNo, WaybillTaskIds: waybillTaskIds})
  1169. // 最高温度、最低温度、最高湿度、最低湿度
  1170. var maxTemp, minTemp, maxHumidity, minHumidity float32
  1171. // 最高温度时间、最低温度时间、最高湿度时间、最低湿度时间
  1172. var maxTempTime, minTempTime, maxHumidityTime, minHumidityTime string
  1173. // 总温度 总湿度
  1174. var totalTemp, totalHumidity float32
  1175. // 平均温度 平均湿度
  1176. var avgTemp, avgHumidity float32
  1177. // 温度阈值,湿度阈值
  1178. var tempThreshold, humidityThreshold string
  1179. // 记录开始时间,记录结束时间
  1180. var s_time, e_time string
  1181. if len(DeviceSensor_data) > 0 {
  1182. tempThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_tl, DeviceSensor_data[0].T_tu)
  1183. humidityThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_rhl, DeviceSensor_data[0].T_rhu)
  1184. s_time = DeviceSensor_data[0].T_time
  1185. e_time = DeviceSensor_data[len(DeviceSensor_data)-1].T_time
  1186. // 最高温度及时刻
  1187. maxTemp = DeviceSensor_data[0].T_t
  1188. maxTempTime = DeviceSensor_data[0].T_time
  1189. // 最低温度及时刻
  1190. minTemp = DeviceSensor_data[0].T_t
  1191. minTempTime = DeviceSensor_data[0].T_time
  1192. // 最高湿度及时刻
  1193. maxHumidity = DeviceSensor_data[0].T_rh
  1194. maxHumidityTime = DeviceSensor_data[0].T_time
  1195. // 获取最低湿度及时刻
  1196. minHumidity = DeviceSensor_data[0].T_rh
  1197. minHumidityTime = DeviceSensor_data[0].T_time
  1198. for i := 0; i < len(DeviceSensor_data); i++ {
  1199. data := DeviceSensor_data[i]
  1200. if data.T_t > maxTemp {
  1201. maxTemp = data.T_t
  1202. maxTempTime = data.T_time
  1203. }
  1204. if data.T_t < minTemp {
  1205. minTemp = data.T_t
  1206. minTempTime = data.T_time
  1207. }
  1208. totalTemp += data.T_t
  1209. if data.T_rh > maxHumidity {
  1210. maxHumidity = data.T_rh
  1211. maxHumidityTime = data.T_time
  1212. }
  1213. if data.T_rh < minHumidity {
  1214. minHumidity = data.T_rh
  1215. minHumidityTime = data.T_time
  1216. }
  1217. totalHumidity += data.T_rh
  1218. }
  1219. // 平均温度
  1220. avgTemp = totalTemp / float32(len(DeviceSensor_data))
  1221. // 平均湿度
  1222. avgHumidity = totalHumidity / float32(len(DeviceSensor_data))
  1223. }
  1224. // -------------------获取最高温湿度、温蒂温湿度、平均温湿度结束
  1225. pdf := &gopdf.GoPdf{}
  1226. pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
  1227. err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf")
  1228. if err != nil {
  1229. return
  1230. }
  1231. err = pdf.SetFont("wts", "", 20)
  1232. if err != nil {
  1233. return
  1234. }
  1235. pdf.SetGrayFill(0.5)
  1236. pdf.SetMargins(0, 20, 0, 20)
  1237. pdf.AddPage()
  1238. var fileName2 string
  1239. if len(company.Logo) > 0 {
  1240. imgH, errImg := lib.GetImage(company.Logo)
  1241. if errImg != nil {
  1242. err = errors.New("获取图片失败")
  1243. return
  1244. }
  1245. imgWidth := float64(imgH.Bounds().Dx())
  1246. imgHeight := float64(imgH.Bounds().Dy())
  1247. H := 60.
  1248. W := (imgWidth * H) / imgHeight
  1249. if strings.Contains(company.Logo, ".png") {
  1250. err = pdf.ImageFrom(imgH, 10, 0, &gopdf.Rect{W: W, H: H})
  1251. if err != nil {
  1252. err = errors.New("写入图片失败")
  1253. return
  1254. }
  1255. } else {
  1256. fileName := "./ofile/" + time.Now().Format("20060102150405") + ".png"
  1257. f, _ := os.Create(fileName)
  1258. defer f.Close()
  1259. defer func() {
  1260. os.Remove(fileName)
  1261. }()
  1262. png.Encode(f, imgH)
  1263. err = pdf.Image(fileName, 10, 0, &gopdf.Rect{W: W, H: H})
  1264. if err != nil {
  1265. if err.Error() == "16-bit depth not supported" {
  1266. fileName2 = "./ofile/" + time.Now().Format("20060102150405") + ".png"
  1267. f2, _ := os.Create(fileName2)
  1268. defer f.Close()
  1269. defer func() {
  1270. os.Remove(fileName2)
  1271. }()
  1272. jpeg.Encode(f2, imgH, &jpeg.Options{100})
  1273. err = pdf.Image(fileName2, 10, 0, &gopdf.Rect{W: W, H: H})
  1274. }
  1275. if err != nil {
  1276. err = errors.New("写入图片失败")
  1277. return
  1278. }
  1279. }
  1280. }
  1281. }
  1282. var imgHSeal image.Image
  1283. var existSealImg bool
  1284. if len(company.Seal) > 0 {
  1285. existSealImg = true
  1286. var errImg error
  1287. imgHSeal, errImg = lib.GetImage(company.Seal)
  1288. if errImg != nil {
  1289. err = errors.New("获取图片失败")
  1290. return
  1291. }
  1292. }
  1293. title := "运单" + waybill.WaybillNo + "温度记录"
  1294. if humidityShow {
  1295. title = "运单" + waybill.WaybillNo + "温湿度记录"
  1296. }
  1297. var y float64 = 70
  1298. textw, _ := pdf.MeasureTextWidth(title)
  1299. pdf.SetX((595 / 2) - (textw / 2))
  1300. pdf.SetY(y)
  1301. pdf.Text(title)
  1302. y += 30
  1303. pdf.SetFont("wts", "", 16)
  1304. pdf.SetXY(10, y)
  1305. pdf.Text("记录概要信息")
  1306. // 线
  1307. y += 10
  1308. pdf.SetLineWidth(0.5)
  1309. pdf.SetStrokeColor(169, 169, 169)
  1310. pdf.Line(10, y, 585, y)
  1311. y += 20
  1312. pdf.SetFont("wts", "", 10)
  1313. pdf.SetXY(10, y)
  1314. pdf.Text(fmt.Sprintf("记录开始时间:%s", s_time))
  1315. pdf.SetXY(240, y)
  1316. pdf.Text(fmt.Sprintf("记录结束时间:%s", e_time))
  1317. sTime, _ := lib.TimeStrToTime(s_time)
  1318. eTime, _ := lib.TimeStrToTime(e_time)
  1319. pdf.SetXY(470, y)
  1320. minutes := int(eTime.Sub(sTime).Minutes())
  1321. hours := minutes / 60
  1322. remainingMinutes := minutes % 60
  1323. pdf.Text(fmt.Sprintf("记录总时间:%dh%dmin", hours, remainingMinutes))
  1324. // -------------最高温/湿度 最低温/湿度 平均温/湿度
  1325. y += 15
  1326. pdf.SetXY(10, y)
  1327. pdf.Text(fmt.Sprintf("最高温度:%.1f℃,%s", lib.RoundToDecimal(float64(maxTemp), 1), maxTempTime))
  1328. pdf.SetXY(240, y)
  1329. pdf.Text(fmt.Sprintf("最低温度:%.1f℃,%s", lib.RoundToDecimal(float64(minTemp), 1), minTempTime))
  1330. pdf.SetXY(470, y)
  1331. pdf.Text(fmt.Sprintf("平均温度:%.1f℃", lib.RoundToDecimal(float64(avgTemp), 1)))
  1332. if humidityShow {
  1333. y += 15
  1334. pdf.SetXY(10, y)
  1335. pdf.Text(fmt.Sprintf("最高湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(maxHumidity), 1), maxHumidityTime))
  1336. pdf.SetXY(240, y)
  1337. pdf.Text(fmt.Sprintf("最低湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(minHumidity), 1), minHumidityTime))
  1338. pdf.SetXY(470, y)
  1339. pdf.Text(fmt.Sprintf("平均湿度:%.1f%%RH", lib.RoundToDecimal(float64(avgHumidity), 1)))
  1340. }
  1341. // -------------温/湿度阈值
  1342. y += 15
  1343. pdf.SetXY(10, y)
  1344. pdf.Text(fmt.Sprintf("温度阈值:%s℃", tempThreshold))
  1345. if humidityShow {
  1346. pdf.SetXY(240, y)
  1347. pdf.Text(fmt.Sprintf("温度阈值:%s%%", humidityThreshold))
  1348. }
  1349. //-------------发货单位,收货单位,备注
  1350. y += 15
  1351. pdf.SetXY(10, y)
  1352. T_forwarding_unit_temp := []rune(waybill.SenderAddressName)
  1353. if len(T_forwarding_unit_temp) > 17 {
  1354. pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp[0:17])))
  1355. pdf.SetXY(60, y+15)
  1356. pdf.Text(fmt.Sprintf("%s", string(T_forwarding_unit_temp[17:])))
  1357. } else {
  1358. pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp)))
  1359. }
  1360. pdf.SetXY(240, y)
  1361. T_consignee_unit_temp := []rune(waybill.ConsigneeAddressName)
  1362. if len(T_consignee_unit_temp) > 17 {
  1363. pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp[0:17])))
  1364. pdf.SetXY(290, y+15)
  1365. pdf.Text(fmt.Sprintf("%s", string(T_consignee_unit_temp[17:])))
  1366. } else {
  1367. pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp)))
  1368. }
  1369. // 承运方
  1370. y += 15
  1371. pdf.SetXY(10, y)
  1372. company_name := []rune(waybill.Dept.Name)
  1373. pdf.Text(fmt.Sprintf("承运方:%s", string(company_name)))
  1374. y += 15
  1375. pdf.SetXY(10, y)
  1376. T_remark_temp := []rune(waybill.Remark)
  1377. if len(T_remark_temp) > 35 {
  1378. pdf.Text(fmt.Sprintf("备注:%s", string(T_remark_temp[0:35])))
  1379. pdf.SetXY(10, y+15)
  1380. pdf.Text(fmt.Sprintf("%s", string(T_remark_temp[35:])))
  1381. } else {
  1382. pdf.Text(fmt.Sprintf("备注: %s", string(T_remark_temp)))
  1383. }
  1384. y += 35
  1385. pdf.SetFont("wts", "", 16)
  1386. pdf.SetXY(10, y)
  1387. pdf.Text("记录曲线信息")
  1388. // 线
  1389. y += 10
  1390. pdf.SetLineWidth(0.5)
  1391. pdf.SetStrokeColor(169, 169, 169)
  1392. pdf.Line(10, y, 585, y)
  1393. y += 1
  1394. var tempFilepath string
  1395. tempFilepath, err = DeviceDataTemperatureJPG(s_time, e_time, waybillPDF)
  1396. if err == nil {
  1397. imgH, _ := gopdf.ImageHolderByPath(tempFilepath)
  1398. pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
  1399. y += 315
  1400. }
  1401. //var humidityFilepath string
  1402. //if req.HumidityShow {
  1403. // humidityFilepath, err = DeviceDataHumidityJPG2(s_time, e_time, waybillPDF)
  1404. // if err == nil {
  1405. // imgH, _ := gopdf.ImageHolderByPath(humidityFilepath)
  1406. // pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
  1407. // y += 315
  1408. // }
  1409. //}
  1410. if y > 841.89 {
  1411. // 图片结束直接分页
  1412. addStampImage(pdf, existSealImg, imgHSeal, 455, 660)
  1413. pdf.AddPage()
  1414. y = 20
  1415. }
  1416. y += 20
  1417. pdf.SetFont("wts", "", 16)
  1418. pdf.SetXY(10, y)
  1419. pdf.Text("记录数据信息")
  1420. // 线
  1421. y += 10
  1422. pdf.SetLineWidth(0.5)
  1423. pdf.SetStrokeColor(169, 169, 169)
  1424. pdf.Line(10, y, 585, y)
  1425. y += 10
  1426. pdf.SetFont("wts", "", 10)
  1427. var x float64 = 12
  1428. var w float64 = 110
  1429. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1430. x = x + w
  1431. w = 100
  1432. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1433. x = x + w
  1434. w = 37
  1435. lib.RectFillColor(pdf, "T1", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1436. x = x + w
  1437. lib.RectFillColor(pdf, "T2", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1438. x = x + w
  1439. w = 110
  1440. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1441. x = x + w
  1442. w = 100
  1443. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1444. x = x + w
  1445. w = 37
  1446. lib.RectFillColor(pdf, "T1", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1447. x = x + w
  1448. lib.RectFillColor(pdf, "T2", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1449. for i, v := range Pdf_data {
  1450. if i%2 == 0 {
  1451. y += 20
  1452. //var textH float64 = 25 // if text height is 25px.
  1453. //pdf.SetNewY(y, textH)
  1454. if y > 800 {
  1455. addStampImage(pdf, existSealImg, imgHSeal, 455, y-130)
  1456. pdf.AddPage()
  1457. y = 20
  1458. x = 12
  1459. w = 110
  1460. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1461. x = x + w
  1462. w = 100
  1463. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1464. x = x + w
  1465. w = 37
  1466. lib.RectFillColor(pdf, "T1", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1467. x = x + w
  1468. lib.RectFillColor(pdf, "T2", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1469. x = x + w
  1470. w = 110
  1471. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1472. x = x + w
  1473. w = 100
  1474. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1475. x = x + w
  1476. w = 37
  1477. lib.RectFillColor(pdf, "T1", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1478. x = x + w
  1479. lib.RectFillColor(pdf, "T2", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1480. y += 20
  1481. }
  1482. //y = pdf.GetY()
  1483. x, w = 12, 110
  1484. lib.RectFillColor(pdf, v.T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1485. x = x + w
  1486. w = 100
  1487. lib.RectFillColor(pdf, v.T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1488. x = x + w
  1489. w = 37
  1490. lib.RectFillColor(pdf, lib.Float32_to_string_forPDF(v.T_id1), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1491. x = x + w
  1492. lib.RectFillColor(pdf, lib.Float32_to_string_forPDF(v.T_id2), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1493. }
  1494. if i%2 == 1 {
  1495. x = x + w
  1496. w = 110
  1497. lib.RectFillColor(pdf, v.T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1498. x = x + w
  1499. w = 100
  1500. lib.RectFillColor(pdf, v.T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1501. x = x + w
  1502. w = 37
  1503. lib.RectFillColor(pdf, lib.Float32_to_string_forPDF(v.T_id1), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1504. x = x + w
  1505. lib.RectFillColor(pdf, lib.Float32_to_string_forPDF(v.T_id2), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1506. }
  1507. }
  1508. if y <= 800 {
  1509. if y < 150 {
  1510. y = 20
  1511. } else {
  1512. y = y - 130
  1513. }
  1514. addStampImage(pdf, existSealImg, imgHSeal, 455, y)
  1515. }
  1516. filename = "运单" + waybill.WaybillNo + "温度记录" + time.Now().Format("20060102150405") + ".pdf"
  1517. filePath = "ofile/" + filename
  1518. err = pdf.WritePdf(filePath)
  1519. if err != nil {
  1520. return
  1521. }
  1522. defer func() {
  1523. os.Remove(tempFilepath)
  1524. os.Remove(fileName2)
  1525. }()
  1526. return filename, filePath, nil
  1527. }
  1528. // WaybillPDF 导出运单pdf
  1529. // @Summary 导出运单pdf
  1530. // @Description 导出运单pdf
  1531. // @Tags 运单
  1532. // @Param waybillNo query string false "运单号"
  1533. // @Param pageSize query int false "页条数"
  1534. // @Param page query int false "页码"
  1535. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  1536. // @Router /api/waybill/waybill-pdf [get]
  1537. // @Security Bearer
  1538. func (e WaybillController) WaybillPDF(c *gin.Context) {
  1539. s := service.Waybill{}
  1540. companySvc := service.Company{}
  1541. req := dto.WaybillGetByWaybillPdfReq{}
  1542. err := e.MakeContext(c).
  1543. MakeOrm().
  1544. Bind(&req, binding.Query).
  1545. MakeService(&s.Service).
  1546. MakeService(&companySvc.Service).
  1547. Errors
  1548. if err != nil {
  1549. e.Logger.Error(err)
  1550. e.Error(500, err, err.Error())
  1551. return
  1552. }
  1553. var waybill model.Waybill
  1554. var company model.SysDept
  1555. //err = s.GetByWaybillNo(&req, &waybill, p)
  1556. err = s.GetByWaybillNo(&req, &waybill, nil)
  1557. if err != nil {
  1558. e.Error(500, err, err.Error())
  1559. return
  1560. }
  1561. err = companySvc.Get(&dto.CompanyGetReq{Id: waybill.DeptId}, &company)
  1562. if err != nil {
  1563. e.Error(500, err, err.Error())
  1564. return
  1565. }
  1566. // -------------------生成运单条码
  1567. // 运单条码
  1568. cs, _ := code128.Encode(waybill.WaybillNo)
  1569. // 创建一个要输出数据的文件
  1570. imgPath := "ofile/img/" + waybill.WaybillNo + ".png"
  1571. file, _ := os.Create(imgPath)
  1572. defer file.Close()
  1573. // 设置图片像素大小
  1574. barCode, _ := barcode.Scale(cs, 205, 50)
  1575. // 将code128的条形码编码为png图片
  1576. png.Encode(file, barCode)
  1577. imgPath2 := "ofile/img/" + waybill.WaybillNo + ".jpg"
  1578. png2j.Con2jpg(imgPath, imgPath2)
  1579. qrcode, err := qrcode.Encode(fmt.Sprintf("%s/WaybillInquiry?waybillNo=%s", conf.ExtConfig.Service.Domain, waybill.WaybillNo),
  1580. qrcode.Medium, 70)
  1581. if err != nil {
  1582. e.Error(500, err, err.Error())
  1583. return
  1584. }
  1585. qrCodeImgH, err := gopdf.ImageHolderByBytes(qrcode)
  1586. if err != nil {
  1587. e.Error(500, err, err.Error())
  1588. return
  1589. }
  1590. pdf := &gopdf.GoPdf{}
  1591. pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 283.46, H: 283.46}}) //595.28, 841.89 = A4
  1592. //pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
  1593. err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf")
  1594. if err != nil {
  1595. return
  1596. }
  1597. pdf.SetGrayFill(0.5)
  1598. pdf.SetMargins(0, 10, 0, 10)
  1599. for i := 0; i < waybill.Quantity; i++ {
  1600. pdf.AddPage()
  1601. var y float64 = 20
  1602. pdf.SetFont("wts", "", 10)
  1603. //y += 12
  1604. pdf.SetXY(250, 20)
  1605. pdf.SetFont("wts", "", 13)
  1606. if waybill.Quantity > 1 {
  1607. pdf.Text(fmt.Sprintf("%d/%d", i+1, waybill.Quantity))
  1608. }
  1609. pdf.SetFont("wts", "", 10)
  1610. y += 10
  1611. pdf.Image(imgPath2, 20, y, &gopdf.Rect{W: 240, H: 30})
  1612. y += 43
  1613. textw, _ := pdf.MeasureTextWidth(waybill.WaybillNo)
  1614. pdf.SetX((283.46 / 2) - (textw / 2))
  1615. pdf.SetY(y)
  1616. pdf.Text(waybill.WaybillNo)
  1617. if len(company.Logo) > 0 {
  1618. imgH, errImg := lib.GetImage(company.Logo)
  1619. if errImg != nil {
  1620. err = errors.New("获取图片失败")
  1621. e.Error(500, err, err.Error())
  1622. return
  1623. }
  1624. imgWidth := float64(imgH.Bounds().Dx())
  1625. imgHeight := float64(imgH.Bounds().Dy())
  1626. H := 30.
  1627. W := (imgWidth * H) / imgHeight
  1628. if strings.Contains(company.Logo, ".png") {
  1629. err = pdf.ImageFrom(imgH, 10, 0, &gopdf.Rect{W: W, H: H})
  1630. if err != nil {
  1631. err = errors.New("写入图片失败")
  1632. e.Error(500, err, err.Error())
  1633. return
  1634. }
  1635. } else {
  1636. fileName := "./ofile/" + time.Now().Format("20060102150405") + ".png"
  1637. f, _ := os.Create(fileName)
  1638. defer f.Close()
  1639. defer func() {
  1640. os.Remove(fileName)
  1641. }()
  1642. png.Encode(f, imgH)
  1643. err = pdf.Image(fileName, 10, 0, &gopdf.Rect{W: W, H: H})
  1644. if err != nil {
  1645. if err.Error() == "16-bit depth not supported" {
  1646. fileName2 := "./ofile/" + time.Now().Format("20060102150405") + ".png"
  1647. f2, _ := os.Create(fileName2)
  1648. defer f.Close()
  1649. defer func() {
  1650. os.Remove(fileName2)
  1651. }()
  1652. jpeg.Encode(f2, imgH, &jpeg.Options{100})
  1653. err = pdf.Image(fileName2, 10, 0, &gopdf.Rect{W: W, H: H})
  1654. }
  1655. if err != nil {
  1656. err = errors.New("写入图片失败")
  1657. e.Error(500, err, err.Error())
  1658. return
  1659. }
  1660. }
  1661. }
  1662. } else {
  1663. title := "#" + company.Name
  1664. pdf.SetXY(10, 20)
  1665. pdf.Text(title)
  1666. }
  1667. // 线
  1668. y += 6
  1669. pdf.SetLineWidth(0.5)
  1670. pdf.SetLineType("dotted")
  1671. pdf.Line(10, y, 273, y)
  1672. y += 28
  1673. pdf.SetFont("wts", "", 18)
  1674. pdf.SetXY(12, y+3)
  1675. pdf.Text("收")
  1676. pdf.SetFont("wts", "", 10)
  1677. y -= 5
  1678. pdf.SetXY(40, y)
  1679. pdf.Text(fmt.Sprintf("%s %s", lib.MaskStr(waybill.ConsigneeAddressName), lib.MaskPhoneNumber(waybill.ConsigneeAddressPhone)))
  1680. y += 15
  1681. pdf.SetXY(40, y)
  1682. pdf.Text(waybill.ConsigneeAddressDetails)
  1683. // 线
  1684. y += 8
  1685. pdf.SetLineWidth(0.5)
  1686. pdf.SetLineType("dotted")
  1687. pdf.Line(10, y, 273, y)
  1688. y += 22
  1689. pdf.SetFont("wts", "", 13)
  1690. pdf.SetXY(14, y+3)
  1691. pdf.Text("寄")
  1692. pdf.SetFont("wts", "", 10)
  1693. y -= 5
  1694. pdf.SetXY(40, y)
  1695. pdf.Text(fmt.Sprintf("%s %s", lib.MaskStr(waybill.SenderAddressName), lib.MaskPhoneNumber(waybill.SenderAddressPhone)))
  1696. y += 15
  1697. pdf.SetXY(40, y)
  1698. pdf.Text(waybill.SenderAddressDetails)
  1699. // 线
  1700. y += 10
  1701. pdf.SetLineWidth(0.5)
  1702. //pdf.SetLineType("dashed")
  1703. pdf.SetLineType("dotted")
  1704. pdf.Line(10, y, 273, y)
  1705. y += 12
  1706. pdf.SetXY(10, y)
  1707. pdf.SetFont("wts", "", 8)
  1708. pdf.Text("下单时间:" + waybill.OrderTime.String())
  1709. // 线
  1710. y += 6
  1711. pdf.SetLineWidth(0.5)
  1712. pdf.SetLineType("dotted")
  1713. pdf.Line(10, y, 273, y)
  1714. pdf.SetFont("wts", "", 10)
  1715. y += 20
  1716. pdf.SetXY(10, y)
  1717. pdf.Text("备注:")
  1718. pdf.SetFont("wts", "", 8)
  1719. y += 15
  1720. pdf.SetXY(30, y)
  1721. pdf.Text("货物类型:" + waybill.CargoType)
  1722. y += 15
  1723. pdf.SetXY(30, y)
  1724. pdf.Text("温度要求:" + waybill.TemperatureInterval)
  1725. y += 15
  1726. pdf.SetXY(30, y)
  1727. pdf.Text("配送要求:" + waybill.DeliveryCondition)
  1728. x := 170.
  1729. //pdf.Image(qrcodeImgPath2, x, y-55, &gopdf.Rect{W: 70, H: 70})
  1730. pdf.ImageByHolder(qrCodeImgH, x, y-63, &gopdf.Rect{W: 70, H: 70})
  1731. pdf.SetFont("wts", "", 8)
  1732. y += 10
  1733. textw, _ = pdf.MeasureTextWidth("扫码查询")
  1734. pdf.SetX(x + 35 - (textw / 2))
  1735. pdf.SetY(y)
  1736. pdf.Text("扫码查询")
  1737. y += 10
  1738. textw, _ = pdf.MeasureTextWidth("物流温湿度信息")
  1739. pdf.SetX(x + 35 - (textw / 2))
  1740. pdf.SetY(y)
  1741. pdf.Text("物流温湿度信息")
  1742. }
  1743. filename := "运单" + req.WaybillNo + ".pdf"
  1744. filePath := "ofile/" + filename
  1745. err = pdf.WritePdf(filePath)
  1746. if err != nil {
  1747. return
  1748. }
  1749. defer func() {
  1750. os.Remove(filePath)
  1751. os.Remove(imgPath)
  1752. os.Remove(imgPath2)
  1753. }()
  1754. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(filename))
  1755. c.Header("Content-Transfer-Encoding", "binary")
  1756. c.File(filePath)
  1757. }
  1758. // SendMail 发送邮件
  1759. // @Summary 发送邮件
  1760. // @Description 发送邮件
  1761. // @Tags 运单
  1762. // @Param data body dto.WaybillSendMailPdfReq true "data"
  1763. // @Success 200 {object} response.Response{data=model.Waybill} "{"code": 200, "data": [...]}"
  1764. // @Router /api/waybill/send-mail [post]
  1765. // @Security Bearer
  1766. func (e WaybillController) SendMail(c *gin.Context) {
  1767. s := service.Waybill{}
  1768. companySvc := service.Company{}
  1769. req := dto.WaybillSendMailPdfReq{}
  1770. err := e.MakeContext(c).
  1771. MakeOrm().
  1772. Bind(&req, binding.JSON, nil).
  1773. MakeService(&s.Service).
  1774. MakeService(&companySvc.Service).
  1775. Errors
  1776. if err != nil {
  1777. e.Logger.Error(err)
  1778. e.Error(500, err, err.Error())
  1779. return
  1780. }
  1781. var waybill model.Waybill
  1782. err = s.GetByWaybillNo(&dto.WaybillGetByWaybillPdfReq{WaybillNo: req.WaybillNo, HumidityShow: req.HumidityShow}, &waybill, nil)
  1783. if err != nil {
  1784. e.Error(500, err, err.Error())
  1785. return
  1786. }
  1787. var company model.SysDept
  1788. err = companySvc.Get(&dto.CompanyGetReq{Id: waybill.DeptId}, &company)
  1789. if err != nil {
  1790. e.Error(500, err, err.Error())
  1791. return
  1792. }
  1793. _, filePath, err := PDF(s, waybill, company, req.WaybillTaskIds, req.HumidityShow)
  1794. defer func() {
  1795. os.Remove(filePath)
  1796. }()
  1797. em := email.NewEmail()
  1798. em.From = "冷链物流运输 <bzdcold@163.com>"
  1799. em.To = req.To
  1800. em.Subject = fmt.Sprintf("【冷链物流运输】运单%s温湿度记录", waybill.WaybillNo)
  1801. em.Text = []byte(fmt.Sprintf("运单%s温湿度记录", waybill.WaybillNo))
  1802. // 主要就是在这个位置添加了附件,注意:这里AttachFile是Email结构体的方法而不是字段,所以不是用等于而是括号
  1803. em.AttachFile(filePath)
  1804. err = em.Send("smtp.163.com:25", smtp.PlainAuth("", "bzdcold@163.com", "ZIZXBCDKVTMPJMVX", "smtp.163.com"))
  1805. if err != nil {
  1806. e.Logger.Error(err)
  1807. e.Error(500, err, err.Error())
  1808. return
  1809. }
  1810. e.OK(nil, "发送成功")
  1811. }
  1812. // 获取温度图片
  1813. func DeviceDataTemperatureJPG(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  1814. if len(waybillPDF) == 0 {
  1815. return "", errors.New("暂无数据可生成图片")
  1816. }
  1817. deviceSensorList := []nats_server.DeviceSensor_R{}
  1818. dataList := []nats_server.DeviceData_R{}
  1819. deviceDataPdfList := []service.DeviceDataPdf{}
  1820. for _, w := range waybillPDF {
  1821. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  1822. dataList = append(dataList, w.Data...)
  1823. deviceDataPdfList = append(deviceDataPdfList, w.DeviceDataPdf...)
  1824. }
  1825. TemperatureMin := deviceSensorList[0].T_DeviceSensorParameter.T_Tlower
  1826. TemperatureMax := deviceSensorList[0].T_DeviceSensorParameter.T_Tupper
  1827. var ymin, ymax float32
  1828. for i, r := range dataList {
  1829. if i == 0 {
  1830. ymin = r.T_t
  1831. ymax = r.T_t
  1832. }
  1833. if ymin > r.T_t {
  1834. ymin = r.T_t
  1835. }
  1836. if ymax < r.T_t {
  1837. ymax = r.T_t
  1838. }
  1839. }
  1840. sort.Slice(deviceDataPdfList, func(i, j int) bool {
  1841. return deviceDataPdfList[i].T_time < deviceDataPdfList[j].T_time
  1842. })
  1843. series := make([]chart.Series, 0)
  1844. // 创建温度线
  1845. xValues1 := make([]time.Time, len(deviceDataPdfList))
  1846. xValues2 := make([]time.Time, 0)
  1847. yValues1 := make([]float64, len(deviceDataPdfList))
  1848. yValues2 := make([]float64, len(deviceDataPdfList))
  1849. for i := 0; i < len(deviceDataPdfList); i++ {
  1850. t, _ := lib.TimeStrToTime(deviceDataPdfList[i].T_time)
  1851. xValues1[i] = t
  1852. if deviceDataPdfList[i].T_id1 != nil {
  1853. yValues1[i] = float64(*deviceDataPdfList[i].T_id1)
  1854. }
  1855. if deviceDataPdfList[i].T_id2 != nil {
  1856. xValues2 = append(xValues2, t)
  1857. yValues2[i] = float64(*deviceDataPdfList[i].T_id2)
  1858. }
  1859. }
  1860. series = append(series, chart.TimeSeries{
  1861. Name: "T1",
  1862. XValues: xValues1,
  1863. YValues: yValues1,
  1864. })
  1865. series = append(series, chart.TimeSeries{
  1866. Name: "T2",
  1867. XValues: xValues2,
  1868. YValues: yValues2,
  1869. })
  1870. if ymax < TemperatureMax {
  1871. ymax = TemperatureMax
  1872. }
  1873. if ymin > 0 {
  1874. ymin = 0
  1875. }
  1876. if ymin > TemperatureMin {
  1877. ymin = TemperatureMin
  1878. }
  1879. st, _ := lib.TimeStrToTime(startTime)
  1880. et, _ := lib.TimeStrToTime(endTime)
  1881. series = append(series, chart.TimeSeries{
  1882. Style: chart.Style{
  1883. StrokeColor: drawing.ColorRed,
  1884. StrokeDashArray: []float64{5.0, 5.0},
  1885. },
  1886. XValues: []time.Time{st, et},
  1887. YValues: []float64{float64(TemperatureMin), float64(TemperatureMin)},
  1888. })
  1889. series = append(series, chart.TimeSeries{
  1890. Style: chart.Style{
  1891. StrokeColor: drawing.ColorRed,
  1892. StrokeDashArray: []float64{5.0, 5.0},
  1893. },
  1894. XValues: []time.Time{st, et},
  1895. YValues: []float64{float64(TemperatureMax), float64(TemperatureMax)},
  1896. })
  1897. font := getZWFont()
  1898. graph := chart.Chart{
  1899. Title: "温度记录",
  1900. TitleStyle: chart.Style{
  1901. FontSize: 14,
  1902. },
  1903. Background: chart.Style{
  1904. Padding: chart.Box{
  1905. Top: 20,
  1906. },
  1907. },
  1908. Font: font,
  1909. XAxis: chart.XAxis{
  1910. Name: "时间",
  1911. ValueFormatter: chart.TimeValueFormatterWithFormat("2006-01-02 15:04"),
  1912. },
  1913. YAxis: chart.YAxis{
  1914. Name: "温度",
  1915. Range: &chart.ContinuousRange{
  1916. Min: float64(ymin),
  1917. Max: float64(ymax + 2),
  1918. },
  1919. },
  1920. Series: series,
  1921. }
  1922. //graph.Elements = []chart.Renderable{
  1923. // chart.Legend(&graph),
  1924. //}
  1925. filepath := "ofile/" + "temperature" + deviceSensorList[0].T_sn + ".jpg"
  1926. f, _ := os.Create(filepath)
  1927. defer f.Close()
  1928. graph.Render(chart.PNG, f)
  1929. return filepath, nil
  1930. }
  1931. // getZWFont 加载字体
  1932. func getZWFont() *truetype.Font {
  1933. fontFile := "./static/fonts/MiSans-Medium.ttf"
  1934. fontBytes, err := os.ReadFile(fontFile)
  1935. if err != nil {
  1936. log.Println(err)
  1937. return nil
  1938. }
  1939. font, err := truetype.Parse(fontBytes)
  1940. if err != nil {
  1941. log.Println(err)
  1942. return nil
  1943. }
  1944. return font
  1945. }
  1946. func addStampImage(pdf *gopdf.GoPdf, existSealImg bool, imgHSeal image.Image, x, y float64) {
  1947. if !existSealImg {
  1948. return
  1949. }
  1950. if x < 10 {
  1951. x = 10
  1952. }
  1953. if y < 20 {
  1954. y = 20
  1955. }
  1956. err := pdf.ImageFrom(imgHSeal, x, y, &gopdf.Rect{W: 123, H: 128.6})
  1957. if err != nil {
  1958. log.Print(err.Error())
  1959. }
  1960. }