waybill.go 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160
  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. // Transfer 运单转箱
  921. // @Summary 运单转箱
  922. // @Description 运单转箱
  923. // @Tags 运单
  924. // @Accept application/json
  925. // @Product application/json
  926. // @Param data body dto.WaybillInsertReq true "data"
  927. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  928. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  929. // @Router /api/waybill/transfer [post]
  930. // @Security Bearer
  931. func (e WaybillController) Transfer(c *gin.Context) {
  932. s := service.Waybill{}
  933. userSvc := service.SysUser{}
  934. req := dto.WaybillTransfer{}
  935. err := e.MakeContext(c).
  936. MakeOrm().
  937. Bind(&req, binding.JSON).
  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. p := actions.GetPermissionFromContext(c)
  947. err = s.TransferBox(&req, p)
  948. if err != nil {
  949. e.Error(500, err, err.Error())
  950. return
  951. }
  952. e.OK(req.OldCoolerBoxId, "转箱成功")
  953. }
  954. // Import 导入运单
  955. // @Summary 导入运单
  956. // @Description 导入运单
  957. // @Tags 运单
  958. // @Accept application/json
  959. // @Product application/json
  960. // @Param data body dto.WaybillImportReq true "data"
  961. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  962. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  963. // @Router /api/waybill/import [post]
  964. // @Security Bearer
  965. func (e WaybillController) Import(c *gin.Context) {
  966. s := service.Waybill{}
  967. userSvc := service.SysUser{}
  968. req := dto.WaybillImportReq{}
  969. err := e.MakeContext(c).
  970. MakeOrm().
  971. Bind(&req, binding.Form).
  972. MakeService(&s.Service).
  973. MakeService(&userSvc.Service).
  974. Errors
  975. if err != nil {
  976. e.Logger.Error(err)
  977. e.Error(500, err, err.Error())
  978. return
  979. }
  980. //读取第一fileName的文件
  981. fileHeader, err := c.FormFile("file")
  982. if err != nil {
  983. err = errors.New("文件格式错误" + err.Error())
  984. e.Logger.Error(err)
  985. e.Error(500, err, err.Error())
  986. return
  987. }
  988. if fileHeader.Size > 1024*1024*2 {
  989. err = errors.New("文件大小超过2M")
  990. e.Logger.Error(err)
  991. e.Error(500, err, err.Error())
  992. return
  993. }
  994. file, err := fileHeader.Open()
  995. if err != nil {
  996. err = errors.New("文件格式错误" + err.Error())
  997. e.Logger.Error(err)
  998. e.Error(500, err, err.Error())
  999. return
  1000. }
  1001. defer file.Close()
  1002. xlsx, err := excelize.OpenReader(bufio.NewReader(file))
  1003. if err != nil {
  1004. err = errors.New("文件格式错误" + err.Error())
  1005. e.Logger.Error(err)
  1006. e.Error(500, err, err.Error())
  1007. return
  1008. }
  1009. p := actions.GetPermissionFromContext(c)
  1010. if p.DeptId == 0 {
  1011. e.Error(500, err, "获取用户信息失败")
  1012. return
  1013. }
  1014. var userObj model.SysUser
  1015. err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
  1016. if err != nil {
  1017. e.Error(500, err, "获取用户信息失败")
  1018. return
  1019. }
  1020. var customerId int
  1021. //customerName := req.CustomerName
  1022. if userObj.UserType == model.UserTypeCustomer {
  1023. customerId = userObj.Id
  1024. //customerName = userObj.NickName
  1025. }
  1026. rows, _ := xlsx.GetRows("Sheet1")
  1027. for indexRow, row := range rows {
  1028. if indexRow == 0 {
  1029. continue
  1030. }
  1031. if len(row) < 12 {
  1032. for i := 0; i < 12-len(row); i++ {
  1033. row = append(row, "")
  1034. }
  1035. }
  1036. for i, colCell := range row {
  1037. fmt.Println(i, ":", colCell)
  1038. }
  1039. quantity, _ := strconv.Atoi(row[10])
  1040. obj := dto.WaybillInsertReq{
  1041. Status: 1,
  1042. SenderAddressName: row[0],
  1043. SenderAddressPhone: row[1],
  1044. SenderAddressDetails: row[2],
  1045. CustomerName: row[3],
  1046. ConsigneeAddressName: row[4],
  1047. ConsigneeAddressPhone: row[5],
  1048. ConsigneeAddressDetails: row[6],
  1049. TemperatureInterval: row[7],
  1050. DeliveryCondition: row[8],
  1051. CargoType: row[9],
  1052. Quantity: quantity,
  1053. Remark: row[11],
  1054. CustomerId: customerId,
  1055. }
  1056. obj.SetDeptId(p.DeptId)
  1057. obj.SetCreateBy(user.GetUserId(c))
  1058. err = s.Insert(&obj)
  1059. if err != nil {
  1060. e.Error(500, err, err.Error())
  1061. return
  1062. }
  1063. }
  1064. e.OK(len(rows)-1, "导入成功")
  1065. }
  1066. // ExportTemplate 导出运单模板
  1067. // @Summary 导出运单模板
  1068. // @Description 导出运单模板
  1069. // @Tags 运单
  1070. // @Accept application/json
  1071. // @Product application/json
  1072. // @Router /api/waybill/export-template [post]
  1073. // @Security Bearer
  1074. func (e WaybillController) ExportTemplate(c *gin.Context) {
  1075. s := service.Waybill{}
  1076. err := e.MakeContext(c).
  1077. MakeOrm().
  1078. MakeService(&s.Service).
  1079. Errors
  1080. if err != nil {
  1081. e.Logger.Error(err)
  1082. e.Error(500, err, err.Error())
  1083. return
  1084. }
  1085. filePath := "/ofile/运单导入模板.xlsx"
  1086. //打开文件
  1087. fileTmp, errByOpenFile := os.Open(filePath)
  1088. defer fileTmp.Close()
  1089. //获取文件的名称
  1090. fileName := path.Base(filePath)
  1091. if errByOpenFile != nil {
  1092. e.Logger.Error(err)
  1093. e.Error(500, err, err.Error())
  1094. return
  1095. }
  1096. c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
  1097. // PathEscape 函数对中文做处理
  1098. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(fileName))
  1099. c.Header("Content-Transfer-Encoding", "binary")
  1100. c.File(filePath)
  1101. }
  1102. // TemperaturePDF 导出温度记录pdf
  1103. // @Summary 导出温度记录pdf
  1104. // @Description 导出温度记录pdf
  1105. // @Tags 运单
  1106. // @Accept application/json
  1107. // @Product application/json
  1108. // @Param data body dto.WaybillGetByWaybillPdfReq true "data"
  1109. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  1110. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  1111. // @Router /api/waybill/temperature-pdf [post]
  1112. // @Security Bearer
  1113. func (e WaybillController) TemperaturePDF(c *gin.Context) {
  1114. s := service.Waybill{}
  1115. companySvc := service.Company{}
  1116. req := dto.WaybillGetByWaybillPdfReq{}
  1117. err := e.MakeContext(c).
  1118. MakeOrm().
  1119. Bind(&req, binding.JSON, nil).
  1120. MakeService(&s.Service).
  1121. MakeService(&companySvc.Service).
  1122. Errors
  1123. if err != nil {
  1124. e.Logger.Error(err)
  1125. e.Error(500, err, err.Error())
  1126. return
  1127. }
  1128. var waybill model.Waybill
  1129. err = s.GetByWaybillNo(&req, &waybill, nil)
  1130. if err != nil {
  1131. e.Error(500, err, err.Error())
  1132. return
  1133. }
  1134. var company model.SysDept
  1135. err = companySvc.Get(&dto.CompanyGetReq{Id: waybill.DeptId}, &company)
  1136. if err != nil {
  1137. e.Error(500, err, err.Error())
  1138. return
  1139. }
  1140. req.HumidityShow = false
  1141. filename, filePath, err := PDF(s, waybill, company, req.WaybillTaskIds, req.HumidityShow)
  1142. defer func() {
  1143. os.Remove(filePath)
  1144. }()
  1145. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(filename))
  1146. c.Header("Content-Transfer-Encoding", "binary")
  1147. c.Header("Content-Type", "application/pdf")
  1148. c.File(filePath)
  1149. }
  1150. // TemperaturePDFUrl 导出温度记录pdf链接
  1151. // @Summary 导出温度记录pdf链接
  1152. // @Description 导出温度记录pdf链接
  1153. // @Tags 运单
  1154. // @Accept application/json
  1155. // @Product application/json
  1156. // @Param data body dto.WaybillGetByWaybillPdfReq true "data"
  1157. // @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
  1158. // @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
  1159. // @Router /api/waybill/temperature-pdf [post]
  1160. // @Security Bearer
  1161. func (e WaybillController) TemperaturePDFUrl(c *gin.Context) {
  1162. s := service.Waybill{}
  1163. companySvc := service.Company{}
  1164. req := dto.WaybillGetByWaybillPdfReq{}
  1165. err := e.MakeContext(c).
  1166. MakeOrm().
  1167. Bind(&req, binding.JSON, nil).
  1168. MakeService(&s.Service).
  1169. MakeService(&companySvc.Service).
  1170. Errors
  1171. if err != nil {
  1172. e.Logger.Error(err)
  1173. e.Error(500, err, err.Error())
  1174. return
  1175. }
  1176. var waybill model.Waybill
  1177. err = s.GetByWaybillNo(&req, &waybill, nil)
  1178. if err != nil {
  1179. e.Error(500, err, err.Error())
  1180. return
  1181. }
  1182. var company model.SysDept
  1183. err = companySvc.Get(&dto.CompanyGetReq{Id: waybill.DeptId}, &company)
  1184. if err != nil {
  1185. e.Error(500, err, err.Error())
  1186. return
  1187. }
  1188. filename, filePath, err := PDF(s, waybill, company, req.WaybillTaskIds, req.HumidityShow)
  1189. defer func() {
  1190. os.Remove(filePath)
  1191. }()
  1192. err = file_store.QiniuFileStore.UpLoad(filename, filePath)
  1193. if err != nil {
  1194. c.JSON(400, gin.H{"error": "文件上传失败"})
  1195. return
  1196. }
  1197. e.Custom(gin.H{
  1198. "code": 200,
  1199. "data": conf.ExtConfig.Qiniu.Endpoint + filename,
  1200. "msg": "success",
  1201. })
  1202. }
  1203. func PDF(s service.Waybill, waybill model.Waybill, company model.SysDept, waybillTaskIds []int, humidityShow bool) (filename, filePath string, err error) {
  1204. DeviceSensor_data, Pdf_data, waybillPDF, err := s.GetTwoDeviceSensorData(&dto.WaybillPdfReq{WaybillNo: waybill.WaybillNo, WaybillTaskIds: waybillTaskIds})
  1205. // 最高温度、最低温度、最高湿度、最低湿度
  1206. var maxTemp, minTemp, maxHumidity, minHumidity float32
  1207. // 最高温度时间、最低温度时间、最高湿度时间、最低湿度时间
  1208. var maxTempTime, minTempTime, maxHumidityTime, minHumidityTime string
  1209. // 总温度 总湿度
  1210. var totalTemp, totalHumidity float32
  1211. // 平均温度 平均湿度
  1212. var avgTemp, avgHumidity float32
  1213. // 温度阈值,湿度阈值
  1214. var tempThreshold, humidityThreshold string
  1215. // 记录开始时间,记录结束时间
  1216. var s_time, e_time string
  1217. if len(DeviceSensor_data) > 0 {
  1218. tempThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_tl, DeviceSensor_data[0].T_tu)
  1219. humidityThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_rhl, DeviceSensor_data[0].T_rhu)
  1220. s_time = DeviceSensor_data[0].T_time
  1221. e_time = DeviceSensor_data[len(DeviceSensor_data)-1].T_time
  1222. // 最高温度及时刻
  1223. maxTemp = DeviceSensor_data[0].T_t
  1224. maxTempTime = DeviceSensor_data[0].T_time
  1225. // 最低温度及时刻
  1226. minTemp = DeviceSensor_data[0].T_t
  1227. minTempTime = DeviceSensor_data[0].T_time
  1228. // 最高湿度及时刻
  1229. maxHumidity = DeviceSensor_data[0].T_rh
  1230. maxHumidityTime = DeviceSensor_data[0].T_time
  1231. // 获取最低湿度及时刻
  1232. minHumidity = DeviceSensor_data[0].T_rh
  1233. minHumidityTime = DeviceSensor_data[0].T_time
  1234. for i := 0; i < len(DeviceSensor_data); i++ {
  1235. data := DeviceSensor_data[i]
  1236. if data.T_t > maxTemp {
  1237. maxTemp = data.T_t
  1238. maxTempTime = data.T_time
  1239. }
  1240. if data.T_t < minTemp {
  1241. minTemp = data.T_t
  1242. minTempTime = data.T_time
  1243. }
  1244. totalTemp += data.T_t
  1245. if data.T_rh > maxHumidity {
  1246. maxHumidity = data.T_rh
  1247. maxHumidityTime = data.T_time
  1248. }
  1249. if data.T_rh < minHumidity {
  1250. minHumidity = data.T_rh
  1251. minHumidityTime = data.T_time
  1252. }
  1253. totalHumidity += data.T_rh
  1254. }
  1255. // 平均温度
  1256. avgTemp = totalTemp / float32(len(DeviceSensor_data))
  1257. // 平均湿度
  1258. avgHumidity = totalHumidity / float32(len(DeviceSensor_data))
  1259. }
  1260. // -------------------获取最高温湿度、温蒂温湿度、平均温湿度结束
  1261. pdf := &gopdf.GoPdf{}
  1262. pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
  1263. err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf")
  1264. if err != nil {
  1265. return
  1266. }
  1267. err = pdf.SetFont("wts", "", 20)
  1268. if err != nil {
  1269. return
  1270. }
  1271. pdf.SetGrayFill(0.5)
  1272. pdf.SetMargins(0, 20, 0, 20)
  1273. pdf.AddPage()
  1274. var fileName2 string
  1275. if len(company.Logo) > 0 {
  1276. imgH, errImg := lib.GetImage(company.Logo)
  1277. if errImg != nil {
  1278. err = errors.New("获取图片失败")
  1279. return
  1280. }
  1281. imgWidth := float64(imgH.Bounds().Dx())
  1282. imgHeight := float64(imgH.Bounds().Dy())
  1283. H := 60.
  1284. W := (imgWidth * H) / imgHeight
  1285. if strings.Contains(company.Logo, ".png") {
  1286. err = pdf.ImageFrom(imgH, 10, 0, &gopdf.Rect{W: W, H: H})
  1287. if err != nil {
  1288. err = errors.New("写入图片失败")
  1289. return
  1290. }
  1291. } else {
  1292. fileName := "./ofile/" + time.Now().Format("20060102150405") + ".png"
  1293. f, _ := os.Create(fileName)
  1294. defer f.Close()
  1295. defer func() {
  1296. os.Remove(fileName)
  1297. }()
  1298. png.Encode(f, imgH)
  1299. err = pdf.Image(fileName, 10, 0, &gopdf.Rect{W: W, H: H})
  1300. if err != nil {
  1301. if err.Error() == "16-bit depth not supported" {
  1302. fileName2 = "./ofile/" + time.Now().Format("20060102150405") + ".png"
  1303. f2, _ := os.Create(fileName2)
  1304. defer f.Close()
  1305. defer func() {
  1306. os.Remove(fileName2)
  1307. }()
  1308. jpeg.Encode(f2, imgH, &jpeg.Options{100})
  1309. err = pdf.Image(fileName2, 10, 0, &gopdf.Rect{W: W, H: H})
  1310. }
  1311. if err != nil {
  1312. err = errors.New("写入图片失败")
  1313. return
  1314. }
  1315. }
  1316. }
  1317. }
  1318. var imgHSeal image.Image
  1319. var existSealImg bool
  1320. if len(company.Seal) > 0 {
  1321. existSealImg = true
  1322. var errImg error
  1323. imgHSeal, errImg = lib.GetImage(company.Seal)
  1324. if errImg != nil {
  1325. err = errors.New("获取图片失败")
  1326. return
  1327. }
  1328. }
  1329. title := "运单" + waybill.WaybillNo + "温度记录"
  1330. if humidityShow {
  1331. title = "运单" + waybill.WaybillNo + "温湿度记录"
  1332. }
  1333. var y float64 = 70
  1334. textw, _ := pdf.MeasureTextWidth(title)
  1335. pdf.SetX((595 / 2) - (textw / 2))
  1336. pdf.SetY(y)
  1337. pdf.Text(title)
  1338. y += 30
  1339. pdf.SetFont("wts", "", 16)
  1340. pdf.SetXY(10, y)
  1341. pdf.Text("记录概要信息")
  1342. // 线
  1343. y += 10
  1344. pdf.SetLineWidth(0.5)
  1345. pdf.SetStrokeColor(169, 169, 169)
  1346. pdf.Line(10, y, 585, y)
  1347. y += 20
  1348. pdf.SetFont("wts", "", 10)
  1349. pdf.SetXY(10, y)
  1350. pdf.Text(fmt.Sprintf("记录开始时间:%s", s_time))
  1351. pdf.SetXY(240, y)
  1352. pdf.Text(fmt.Sprintf("记录结束时间:%s", e_time))
  1353. sTime, _ := lib.TimeStrToTime(s_time)
  1354. eTime, _ := lib.TimeStrToTime(e_time)
  1355. pdf.SetXY(470, y)
  1356. minutes := int(eTime.Sub(sTime).Minutes())
  1357. hours := minutes / 60
  1358. remainingMinutes := minutes % 60
  1359. pdf.Text(fmt.Sprintf("记录总时间:%dh%dmin", hours, remainingMinutes))
  1360. // -------------最高温/湿度 最低温/湿度 平均温/湿度
  1361. y += 15
  1362. pdf.SetXY(10, y)
  1363. pdf.Text(fmt.Sprintf("最高温度:%.1f℃,%s", lib.RoundToDecimal(float64(maxTemp), 1), maxTempTime))
  1364. pdf.SetXY(240, y)
  1365. pdf.Text(fmt.Sprintf("最低温度:%.1f℃,%s", lib.RoundToDecimal(float64(minTemp), 1), minTempTime))
  1366. pdf.SetXY(470, y)
  1367. pdf.Text(fmt.Sprintf("平均温度:%.1f℃", lib.RoundToDecimal(float64(avgTemp), 1)))
  1368. if humidityShow {
  1369. y += 15
  1370. pdf.SetXY(10, y)
  1371. pdf.Text(fmt.Sprintf("最高湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(maxHumidity), 1), maxHumidityTime))
  1372. pdf.SetXY(240, y)
  1373. pdf.Text(fmt.Sprintf("最低湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(minHumidity), 1), minHumidityTime))
  1374. pdf.SetXY(470, y)
  1375. pdf.Text(fmt.Sprintf("平均湿度:%.1f%%RH", lib.RoundToDecimal(float64(avgHumidity), 1)))
  1376. }
  1377. // -------------温/湿度阈值
  1378. y += 15
  1379. pdf.SetXY(10, y)
  1380. pdf.Text(fmt.Sprintf("温度阈值:%s℃", tempThreshold))
  1381. if humidityShow {
  1382. pdf.SetXY(240, y)
  1383. pdf.Text(fmt.Sprintf("温度阈值:%s%%", humidityThreshold))
  1384. }
  1385. //-------------发货单位,收货单位,备注
  1386. y += 15
  1387. pdf.SetXY(10, y)
  1388. T_forwarding_unit_temp := []rune(waybill.SenderAddressName)
  1389. if len(T_forwarding_unit_temp) > 17 {
  1390. pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp[0:17])))
  1391. pdf.SetXY(60, y+15)
  1392. pdf.Text(fmt.Sprintf("%s", string(T_forwarding_unit_temp[17:])))
  1393. } else {
  1394. pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp)))
  1395. }
  1396. pdf.SetXY(240, y)
  1397. T_consignee_unit_temp := []rune(waybill.ConsigneeAddressName)
  1398. if len(T_consignee_unit_temp) > 17 {
  1399. pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp[0:17])))
  1400. pdf.SetXY(290, y+15)
  1401. pdf.Text(fmt.Sprintf("%s", string(T_consignee_unit_temp[17:])))
  1402. } else {
  1403. pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp)))
  1404. }
  1405. // 承运方
  1406. y += 15
  1407. pdf.SetXY(10, y)
  1408. company_name := []rune(waybill.Dept.Name)
  1409. pdf.Text(fmt.Sprintf("承运方:%s", string(company_name)))
  1410. y += 15
  1411. pdf.SetXY(10, y)
  1412. T_remark_temp := []rune(waybill.Remark)
  1413. if len(T_remark_temp) > 35 {
  1414. pdf.Text(fmt.Sprintf("备注:%s", string(T_remark_temp[0:35])))
  1415. pdf.SetXY(10, y+15)
  1416. pdf.Text(fmt.Sprintf("%s", string(T_remark_temp[35:])))
  1417. } else {
  1418. pdf.Text(fmt.Sprintf("备注: %s", string(T_remark_temp)))
  1419. }
  1420. y += 35
  1421. pdf.SetFont("wts", "", 16)
  1422. pdf.SetXY(10, y)
  1423. pdf.Text("记录曲线信息")
  1424. // 线
  1425. y += 10
  1426. pdf.SetLineWidth(0.5)
  1427. pdf.SetStrokeColor(169, 169, 169)
  1428. pdf.Line(10, y, 585, y)
  1429. y += 1
  1430. var tempFilepath string
  1431. tempFilepath, err = DeviceDataTemperatureJPG(s_time, e_time, waybillPDF)
  1432. if err == nil {
  1433. imgH, _ := gopdf.ImageHolderByPath(tempFilepath)
  1434. pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
  1435. y += 315
  1436. }
  1437. //var humidityFilepath string
  1438. //if req.HumidityShow {
  1439. // humidityFilepath, err = DeviceDataHumidityJPG2(s_time, e_time, waybillPDF)
  1440. // if err == nil {
  1441. // imgH, _ := gopdf.ImageHolderByPath(humidityFilepath)
  1442. // pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
  1443. // y += 315
  1444. // }
  1445. //}
  1446. if y > 841.89 {
  1447. // 图片结束直接分页
  1448. addStampImage(pdf, existSealImg, imgHSeal, 455, 660)
  1449. pdf.AddPage()
  1450. y = 20
  1451. }
  1452. y += 20
  1453. pdf.SetFont("wts", "", 16)
  1454. pdf.SetXY(10, y)
  1455. pdf.Text("记录数据信息")
  1456. // 线
  1457. y += 10
  1458. pdf.SetLineWidth(0.5)
  1459. pdf.SetStrokeColor(169, 169, 169)
  1460. pdf.Line(10, y, 585, y)
  1461. y += 10
  1462. pdf.SetFont("wts", "", 10)
  1463. var x float64 = 12
  1464. var w float64 = 110
  1465. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1466. x = x + w
  1467. w = 100
  1468. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1469. x = x + w
  1470. w = 37
  1471. lib.RectFillColor(pdf, "T1", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1472. x = x + w
  1473. lib.RectFillColor(pdf, "T2", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1474. x = x + w
  1475. w = 110
  1476. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1477. x = x + w
  1478. w = 100
  1479. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1480. x = x + w
  1481. w = 37
  1482. lib.RectFillColor(pdf, "T1", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1483. x = x + w
  1484. lib.RectFillColor(pdf, "T2", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1485. for i, v := range Pdf_data {
  1486. if i%2 == 0 {
  1487. y += 20
  1488. //var textH float64 = 25 // if text height is 25px.
  1489. //pdf.SetNewY(y, textH)
  1490. if y > 800 {
  1491. addStampImage(pdf, existSealImg, imgHSeal, 455, y-130)
  1492. pdf.AddPage()
  1493. y = 20
  1494. x = 12
  1495. w = 110
  1496. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1497. x = x + w
  1498. w = 100
  1499. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1500. x = x + w
  1501. w = 37
  1502. lib.RectFillColor(pdf, "T1", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1503. x = x + w
  1504. lib.RectFillColor(pdf, "T2", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1505. x = x + w
  1506. w = 110
  1507. lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1508. x = x + w
  1509. w = 100
  1510. lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1511. x = x + w
  1512. w = 37
  1513. lib.RectFillColor(pdf, "T1", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1514. x = x + w
  1515. lib.RectFillColor(pdf, "T2", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1516. y += 20
  1517. }
  1518. //y = pdf.GetY()
  1519. x, w = 12, 110
  1520. lib.RectFillColor(pdf, v.T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1521. x = x + w
  1522. w = 100
  1523. lib.RectFillColor(pdf, v.T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1524. x = x + w
  1525. w = 37
  1526. lib.RectFillColor(pdf, lib.Float32_to_string_forPDF(v.T_id1), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1527. x = x + w
  1528. lib.RectFillColor(pdf, lib.Float32_to_string_forPDF(v.T_id2), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1529. }
  1530. if i%2 == 1 {
  1531. x = x + w
  1532. w = 110
  1533. lib.RectFillColor(pdf, v.T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1534. x = x + w
  1535. w = 100
  1536. lib.RectFillColor(pdf, v.T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1537. x = x + w
  1538. w = 37
  1539. lib.RectFillColor(pdf, lib.Float32_to_string_forPDF(v.T_id1), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1540. x = x + w
  1541. lib.RectFillColor(pdf, lib.Float32_to_string_forPDF(v.T_id2), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
  1542. }
  1543. }
  1544. if y <= 800 {
  1545. if y < 150 {
  1546. y = 20
  1547. } else {
  1548. y = y - 130
  1549. }
  1550. addStampImage(pdf, existSealImg, imgHSeal, 455, y)
  1551. }
  1552. filename = "运单" + waybill.WaybillNo + "温度记录" + time.Now().Format("20060102150405") + ".pdf"
  1553. filePath = "./ofile/" + filename
  1554. err = pdf.WritePdf(filePath)
  1555. if err != nil {
  1556. return
  1557. }
  1558. defer func() {
  1559. os.Remove(tempFilepath)
  1560. os.Remove(fileName2)
  1561. }()
  1562. return filename, filePath, nil
  1563. }
  1564. // WaybillPDF 导出运单pdf
  1565. // @Summary 导出运单pdf
  1566. // @Description 导出运单pdf
  1567. // @Tags 运单
  1568. // @Param waybillNo query string false "运单号"
  1569. // @Param pageSize query int false "页条数"
  1570. // @Param page query int false "页码"
  1571. // @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
  1572. // @Router /api/waybill/waybill-pdf [get]
  1573. // @Security Bearer
  1574. func (e WaybillController) WaybillPDF(c *gin.Context) {
  1575. s := service.Waybill{}
  1576. companySvc := service.Company{}
  1577. req := dto.WaybillGetByWaybillPdfReq{}
  1578. err := e.MakeContext(c).
  1579. MakeOrm().
  1580. Bind(&req, binding.Query).
  1581. MakeService(&s.Service).
  1582. MakeService(&companySvc.Service).
  1583. Errors
  1584. if err != nil {
  1585. e.Logger.Error(err)
  1586. e.Error(500, err, err.Error())
  1587. return
  1588. }
  1589. var waybill model.Waybill
  1590. var company model.SysDept
  1591. //err = s.GetByWaybillNo(&req, &waybill, p)
  1592. err = s.GetByWaybillNo(&req, &waybill, nil)
  1593. if err != nil {
  1594. e.Error(500, err, err.Error())
  1595. return
  1596. }
  1597. err = companySvc.Get(&dto.CompanyGetReq{Id: waybill.DeptId}, &company)
  1598. if err != nil {
  1599. e.Error(500, err, err.Error())
  1600. return
  1601. }
  1602. // -------------------生成运单条码
  1603. // 运单条码
  1604. cs, _ := code128.Encode(waybill.WaybillNo)
  1605. // 创建一个要输出数据的文件
  1606. imgPath := "ofile/img/" + waybill.WaybillNo + ".png"
  1607. file, _ := os.Create(imgPath)
  1608. defer file.Close()
  1609. // 设置图片像素大小
  1610. barCode, _ := barcode.Scale(cs, 205, 50)
  1611. // 将code128的条形码编码为png图片
  1612. png.Encode(file, barCode)
  1613. imgPath2 := "ofile/img/" + waybill.WaybillNo + ".jpg"
  1614. png2j.Con2jpg(imgPath, imgPath2)
  1615. qrcode, err := qrcode.Encode(fmt.Sprintf("%s/WaybillInquiry?waybillNo=%s", conf.ExtConfig.Service.Domain, waybill.WaybillNo),
  1616. qrcode.Medium, 70)
  1617. if err != nil {
  1618. e.Error(500, err, err.Error())
  1619. return
  1620. }
  1621. qrCodeImgH, err := gopdf.ImageHolderByBytes(qrcode)
  1622. if err != nil {
  1623. e.Error(500, err, err.Error())
  1624. return
  1625. }
  1626. pdf := &gopdf.GoPdf{}
  1627. pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 283.46, H: 283.46}}) //595.28, 841.89 = A4
  1628. //pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
  1629. err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf")
  1630. if err != nil {
  1631. return
  1632. }
  1633. pdf.SetGrayFill(0.5)
  1634. pdf.SetMargins(0, 10, 0, 10)
  1635. for i := 0; i < waybill.Quantity; i++ {
  1636. pdf.AddPage()
  1637. var y float64 = 20
  1638. pdf.SetFont("wts", "", 10)
  1639. //y += 12
  1640. pdf.SetXY(250, 20)
  1641. pdf.SetFont("wts", "", 13)
  1642. if waybill.Quantity > 1 {
  1643. pdf.Text(fmt.Sprintf("%d/%d", i+1, waybill.Quantity))
  1644. }
  1645. pdf.SetFont("wts", "", 10)
  1646. y += 10
  1647. pdf.Image(imgPath2, 20, y, &gopdf.Rect{W: 240, H: 30})
  1648. y += 43
  1649. textw, _ := pdf.MeasureTextWidth(waybill.WaybillNo)
  1650. pdf.SetX((283.46 / 2) - (textw / 2))
  1651. pdf.SetY(y)
  1652. pdf.Text(waybill.WaybillNo)
  1653. if len(company.Logo) > 0 {
  1654. imgH, errImg := lib.GetImage(company.Logo)
  1655. if errImg != nil {
  1656. err = errors.New("获取图片失败")
  1657. e.Error(500, err, err.Error())
  1658. return
  1659. }
  1660. imgWidth := float64(imgH.Bounds().Dx())
  1661. imgHeight := float64(imgH.Bounds().Dy())
  1662. H := 30.
  1663. W := (imgWidth * H) / imgHeight
  1664. if strings.Contains(company.Logo, ".png") {
  1665. err = pdf.ImageFrom(imgH, 10, 0, &gopdf.Rect{W: W, H: H})
  1666. if err != nil {
  1667. err = errors.New("写入图片失败")
  1668. e.Error(500, err, err.Error())
  1669. return
  1670. }
  1671. } else {
  1672. fileName := "./ofile/" + time.Now().Format("20060102150405") + ".png"
  1673. f, _ := os.Create(fileName)
  1674. defer f.Close()
  1675. defer func() {
  1676. os.Remove(fileName)
  1677. }()
  1678. png.Encode(f, imgH)
  1679. err = pdf.Image(fileName, 10, 0, &gopdf.Rect{W: W, H: H})
  1680. if err != nil {
  1681. if err.Error() == "16-bit depth not supported" {
  1682. fileName2 := "./ofile/" + time.Now().Format("20060102150405") + ".png"
  1683. f2, _ := os.Create(fileName2)
  1684. defer f.Close()
  1685. defer func() {
  1686. os.Remove(fileName2)
  1687. }()
  1688. jpeg.Encode(f2, imgH, &jpeg.Options{100})
  1689. err = pdf.Image(fileName2, 10, 0, &gopdf.Rect{W: W, H: H})
  1690. }
  1691. if err != nil {
  1692. err = errors.New("写入图片失败")
  1693. e.Error(500, err, err.Error())
  1694. return
  1695. }
  1696. }
  1697. }
  1698. } else {
  1699. title := "#" + company.Name
  1700. pdf.SetXY(10, 20)
  1701. pdf.Text(title)
  1702. }
  1703. // 线
  1704. y += 6
  1705. pdf.SetLineWidth(0.5)
  1706. pdf.SetLineType("dotted")
  1707. pdf.Line(10, y, 273, y)
  1708. y += 28
  1709. pdf.SetFont("wts", "", 18)
  1710. pdf.SetXY(12, y+3)
  1711. pdf.Text("收")
  1712. pdf.SetFont("wts", "", 10)
  1713. y -= 5
  1714. pdf.SetXY(40, y)
  1715. pdf.Text(fmt.Sprintf("%s %s", lib.MaskStr(waybill.ConsigneeAddressName), lib.MaskPhoneNumber(waybill.ConsigneeAddressPhone)))
  1716. y += 15
  1717. pdf.SetXY(40, y)
  1718. pdf.Text(waybill.ConsigneeAddressDetails)
  1719. // 线
  1720. y += 8
  1721. pdf.SetLineWidth(0.5)
  1722. pdf.SetLineType("dotted")
  1723. pdf.Line(10, y, 273, y)
  1724. y += 22
  1725. pdf.SetFont("wts", "", 13)
  1726. pdf.SetXY(14, y+3)
  1727. pdf.Text("寄")
  1728. pdf.SetFont("wts", "", 10)
  1729. y -= 5
  1730. pdf.SetXY(40, y)
  1731. pdf.Text(fmt.Sprintf("%s %s", lib.MaskStr(waybill.SenderAddressName), lib.MaskPhoneNumber(waybill.SenderAddressPhone)))
  1732. y += 15
  1733. pdf.SetXY(40, y)
  1734. pdf.Text(waybill.SenderAddressDetails)
  1735. // 线
  1736. y += 10
  1737. pdf.SetLineWidth(0.5)
  1738. //pdf.SetLineType("dashed")
  1739. pdf.SetLineType("dotted")
  1740. pdf.Line(10, y, 273, y)
  1741. y += 12
  1742. pdf.SetXY(10, y)
  1743. pdf.SetFont("wts", "", 8)
  1744. pdf.Text("下单时间:" + waybill.OrderTime.String())
  1745. // 线
  1746. y += 6
  1747. pdf.SetLineWidth(0.5)
  1748. pdf.SetLineType("dotted")
  1749. pdf.Line(10, y, 273, y)
  1750. pdf.SetFont("wts", "", 10)
  1751. y += 20
  1752. pdf.SetXY(10, y)
  1753. pdf.Text("备注:")
  1754. pdf.SetFont("wts", "", 8)
  1755. y += 15
  1756. pdf.SetXY(30, y)
  1757. pdf.Text("货物类型:" + waybill.CargoType)
  1758. y += 15
  1759. pdf.SetXY(30, y)
  1760. pdf.Text("温度要求:" + waybill.TemperatureInterval)
  1761. y += 15
  1762. pdf.SetXY(30, y)
  1763. pdf.Text("配送要求:" + waybill.DeliveryCondition)
  1764. x := 170.
  1765. //pdf.Image(qrcodeImgPath2, x, y-55, &gopdf.Rect{W: 70, H: 70})
  1766. pdf.ImageByHolder(qrCodeImgH, x, y-63, &gopdf.Rect{W: 70, H: 70})
  1767. pdf.SetFont("wts", "", 8)
  1768. y += 10
  1769. textw, _ = pdf.MeasureTextWidth("扫码查询")
  1770. pdf.SetX(x + 35 - (textw / 2))
  1771. pdf.SetY(y)
  1772. pdf.Text("扫码查询")
  1773. y += 10
  1774. textw, _ = pdf.MeasureTextWidth("物流温湿度信息")
  1775. pdf.SetX(x + 35 - (textw / 2))
  1776. pdf.SetY(y)
  1777. pdf.Text("物流温湿度信息")
  1778. }
  1779. filename := "运单" + req.WaybillNo + ".pdf"
  1780. filePath := "ofile/" + filename
  1781. err = pdf.WritePdf(filePath)
  1782. if err != nil {
  1783. return
  1784. }
  1785. defer func() {
  1786. os.Remove(filePath)
  1787. os.Remove(imgPath)
  1788. os.Remove(imgPath2)
  1789. }()
  1790. c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(filename))
  1791. c.Header("Content-Transfer-Encoding", "binary")
  1792. c.File(filePath)
  1793. }
  1794. // SendMail 发送邮件
  1795. // @Summary 发送邮件
  1796. // @Description 发送邮件
  1797. // @Tags 运单
  1798. // @Param data body dto.WaybillSendMailPdfReq true "data"
  1799. // @Success 200 {object} response.Response{data=model.Waybill} "{"code": 200, "data": [...]}"
  1800. // @Router /api/waybill/send-mail [post]
  1801. // @Security Bearer
  1802. func (e WaybillController) SendMail(c *gin.Context) {
  1803. s := service.Waybill{}
  1804. companySvc := service.Company{}
  1805. req := dto.WaybillSendMailPdfReq{}
  1806. err := e.MakeContext(c).
  1807. MakeOrm().
  1808. Bind(&req, binding.JSON, nil).
  1809. MakeService(&s.Service).
  1810. MakeService(&companySvc.Service).
  1811. Errors
  1812. if err != nil {
  1813. e.Logger.Error(err)
  1814. e.Error(500, err, err.Error())
  1815. return
  1816. }
  1817. var waybill model.Waybill
  1818. err = s.GetByWaybillNo(&dto.WaybillGetByWaybillPdfReq{WaybillNo: req.WaybillNo, HumidityShow: req.HumidityShow}, &waybill, nil)
  1819. if err != nil {
  1820. e.Error(500, err, err.Error())
  1821. return
  1822. }
  1823. var company model.SysDept
  1824. err = companySvc.Get(&dto.CompanyGetReq{Id: waybill.DeptId}, &company)
  1825. if err != nil {
  1826. e.Error(500, err, err.Error())
  1827. return
  1828. }
  1829. _, filePath, err := PDF(s, waybill, company, req.WaybillTaskIds, req.HumidityShow)
  1830. defer func() {
  1831. os.Remove(filePath)
  1832. }()
  1833. em := email.NewEmail()
  1834. em.From = "冷链物流运输 <bzdcold@163.com>"
  1835. em.To = req.To
  1836. em.Subject = fmt.Sprintf("【冷链物流运输】运单%s温湿度记录", waybill.WaybillNo)
  1837. em.Text = []byte(fmt.Sprintf("运单%s温湿度记录", waybill.WaybillNo))
  1838. // 主要就是在这个位置添加了附件,注意:这里AttachFile是Email结构体的方法而不是字段,所以不是用等于而是括号
  1839. em.AttachFile(filePath)
  1840. err = em.Send("smtp.163.com:25", smtp.PlainAuth("", "bzdcold@163.com", "ZIZXBCDKVTMPJMVX", "smtp.163.com"))
  1841. if err != nil {
  1842. e.Logger.Error(err)
  1843. e.Error(500, err, err.Error())
  1844. return
  1845. }
  1846. e.OK(nil, "发送成功")
  1847. }
  1848. // 获取温度图片
  1849. func DeviceDataTemperatureJPG(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
  1850. if len(waybillPDF) == 0 {
  1851. return "", errors.New("暂无数据可生成图片")
  1852. }
  1853. deviceSensorList := []nats_server.DeviceSensor_R{}
  1854. dataList := []nats_server.DeviceData_R{}
  1855. deviceDataPdfList := []service.DeviceDataPdf{}
  1856. for _, w := range waybillPDF {
  1857. deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
  1858. dataList = append(dataList, w.Data...)
  1859. deviceDataPdfList = append(deviceDataPdfList, w.DeviceDataPdf...)
  1860. }
  1861. TemperatureMin := deviceSensorList[0].T_DeviceSensorParameter.T_Tlower
  1862. TemperatureMax := deviceSensorList[0].T_DeviceSensorParameter.T_Tupper
  1863. var ymin, ymax float32
  1864. for i, r := range dataList {
  1865. if i == 0 {
  1866. ymin = r.T_t
  1867. ymax = r.T_t
  1868. }
  1869. if ymin > r.T_t {
  1870. ymin = r.T_t
  1871. }
  1872. if ymax < r.T_t {
  1873. ymax = r.T_t
  1874. }
  1875. }
  1876. sort.Slice(deviceDataPdfList, func(i, j int) bool {
  1877. return deviceDataPdfList[i].T_time < deviceDataPdfList[j].T_time
  1878. })
  1879. series := make([]chart.Series, 0)
  1880. // 创建温度线
  1881. xValues1 := make([]time.Time, len(deviceDataPdfList))
  1882. xValues2 := make([]time.Time, 0)
  1883. yValues1 := make([]float64, len(deviceDataPdfList))
  1884. yValues2 := make([]float64, len(deviceDataPdfList))
  1885. for i := 0; i < len(deviceDataPdfList); i++ {
  1886. t, _ := lib.TimeStrToTime(deviceDataPdfList[i].T_time)
  1887. xValues1[i] = t
  1888. if deviceDataPdfList[i].T_id1 != nil {
  1889. yValues1[i] = float64(*deviceDataPdfList[i].T_id1)
  1890. }
  1891. if deviceDataPdfList[i].T_id2 != nil {
  1892. xValues2 = append(xValues2, t)
  1893. yValues2[i] = float64(*deviceDataPdfList[i].T_id2)
  1894. }
  1895. }
  1896. series = append(series, chart.TimeSeries{
  1897. Name: "T1",
  1898. XValues: xValues1,
  1899. YValues: yValues1,
  1900. })
  1901. series = append(series, chart.TimeSeries{
  1902. Name: "T2",
  1903. XValues: xValues2,
  1904. YValues: yValues2,
  1905. })
  1906. if ymax < TemperatureMax {
  1907. ymax = TemperatureMax
  1908. }
  1909. if ymin > 0 {
  1910. ymin = 0
  1911. }
  1912. if ymin > TemperatureMin {
  1913. ymin = TemperatureMin
  1914. }
  1915. st, _ := lib.TimeStrToTime(startTime)
  1916. et, _ := lib.TimeStrToTime(endTime)
  1917. series = append(series, chart.TimeSeries{
  1918. Style: chart.Style{
  1919. StrokeColor: drawing.ColorRed,
  1920. StrokeDashArray: []float64{5.0, 5.0},
  1921. },
  1922. XValues: []time.Time{st, et},
  1923. YValues: []float64{float64(TemperatureMin), float64(TemperatureMin)},
  1924. })
  1925. series = append(series, chart.TimeSeries{
  1926. Style: chart.Style{
  1927. StrokeColor: drawing.ColorRed,
  1928. StrokeDashArray: []float64{5.0, 5.0},
  1929. },
  1930. XValues: []time.Time{st, et},
  1931. YValues: []float64{float64(TemperatureMax), float64(TemperatureMax)},
  1932. })
  1933. font := getZWFont()
  1934. graph := chart.Chart{
  1935. Title: "温度记录",
  1936. TitleStyle: chart.Style{
  1937. FontSize: 14,
  1938. },
  1939. Background: chart.Style{
  1940. Padding: chart.Box{
  1941. Top: 20,
  1942. },
  1943. },
  1944. Font: font,
  1945. XAxis: chart.XAxis{
  1946. Name: "时间",
  1947. ValueFormatter: chart.TimeValueFormatterWithFormat("2006-01-02 15:04"),
  1948. },
  1949. YAxis: chart.YAxis{
  1950. Name: "温度",
  1951. Range: &chart.ContinuousRange{
  1952. Min: float64(ymin),
  1953. Max: float64(ymax + 2),
  1954. },
  1955. },
  1956. Series: series,
  1957. }
  1958. //graph.Elements = []chart.Renderable{
  1959. // chart.Legend(&graph),
  1960. //}
  1961. filepath := "./ofile/" + "temperature" + deviceSensorList[0].T_sn + ".jpg"
  1962. f, _ := os.Create(filepath)
  1963. defer f.Close()
  1964. graph.Render(chart.PNG, f)
  1965. return filepath, nil
  1966. }
  1967. // getZWFont 加载字体
  1968. func getZWFont() *truetype.Font {
  1969. fontFile := "./static/fonts/MiSans-Medium.ttf"
  1970. fontBytes, err := os.ReadFile(fontFile)
  1971. if err != nil {
  1972. log.Println(err)
  1973. return nil
  1974. }
  1975. font, err := truetype.Parse(fontBytes)
  1976. if err != nil {
  1977. log.Println(err)
  1978. return nil
  1979. }
  1980. return font
  1981. }
  1982. func addStampImage(pdf *gopdf.GoPdf, existSealImg bool, imgHSeal image.Image, x, y float64) {
  1983. if !existSealImg {
  1984. return
  1985. }
  1986. if x < 10 {
  1987. x = 10
  1988. }
  1989. if y < 20 {
  1990. y = 20
  1991. }
  1992. err := pdf.ImageFrom(imgHSeal, x, y, &gopdf.Rect{W: 123, H: 128.6})
  1993. if err != nil {
  1994. log.Print(err.Error())
  1995. }
  1996. }