|
@@ -0,0 +1,2057 @@
|
|
|
+package controller
|
|
|
+
|
|
|
+import (
|
|
|
+ "bufio"
|
|
|
+ "cold-delivery/app/admin/model"
|
|
|
+ "cold-delivery/app/admin/service"
|
|
|
+ "cold-delivery/app/admin/service/dto"
|
|
|
+ "cold-delivery/common/actions"
|
|
|
+ "cold-delivery/common/lib"
|
|
|
+ "cold-delivery/common/nats/nats_server"
|
|
|
+ "errors"
|
|
|
+ "fmt"
|
|
|
+ "github.com/beego/beego/v2/core/logs"
|
|
|
+ "github.com/gin-gonic/gin"
|
|
|
+ "github.com/gin-gonic/gin/binding"
|
|
|
+ "github.com/golang/freetype/truetype"
|
|
|
+ "github.com/signintech/gopdf"
|
|
|
+ "github.com/wcharczuk/go-chart/v2"
|
|
|
+ "github.com/wcharczuk/go-chart/v2/drawing"
|
|
|
+ "github.com/xuri/excelize/v2"
|
|
|
+ "gogs.baozhida.cn/zoie/OAuth-core/api"
|
|
|
+ "gogs.baozhida.cn/zoie/OAuth-core/pkg/jwtauth/user"
|
|
|
+ _ "gogs.baozhida.cn/zoie/OAuth-core/pkg/response"
|
|
|
+ "gonum.org/v1/plot"
|
|
|
+ "gonum.org/v1/plot/plotter"
|
|
|
+ "gonum.org/v1/plot/vg"
|
|
|
+ "gonum.org/v1/plot/vg/draw"
|
|
|
+ "image/color"
|
|
|
+ "log"
|
|
|
+ "math"
|
|
|
+ "net/url"
|
|
|
+ "os"
|
|
|
+ "path"
|
|
|
+ "sort"
|
|
|
+ "strconv"
|
|
|
+ "sync"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+type WaybillController struct {
|
|
|
+ api.Api
|
|
|
+}
|
|
|
+
|
|
|
+// GetPage 获取运单列表
|
|
|
+// @Summary 获取运单列表
|
|
|
+// @Description 获取运单列表
|
|
|
+// @Tags 运单
|
|
|
+// @Param no query string false "运单号"
|
|
|
+// @Param pageSize query int false "页条数"
|
|
|
+// @Param page query int false "页码"
|
|
|
+// @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
|
|
|
+// @Router /api/waybill [get]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) GetPage(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillGetPageReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.Query).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //数据权限检查
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+
|
|
|
+ list := make([]model.Waybill, 0)
|
|
|
+ var count int64
|
|
|
+
|
|
|
+ err = s.GetPage(&req, &list, &count, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
|
|
|
+}
|
|
|
+
|
|
|
+// GetPage 获取运单列表
|
|
|
+// @Summary 获取运单列表
|
|
|
+// @Description 获取运单列表
|
|
|
+// @Tags 运单
|
|
|
+// @Param no query string false "运单号"
|
|
|
+// @Param pageSize query int false "页条数"
|
|
|
+// @Param page query int false "页码"
|
|
|
+// @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
|
|
|
+// @Router /api/waybill [get]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) Export(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillGetPageReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.Query).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //数据权限检查
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+
|
|
|
+ list := make([]model.Waybill, 0)
|
|
|
+ var count int64
|
|
|
+ req.PageSize = 9999
|
|
|
+ err = s.GetPage(&req, &list, &count, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ f := excelize.NewFile() // 设置单元格的值
|
|
|
+ // 这里设置表头ÒÒ
|
|
|
+ f.SetCellValue("Sheet1", "A1", "序号")
|
|
|
+ f.SetCellValue("Sheet1", "B1", "状态")
|
|
|
+ f.SetCellValue("Sheet1", "C1", "寄件人名称")
|
|
|
+ f.SetCellValue("Sheet1", "D1", "寄件人电话")
|
|
|
+ f.SetCellValue("Sheet1", "E1", "寄件人地址")
|
|
|
+ f.SetCellValue("Sheet1", "F1", "收件人名称")
|
|
|
+ f.SetCellValue("Sheet1", "G1", "收件人电话")
|
|
|
+ f.SetCellValue("Sheet1", "H1", "收件人地址")
|
|
|
+ f.SetCellValue("Sheet1", "I1", "防拆标签码")
|
|
|
+ f.SetCellValue("Sheet1", "J1", "运输备注")
|
|
|
+ //f.SetCellValue("Sheet1", "K1", "货物类型")
|
|
|
+ //f.SetCellValue("Sheet1", "L1", "运输备注")
|
|
|
+
|
|
|
+ // 设置列宽
|
|
|
+ f.SetColWidth("Sheet1", "A", "A", 6)
|
|
|
+ f.SetColWidth("Sheet1", "B", "B", 8)
|
|
|
+ f.SetColWidth("Sheet1", "C", "C", 14)
|
|
|
+ f.SetColWidth("Sheet1", "D", "D", 14)
|
|
|
+ f.SetColWidth("Sheet1", "E", "E", 30)
|
|
|
+ f.SetColWidth("Sheet1", "F", "F", 14)
|
|
|
+ f.SetColWidth("Sheet1", "G", "G", 14)
|
|
|
+ f.SetColWidth("Sheet1", "H", "H", 30)
|
|
|
+ f.SetColWidth("Sheet1", "I", "K", 15)
|
|
|
+ f.SetColWidth("Sheet1", "L", "L", 15)
|
|
|
+
|
|
|
+ line := 1
|
|
|
+
|
|
|
+ // 循环写入数据
|
|
|
+ for i, v := range list {
|
|
|
+ line++
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), i+1)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), model.WaybillStatusMap[v.Status])
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.SenderAddressName)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.SenderAddressPhone)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.SenderAddressDetails)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.ConsigneeAddressName)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.ConsigneeAddressPhone)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), v.ConsigneeAddressDetails)
|
|
|
+ //f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), v.TemperatureInterval)
|
|
|
+ //f.SetCellValue("Sheet1", fmt.Sprintf("J%d", line), v.DeliveryCondition)
|
|
|
+ //f.SetCellValue("Sheet1", fmt.Sprintf("K%d", line), v.CargoType)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), v.Remark)
|
|
|
+
|
|
|
+ }
|
|
|
+ timeStr := time.Now().Format("20060102150405")
|
|
|
+ filePath := "ofile/" + "运单" + timeStr + ".xlsx"
|
|
|
+ // 保存文件
|
|
|
+ if err = f.SaveAs(filePath); err != nil {
|
|
|
+ logs.Error("保存运单失败:", err)
|
|
|
+ }
|
|
|
+ defer func() {
|
|
|
+ os.Remove(filePath)
|
|
|
+ }()
|
|
|
+ c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
|
|
|
+ // PathEscape 函数对中文做处理
|
|
|
+ c.Header("Content-Disposition", "attachment; filename="+url.PathEscape("运单"+timeStr+".xlsx"))
|
|
|
+ c.Header("Content-Transfer-Encoding", "binary")
|
|
|
+ c.File(filePath)
|
|
|
+}
|
|
|
+
|
|
|
+// Home 首页统计
|
|
|
+// @Summary 首页统计
|
|
|
+// @Description 首页统计
|
|
|
+// @Tags 运单
|
|
|
+// @Param no query string false "运单号"
|
|
|
+// @Param pageSize query int false "页条数"
|
|
|
+// @Param page query int false "页码"
|
|
|
+// @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
|
|
|
+// @Router /api/waybill [get]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) Home(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillStatsReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.Query).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //数据权限检查
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+
|
|
|
+ res := s.GetBasicsStats(&req, p)
|
|
|
+ e.OK(res, "查询成功")
|
|
|
+}
|
|
|
+
|
|
|
+// GetAppletPage 获取运单列表
|
|
|
+// @Summary 获取运单列表
|
|
|
+// @Description 获取运单列表
|
|
|
+// @Tags 运单
|
|
|
+// @Param no query string false "运单号"
|
|
|
+// @Param pageSize query int false "页条数"
|
|
|
+// @Param page query int false "页码"
|
|
|
+// @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
|
|
|
+// @Router /api/waybill [get]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) GetAppletPage(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillGetAppletPageReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.Query).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //数据权限检查
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+
|
|
|
+ list := make([]model.Waybill, 0)
|
|
|
+ var count int64
|
|
|
+ err = s.GetAppletPage(&req, &list, &count, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
|
|
|
+}
|
|
|
+
|
|
|
+// GetAppletCount 获取app运单统计数量
|
|
|
+// @Summary 获取app运单统计数量
|
|
|
+// @Description 获取app运单统计数量
|
|
|
+// @Tags 运单
|
|
|
+// @Param no query string false "运单号"
|
|
|
+// @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
|
|
|
+// @Router /api/waybill/applet-count [get]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) GetAppletCount(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ userSvc := service.SysUser{}
|
|
|
+ req := dto.WaybillGetAppletPageReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.Query).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ MakeService(&userSvc.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //数据权限检查
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+ var userObj model.SysUser
|
|
|
+ err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ list := make([]model.Waybill, 0)
|
|
|
+ var count int64
|
|
|
+
|
|
|
+ if userObj.UserType == "customer" {
|
|
|
+ r := dto.WaybillGetCustomerPageReq{}
|
|
|
+ r.PageSize = 9999
|
|
|
+ r.CustomerId = p.UserId
|
|
|
+ err = s.GetCustomerPage(&r, &list, &count, p)
|
|
|
+ var statusCount = make(map[int]int)
|
|
|
+ statusCount[0] = int(count)
|
|
|
+ for _, waybill := range list {
|
|
|
+ if _, ok := statusCount[waybill.Status]; ok {
|
|
|
+ statusCount[waybill.Status] += 1
|
|
|
+ } else {
|
|
|
+ statusCount[waybill.Status] = 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ e.OK(statusCount, "查询成功")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ err = s.GetAppletCount(&list, &count, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ var statusCount = make(map[int]int)
|
|
|
+ statusCount[0] = int(count)
|
|
|
+ for _, waybill := range list {
|
|
|
+ if _, ok := statusCount[waybill.Status]; ok {
|
|
|
+ statusCount[waybill.Status] += 1
|
|
|
+ } else {
|
|
|
+ statusCount[waybill.Status] = 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ e.OK(statusCount, "查询成功")
|
|
|
+}
|
|
|
+
|
|
|
+// Get 通过id获取运单
|
|
|
+// @Summary 通过id获取运单
|
|
|
+// @Description 通过id获取运单
|
|
|
+// @Tags 运单
|
|
|
+// @Param id path string true "运单id"
|
|
|
+// @Success 200 {object} response.Response{data=model.Waybill} "{"code": 200, "data": [...]}"
|
|
|
+// @Router /api/waybill/{id} [get]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) Get(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillGetReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, nil).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var object model.Waybill
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+
|
|
|
+ //数据权限检查
|
|
|
+ err = s.Get(&req, &object, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ e.OK(object, "查询成功")
|
|
|
+}
|
|
|
+
|
|
|
+// GetByWaybillNo 通过id获取运单
|
|
|
+// @Summary 通过id获取运单
|
|
|
+// @Description 通过id获取运单
|
|
|
+// @Tags 运单
|
|
|
+// @Param id path string true "运单id"
|
|
|
+// @Success 200 {object} response.Response{data=model.Waybill} "{"code": 200, "data": [...]}"
|
|
|
+// @Router /api/waybill/no [get]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) GetByWaybillNo(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillGetByWaybillPdfReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.Query).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var object model.Waybill
|
|
|
+
|
|
|
+ //数据权限检查
|
|
|
+ err = s.GetByWaybillNo(&req, &object, nil)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ e.OK(object, "查询成功")
|
|
|
+}
|
|
|
+
|
|
|
+// Insert 添加运单
|
|
|
+// @Summary 添加运单
|
|
|
+// @Description 添加运单
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillInsertReq true "data"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
|
|
|
+// @Router /api/waybill [post]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) Insert(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillInsertReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.JSON).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+ // 设置创建人
|
|
|
+ req.SetCreateBy(user.GetUserId(c))
|
|
|
+ req.SetDeptId(p.DeptId)
|
|
|
+ err = s.Insert(&req)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.OK(req.GetId(), "创建成功")
|
|
|
+}
|
|
|
+
|
|
|
+// AppletInsert 添加运单app
|
|
|
+// @Summary 添加运单app
|
|
|
+// @Description 添加运单app
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillInsertReq true "data"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
|
|
|
+// @Router /api/waybill [post]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) AppletInsert(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillInsertReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.JSON).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+
|
|
|
+ err = s.AppletInsert(&req, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.OK(req.GetId(), "添加成功")
|
|
|
+}
|
|
|
+
|
|
|
+// UpdateStatus 修改运单状态
|
|
|
+// @Summary 修改运单状态
|
|
|
+// @Description 修改运单状态
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillUpdateStatusReq true "body"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
|
|
|
+// @Router /api/waybill [put]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) UpdateStatus(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillUpdateStatusReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+
|
|
|
+ req.SetUpdateBy(user.GetUserId(c))
|
|
|
+ err = s.UpdateStatus(&req, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.OK(req.GetId(), "更新成功")
|
|
|
+}
|
|
|
+
|
|
|
+// Update 修改运单
|
|
|
+// @Summary 修改运单
|
|
|
+// @Description 修改运单
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillUpdateReq true "body"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
|
|
|
+// @Router /api/waybill [put]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) Update(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillUpdateReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+
|
|
|
+ req.SetUpdateBy(user.GetUserId(c))
|
|
|
+ err = s.Update(&req, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.OK(req.GetId(), "更新成功")
|
|
|
+}
|
|
|
+
|
|
|
+// Delivery 派单
|
|
|
+// @Summary 派单
|
|
|
+// @Description 派单
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillDeliveryReq true "body"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
|
|
|
+// @Router /api/waybill [put]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) Delivery(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillDeliveryReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+
|
|
|
+ req.SetUpdateBy(user.GetUserId(c))
|
|
|
+ err = s.Delivery(&req, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ e.OK(req.GetId(), "派单成功")
|
|
|
+}
|
|
|
+
|
|
|
+// Delete 删除运单
|
|
|
+// @Summary 删除运单
|
|
|
+// @Description 删除运单
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillDeleteReq true "body"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
|
|
|
+// @Router /api/waybill [delete]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) Delete(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillDeleteReq{}
|
|
|
+ userSvc := service.SysUser{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.JSON, nil).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ MakeService(&userSvc.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //数据权限检查
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+ err = s.Remove(&req, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.OK(req.GetId(), "删除成功")
|
|
|
+}
|
|
|
+
|
|
|
+// Receipt 签收
|
|
|
+// @Summary 签收
|
|
|
+// @Description 签收
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillInOutReq true "body"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
|
|
|
+// @Router /api/waybill/car-out [post]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) Receipt(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillReceiptReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.JSON, nil).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //数据权限检查
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+ err = s.Receipt(&req, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.OK(req.WaybillNo, "签收成功")
|
|
|
+}
|
|
|
+
|
|
|
+// CustomerReceipt 客户签收
|
|
|
+// @Summary 客户签收
|
|
|
+// @Description 客户签收
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillReceiptReq true "body"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
|
|
|
+// @Router /api/waybill/car-out [post]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) CustomerReceipt(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillReceiptReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.JSON, nil).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ req.WaybillNo = lib.AesDecryptCBC(req.WaybillNo, lib.AesKey)
|
|
|
+ //数据权限检查
|
|
|
+ err = s.Receipt(&req, nil)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.OK(req.WaybillNo, "签收成功")
|
|
|
+}
|
|
|
+
|
|
|
+// GetCustomerPage 获取客户运单列表
|
|
|
+// @Summary 获取客户运单列表
|
|
|
+// @Description 获取客户运单列表
|
|
|
+// @Tags 运单
|
|
|
+// @Param no query string false "运单号"
|
|
|
+// @Param pageSize query int false "页条数"
|
|
|
+// @Param page query int false "页码"
|
|
|
+// @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
|
|
|
+// @Router /api/waybill/customer [get]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) GetCustomerPage(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillGetCustomerPageReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.Query).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //数据权限检查
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+
|
|
|
+ list := make([]model.Waybill, 0)
|
|
|
+ var count int64
|
|
|
+ req.CustomerId = p.UserId
|
|
|
+ err = s.GetCustomerPage(&req, &list, &count, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
|
|
|
+}
|
|
|
+
|
|
|
+func (e WaybillController) CustomerExport(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillGetCustomerPageReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.Query).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //数据权限检查
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+
|
|
|
+ list := make([]model.Waybill, 0)
|
|
|
+ var count int64
|
|
|
+ req.CustomerId = p.UserId
|
|
|
+ req.PageSize = 9999
|
|
|
+ err = s.GetCustomerPage(&req, &list, &count, p)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ f := excelize.NewFile() // 设置单元格的值
|
|
|
+ // 这里设置表头ÒÒ
|
|
|
+ f.SetCellValue("Sheet1", "A1", "序号")
|
|
|
+ f.SetCellValue("Sheet1", "B1", "状态")
|
|
|
+ f.SetCellValue("Sheet1", "C1", "寄件人名称")
|
|
|
+ f.SetCellValue("Sheet1", "D1", "寄件人电话")
|
|
|
+ f.SetCellValue("Sheet1", "E1", "寄件人地址")
|
|
|
+ f.SetCellValue("Sheet1", "F1", "收件人名称")
|
|
|
+ f.SetCellValue("Sheet1", "G1", "收件人电话")
|
|
|
+ f.SetCellValue("Sheet1", "H1", "收件人地址")
|
|
|
+ f.SetCellValue("Sheet1", "I1", "温度要求")
|
|
|
+ f.SetCellValue("Sheet1", "J1", "配送要求")
|
|
|
+ f.SetCellValue("Sheet1", "K1", "货物类型")
|
|
|
+ f.SetCellValue("Sheet1", "L1", "运输备注")
|
|
|
+
|
|
|
+ // 设置列宽
|
|
|
+ f.SetColWidth("Sheet1", "A", "A", 6)
|
|
|
+ f.SetColWidth("Sheet1", "B", "B", 8)
|
|
|
+ f.SetColWidth("Sheet1", "C", "C", 14)
|
|
|
+ f.SetColWidth("Sheet1", "D", "D", 14)
|
|
|
+ f.SetColWidth("Sheet1", "E", "E", 30)
|
|
|
+ f.SetColWidth("Sheet1", "F", "F", 14)
|
|
|
+ f.SetColWidth("Sheet1", "G", "G", 14)
|
|
|
+ f.SetColWidth("Sheet1", "H", "H", 30)
|
|
|
+ f.SetColWidth("Sheet1", "I", "I", 15)
|
|
|
+
|
|
|
+ line := 1
|
|
|
+
|
|
|
+ // 循环写入数据
|
|
|
+ for i, v := range list {
|
|
|
+ line++
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), i+1)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), model.WaybillStatusMap[v.Status])
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.SenderAddressName)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.SenderAddressPhone)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.SenderAddressDetails)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.ConsigneeAddressName)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.ConsigneeAddressPhone)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), v.ConsigneeAddressDetails)
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), v.Remark)
|
|
|
+
|
|
|
+ }
|
|
|
+ timeStr := time.Now().Format("20060102150405")
|
|
|
+ filePath := "ofile/" + "运单" + timeStr + ".xlsx"
|
|
|
+ defer func() {
|
|
|
+ os.Remove(filePath)
|
|
|
+ }()
|
|
|
+ // 保存文件
|
|
|
+ if err = f.SaveAs(filePath); err != nil {
|
|
|
+ logs.Error("保存运单失败:", err)
|
|
|
+ }
|
|
|
+ c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
|
|
|
+ // PathEscape 函数对中文做处理
|
|
|
+ c.Header("Content-Disposition", "attachment; filename="+url.PathEscape("运单"+timeStr+".xlsx"))
|
|
|
+ c.Header("Content-Transfer-Encoding", "binary")
|
|
|
+ c.File(filePath)
|
|
|
+}
|
|
|
+
|
|
|
+// CustomerInsert 客户添加运单
|
|
|
+// @Summary 客户添加运单
|
|
|
+// @Description 客户添加运单
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillInsertReq true "data"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
|
|
|
+// @Router /api/waybill/customer [post]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) CustomerInsert(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ userSvc := service.SysUser{}
|
|
|
+ req := dto.WaybillInsertReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.JSON).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ MakeService(&userSvc.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+ var userObj model.SysUser
|
|
|
+ err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, "获取用户信息失败")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if p.DeptId == 0 && req.DeptId == 0 {
|
|
|
+ e.Error(500, err, "请先选择运输公司")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 设置创建人
|
|
|
+ req.SetCreateBy(user.GetUserId(c))
|
|
|
+ if p.DeptId > 0 {
|
|
|
+ req.SetDeptId(p.DeptId)
|
|
|
+ }
|
|
|
+ err = s.Insert(&req)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.OK(req.GetId(), "创建成功")
|
|
|
+}
|
|
|
+
|
|
|
+// Import 导入运单
|
|
|
+// @Summary 导入运单
|
|
|
+// @Description 导入运单
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillInsertReq true "data"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
|
|
|
+// @Router /api/waybill/import [post]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) Import(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ userSvc := service.SysUser{}
|
|
|
+ req := dto.WaybillImportReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.Form).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ MakeService(&userSvc.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //读取第一fileName的文件
|
|
|
+ fileHeader, err := c.FormFile("file")
|
|
|
+ if err != nil {
|
|
|
+ err = errors.New("文件格式错误" + err.Error())
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if fileHeader.Size > 1024*1024*2 {
|
|
|
+ err = errors.New("文件大小超过2M")
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ file, err := fileHeader.Open()
|
|
|
+ if err != nil {
|
|
|
+ err = errors.New("文件格式错误" + err.Error())
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ defer file.Close()
|
|
|
+
|
|
|
+ xlsx, err := excelize.OpenReader(bufio.NewReader(file))
|
|
|
+ if err != nil {
|
|
|
+ err = errors.New("文件格式错误" + err.Error())
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ p := actions.GetPermissionFromContext(c)
|
|
|
+ if p.DeptId == 0 {
|
|
|
+ e.Error(500, err, "获取用户信息失败")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ var userObj model.SysUser
|
|
|
+ err = userSvc.Get(&dto.SysUserGetReq{Id: p.UserId}, nil, &userObj)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, "获取用户信息失败")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ rows, _ := xlsx.GetRows("Sheet1")
|
|
|
+ for indexRow, row := range rows {
|
|
|
+ if indexRow == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if len(row) < 10 {
|
|
|
+ for i := 0; i < 10-len(row); i++ {
|
|
|
+ row = append(row, "")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for i, colCell := range row {
|
|
|
+ fmt.Println(i, ":", colCell)
|
|
|
+ }
|
|
|
+ quantity, _ := strconv.Atoi(row[6])
|
|
|
+ obj := dto.WaybillInsertReq{
|
|
|
+ Status: 1,
|
|
|
+ SenderAddressName: row[0],
|
|
|
+ SenderAddressPhone: row[1],
|
|
|
+ SenderAddressDetails: row[2],
|
|
|
+ //CustomerName: row[3],
|
|
|
+ ConsigneeAddressName: row[3],
|
|
|
+ ConsigneeAddressPhone: row[4],
|
|
|
+ ConsigneeAddressDetails: row[5],
|
|
|
+ //TemperatureInterval: row[7],
|
|
|
+ //DeliveryCondition: row[8],
|
|
|
+ //CargoType: row[9],
|
|
|
+ Quantity: quantity,
|
|
|
+ TamperProofLabel: row[7], // 防拆标签
|
|
|
+ Remark: row[8],
|
|
|
+ }
|
|
|
+ obj.SetDeptId(p.DeptId)
|
|
|
+ obj.SetCreateBy(user.GetUserId(c))
|
|
|
+ err = s.Insert(&obj)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ e.OK(len(rows)-1, "导入成功")
|
|
|
+}
|
|
|
+
|
|
|
+// ExportTemplate 导出运单模板
|
|
|
+// @Summary 导出运单模板
|
|
|
+// @Description 导出运单模板
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillInsertReq true "data"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
|
|
|
+// @Router /api/waybill/export-template [post]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) ExportTemplate(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ filePath := "./ofile/运单导入模板.xlsx"
|
|
|
+ //打开文件
|
|
|
+ fileTmp, errByOpenFile := os.Open(filePath)
|
|
|
+ defer fileTmp.Close()
|
|
|
+
|
|
|
+ //获取文件的名称
|
|
|
+ fileName := path.Base(filePath)
|
|
|
+ if errByOpenFile != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
|
|
|
+ // PathEscape 函数对中文做处理
|
|
|
+ c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(fileName))
|
|
|
+ c.Header("Content-Transfer-Encoding", "binary")
|
|
|
+ c.File(filePath)
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// TemperaturePDF 导出温度记录
|
|
|
+// @Summary 导出温度记录
|
|
|
+// @Description 导出温度记录
|
|
|
+// @Tags 运单
|
|
|
+// @Accept application/json
|
|
|
+// @Product application/json
|
|
|
+// @Param data body dto.WaybillInsertReq true "data"
|
|
|
+// @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
|
|
|
+// @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
|
|
|
+// @Router /api/waybill/temperature-pdf [post]
|
|
|
+// @Security Bearer
|
|
|
+func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
+ s := service.Waybill{}
|
|
|
+ req := dto.WaybillGetByWaybillPdfReq{}
|
|
|
+ err := e.MakeContext(c).
|
|
|
+ MakeOrm().
|
|
|
+ Bind(&req, binding.Query).
|
|
|
+ MakeService(&s.Service).
|
|
|
+ Errors
|
|
|
+ if err != nil {
|
|
|
+ e.Logger.Error(err)
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var waybill model.Waybill
|
|
|
+ //p := actions.GetPermissionFromContext(c)
|
|
|
+ //err = s.GetByWaybillNo(&req, &waybill, p)
|
|
|
+ err = s.GetByWaybillNo(&req, &waybill, nil)
|
|
|
+ if err != nil {
|
|
|
+ e.Error(500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ DeviceSensor_data, waybillPDF, err := s.GetAllData(&dto.WaybillGetByWaybillNoReq{WaybillNo: req.WaybillNo})
|
|
|
+ // 最高温度、最低温度、最高湿度、最低湿度
|
|
|
+ var maxTemp, minTemp, maxHumidity, minHumidity float32
|
|
|
+ // 最高温度时间、最低温度时间、最高湿度时间、最低湿度时间
|
|
|
+ var maxTempTime, minTempTime, maxHumidityTime, minHumidityTime string
|
|
|
+ // 总温度 总湿度
|
|
|
+ var totalTemp, totalHumidity float32
|
|
|
+ // 平均温度 平均湿度
|
|
|
+ var avgTemp, avgHumidity float32
|
|
|
+ // 温度阈值,湿度阈值
|
|
|
+ var tempThreshold, humidityThreshold string
|
|
|
+ // 记录开始时间,记录结束时间
|
|
|
+ var s_time, e_time string
|
|
|
+
|
|
|
+ var lastTime string
|
|
|
+ var isFirst, isSecond = true, false
|
|
|
+ var first_column, second_column []nats_server.DeviceData_R
|
|
|
+
|
|
|
+ if len(DeviceSensor_data) > 0 {
|
|
|
+ tempThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_tl, DeviceSensor_data[0].T_tu)
|
|
|
+ humidityThreshold = fmt.Sprintf("%.1f-%.1f", DeviceSensor_data[0].T_rhl, DeviceSensor_data[0].T_rhu)
|
|
|
+ s_time = DeviceSensor_data[0].T_time
|
|
|
+ e_time = DeviceSensor_data[len(DeviceSensor_data)-1].T_time
|
|
|
+ // 最高温度及时刻
|
|
|
+ maxTemp = DeviceSensor_data[0].T_t
|
|
|
+ maxTempTime = DeviceSensor_data[0].T_time
|
|
|
+ // 最低温度及时刻
|
|
|
+ minTemp = DeviceSensor_data[0].T_t
|
|
|
+ minTempTime = DeviceSensor_data[0].T_time
|
|
|
+
|
|
|
+ // 最高湿度及时刻
|
|
|
+ maxHumidity = DeviceSensor_data[0].T_rh
|
|
|
+ maxHumidityTime = DeviceSensor_data[0].T_time
|
|
|
+ // 获取最低湿度及时刻
|
|
|
+ minHumidity = DeviceSensor_data[0].T_rh
|
|
|
+ minHumidityTime = DeviceSensor_data[0].T_time
|
|
|
+ for i := 0; i < len(DeviceSensor_data); i++ {
|
|
|
+ data := DeviceSensor_data[i]
|
|
|
+ if data.T_t > maxTemp {
|
|
|
+ maxTemp = data.T_t
|
|
|
+ maxTempTime = data.T_time
|
|
|
+ }
|
|
|
+ if data.T_t < minTemp {
|
|
|
+ minTemp = data.T_t
|
|
|
+ minTempTime = data.T_time
|
|
|
+ }
|
|
|
+ totalTemp += data.T_t
|
|
|
+
|
|
|
+ if data.T_rh > maxHumidity {
|
|
|
+ maxHumidity = data.T_rh
|
|
|
+ maxHumidityTime = data.T_time
|
|
|
+ }
|
|
|
+ if data.T_rh < minHumidity {
|
|
|
+ minHumidity = data.T_rh
|
|
|
+ minHumidityTime = data.T_time
|
|
|
+ }
|
|
|
+ totalHumidity += data.T_rh
|
|
|
+
|
|
|
+ }
|
|
|
+ var sn string
|
|
|
+ for _, w := range waybillPDF {
|
|
|
+ for _, data := range w.Data {
|
|
|
+ if len(lastTime) > 0 {
|
|
|
+ if lastTime != data.T_time && isFirst == true {
|
|
|
+ isFirst = false
|
|
|
+ isSecond = true
|
|
|
+ } else if lastTime != data.T_time && isSecond == true {
|
|
|
+ isFirst = true
|
|
|
+ isSecond = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len(sn) > 0 && sn != data.T_sn && len(first_column)%2 == 1 {
|
|
|
+ isFirst, isSecond = isSecond, isFirst
|
|
|
+ }
|
|
|
+ if isFirst {
|
|
|
+ first_column = append(first_column, data)
|
|
|
+ lastTime = data.T_time
|
|
|
+ sn = data.T_sn
|
|
|
+ }
|
|
|
+ if isSecond {
|
|
|
+ second_column = append(second_column, data)
|
|
|
+ lastTime = data.T_time
|
|
|
+ sn = data.T_sn
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 平均温度
|
|
|
+ avgTemp = totalTemp / float32(len(DeviceSensor_data))
|
|
|
+ // 平均湿度
|
|
|
+ avgHumidity = totalHumidity / float32(len(DeviceSensor_data))
|
|
|
+ }
|
|
|
+
|
|
|
+ // -------------------获取最高温湿度、温蒂温湿度、平均温湿度结束
|
|
|
+
|
|
|
+ pdf := &gopdf.GoPdf{}
|
|
|
+ pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
|
|
|
+
|
|
|
+ err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf")
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = pdf.SetFont("wts", "", 20)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ pdf.SetGrayFill(0.5)
|
|
|
+
|
|
|
+ pdf.SetMargins(0, 20, 0, 20)
|
|
|
+ pdf.AddPage()
|
|
|
+ title := "运单" + req.WaybillNo + "温度记录"
|
|
|
+ if req.HumidityShow {
|
|
|
+ title = "运单" + req.WaybillNo + "温湿度记录"
|
|
|
+ }
|
|
|
+ var y float64 = 40
|
|
|
+ textw, _ := pdf.MeasureTextWidth(title)
|
|
|
+ pdf.SetX((595 / 2) - (textw / 2))
|
|
|
+ pdf.SetY(y)
|
|
|
+ pdf.Text(title)
|
|
|
+
|
|
|
+ //y += 30
|
|
|
+ //pdf.SetFont("wts", "", 16)
|
|
|
+ //pdf.SetXY(10, y)
|
|
|
+ //pdf.Text("实施设备信息")
|
|
|
+ //// 线
|
|
|
+ //y += 10
|
|
|
+ //pdf.SetLineWidth(0.5)
|
|
|
+ //pdf.SetStrokeColor(169, 169, 169)
|
|
|
+ //pdf.Line(10, y, 585, y)
|
|
|
+ //pdf.SetFont("wts", "", 10)
|
|
|
+ //y += 20
|
|
|
+ //pdf.SetXY(10, y)
|
|
|
+ //pdf.Text(fmt.Sprintf("主机名称:%s", device.T_devName))
|
|
|
+ //pdf.SetXY(300, y)
|
|
|
+ //pdf.Text(fmt.Sprintf("主机编号:%s", device.T_sn))
|
|
|
+
|
|
|
+ y += 25
|
|
|
+ pdf.SetFont("wts", "", 16)
|
|
|
+ pdf.SetXY(10, y)
|
|
|
+ pdf.Text("记录概要信息")
|
|
|
+ // 线
|
|
|
+ y += 10
|
|
|
+ pdf.SetLineWidth(0.5)
|
|
|
+ pdf.SetStrokeColor(169, 169, 169)
|
|
|
+ pdf.Line(10, y, 585, y)
|
|
|
+
|
|
|
+ y += 20
|
|
|
+ pdf.SetFont("wts", "", 10)
|
|
|
+ pdf.SetXY(10, y)
|
|
|
+ pdf.Text(fmt.Sprintf("记录开始时间:%s", s_time))
|
|
|
+
|
|
|
+ pdf.SetXY(240, y)
|
|
|
+ pdf.Text(fmt.Sprintf("记录结束时间:%s", e_time))
|
|
|
+
|
|
|
+ sTime, _ := lib.TimeStrToTime(s_time)
|
|
|
+ eTime, _ := lib.TimeStrToTime(e_time)
|
|
|
+ pdf.SetXY(470, y)
|
|
|
+ minutes := int(eTime.Sub(sTime).Minutes())
|
|
|
+ hours := minutes / 60
|
|
|
+ remainingMinutes := minutes % 60
|
|
|
+ pdf.Text(fmt.Sprintf("记录总时间:%dh%dmin", hours, remainingMinutes))
|
|
|
+
|
|
|
+ // -------------最高温/湿度 最低温/湿度 平均温/湿度
|
|
|
+ y += 15
|
|
|
+ pdf.SetXY(10, y)
|
|
|
+ pdf.Text(fmt.Sprintf("最高温度:%.1f℃,%s", lib.RoundToDecimal(float64(maxTemp), 1), maxTempTime))
|
|
|
+
|
|
|
+ pdf.SetXY(240, y)
|
|
|
+ pdf.Text(fmt.Sprintf("最低温度:%.1f℃,%s", lib.RoundToDecimal(float64(minTemp), 1), minTempTime))
|
|
|
+
|
|
|
+ pdf.SetXY(470, y)
|
|
|
+ pdf.Text(fmt.Sprintf("平均温度:%.1f℃", lib.RoundToDecimal(float64(avgTemp), 1)))
|
|
|
+
|
|
|
+ if req.HumidityShow {
|
|
|
+ y += 15
|
|
|
+ pdf.SetXY(10, y)
|
|
|
+ pdf.Text(fmt.Sprintf("最高湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(maxHumidity), 1), maxHumidityTime))
|
|
|
+
|
|
|
+ pdf.SetXY(240, y)
|
|
|
+ pdf.Text(fmt.Sprintf("最低湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(minHumidity), 1), minHumidityTime))
|
|
|
+
|
|
|
+ pdf.SetXY(470, y)
|
|
|
+ pdf.Text(fmt.Sprintf("平均湿度:%.1f%%RH", lib.RoundToDecimal(float64(avgHumidity), 1)))
|
|
|
+ }
|
|
|
+
|
|
|
+ // -------------温/湿度阈值
|
|
|
+
|
|
|
+ y += 15
|
|
|
+ pdf.SetXY(10, y)
|
|
|
+ pdf.Text(fmt.Sprintf("温度阈值:%s℃", tempThreshold))
|
|
|
+
|
|
|
+ if req.HumidityShow {
|
|
|
+ pdf.SetXY(240, y)
|
|
|
+ pdf.Text(fmt.Sprintf("温度阈值:%s%%", humidityThreshold))
|
|
|
+ }
|
|
|
+
|
|
|
+ //-------------发货单位,收货单位,备注
|
|
|
+ y += 15
|
|
|
+ pdf.SetXY(10, y)
|
|
|
+ T_forwarding_unit_temp := []rune(waybill.SenderAddressName)
|
|
|
+ if len(T_forwarding_unit_temp) > 17 {
|
|
|
+ pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp[0:17])))
|
|
|
+ pdf.SetXY(60, y+15)
|
|
|
+ pdf.Text(fmt.Sprintf("%s", string(T_forwarding_unit_temp[17:])))
|
|
|
+ } else {
|
|
|
+ pdf.Text(fmt.Sprintf("发货人:%s", string(T_forwarding_unit_temp)))
|
|
|
+ }
|
|
|
+
|
|
|
+ pdf.SetXY(240, y)
|
|
|
+ T_consignee_unit_temp := []rune(waybill.ConsigneeAddressName)
|
|
|
+ if len(T_consignee_unit_temp) > 17 {
|
|
|
+ pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp[0:17])))
|
|
|
+ pdf.SetXY(290, y+15)
|
|
|
+ pdf.Text(fmt.Sprintf("%s", string(T_consignee_unit_temp[17:])))
|
|
|
+ } else {
|
|
|
+ pdf.Text(fmt.Sprintf("收货人:%s", string(T_consignee_unit_temp)))
|
|
|
+ }
|
|
|
+
|
|
|
+ // 承运方
|
|
|
+ y += 15
|
|
|
+ pdf.SetXY(10, y)
|
|
|
+ company_name := []rune(waybill.Dept.Name)
|
|
|
+ pdf.Text(fmt.Sprintf("承运方:%s", string(company_name)))
|
|
|
+
|
|
|
+ y += 15
|
|
|
+ pdf.SetXY(10, y)
|
|
|
+ T_remark_temp := []rune(waybill.Remark)
|
|
|
+ if len(waybill.Remark) > 35 {
|
|
|
+ pdf.Text(fmt.Sprintf("备注:%s", string(T_remark_temp[0:35])))
|
|
|
+ pdf.SetXY(10, y+15)
|
|
|
+ pdf.Text(fmt.Sprintf("%s", string(T_remark_temp[35:])))
|
|
|
+ } else {
|
|
|
+ pdf.Text(fmt.Sprintf("备注: %s", string(T_remark_temp)))
|
|
|
+ }
|
|
|
+
|
|
|
+ y += 15
|
|
|
+ //pdf.SetFont("wts", "", 16)
|
|
|
+ //pdf.SetXY(10, y)
|
|
|
+ //pdf.Text("记录曲线信息")
|
|
|
+ //// 线
|
|
|
+ //y += 10
|
|
|
+ //pdf.SetLineWidth(0.5)
|
|
|
+ //pdf.SetStrokeColor(169, 169, 169)
|
|
|
+ //pdf.Line(10, y, 585, y)
|
|
|
+ //y += 1
|
|
|
+ //
|
|
|
+ //var tempFilepath string
|
|
|
+ //tempFilepath, err = DeviceDataTemperatureJPG2(s_time, e_time, waybillPDF)
|
|
|
+ //if err == nil {
|
|
|
+ // imgH, _ := gopdf.ImageHolderByPath(tempFilepath)
|
|
|
+ // pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
|
|
|
+ // y += 315
|
|
|
+ //}
|
|
|
+ //
|
|
|
+ //var humidityFilepath string
|
|
|
+ //if req.HumidityShow {
|
|
|
+ // humidityFilepath, err = DeviceDataHumidityJPG2(s_time, e_time, waybillPDF)
|
|
|
+ // if err == nil {
|
|
|
+ // imgH, _ := gopdf.ImageHolderByPath(humidityFilepath)
|
|
|
+ // pdf.ImageByHolder(imgH, 10, y, &gopdf.Rect{W: 575, H: 315})
|
|
|
+ // y += 315
|
|
|
+ // }
|
|
|
+ //}
|
|
|
+
|
|
|
+ if y > 841.89 {
|
|
|
+ // 图片结束直接分页
|
|
|
+ pdf.AddPage()
|
|
|
+ y = 20
|
|
|
+ }
|
|
|
+ y += 20
|
|
|
+ pdf.SetFont("wts", "", 16)
|
|
|
+ pdf.SetXY(10, y)
|
|
|
+ pdf.Text("记录数据信息")
|
|
|
+ // 线
|
|
|
+ y += 10
|
|
|
+ pdf.SetLineWidth(0.5)
|
|
|
+ pdf.SetStrokeColor(169, 169, 169)
|
|
|
+ pdf.Line(10, y, 585, y)
|
|
|
+ y += 10
|
|
|
+ pdf.SetFont("wts", "", 10)
|
|
|
+ var x float64 = 10
|
|
|
+ var w float64 = 112
|
|
|
+ lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ x = x + w
|
|
|
+ w = 101
|
|
|
+ lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+
|
|
|
+ if req.HumidityShow {
|
|
|
+ x = x + w
|
|
|
+ w = 37
|
|
|
+ lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ x = x + w
|
|
|
+ w = 37
|
|
|
+ lib.RectFillColor(pdf, "湿度%", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ } else {
|
|
|
+ x = x + w
|
|
|
+ w = 37 * 2
|
|
|
+ lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ }
|
|
|
+ x = x + w
|
|
|
+ w = 112
|
|
|
+ lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ x = x + w
|
|
|
+ w = 101
|
|
|
+ lib.RectFillColor(pdf, "名称", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+
|
|
|
+ if req.HumidityShow {
|
|
|
+ x = x + w
|
|
|
+ w = 37
|
|
|
+ lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ x = x + w
|
|
|
+ w = 37
|
|
|
+ lib.RectFillColor(pdf, "湿度%", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ } else {
|
|
|
+ x = x + w
|
|
|
+ w = 37 * 2
|
|
|
+ lib.RectFillColor(pdf, "温度℃", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ }
|
|
|
+ y += 20
|
|
|
+ var textH float64 = 25 // if text height is 25px.
|
|
|
+ for i, v := range first_column {
|
|
|
+ pdf.SetNewY(y, textH)
|
|
|
+ y = pdf.GetY()
|
|
|
+ x, w = 10, 112
|
|
|
+
|
|
|
+ lib.RectFillColor(pdf, v.T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ x = x + w
|
|
|
+ w = 101
|
|
|
+ lib.RectFillColor(pdf, v.T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+
|
|
|
+ // 显示温湿度
|
|
|
+ if req.HumidityShow {
|
|
|
+ x = x + w
|
|
|
+ w = 37
|
|
|
+ lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", v.T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ x = x + w
|
|
|
+ w = 37
|
|
|
+ lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", v.T_rh), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ } else {
|
|
|
+ x = x + w
|
|
|
+ w = 37 * 2
|
|
|
+ lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", v.T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ }
|
|
|
+ if i < len(second_column) {
|
|
|
+ x = x + w
|
|
|
+ w = 112
|
|
|
+ lib.RectFillColor(pdf, second_column[i].T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ x = x + w
|
|
|
+ w = 101
|
|
|
+ lib.RectFillColor(pdf, second_column[i].T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+
|
|
|
+ if req.HumidityShow {
|
|
|
+ x = x + w
|
|
|
+ w = 37
|
|
|
+ lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ x = x + w
|
|
|
+ w = 37
|
|
|
+ lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_rh), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ } else {
|
|
|
+ x = x + w
|
|
|
+ w = 37 * 2
|
|
|
+ lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ y += 20
|
|
|
+ }
|
|
|
+ if len(second_column) > len(first_column) {
|
|
|
+ for i := len(first_column); i < len(second_column); i++ {
|
|
|
+ pdf.SetNewY(y, textH)
|
|
|
+ y = pdf.GetY()
|
|
|
+ x, w = 297, 112
|
|
|
+ lib.RectFillColor(pdf, second_column[i].T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ x = x + w
|
|
|
+ w = 101
|
|
|
+ lib.RectFillColor(pdf, second_column[i].T_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+
|
|
|
+ if req.HumidityShow {
|
|
|
+ x = x + w
|
|
|
+ w = 37
|
|
|
+ lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ x = x + w
|
|
|
+ w = 37
|
|
|
+ lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_rh), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+ } else {
|
|
|
+ x = x + w
|
|
|
+ w = 37 * 2
|
|
|
+ lib.RectFillColor(pdf, fmt.Sprintf(" %.1f ", second_column[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
|
|
|
+
|
|
|
+ }
|
|
|
+ y += 20
|
|
|
+ }
|
|
|
+ }
|
|
|
+ filename := "运单" + req.WaybillNo + "温湿度记录" + time.Now().Format("20060102150405") + ".pdf"
|
|
|
+ filePath := "ofile/" + filename
|
|
|
+
|
|
|
+ err = pdf.WritePdf(filePath)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ defer func() {
|
|
|
+ //os.Remove(tempFilepath)
|
|
|
+ //os.Remove(humidityFilepath)
|
|
|
+ os.Remove(filePath)
|
|
|
+ }()
|
|
|
+
|
|
|
+ c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(filename))
|
|
|
+ c.Header("Content-Transfer-Encoding", "binary")
|
|
|
+ c.File(filePath)
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// 获取温度图片
|
|
|
+func DeviceDataTemperatureJPG(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
|
|
|
+
|
|
|
+ if len(waybillPDF) == 0 {
|
|
|
+ return "", errors.New("暂无数据可生成图片")
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建一个新的绘图
|
|
|
+ p := plot.New()
|
|
|
+
|
|
|
+ // 设置绘图标题和标签
|
|
|
+ p.Title.Text = "temperature"
|
|
|
+ //p.Legend.ThumbnailWidth = 20
|
|
|
+
|
|
|
+ deviceSensorList := []nats_server.DeviceSensor_R{}
|
|
|
+ dataList := []nats_server.DeviceData_R{}
|
|
|
+
|
|
|
+ for _, w := range waybillPDF {
|
|
|
+ deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
|
|
|
+ dataList = append(dataList, w.Data...)
|
|
|
+ }
|
|
|
+
|
|
|
+ TemperatureMin := deviceSensorList[0].T_DeviceSensorParameter.T_Tlower
|
|
|
+ TemperatureMax := deviceSensorList[0].T_DeviceSensorParameter.T_Tupper
|
|
|
+
|
|
|
+ var ymin, ymax float32
|
|
|
+ for i, r := range dataList {
|
|
|
+ if i == 0 {
|
|
|
+ ymin = r.T_t
|
|
|
+ ymax = r.T_t
|
|
|
+ }
|
|
|
+ if ymin > r.T_t {
|
|
|
+ ymin = r.T_t
|
|
|
+ }
|
|
|
+ if ymax < r.T_t {
|
|
|
+ ymax = r.T_t
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var chData = make(chan int, 10)
|
|
|
+ var jobGroup sync.WaitGroup
|
|
|
+ // 创建温度线
|
|
|
+ for i := 0; i < len(deviceSensorList); i++ {
|
|
|
+ chData <- 1
|
|
|
+ jobGroup.Add(1)
|
|
|
+ go func(index int) {
|
|
|
+ defer func() {
|
|
|
+ <-chData // 完成时chan取出1个
|
|
|
+ jobGroup.Done() // 完成时将等待组值减1
|
|
|
+ }()
|
|
|
+ sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
|
|
|
+ r_maps := []nats_server.DeviceData_R{}
|
|
|
+ for _, data := range dataList {
|
|
|
+ if data.T_sn == sn && data.T_id == id {
|
|
|
+ r_maps = append(r_maps, data)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Println(r_maps)
|
|
|
+ if len(r_maps) == 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sort.Slice(r_maps, func(i, j int) bool {
|
|
|
+ return r_maps[i].T_time < r_maps[j].T_time
|
|
|
+ })
|
|
|
+
|
|
|
+ pts := make(plotter.XYs, len(r_maps))
|
|
|
+ for j, d := range r_maps {
|
|
|
+ t, _ := lib.TimeStrToTime(d.T_time)
|
|
|
+ pts[j].X = float64(t.Unix())
|
|
|
+ pts[j].Y = float64(d.T_t)
|
|
|
+ }
|
|
|
+
|
|
|
+ line, err := plotter.NewLine(pts)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ line.Color = randomColor(index)
|
|
|
+ p.Add(line)
|
|
|
+ }(i)
|
|
|
+ }
|
|
|
+ jobGroup.Wait()
|
|
|
+
|
|
|
+ st, _ := lib.TimeStrToTime(startTime)
|
|
|
+ et, _ := lib.TimeStrToTime(endTime)
|
|
|
+ xmin, xmax := float64(st.Unix()), float64(et.Unix())
|
|
|
+ // 添加最高,最低标准线 用红色虚线标识
|
|
|
+ p.Add(horizontalLine(xmin, xmax, float64(TemperatureMin)))
|
|
|
+ p.Add(horizontalLine(xmin, xmax, float64(TemperatureMax)))
|
|
|
+
|
|
|
+ if ymax < TemperatureMax {
|
|
|
+ ymax = TemperatureMax
|
|
|
+ }
|
|
|
+ if ymin > 0 {
|
|
|
+ ymin = 0
|
|
|
+ }
|
|
|
+
|
|
|
+ p.Y.Min, p.Y.Max = float64(ymin), float64(ymax)
|
|
|
+
|
|
|
+ p.X.Min, p.X.Max = xmin, xmax
|
|
|
+ p.Y.Tick.Marker = commaTicks{}
|
|
|
+ p.X.Tick.Marker = timeTicks{}
|
|
|
+ p.X.Tick.Label.Rotation = math.Pi / 5
|
|
|
+ p.X.Tick.Label.YAlign = draw.YCenter
|
|
|
+ p.X.Tick.Label.XAlign = draw.XRight
|
|
|
+
|
|
|
+ filepath := "ofile/" + "temperature" + deviceSensorList[0].T_sn + ".jpg"
|
|
|
+ // 保存文件
|
|
|
+ if err := p.Save(10*vg.Inch, 4*vg.Inch, filepath); err != nil {
|
|
|
+
|
|
|
+ logs.Error(lib.FuncName(), "生成图片失败", err)
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ return filepath, nil
|
|
|
+
|
|
|
+}
|
|
|
+func DeviceDataTemperatureJPG2(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
|
|
|
+
|
|
|
+ if len(waybillPDF) == 0 {
|
|
|
+ return "", errors.New("暂无数据可生成图片")
|
|
|
+ }
|
|
|
+
|
|
|
+ deviceSensorList := []nats_server.DeviceSensor_R{}
|
|
|
+ dataList := []nats_server.DeviceData_R{}
|
|
|
+
|
|
|
+ for _, w := range waybillPDF {
|
|
|
+ deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
|
|
|
+ dataList = append(dataList, w.Data...)
|
|
|
+ }
|
|
|
+ TemperatureMin := deviceSensorList[0].T_DeviceSensorParameter.T_Tlower
|
|
|
+ TemperatureMax := deviceSensorList[0].T_DeviceSensorParameter.T_Tupper
|
|
|
+
|
|
|
+ var ymin, ymax float32
|
|
|
+ for i, r := range dataList {
|
|
|
+ if i == 0 {
|
|
|
+ ymin = r.T_t
|
|
|
+ ymax = r.T_t
|
|
|
+ }
|
|
|
+ if ymin > r.T_t {
|
|
|
+ ymin = r.T_t
|
|
|
+ }
|
|
|
+ if ymax < r.T_t {
|
|
|
+ ymax = r.T_t
|
|
|
+ }
|
|
|
+ }
|
|
|
+ series := make([]chart.Series, 0)
|
|
|
+ var chData = make(chan int, 10)
|
|
|
+ var jobGroup sync.WaitGroup
|
|
|
+ // 创建温度线
|
|
|
+ for i := 0; i < len(deviceSensorList); i++ {
|
|
|
+ chData <- 1
|
|
|
+ jobGroup.Add(1)
|
|
|
+ go func(index int) {
|
|
|
+ defer func() {
|
|
|
+ <-chData // 完成时chan取出1个
|
|
|
+ jobGroup.Done() // 完成时将等待组值减1
|
|
|
+ }()
|
|
|
+ sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
|
|
|
+ r_maps := []nats_server.DeviceData_R{}
|
|
|
+ for _, data := range dataList {
|
|
|
+ if data.T_sn == sn && data.T_id == id {
|
|
|
+ r_maps = append(r_maps, data)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Println(r_maps)
|
|
|
+ if len(r_maps) == 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sort.Slice(r_maps, func(i, j int) bool {
|
|
|
+ return r_maps[i].T_time < r_maps[j].T_time
|
|
|
+ })
|
|
|
+
|
|
|
+ xValues := make([]time.Time, len(r_maps))
|
|
|
+ yValues := make([]float64, len(r_maps))
|
|
|
+
|
|
|
+ for j := 0; j < len(r_maps); j++ {
|
|
|
+ t, _ := lib.TimeStrToTime(r_maps[j].T_time)
|
|
|
+ xValues[j] = t
|
|
|
+ yValues[j] = float64(r_maps[j].T_t)
|
|
|
+ }
|
|
|
+ series = append(series, chart.TimeSeries{
|
|
|
+ Name: fmt.Sprintf("%s-%d", sn, id),
|
|
|
+ XValues: xValues,
|
|
|
+ YValues: yValues,
|
|
|
+ })
|
|
|
+ }(i)
|
|
|
+ }
|
|
|
+ jobGroup.Wait()
|
|
|
+ if ymax < TemperatureMax {
|
|
|
+ ymax = TemperatureMax
|
|
|
+ }
|
|
|
+ if ymin > 0 {
|
|
|
+ ymin = 0
|
|
|
+ }
|
|
|
+
|
|
|
+ if ymin > TemperatureMin {
|
|
|
+ ymin = TemperatureMin
|
|
|
+ }
|
|
|
+
|
|
|
+ st, _ := lib.TimeStrToTime(startTime)
|
|
|
+ et, _ := lib.TimeStrToTime(endTime)
|
|
|
+ series = append(series, chart.TimeSeries{
|
|
|
+ Style: chart.Style{
|
|
|
+ StrokeColor: drawing.ColorRed,
|
|
|
+ StrokeDashArray: []float64{5.0, 5.0},
|
|
|
+ },
|
|
|
+ XValues: []time.Time{st, et},
|
|
|
+ YValues: []float64{float64(TemperatureMin), float64(TemperatureMin)},
|
|
|
+ })
|
|
|
+ series = append(series, chart.TimeSeries{
|
|
|
+ Style: chart.Style{
|
|
|
+ StrokeColor: drawing.ColorRed,
|
|
|
+ StrokeDashArray: []float64{5.0, 5.0},
|
|
|
+ },
|
|
|
+ XValues: []time.Time{st, et},
|
|
|
+ YValues: []float64{float64(TemperatureMax), float64(TemperatureMax)},
|
|
|
+ })
|
|
|
+ font := getZWFont()
|
|
|
+ graph := chart.Chart{
|
|
|
+ Title: "温度记录",
|
|
|
+ TitleStyle: chart.Style{
|
|
|
+ FontSize: 15,
|
|
|
+ },
|
|
|
+ Background: chart.Style{
|
|
|
+ Padding: chart.Box{
|
|
|
+ Top: 20,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ Font: font,
|
|
|
+ XAxis: chart.XAxis{
|
|
|
+ Name: "时间",
|
|
|
+ ValueFormatter: chart.TimeValueFormatterWithFormat("2006-01-02 15:04"),
|
|
|
+ },
|
|
|
+ YAxis: chart.YAxis{
|
|
|
+ Name: "温度",
|
|
|
+ Range: &chart.ContinuousRange{
|
|
|
+ Min: float64(ymin),
|
|
|
+ Max: float64(ymax + 2),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ Series: series,
|
|
|
+ }
|
|
|
+ //graph.Elements = []chart.Renderable{
|
|
|
+ // chart.Legend(&graph),
|
|
|
+ //}
|
|
|
+
|
|
|
+ filepath := "ofile/" + "temperature" + deviceSensorList[0].T_sn + ".jpg"
|
|
|
+ f, _ := os.Create(filepath)
|
|
|
+ defer f.Close()
|
|
|
+ graph.Render(chart.PNG, f)
|
|
|
+
|
|
|
+ return filepath, nil
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// 获取湿度图片
|
|
|
+func DeviceDataHumidityJPG(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
|
|
|
+
|
|
|
+ if len(waybillPDF) == 0 {
|
|
|
+ return "", errors.New("暂无数据可生成图片")
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建一个新的绘图
|
|
|
+ p := plot.New()
|
|
|
+
|
|
|
+ // 设置绘图标题和标签
|
|
|
+ p.Title.Text = "humidity"
|
|
|
+
|
|
|
+ deviceSensorList := []nats_server.DeviceSensor_R{}
|
|
|
+ dataList := []nats_server.DeviceData_R{}
|
|
|
+
|
|
|
+ for _, w := range waybillPDF {
|
|
|
+ deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
|
|
|
+ dataList = append(dataList, w.Data...)
|
|
|
+ }
|
|
|
+
|
|
|
+ humidityMin := deviceSensorList[0].T_DeviceSensorParameter.T_RHlower
|
|
|
+ humidityMax := deviceSensorList[0].T_DeviceSensorParameter.T_RHupper
|
|
|
+
|
|
|
+ var ymin, ymax float32
|
|
|
+ for i, r := range dataList {
|
|
|
+ if i == 0 {
|
|
|
+ ymin = r.T_rh
|
|
|
+ ymax = r.T_rh
|
|
|
+ }
|
|
|
+ if ymin > r.T_rh {
|
|
|
+ ymin = r.T_rh
|
|
|
+ }
|
|
|
+ if ymax < r.T_rh {
|
|
|
+ ymax = r.T_rh
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var chData = make(chan int, 10)
|
|
|
+ var jobGroup sync.WaitGroup
|
|
|
+ // 创建温度线
|
|
|
+ for i := 0; i < len(deviceSensorList); i++ {
|
|
|
+ chData <- 1
|
|
|
+ jobGroup.Add(1)
|
|
|
+ go func(index int) {
|
|
|
+ defer func() {
|
|
|
+ <-chData // 完成时chan取出1个
|
|
|
+ jobGroup.Done() // 完成时将等待组值减1
|
|
|
+ }()
|
|
|
+ sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
|
|
|
+ r_maps := []nats_server.DeviceData_R{}
|
|
|
+ for _, data := range dataList {
|
|
|
+ if data.T_sn == sn && data.T_id == id {
|
|
|
+ r_maps = append(r_maps, data)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len(r_maps) == 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sort.Slice(r_maps, func(i, j int) bool {
|
|
|
+ return r_maps[i].T_time < r_maps[j].T_time
|
|
|
+ })
|
|
|
+
|
|
|
+ pts := make(plotter.XYs, len(r_maps))
|
|
|
+ for j, d := range r_maps {
|
|
|
+ t, _ := lib.TimeStrToTime(d.T_time)
|
|
|
+ pts[j].X = float64(t.Unix())
|
|
|
+ pts[j].Y = float64(d.T_rh)
|
|
|
+ }
|
|
|
+
|
|
|
+ line, err := plotter.NewLine(pts)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ line.Color = randomColor(index)
|
|
|
+ p.Add(line)
|
|
|
+ }(i)
|
|
|
+ }
|
|
|
+ jobGroup.Wait()
|
|
|
+
|
|
|
+ st, _ := lib.TimeStrToTime(startTime)
|
|
|
+ et, _ := lib.TimeStrToTime(endTime)
|
|
|
+ xmin, xmax := float64(st.Unix()), float64(et.Unix())
|
|
|
+ // 添加最高,最低标准线 用红色虚线标识
|
|
|
+ p.Add(horizontalLine(xmin, xmax, float64(humidityMin)))
|
|
|
+ p.Add(horizontalLine(xmin, xmax, float64(humidityMax)))
|
|
|
+
|
|
|
+ if ymax < humidityMax {
|
|
|
+ ymax = humidityMax
|
|
|
+ }
|
|
|
+ if ymin > 0 {
|
|
|
+ ymin = 0
|
|
|
+ }
|
|
|
+
|
|
|
+ p.Y.Min, p.Y.Max = float64(ymin), float64(ymax)
|
|
|
+
|
|
|
+ p.X.Min, p.X.Max = xmin, xmax
|
|
|
+ p.Y.Tick.Marker = commaTicks{}
|
|
|
+ //p.X.Tick.Marker = plot.TimeTicks{Format: "2006-01-02 15:04:05"}
|
|
|
+ p.X.Tick.Marker = timeTicks{}
|
|
|
+ p.X.Tick.Label.Rotation = math.Pi / 5
|
|
|
+ p.X.Tick.Label.YAlign = draw.YCenter
|
|
|
+ p.X.Tick.Label.XAlign = draw.XRight
|
|
|
+
|
|
|
+ filepath := "ofile/" + "humidity" + deviceSensorList[0].T_sn + ".jpg"
|
|
|
+ // 保存文件
|
|
|
+ if err := p.Save(10*vg.Inch, 4*vg.Inch, filepath); err != nil {
|
|
|
+
|
|
|
+ logs.Error(lib.FuncName(), "生成图片失败", err)
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ return filepath, nil
|
|
|
+
|
|
|
+}
|
|
|
+func DeviceDataHumidityJPG2(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
|
|
|
+
|
|
|
+ if len(waybillPDF) == 0 {
|
|
|
+ return "", errors.New("暂无数据可生成图片")
|
|
|
+ }
|
|
|
+
|
|
|
+ deviceSensorList := []nats_server.DeviceSensor_R{}
|
|
|
+ dataList := []nats_server.DeviceData_R{}
|
|
|
+
|
|
|
+ for _, w := range waybillPDF {
|
|
|
+ deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
|
|
|
+ dataList = append(dataList, w.Data...)
|
|
|
+ }
|
|
|
+ humidityMin := deviceSensorList[0].T_DeviceSensorParameter.T_RHlower
|
|
|
+ humidityMax := deviceSensorList[0].T_DeviceSensorParameter.T_RHupper
|
|
|
+
|
|
|
+ var ymin, ymax float32
|
|
|
+ for i, r := range dataList {
|
|
|
+ if i == 0 {
|
|
|
+ ymin = r.T_t
|
|
|
+ ymax = r.T_t
|
|
|
+ }
|
|
|
+ if ymin > r.T_t {
|
|
|
+ ymin = r.T_t
|
|
|
+ }
|
|
|
+ if ymax < r.T_t {
|
|
|
+ ymax = r.T_t
|
|
|
+ }
|
|
|
+ }
|
|
|
+ series := make([]chart.Series, 0)
|
|
|
+ var chData = make(chan int, 10)
|
|
|
+ var jobGroup sync.WaitGroup
|
|
|
+ // 创建温度线
|
|
|
+ for i := 0; i < len(deviceSensorList); i++ {
|
|
|
+ chData <- 1
|
|
|
+ jobGroup.Add(1)
|
|
|
+ go func(index int) {
|
|
|
+ defer func() {
|
|
|
+ <-chData // 完成时chan取出1个
|
|
|
+ jobGroup.Done() // 完成时将等待组值减1
|
|
|
+ }()
|
|
|
+ sn, id := deviceSensorList[index].T_sn, deviceSensorList[index].T_id
|
|
|
+ r_maps := []nats_server.DeviceData_R{}
|
|
|
+ for _, data := range dataList {
|
|
|
+ if data.T_sn == sn && data.T_id == id {
|
|
|
+ r_maps = append(r_maps, data)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(r_maps) == 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sort.Slice(r_maps, func(i, j int) bool {
|
|
|
+ return r_maps[i].T_time < r_maps[j].T_time
|
|
|
+ })
|
|
|
+
|
|
|
+ xValues := make([]time.Time, len(r_maps))
|
|
|
+ yValues := make([]float64, len(r_maps))
|
|
|
+
|
|
|
+ for j := 0; j < len(r_maps); j++ {
|
|
|
+ t, _ := lib.TimeStrToTime(r_maps[j].T_time)
|
|
|
+ xValues[j] = t
|
|
|
+ yValues[j] = float64(r_maps[j].T_rh)
|
|
|
+ }
|
|
|
+ series = append(series, chart.TimeSeries{
|
|
|
+ Name: fmt.Sprintf("%s-%d", sn, id),
|
|
|
+ XValues: xValues,
|
|
|
+ YValues: yValues,
|
|
|
+ })
|
|
|
+ }(i)
|
|
|
+ }
|
|
|
+ jobGroup.Wait()
|
|
|
+ if ymax < humidityMax {
|
|
|
+ ymax = humidityMax
|
|
|
+ }
|
|
|
+ if ymin > 0 {
|
|
|
+ ymin = 0
|
|
|
+ }
|
|
|
+
|
|
|
+ if ymin > humidityMin {
|
|
|
+ ymin = humidityMin
|
|
|
+ }
|
|
|
+
|
|
|
+ st, _ := lib.TimeStrToTime(startTime)
|
|
|
+ et, _ := lib.TimeStrToTime(endTime)
|
|
|
+ series = append(series, chart.TimeSeries{
|
|
|
+ Style: chart.Style{
|
|
|
+ StrokeColor: drawing.ColorRed,
|
|
|
+ StrokeDashArray: []float64{5.0, 5.0},
|
|
|
+ },
|
|
|
+ XValues: []time.Time{st, et},
|
|
|
+ YValues: []float64{float64(humidityMin), float64(humidityMin)},
|
|
|
+ })
|
|
|
+ series = append(series, chart.TimeSeries{
|
|
|
+ Style: chart.Style{
|
|
|
+ StrokeColor: drawing.ColorRed,
|
|
|
+ StrokeDashArray: []float64{5.0, 5.0},
|
|
|
+ },
|
|
|
+ XValues: []time.Time{st, et},
|
|
|
+ YValues: []float64{float64(humidityMax), float64(humidityMax)},
|
|
|
+ })
|
|
|
+ font := getZWFont()
|
|
|
+ graph := chart.Chart{
|
|
|
+ Title: "湿度记录",
|
|
|
+ TitleStyle: chart.Style{
|
|
|
+ FontSize: 15,
|
|
|
+ },
|
|
|
+ Background: chart.Style{
|
|
|
+ Padding: chart.Box{
|
|
|
+ Top: 20,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ Font: font,
|
|
|
+ XAxis: chart.XAxis{
|
|
|
+ Name: "时间",
|
|
|
+ ValueFormatter: chart.TimeValueFormatterWithFormat("2006-01-02 15:04"),
|
|
|
+ },
|
|
|
+ YAxis: chart.YAxis{
|
|
|
+ Name: "湿度",
|
|
|
+ Range: &chart.ContinuousRange{
|
|
|
+ Min: float64(ymin),
|
|
|
+ Max: float64(ymax + 2),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ Series: series,
|
|
|
+ }
|
|
|
+ //graph.Elements = []chart.Renderable{
|
|
|
+ // chart.Legend(&graph),
|
|
|
+ //}
|
|
|
+
|
|
|
+ filepath := "ofile/" + "humidity" + deviceSensorList[0].T_sn + ".jpg"
|
|
|
+ f, _ := os.Create(filepath)
|
|
|
+ defer f.Close()
|
|
|
+ graph.Render(chart.PNG, f)
|
|
|
+
|
|
|
+ return filepath, nil
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func horizontalLine(xmin, xmax, y float64) *plotter.Line {
|
|
|
+ pts := make(plotter.XYs, 2)
|
|
|
+ pts[0].X = xmin
|
|
|
+ pts[0].Y = y
|
|
|
+ pts[1].X = xmax
|
|
|
+ pts[1].Y = y
|
|
|
+ line, err := plotter.NewLine(pts)
|
|
|
+ if err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ line.LineStyle.Dashes = []vg.Length{vg.Points(8), vg.Points(5), vg.Points(1), vg.Points(5)}
|
|
|
+ line.Color = color.RGBA{R: 255, A: 255}
|
|
|
+ return line
|
|
|
+}
|
|
|
+
|
|
|
+type timeTicks struct{}
|
|
|
+
|
|
|
+func (timeTicks) Ticks(min, max float64) []plot.Tick {
|
|
|
+ tks := plot.TimeTicks{}.Ticks(min, max)
|
|
|
+ for i, t := range tks {
|
|
|
+ //if t.Label == "" { // Skip minor ticks, they are fine.
|
|
|
+ // continue
|
|
|
+ //}
|
|
|
+ tks[i].Label = time.Unix(int64(t.Value), 0).Format("2006-01-02 15:04:05")
|
|
|
+ }
|
|
|
+
|
|
|
+ return tks
|
|
|
+}
|
|
|
+
|
|
|
+type commaTicks struct{}
|
|
|
+
|
|
|
+// Ticks computes the default tick marks, but inserts commas
|
|
|
+// into the labels for the major tick marks.
|
|
|
+func (commaTicks) Ticks(min, max float64) []plot.Tick {
|
|
|
+ tks := plot.DefaultTicks{}.Ticks(min, max)
|
|
|
+ for i, t := range tks {
|
|
|
+ //if t.Label == "" { // Skip minor ticks, they are fine.
|
|
|
+ // continue
|
|
|
+ //}
|
|
|
+ tks[i].Label = fmt.Sprintf("%.0f", t.Value)
|
|
|
+ }
|
|
|
+
|
|
|
+ return tks
|
|
|
+}
|
|
|
+
|
|
|
+// 生成随机颜色的辅助函数
|
|
|
+func randomColor(i int) color.RGBA {
|
|
|
+ var colors []color.RGBA
|
|
|
+ colors = append(colors,
|
|
|
+ color.RGBA{R: 52, G: 152, B: 219, A: 255},
|
|
|
+ color.RGBA{R: 230, G: 126, B: 34, A: 255},
|
|
|
+ color.RGBA{R: 142, G: 68, B: 173, A: 255},
|
|
|
+ color.RGBA{R: 211, G: 84, B: 0, A: 255},
|
|
|
+ color.RGBA{R: 231, G: 76, B: 60, A: 255},
|
|
|
+ color.RGBA{R: 26, G: 188, B: 156, A: 255},
|
|
|
+ color.RGBA{R: 243, G: 156, B: 18, A: 255},
|
|
|
+ color.RGBA{R: 22, G: 160, B: 133, A: 255},
|
|
|
+ color.RGBA{R: 46, G: 204, B: 113, A: 255},
|
|
|
+ color.RGBA{R: 39, G: 174, B: 96, A: 255},
|
|
|
+ color.RGBA{R: 41, G: 128, B: 185, A: 255},
|
|
|
+ color.RGBA{R: 155, G: 89, B: 182, A: 255},
|
|
|
+ color.RGBA{R: 192, G: 57, B: 43, A: 255},
|
|
|
+ color.RGBA{R: 241, G: 196, B: 15, A: 255},
|
|
|
+ )
|
|
|
+
|
|
|
+ return colors[i%len(colors)]
|
|
|
+}
|
|
|
+func randomColor2(i int) drawing.Color {
|
|
|
+ var colors []drawing.Color
|
|
|
+ colors = append(colors,
|
|
|
+ drawing.Color{R: 52, G: 152, B: 219, A: 255},
|
|
|
+ drawing.Color{R: 230, G: 126, B: 34, A: 255},
|
|
|
+ drawing.Color{R: 142, G: 68, B: 173, A: 255},
|
|
|
+ drawing.Color{R: 211, G: 84, B: 0, A: 255},
|
|
|
+ drawing.Color{R: 231, G: 76, B: 60, A: 255},
|
|
|
+ drawing.Color{R: 26, G: 188, B: 156, A: 255},
|
|
|
+ drawing.Color{R: 243, G: 156, B: 18, A: 255},
|
|
|
+ drawing.Color{R: 22, G: 160, B: 133, A: 255},
|
|
|
+ drawing.Color{R: 46, G: 204, B: 113, A: 255},
|
|
|
+ drawing.Color{R: 39, G: 174, B: 96, A: 255},
|
|
|
+ drawing.Color{R: 41, G: 128, B: 185, A: 255},
|
|
|
+ drawing.Color{R: 155, G: 89, B: 182, A: 255},
|
|
|
+ drawing.Color{R: 192, G: 57, B: 43, A: 255},
|
|
|
+ drawing.Color{R: 241, G: 196, B: 15, A: 255},
|
|
|
+ )
|
|
|
+ return colors[i%len(colors)]
|
|
|
+}
|
|
|
+
|
|
|
+// getZWFont 加载字体
|
|
|
+func getZWFont() *truetype.Font {
|
|
|
+ fontFile := "./static/fonts/MiSans-Medium.ttf"
|
|
|
+ fontBytes, err := os.ReadFile(fontFile)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ font, err := truetype.Parse(fontBytes)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ return font
|
|
|
+}
|