浏览代码

update:优化导出温湿度pdf

zoie 3 月之前
父节点
当前提交
07b284c9b3
共有 6 个文件被更改,包括 257 次插入178 次删除
  1. 2 0
      Nats/Nats.go
  2. 8 0
      Nats/NatsServer/NatsServer.go
  3. 211 178
      controllers/TaskData.go
  4. 26 0
      lib/libString.go
  5. 5 0
      models/Task/Task.go
  6. 5 0
      models/Task/TaskData.go

+ 2 - 0
Nats/Nats.go

@@ -248,6 +248,8 @@ func NatsInit() {
 		if err != nil {
 			logs.Error(lib.FuncName(), err)
 		}
+		// 删除绑定数据区间外的数据
+		NatsServer.Del_TaskData_ByT_BindDeviceDataTime(T_task_id)
 
 		System.Add_UserLogs_T(T_uuid, "任务数据-更新线上数据", "z_task_data_"+T_task_id, "成功")
 		logs.Info("--------导入数据到【线上】成功!---------")

+ 8 - 0
Nats/NatsServer/NatsServer.go

@@ -233,3 +233,11 @@ func Edit_DeviceClassList(T_task_id, T_sn, T_id string) (err error) {
 	return nil
 
 }
+func Del_TaskData_ByT_BindDeviceDataTime(T_task_id string) {
+	logs.Debug("Nats =>", lib.FuncName(), T_task_id)
+	err := lib.Nats.Publish("ColdVerify_Server_Del_TaskData_ByT_BindDeviceDataTime", []byte(T_task_id))
+	if err != nil {
+		logs.Error("Nats =>", lib.FuncName(), err)
+	}
+
+}

+ 211 - 178
controllers/TaskData.go

@@ -96,44 +96,110 @@ func (c *TaskDataController) TaskData_Temperature_Pdf() {
 	Time_start := c.GetString("Time_start")
 	Time_end := c.GetString("Time_end")
 	T_snid := c.GetString("T_snid")
-
 	T_task_id := c.GetString("T_task_id")
-	Task_r, err := NatsServer.Read_Task(T_task_id)
+
+	err := c.TaskData_Pdf(Time_start, Time_end, T_task_id, T_snid, Task.Temperature)
 	if err != nil {
-		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"}
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
 		c.ServeJSON()
 		return
 	}
-	if Task_r.T_collection_state == 2 {
-		c.Data["json"] = lib.JSONS{Code: 202, Msg: "数据采集中,请稍后!"}
+}
+func (c *TaskDataController) TaskData_Humidity_Pdf() {
+
+	Time_start := c.GetString("Time_start")
+	Time_end := c.GetString("Time_end")
+	T_snid := c.GetString("T_snid")
+	T_task_id := c.GetString("T_task_id")
+	err := c.TaskData_Pdf(Time_start, Time_end, T_task_id, T_snid, Task.Humidity)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
 		c.ServeJSON()
 		return
 	}
+
+}
+func (c *TaskDataController) TaskData_Pdf(Time_start, Time_end, T_task_id, T_snid, T_type string) (err error) {
+
+	Time_start_b := Time_start
+	Time_end_b := Time_end
+
+	Task_r, err := NatsServer.Read_Task(T_task_id)
+	if err != nil {
+		return errors.New("T_task_id 错误!")
+	}
+	if Task_r.T_collection_state == 2 {
+		return errors.New("数据采集中,请稍后!")
+	}
 	user, err := NatsServer.Read_User(Task_r.T_uuid)
 	var T_snid_list []string
 	if len(T_snid) > 0 {
 		T_snid_list = strings.Split(strings.Trim(T_snid, "|"), "|")
 	}
 
+	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", "", 10)
+	if err != nil {
+		return
+	}
+
 	dataMap := make(map[string]string)
 	timeMap := make(map[string]bool)
-	//classList := Task.Read_TaskData_ById_ClassList(Task_r.T_task_id)
-	//for _, i2 := range classList {
-	//	T_snid_list = append(T_snid_list, fmt.Sprintf("%s,%s", i2.T_sn, i2.T_id))
-	//}
+	idWidthMap := make(map[string]float64)
+	dataListMap := make(map[string][]Task.TaskData_)
+	T_snid_list1 := []string{}
+	T_snid_list2 := []string{}
+
 	for _, v := range T_snid_list {
 		sn_id := strings.Split(v, ",")
 		if len(sn_id) == 2 {
 			List, _ := Task.Read_TaskData_ById_List(Task_r.T_task_id, sn_id[0], sn_id[1], Time_start, Time_end, 0, 9999)
-
+			if len(List) == 0 {
+				continue
+			}
+			idw, _ := pdf.MeasureTextWidth(sn_id[1])
+			if !lib.IsNumeric(sn_id[1]) {
+				//IsNotNumeric = true
+				T_snid_list1 = append(T_snid_list1, v)
+				if len(Task_r.T_BindDeviceDataStartTime) > 0 {
+					Time_start = Task_r.T_BindDeviceDataStartTime
+				}
+				if len(Task_r.T_BindDeviceDataEndTime) > 0 {
+					Time_end = Task_r.T_BindDeviceDataEndTime
+				}
+			} else {
+				T_snid_list2 = append(T_snid_list2, v)
+			}
+			if idw > 20 {
+				idWidthMap[sn_id[1]] = idw + 12
+			} else {
+				idWidthMap[sn_id[1]] = 30
+			}
+			sort.Slice(List, func(i, j int) bool {
+				return List[i].T_time < List[j].T_time
+			})
+			dataListMap[sn_id[1]] = List
 			for _, data := range List {
 				k := fmt.Sprintf("%s,%s", data.T_time, data.T_id)
-				dataMap[k] = fmt.Sprintf("%.1f", data.T_t)
+				if T_type == Task.Temperature {
+					dataMap[k] = fmt.Sprintf("%.1f", data.T_t)
+				}
+				if T_type == Task.Humidity {
+					dataMap[k] = fmt.Sprintf("%.1f", data.T_rh)
+				}
 				if _, ok := timeMap[data.T_time]; !ok {
 					timeMap[data.T_time] = true
 				}
 			}
 		}
+		Time_start = Time_start_b
+		Time_end = Time_end_b
 	}
 
 	var timeList []string
@@ -144,13 +210,6 @@ func (c *TaskDataController) TaskData_Temperature_Pdf() {
 		return timeList[i] < timeList[j]
 	})
 
-	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", "", 15)
 	if err != nil {
 		return
@@ -171,12 +230,23 @@ func (c *TaskDataController) TaskData_Temperature_Pdf() {
 	pdf.Text(name)
 
 	y += 20
-	title := Task_r.T_name + "温度验证数据"
+	T_type_name := ""
+	if T_type == Task.Temperature {
+		T_type_name = "温度"
+	}
+	if T_type == Task.Humidity {
+		T_type_name = "湿度"
+	}
+	title := Task_r.T_name + T_type_name + "验证数据"
 	textw, _ = pdf.MeasureTextWidth(title)
 	pdf.SetX((595 / 2) - (textw / 2))
 	pdf.SetY(y)
 	pdf.Text(title)
 
+	err = pdf.SetFont("wts", "", 12)
+	if err != nil {
+		return
+	}
 	if len(timeList) > 0 {
 		y += 20
 		timeStr := fmt.Sprintf("%s - %s", timeList[0], timeList[len(timeList)-1])
@@ -194,180 +264,106 @@ func (c *TaskDataController) TaskData_Temperature_Pdf() {
 	y += 20
 	var x float64 = 10
 	var w float64 = 120
+	sort.Slice(T_snid_list1, func(i, j int) bool {
+		return extractSecondElement(T_snid_list1[i]) < extractSecondElement(T_snid_list1[j])
+	})
+	for _, v := range T_snid_list1 {
+		sn_id := strings.Split(v, ",")
+		id := sn_id[1]
+		dataList2, _ := dataListMap[id]
 
-	chunks := chunkBy(T_snid_list, 15)
-	for _, list := range chunks {
-		x = 10
-		w = 120
-		lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
-		x += w
-		w = 30
-		for _, v2 := range list {
-			sn_id2 := strings.Split(v2, ",")
-			id2 := sn_id2[1]
-			lib.RectFillColor(pdf, id2, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
-			x += w
+		err = pdf.SetFont("wts", "", 15)
+		if err != nil {
+			return
 		}
+		var textH float64 = 20 // if text height is 25px.
 		y += 20
+		pdf.SetNewY(y, textH)
+		y = pdf.GetY()
+		if y > 790 {
+			pdf.AddPage()
+			y = 20
+		}
 
-		for _, t := range timeList {
+		textw, _ = pdf.MeasureTextWidth(id)
+		pdf.SetX((595 / 2) - (textw / 2))
+		pdf.SetY(y)
+		pdf.Text(id)
+		y += 10
+
+		err = pdf.SetFont("wts", "", 10)
+		if err != nil {
+			return
+		}
+		pdf.SetNewY(y, textH)
+		y = pdf.GetY()
+		if y < 790 {
 			x = 10
-			var textH float64 = 20 // if text height is 25px.
-			pdf.SetNewY(y, textH)
-			y = pdf.GetY()
-			if y == 20 {
-				w = 120
+			for i := 0; i < 4; i++ {
+				w = 113.8
 				lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
 				x += w
 				w = 30
-				for _, v2 := range list {
-					sn_id2 := strings.Split(v2, ",")
-					id2 := sn_id2[1]
-					lib.RectFillColor(pdf, id2, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
-					x += w
-				}
-				y += 20
-				x = 10
+				lib.RectFillColor(pdf, T_type_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
+				x += w
 			}
-			w = 120
-			lib.RectFillColor(pdf, t, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
-			x += w
-			w = 30
-			for _, v := range list {
-				sn_id := strings.Split(v, ",")
-				id := sn_id[1]
-				t_t := dataMap[fmt.Sprintf("%s,%s", t, id)]
-				lib.RectFillColor(pdf, t_t, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
+			y += 20
+		} else {
+			pdf.AddPage()
+			y = 20
+			x = 10
+			for i := 0; i < 4; i++ {
+				w = 113.8
+				lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
+				x += w
+				w = 30
+				lib.RectFillColor(pdf, T_type_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
 				x += w
 			}
 			y += 20
-
 		}
-		y += 20
-	}
-	filename := time.Now().Format("20060102150405") + ".pdf"
-	timeStr := "ofile/温度" + filename
+		for i := 0; i < len(dataList2); i++ {
+			temp := i % 4
+			x = 10 + 143.8*float64(temp)
+			w = 113.8
 
-	err = pdf.WritePdf(timeStr)
-	if err != nil {
-		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
-		c.ServeJSON()
-		return
-	}
-
-	defer func() {
-		//删除目录
-		os.Remove(timeStr)
-	}()
-
-	c.Ctx.Output.Download(timeStr)
-
-}
-func (c *TaskDataController) TaskData_Humidity_Pdf() {
-
-	Time_start := c.GetString("Time_start")
-	Time_end := c.GetString("Time_end")
-	T_snid := c.GetString("T_snid")
-
-	T_task_id := c.GetString("T_task_id")
-	Task_r, err := NatsServer.Read_Task(T_task_id)
-	if err != nil {
-		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"}
-		c.ServeJSON()
-		return
-	}
-	if Task_r.T_collection_state == 2 {
-		c.Data["json"] = lib.JSONS{Code: 202, Msg: "数据采集中,请稍后!"}
-		c.ServeJSON()
-		return
-	}
-	user, err := NatsServer.Read_User(Task_r.T_uuid)
-	var T_snid_list []string
-	if len(T_snid) > 0 {
-		T_snid_list = strings.Split(strings.Trim(T_snid, "|"), "|")
-	}
-
-	dataMap := make(map[string]string)
-	timeMap := make(map[string]bool)
-	//classList := Task.Read_TaskData_ById_ClassList(Task_r.T_task_id)
-	//for _, i2 := range classList {
-	//	T_snid_list = append(T_snid_list, fmt.Sprintf("%s,%s", i2.T_sn, i2.T_id))
-	//}
-	for _, v := range T_snid_list {
-		sn_id := strings.Split(v, ",")
-		if len(sn_id) == 2 {
-			List, _ := Task.Read_TaskData_ById_List(Task_r.T_task_id, sn_id[0], sn_id[1], Time_start, Time_end, 0, 9999)
-
-			for _, data := range List {
-				k := fmt.Sprintf("%s,%s", data.T_time, data.T_id)
-				dataMap[k] = fmt.Sprintf("%.1f", data.T_rh)
-				if _, ok := timeMap[data.T_time]; !ok {
-					timeMap[data.T_time] = true
+			lib.RectFillColor(pdf, dataList2[i].T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
+			x += w
+			w = 30
+			if T_type == Task.Temperature {
+				lib.RectFillColor(pdf, fmt.Sprintf("%.1f", dataList2[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
+			}
+			if T_type == Task.Humidity {
+				lib.RectFillColor(pdf, fmt.Sprintf("%.1f", dataList2[i].T_rh), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
+			}
+			if temp == 3 {
+				y += 20
+				pdf.SetNewY(y, textH)
+				y = pdf.GetY()
+				// 每页添加表头
+				if y == 20 {
+					x = 10
+					for k := 0; k < 4; k++ {
+						w = 113.8
+						lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
+						x += w
+						w = 30
+						lib.RectFillColor(pdf, T_type_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
+						x += w
+					}
+					y += 20
 				}
 			}
 		}
-	}
-
-	var timeList []string
-	for k, _ := range timeMap {
-		timeList = append(timeList, k)
-	}
-	sort.Slice(timeList, func(i, j int) bool {
-		return timeList[i] < timeList[j]
-	})
-
-	pdf := &gopdf.GoPdf{}
-	pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
+		y += 25
 
-	err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf")
-	if err != nil {
-		return
-	}
-	err = pdf.SetFont("wts", "", 15)
-	if err != nil {
-		return
 	}
 
-	pdf.SetGrayFill(0.5)
-
-	pdf.SetMargins(0, 20, 0, 20)
-	pdf.AddPage()
-	imgH, _ := gopdf.ImageHolderByPath("./ofile/logo.jpg")
-	err = pdf.ImageByHolder(imgH, 10, 10, &gopdf.Rect{W: 93, H: 32})
-	name := user.T_name
-
-	var y float64 = 40
-	textw, _ := pdf.MeasureTextWidth(name)
-	pdf.SetX((595 / 2) - (textw / 2))
-	pdf.SetY(y)
-	pdf.Text(name)
-
 	y += 20
-	title := Task_r.T_name + "湿度验证数据"
-	textw, _ = pdf.MeasureTextWidth(title)
-	pdf.SetX((595 / 2) - (textw / 2))
-	pdf.SetY(y)
-	pdf.Text(title)
-
-	if len(timeList) > 0 {
-		y += 20
-		timeStr := fmt.Sprintf("%s - %s", timeList[0], timeList[len(timeList)-1])
-		textw, _ = pdf.MeasureTextWidth(timeStr)
-		pdf.SetX((595 / 2) - (textw / 2))
-		pdf.SetY(y)
-		pdf.Text(timeStr)
-	}
-
-	err = pdf.SetFont("wts", "", 10)
-	if err != nil {
-		return
-	}
-
-	y += 20
-	var x float64 = 10
-	var w float64 = 120
-
-	chunks := chunkBy(T_snid_list, 15)
+	sort.Slice(T_snid_list2, func(i, j int) bool {
+		return extractSecondElement(T_snid_list2[i]) < extractSecondElement(T_snid_list2[j])
+	})
+	chunks := splitData(T_snid_list2, 450, idWidthMap)
 	for _, list := range chunks {
 		x = 10
 		w = 120
@@ -377,6 +373,7 @@ func (c *TaskDataController) TaskData_Humidity_Pdf() {
 		for _, v2 := range list {
 			sn_id2 := strings.Split(v2, ",")
 			id2 := sn_id2[1]
+			w = idWidthMap[id2]
 			lib.RectFillColor(pdf, id2, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
 			x += w
 		}
@@ -395,6 +392,7 @@ func (c *TaskDataController) TaskData_Humidity_Pdf() {
 				for _, v2 := range list {
 					sn_id2 := strings.Split(v2, ",")
 					id2 := sn_id2[1]
+					w = idWidthMap[id2]
 					lib.RectFillColor(pdf, id2, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
 					x += w
 				}
@@ -408,8 +406,9 @@ func (c *TaskDataController) TaskData_Humidity_Pdf() {
 			for _, v := range list {
 				sn_id := strings.Split(v, ",")
 				id := sn_id[1]
-				t_t := dataMap[fmt.Sprintf("%s,%s", t, id)]
-				lib.RectFillColor(pdf, t_t, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
+				data := dataMap[fmt.Sprintf("%s,%s", t, id)]
+				w = idWidthMap[id]
+				lib.RectFillColor(pdf, data, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle)
 				x += w
 			}
 			y += 20
@@ -418,12 +417,10 @@ func (c *TaskDataController) TaskData_Humidity_Pdf() {
 		y += 20
 	}
 	filename := time.Now().Format("20060102150405") + ".pdf"
-	timeStr := "ofile/湿度" + filename
+	timeStr := "ofile/" + T_type_name + filename
 
 	err = pdf.WritePdf(timeStr)
 	if err != nil {
-		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
-		c.ServeJSON()
 		return
 	}
 
@@ -433,9 +430,17 @@ func (c *TaskDataController) TaskData_Humidity_Pdf() {
 	}()
 
 	c.Ctx.Output.Download(timeStr)
-
+	return nil
 }
 
+// Function to extract the second element after splitting by comma
+func extractSecondElement(s string) string {
+	parts := strings.Split(s, ",")
+	if len(parts) >= 2 {
+		return parts[1]
+	}
+	return s // return original string if splitting doesn't give expected parts
+}
 func chunkBy[T any](list []T, size int) [][]T {
 	var chunks [][]T
 	for size < len(list) {
@@ -443,6 +448,34 @@ func chunkBy[T any](list []T, size int) [][]T {
 	}
 	return append(chunks, list)
 }
+func splitData(data []string, threshold float64, idWidthMap map[string]float64) [][]string {
+	var result [][]string
+	var currentBatch []string
+	var currentSum float64
+
+	for _, item := range data {
+		sn_id := strings.Split(item, ",")
+		if len(sn_id) == 2 {
+			wd := idWidthMap[sn_id[1]]
+			if currentSum+wd > threshold {
+				// 当前批次超过阈值,切分
+				result = append(result, currentBatch)
+				// 重置当前批次和当前总和
+				currentBatch = []string{}
+				currentSum = 0
+			}
+			currentBatch = append(currentBatch, item)
+			currentSum += wd
+		}
+	}
+
+	// 添加最后一批
+	if len(currentBatch) > 0 {
+		result = append(result, currentBatch)
+	}
+
+	return result
+}
 
 // 列表 -
 func (c *TaskDataController) TaskDataClass_List() {

+ 26 - 0
lib/libString.go

@@ -3,6 +3,7 @@ package lib
 import (
 	"errors"
 	"math/rand"
+	"regexp"
 	"strings"
 	"time"
 )
@@ -67,3 +68,28 @@ func ReplaceSeconds(timeStr string) (string, error) {
 
 	return roundedTimeString, nil
 }
+
+// 判断字符串是否为纯数字
+func IsNumeric(str string) bool {
+	// 定义一个正则表达式来匹配纯数字字符串
+	re := regexp.MustCompile(`^\d+$`)
+	return re.MatchString(str)
+}
+
+func SubtractStringLists(list1, list2 []string) []string {
+	// Create a map to store elements of list2 for fast lookup
+	excludeMap := make(map[string]bool)
+	for _, item := range list2 {
+		excludeMap[item] = true
+	}
+
+	// Initialize the result slice with elements not present in list2
+	var result []string
+	for _, item := range list1 {
+		if !excludeMap[item] {
+			result = append(result, item)
+		}
+	}
+
+	return result
+}

+ 5 - 0
models/Task/Task.go

@@ -24,6 +24,11 @@ type Task struct {
 	T_reporting_state      int    `orm:"size(2);default(0)"`   // 报告编写 状态 0 未完成 1 已完成
 	T_delivery_state       int    `orm:"size(2);default(0)"`   // 交付审核 状态 0 未完成 1 已完成 2 处理中
 
+	T_VerifyDeviceDataStartTime string `orm:"size(256);null"` // 验证设备数据开始时间
+	T_VerifyDeviceDataEndTime   string `orm:"size(256);null"` // 验证设备数据开始时间
+	T_BindDeviceDataStartTime   string `orm:"size(256);null"` // 绑定设备数据开始时间
+	T_BindDeviceDataEndTime     string `orm:"size(256);null"` // 绑定设备数据结束时间
+
 	T_doc1 string `orm:"type(text);null"` // 封面
 	T_pdf1 string `orm:"type(text);null"` // 封面
 	T_doc2 string `orm:"type(text);null"` // 报告

+ 5 - 0
models/Task/TaskData.go

@@ -16,6 +16,11 @@ import (
 	"time"
 )
 
+const (
+	Temperature = "Temperature"
+	Humidity    = "Humidity"
+)
+
 // 模板
 type TaskData struct {
 	Id int `orm:"column(ID);size(11);auto;pk"`