| 
					
				 | 
			
			
				@@ -13,6 +13,7 @@ import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"fmt" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"github.com/beego/beego/v2/client/orm" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	beego "github.com/beego/beego/v2/server/web" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"github.com/signintech/gopdf" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"github.com/vmihailenco/msgpack/v5" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"github.com/xuri/excelize/v2" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"gonum.org/v1/plot" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -21,6 +22,7 @@ import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"gonum.org/v1/plot/vg/draw" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"math" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"os" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"sort" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"strconv" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"strings" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"sync" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -62,8 +64,22 @@ func (c *TaskDataController) TaskData_List() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dcList, err := NatsServer.Device_Class_List(T_task_id) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "获取设备列表失败!"} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		c.ServeJSON() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 保存布局编号和校准证书对应关系 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	var deviceCertificateMap = make(map[string]string) // t_id, T_Certificate_sn 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, v := range dcList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		deviceCertificateMap[v.T_id] = v.T_Certificate_sn 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var cnt int64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	List, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, T_sn, T_id, Time_start, Time_end, page, page_z) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for i := 0; i < len(List); i++ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		List[i].T_Certificate_sn = deviceCertificateMap[List[i].T_id] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	page_size := math.Ceil(float64(cnt) / float64(page_z)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	r_jsons.List = List 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	r_jsons.Page = page 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -75,6 +91,186 @@ func (c *TaskDataController) TaskData_List() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	c.ServeJSON() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (c *TaskDataController) TaskData_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_t) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if _, ok := timeMap[data.T_time]; !ok { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					timeMap[data.T_time] = true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		y += 20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for _, t := range timeList { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			x = 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var textH float64 = 20 // if text height is 25px. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			pdf.SetNewY(y, textH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			y = pdf.GetY() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if y == 20 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				y += 20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				x = 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				x += w 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			y += 20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		y += 20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	filename := time.Now().Format("20060102150405") + ".pdf" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	timeStr := "ofile/" + filename 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	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 chunkBy[T any](list []T, size int) [][]T { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	var chunks [][]T 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for size < len(list) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		list, chunks = list[size:], append(chunks, list[0:size:size]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return append(chunks, list) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // 列表 - 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (c *TaskDataController) TaskDataClass_List() { 
			 |