|
@@ -13,6 +13,7 @@ import (
|
|
|
"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"
|
|
@@ -25,6 +26,7 @@ import (
|
|
|
"gonum.org/v1/plot/vg"
|
|
|
"gonum.org/v1/plot/vg/draw"
|
|
|
"image/color"
|
|
|
+ "log"
|
|
|
"math"
|
|
|
"net/url"
|
|
|
"os"
|
|
@@ -253,11 +255,13 @@ func (e WaybillController) GetAppletPage(c *gin.Context) {
|
|
|
// @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)
|
|
@@ -267,9 +271,33 @@ func (e WaybillController) GetAppletCount(c *gin.Context) {
|
|
|
|
|
|
//数据权限检查
|
|
|
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())
|
|
@@ -1030,7 +1058,7 @@ func (e WaybillController) ExportTemplate(c *gin.Context) {
|
|
|
// @Security Bearer
|
|
|
func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
s := service.Waybill{}
|
|
|
- req := dto.WaybillGetByWaybillNoReq{}
|
|
|
+ req := dto.WaybillGetByWaybillPdfReq{}
|
|
|
err := e.MakeContext(c).
|
|
|
MakeOrm().
|
|
|
Bind(&req, binding.Query).
|
|
@@ -1048,7 +1076,7 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
e.Error(500, err, err.Error())
|
|
|
return
|
|
|
}
|
|
|
- DeviceSensor_data, waybillPDF, err := s.GetAllData(&req)
|
|
|
+ DeviceSensor_data, waybillPDF, err := s.GetAllData(&dto.WaybillGetByWaybillNoReq{WaybillNo: req.WaybillNo})
|
|
|
// 最高温度、最低温度、最高湿度、最低湿度
|
|
|
var maxTemp, minTemp, maxHumidity, minHumidity float32
|
|
|
// 最高温度时间、最低温度时间、最高湿度时间、最低湿度时间
|
|
@@ -1119,7 +1147,7 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
isSecond = false
|
|
|
}
|
|
|
}
|
|
|
- if len(sn) > 0 && sn != data.T_sn {
|
|
|
+ if len(sn) > 0 && sn != data.T_sn && len(first_column)%2 == 1 {
|
|
|
isFirst, isSecond = isSecond, isFirst
|
|
|
}
|
|
|
if isFirst {
|
|
@@ -1184,7 +1212,7 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
//pdf.SetXY(300, y)
|
|
|
//pdf.Text(fmt.Sprintf("主机编号:%s", device.T_sn))
|
|
|
|
|
|
- y += 35
|
|
|
+ y += 25
|
|
|
pdf.SetFont("wts", "", 16)
|
|
|
pdf.SetXY(10, y)
|
|
|
pdf.Text("记录概要信息")
|
|
@@ -1221,15 +1249,17 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
pdf.SetXY(470, y)
|
|
|
pdf.Text(fmt.Sprintf("平均温度:%.1f℃", lib.RoundToDecimal(float64(avgTemp), 1)))
|
|
|
|
|
|
- y += 15
|
|
|
- pdf.SetXY(10, y)
|
|
|
- pdf.Text(fmt.Sprintf("最高湿度:%.1f%%RH,%s", lib.RoundToDecimal(float64(maxHumidity), 1), maxHumidityTime))
|
|
|
+ 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(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)))
|
|
|
+ pdf.SetXY(470, y)
|
|
|
+ pdf.Text(fmt.Sprintf("平均湿度:%.1f%%RH", lib.RoundToDecimal(float64(avgHumidity), 1)))
|
|
|
+ }
|
|
|
|
|
|
// -------------温/湿度阈值
|
|
|
|
|
@@ -1237,8 +1267,10 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
pdf.SetXY(10, y)
|
|
|
pdf.Text(fmt.Sprintf("温度阈值:%s℃", tempThreshold))
|
|
|
|
|
|
- pdf.SetXY(240, y)
|
|
|
- pdf.Text(fmt.Sprintf("温度阈值:%s%%", humidityThreshold))
|
|
|
+ if req.HumidityShow {
|
|
|
+ pdf.SetXY(240, y)
|
|
|
+ pdf.Text(fmt.Sprintf("温度阈值:%s%%", humidityThreshold))
|
|
|
+ }
|
|
|
|
|
|
//-------------发货单位,收货单位,备注
|
|
|
y += 15
|
|
@@ -1260,9 +1292,14 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
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)
|
|
@@ -1286,18 +1323,21 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
y += 1
|
|
|
|
|
|
var tempFilepath string
|
|
|
- tempFilepath, err = DeviceDataTemperatureJPG(s_time, e_time, waybillPDF)
|
|
|
+ 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
|
|
|
- humidityFilepath, err = DeviceDataHumidityJPG(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 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 {
|
|
@@ -1323,13 +1363,18 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
w = 101
|
|
|
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)
|
|
|
- x = x + w
|
|
|
- w = 37
|
|
|
- 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)
|
|
@@ -1337,13 +1382,18 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
w = 101
|
|
|
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)
|
|
|
- x = x + w
|
|
|
- w = 37
|
|
|
- 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 {
|
|
@@ -1357,14 +1407,18 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
lib.RectFillColor(pdf, v.T_name, 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_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)
|
|
|
-
|
|
|
+ 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
|
|
@@ -1373,13 +1427,18 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
w = 101
|
|
|
lib.RectFillColor(pdf, second_column[i].T_name, 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_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)
|
|
|
-
|
|
|
+ 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
|
|
@@ -1394,13 +1453,19 @@ func (e WaybillController) TemperaturePDF(c *gin.Context) {
|
|
|
w = 101
|
|
|
lib.RectFillColor(pdf, second_column[i].T_name, 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_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)
|
|
|
+ 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
|
|
|
}
|
|
|
}
|
|
@@ -1480,6 +1545,8 @@ func DeviceDataTemperatureJPG(startTime, endTime string, waybillPDF []service.Wa
|
|
|
r_maps = append(r_maps, data)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ fmt.Println(r_maps)
|
|
|
if len(r_maps) == 0 {
|
|
|
return
|
|
|
}
|
|
@@ -1538,6 +1605,145 @@ func DeviceDataTemperatureJPG(startTime, endTime string, waybillPDF []service.Wa
|
|
|
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) {
|
|
@@ -1654,6 +1860,145 @@ func DeviceDataHumidityJPG(startTime, endTime string, waybillPDF []service.Waybi
|
|
|
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
|
|
@@ -1742,87 +2087,18 @@ func randomColor2(i int) drawing.Color {
|
|
|
return colors[i%len(colors)]
|
|
|
}
|
|
|
|
|
|
-func DeviceDataHumidityJPG2(startTime, endTime string, waybillPDF []service.WaybillPDF) (string, error) {
|
|
|
-
|
|
|
- graph := chart.Chart{
|
|
|
- // 设置标题
|
|
|
- Title: "温度曲线图",
|
|
|
- // 设置X轴的标签
|
|
|
- XAxis: chart.XAxis{
|
|
|
- Name: "时间",
|
|
|
- // 设置时间轴
|
|
|
- ValueFormatter: chart.TimeValueFormatterWithFormat("2006-01-02 15:04:05"),
|
|
|
- },
|
|
|
- // 设置Y轴的标签
|
|
|
- YAxis: chart.YAxis{
|
|
|
- Name: "温度℃",
|
|
|
- },
|
|
|
- }
|
|
|
- deviceSensorList := []nats_server.DeviceSensor_R{}
|
|
|
- dataList := []nats_server.DeviceData_R{}
|
|
|
-
|
|
|
- for _, w := range waybillPDF {
|
|
|
- deviceSensorList = append(deviceSensorList, w.DeviceSensorList...)
|
|
|
- dataList = append(dataList, w.Data...)
|
|
|
- }
|
|
|
-
|
|
|
- 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
|
|
|
- })
|
|
|
- var XValues []float64
|
|
|
- var YValues []float64
|
|
|
- for _, d := range r_maps {
|
|
|
- t, _ := lib.TimeStrToTime(d.T_time)
|
|
|
- XValues = append(XValues, float64(t.Unix()))
|
|
|
- YValues = append(YValues, float64(d.T_t))
|
|
|
- }
|
|
|
- // 添加第一条折线系列
|
|
|
- graph.Series = append(graph.Series, chart.ContinuousSeries{
|
|
|
- Name: deviceSensorList[index].T_name,
|
|
|
- Style: chart.Style{
|
|
|
- StrokeColor: randomColor2(index),
|
|
|
- StrokeWidth: 2.0,
|
|
|
- },
|
|
|
- XValues: XValues,
|
|
|
- YValues: YValues,
|
|
|
- })
|
|
|
- }(i)
|
|
|
- }
|
|
|
- jobGroup.Wait()
|
|
|
-
|
|
|
- filepath := "ofile/" + "humidity" + deviceSensorList[0].T_sn + ".jpg"
|
|
|
- // 输出图表到PNG文件
|
|
|
- f, err := os.Create(filepath)
|
|
|
+// getZWFont 加载字体
|
|
|
+func getZWFont() *truetype.Font {
|
|
|
+ fontFile := "./static/fonts/MiSans-Medium.ttf"
|
|
|
+ fontBytes, err := os.ReadFile(fontFile)
|
|
|
if err != nil {
|
|
|
- panic(err)
|
|
|
+ log.Println(err)
|
|
|
+ return nil
|
|
|
}
|
|
|
- defer f.Close()
|
|
|
- err = graph.Render(chart.PNG, f)
|
|
|
+ font, err := truetype.Parse(fontBytes)
|
|
|
if err != nil {
|
|
|
- panic(err)
|
|
|
+ log.Println(err)
|
|
|
+ return nil
|
|
|
}
|
|
|
-
|
|
|
- return filepath, nil
|
|
|
-
|
|
|
+ return font
|
|
|
}
|