2 次代碼提交 bb87a22be4 ... 3e85827d0d

作者 SHA1 備註 提交日期
  zoie 3e85827d0d add:自动填写标签数据 2 天之前
  bzdadmin 3d4ad77e34 上传文件至 '' 4 月之前

+ 1 - 1
.gitignore

@@ -35,4 +35,4 @@ ColdVerify_local
 ColdVerify_local6400
 /temp
 /ofile
-Makefile
+nohup.out

+ 2 - 1
ColdVerify_local.go

@@ -36,7 +36,8 @@ func init() {
 		conf.MysqlVerify_Username+":"+conf.MysqlVerify_Password+"@tcp("+conf.MysqlVerify_UrlPort+")/"+conf.MysqlVerify_Database+"?charset=utf8mb4&loc=Local&parseTime=True",
 		conf.MysqlServer2_MaxIdleConnections, conf.MysqlServer2_MaxOpenConnections)
 	println(conf.MysqlVerify_Username + ":" + conf.MysqlVerify_Password + "@tcp(" + conf.MysqlVerify_UrlPort + ")/" + conf.MysqlVerify_Database + "?charset=utf8mb4&loc=Local&parseTime=True")
-
+	orm2.Debug = true
+	orm.Debug = true
 }
 
 func main() {

+ 6 - 0
Makefile

@@ -0,0 +1,6 @@
+build:
+	@echo "+ build"
+	go build -o ColdVerify_local6400 ColdVerify_local.go
+build-linux:
+	@echo "+ build linux"
+	GOOS=linux GOARCH=amd64 go build -o ColdVerify_local6400 ColdVerify_local.go

+ 55 - 55
Nats/Nats.go

@@ -196,61 +196,61 @@ func NatsInit() {
 		Task_r := t_r.Task
 		T_uuid, T_task_id := t_r.T_uuid, Task_r.T_task_id
 
-		if err = lib.Create_Dir(conf.Sql_Temp_Dir); err != nil {
-			logs.Println("创建sql临时文件失败")
-		}
-		sql_file := fmt.Sprintf("%sz_task_data_%s.sql", conf.Sql_Temp_Dir, T_task_id)
-
-		var org string
-
-		//导出线上数据
-		logs.Info("--------开始导出本地数据---------")
-		i := 0
-		for i < 10 {
-			org, err = Task.Dump_TaskData(T_task_id, conf.MysqlServer_Username, conf.MysqlServer_Password, conf.MysqlServer_UrlPort, conf.MysqlServer_Database, sql_file)
-			if err != nil {
-				logs.Error(lib.FuncName(), "导出本地数据失败", err)
-			} else {
-				System.Add_UserLogs_T(T_uuid, "任务数据-导出本地数据失败", "z_task_data_"+T_task_id, org)
-				break
-			}
-			i++
-		}
-
-		logs.Info("--------开始导入数据到【线上】---------")
-		j := 0
-		flag := false
-		for j < 10 {
-			Task.Truncate_TaskData(conf.Server_AliasName, T_task_id)
-			time.Sleep(2 * time.Second)
-			org, err = Task.Insert_TaskData(conf.MysqlServer2_Username, conf.MysqlServer2_Password, conf.MysqlServer2_UrlPort, conf.MysqlServer2_Database, sql_file)
-			if err != nil {
-				logs.Println(T_uuid, "任务数据-更新线上数据", "z_task_data_"+T_task_id, err.Error())
-			} else {
-				if Task.Check_TaskData_Num(T_task_id) {
-					System.Add_UserLogs_T(T_uuid, "任务数据-更新线上数据", "z_task_data_"+T_task_id, org)
-					flag = true
-					break
-				}
-			}
-			j++
-		}
-		// 重试10次后仍然没有成功导入数据
-		if !flag {
-			Task.Truncate_TaskData(conf.Server_AliasName, T_task_id)
-			time.Sleep(2 * time.Second)
-			// 线上数据更新后 将当前任务 交付审核 标志 为 1
-			Task_r.T_delivery_state = 0
-			err = NatsServer.Update_Task(Task_r)
-			if err != nil {
-				logs.Error(lib.FuncName(), err)
-			}
-			System.Add_UserLogs_T(T_uuid, "任务数据-更新线上数据-失败", "z_task_data_"+T_task_id, "重试10次失败")
-			return
-		}
-
-		//删除导出的sql文件
-		_ = os.Remove(sql_file)
+		//if err = lib.Create_Dir(conf.Sql_Temp_Dir); err != nil {
+		//	logs.Println("创建sql临时文件失败")
+		//}
+		//sql_file := fmt.Sprintf("%sz_task_data_%s.sql", conf.Sql_Temp_Dir, T_task_id)
+		//
+		//var org string
+		//
+		////导出线上数据
+		//logs.Info("--------开始导出本地数据---------")
+		//i := 0
+		//for i < 10 {
+		//	org, err = Task.Dump_TaskData(T_task_id, conf.MysqlServer_Username, conf.MysqlServer_Password, conf.MysqlServer_UrlPort, conf.MysqlServer_Database, sql_file)
+		//	if err != nil {
+		//		logs.Error(lib.FuncName(), "导出本地数据失败", err)
+		//	} else {
+		//		System.Add_UserLogs_T(T_uuid, "任务数据-导出本地数据失败", "z_task_data_"+T_task_id, org)
+		//		break
+		//	}
+		//	i++
+		//}
+		//
+		//logs.Info("--------开始导入数据到【线上】---------")
+		//j := 0
+		//flag := false
+		//for j < 10 {
+		//	Task.Truncate_TaskData(conf.Server_AliasName, T_task_id)
+		//	time.Sleep(2 * time.Second)
+		//	org, err = Task.Insert_TaskData(conf.MysqlServer2_Username, conf.MysqlServer2_Password, conf.MysqlServer2_UrlPort, conf.MysqlServer2_Database, sql_file)
+		//	if err != nil {
+		//		logs.Println(T_uuid, "任务数据-更新线上数据", "z_task_data_"+T_task_id, err.Error())
+		//	} else {
+		//		if Task.Check_TaskData_Num(T_task_id) {
+		//			System.Add_UserLogs_T(T_uuid, "任务数据-更新线上数据", "z_task_data_"+T_task_id, org)
+		//			flag = true
+		//			break
+		//		}
+		//	}
+		//	j++
+		//}
+		//// 重试10次后仍然没有成功导入数据
+		//if !flag {
+		//	Task.Truncate_TaskData(conf.Server_AliasName, T_task_id)
+		//	time.Sleep(2 * time.Second)
+		//	// 线上数据更新后 将当前任务 交付审核 标志 为 1
+		//	Task_r.T_delivery_state = 0
+		//	err = NatsServer.Update_Task(Task_r)
+		//	if err != nil {
+		//		logs.Error(lib.FuncName(), err)
+		//	}
+		//	System.Add_UserLogs_T(T_uuid, "任务数据-更新线上数据-失败", "z_task_data_"+T_task_id, "重试10次失败")
+		//	return
+		//}
+		//
+		////删除导出的sql文件
+		//_ = os.Remove(sql_file)
 
 		// 线上数据更新后 将当前任务 交付审核 标志 为 1
 		Task_r.T_delivery_state = 1

+ 1 - 1
Z_Build.bat

@@ -1,8 +1,8 @@
 cd %~dp0
 set GOARCH=amd64
 set GOOS=linux
-set GOPATH=C:\Users\SIKED\go
 set GO111MODULE=auto
 
 
 go build ColdVerify_local.go
+go build -o ColdVerify_local6400 ColdVerify_local.go

+ 11 - 11
conf/app.conf

@@ -12,34 +12,34 @@ NatsServer_Url = "127.0.0.1:43422"
 Sql_Temp_Dir = "./temp/"
 
 # Redis
-Redis_address = "127.0.0.1:43379"
-Redis_password = ""
+Redis_address = "182.44.114.34:6379"
+Redis_password = "redis_KJNswd"
 Redis_dbNum = "2"
 
 # Mysql 本地
 Local_AliasName = "default"
-MysqlServer_UrlPort = "192.168.11.23:3306"
+MysqlServer_UrlPort = "182.44.114.34:3306"
 MysqlServer_Database = "coldverify"
-MysqlServer_Username = "coldverify"
-MysqlServer_Password = "Bd3d34yJ7aibiEi!"
+MysqlServer_Username = "root"
+MysqlServer_Password = "mysql_Ks7WAX"
 MysqlServer_MaxIdleConnections = 100
 MysqlServer_MaxOpenConnections = 200
 
 # # Mysql 线上
 Server_AliasName = "server"
-MysqlServer2_UrlPort = "127.0.0.1:40306"
+MysqlServer2_UrlPort = "182.44.114.34:3306"
 MysqlServer2_Database = "coldverify"
-MysqlServer2_Username = "coldverify"
-MysqlServer2_Password = "Bd3d34yJ7aibiEi!"
+MysqlServer2_Username = "root"
+MysqlServer2_Password = "mysql_Ks7WAX"
 MysqlServer2_MaxIdleConnections = 100
 MysqlServer2_MaxOpenConnections = 200
 
 # Mysql 1.0
 Verify1_AliasName = "Verify1"
-MysqlVerify_UrlPort = "127.0.0.1:3300"
+MysqlVerify_UrlPort = "172.18.0.1:3300"
 MysqlVerify_Database = "cold_verify"
-MysqlVerify_Username = "cold_verify"
-MysqlVerify_Password = "Cdac2yEfzNKKMJwy"
+MysqlVerify_Username = "root"
+MysqlVerify_Password = "mysql_Ks7WAX"
 MysqlVerify_MaxIdleConnections = 100
 MysqlVerify_MaxOpenConnections = 200
 

+ 28 - 0
controllers/Logs.go

@@ -12,6 +12,34 @@ type LogsController struct {
 	beego.Controller
 }
 
+// 自动填写标签数据 标签列表
+func (c *LogsController) ListJson() {
+	mySlice := []string{ // 20250310
+		"外部环境分割线最高温",
+		"外部环境分割线最低温",
+		"内部环境分割线最低温",
+		"内部环境分割线最高温",
+		"冰排释冷开始时间",
+		"冰排释冷结束时间",
+		"冰排释冷分割线最高温",
+		"冰排释冷分割线最低温",
+		"静态第一次开箱注释",
+		"静态第二次开箱注释",
+		"静态第三次开箱注释",
+		"动态第一次开箱注释",
+		"动态第二次开箱注释",
+		"动态第三次开箱注释",
+		"保温箱温度设定值",
+		"保温箱准备开始时间",
+		"冰排预冷保温箱准备结束时间",
+		"温度自动监测设备放置位置开始时间",
+		"温度自动监测设备放置位置结束时间",
+	}
+
+	c.Data["json"] = mySlice
+	c.ServeJSON() // 使用 ServeJSON
+}
+
 // 列表 -
 func (c *LogsController) List() {
 	var log_jsons lib.LOG_JSONS

+ 5 - 0
controllers/TaskContent.go

@@ -0,0 +1,5 @@
+package controllers
+
+import (
+	"C"
+)

+ 2219 - 13
controllers/TaskData.go

@@ -7,6 +7,7 @@ import (
 	"ColdVerify_local/lib"
 	"ColdVerify_local/logs"
 	"ColdVerify_local/models/Certificate"
+	"ColdVerify_local/models/Device"
 	"ColdVerify_local/models/System"
 	"ColdVerify_local/models/Task"
 	"errors"
@@ -21,6 +22,7 @@ import (
 	"gonum.org/v1/plot/vg"
 	"gonum.org/v1/plot/vg/draw"
 	"math"
+	"net/http"
 	"os"
 	"sort"
 	"strconv"
@@ -441,13 +443,7 @@ func extractSecondElement(s string) string {
 	}
 	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) {
-		list, chunks = list[size:], append(chunks, list[0:size:size])
-	}
-	return append(chunks, list)
-}
+
 func splitData(data []string, threshold float64, idWidthMap map[string]float64) [][]string {
 	var result [][]string
 	var currentBatch []string
@@ -1353,6 +1349,120 @@ func (c *TaskDataController) TaskData_Import_TaskData() {
 	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
 	c.ServeJSON()
 
+} // 重置 SN数据
+func (c *TaskDataController) CopyTaskDataSN() {
+	// 获取登录用户的uuid
+	T_uuid, _ := lib.GetAdminT_Uuid(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+
+	T_task_id := c.GetString("T_task_id")
+	T_task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "获取任务信息失败!"}
+		c.ServeJSON()
+		return
+	}
+	To_T_task_id := c.GetString("To_T_task_id")
+	To_T_task_r, err := Task.Read_Task(To_T_task_id)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "获取任务信息失败!"}
+		c.ServeJSON()
+		return
+	}
+	StartTime := c.GetString("StartTime") + ":00"
+	_, ok := lib.TimeStrToTime(StartTime)
+	if !ok {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "时间格式错误!"}
+		c.ServeJSON()
+		return
+	}
+	EndTime := c.GetString("EndTime") + ":00"
+	_, ok = lib.TimeStrToTime(EndTime)
+	if !ok {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "时间格式错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	SN_List := strings.Split(strings.Trim(c.GetString("SN_List"), "|"), "|")
+
+	for _, v := range SN_List {
+		sn_id := strings.Split(v, ",")
+		if len(sn_id) != 2 {
+			continue
+		}
+		sn, id_str := sn_id[0], sn_id[1]
+		_, is := Device.Read_DeviceClassList_T_class_T_sn(To_T_task_r.T_class, sn)
+		if !is {
+			dc, is_ := Device.Read_DeviceClassList_T_class_T_sn(T_task_r.T_class, sn)
+			if is_ {
+				dcr := Device.DeviceClassList{
+					T_class:          To_T_task_r.T_class,
+					T_id:             dc.T_id,
+					T_sn:             dc.T_sn,
+					T_failure_time:   dc.T_failure_time,
+					T_pdf:            dc.T_pdf,
+					T_Certificate_sn: dc.T_Certificate_sn,
+					T_remark:         dc.T_remark,
+					T_State:          1,
+				}
+				Device.Add_DeviceClassList(dcr)
+			}
+		}
+		Task.Import_Task_Back(sn, id_str, T_task_id, To_T_task_id, StartTime, EndTime)
+
+	}
+	System.Add_UserLogs_T(T_uuid, "复制任务数据", fmt.Sprintf("复制任务数据(%s->%s)[%s|%s]", T_task_id, To_T_task_id, StartTime, EndTime), SN_List)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+
+}
+
+// 复制到
+func (c *TaskDataController) Import_TaskData_SN() {
+	// 获取登录用户的uuid
+	T_uuid, _ := lib.GetAdminT_Uuid(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+
+	T_task_id := c.GetString("T_task_id")
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "获取任务信息失败!"}
+		c.ServeJSON()
+		return
+	}
+	T_sn := c.GetString("T_sn")
+	System.Add_UserLogs_T(T_uuid, "重置 SN数据", "Z_TaskData_"+T_task_id, T_sn)
+	DeviceClass_r, is := Device.Read_DeviceClassList_T_class_T_sn(Task_r.T_class, T_sn)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: T_sn + " 没找到!"}
+		c.ServeJSON()
+		return
+	}
+	开始时间 := ""
+	结束时间 := ""
+
+	部点终端_list := Device.Read_DeviceClassList_List_id(Task_r.T_class)
+	for _, v := range 部点终端_list {
+		List_data, _ := Task.Read_TaskData_ById_List(Task_r.T_task_id, v.T_sn, v.T_id, "", "", 0, 9999)
+
+		if len(List_data) < 10 {
+			continue
+		}
+		开始时间 = List_data[len(List_data)-1].T_time
+		结束时间 = List_data[0].T_time
+
+	}
+	if len(开始时间) == 0 || 开始时间 == "null" {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "数据 没找到 一条可用的!"}
+		c.ServeJSON()
+		return
+	}
+
+	Task.Import_TaskData_Back(T_sn, DeviceClass_r.T_id, Task_r.T_task_id, 开始时间, 结束时间)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+
 }
 
 // 更新线上数据
@@ -1599,7 +1709,7 @@ func (c *TaskDataController) RepairSensorData() {
 			n, _ := time.Parse("2006-01-02 15:04:05", next)
 			interval := n.Unix() - c.Unix()
 			//logs.Debug("时间间隔:", interval, "保存时间:", saveTime)
-			fmt.Println("当前:", current, "下一个:", next)
+			//fmt.Println("当前:", current, "下一个:", next)
 			if int(interval) > saveTime {
 				ttInterval := list[i+1].T_t - list[i].T_t
 				ttt := list[i].T_t // 温度临时变量
@@ -1932,14 +2042,14 @@ func (c *TaskDataController) CopyFromPositionAverageSN() {
 	//	return
 	//}
 	StartTime := c.GetString("StartTime")
-	startTime, ok := lib.TimeStrToTime(StartTime)
+	_, ok := lib.TimeStrToTime(StartTime)
 	if !ok {
 		c.Data["json"] = lib.JSONS{Code: 202, Msg: "时间格式错误!"}
 		c.ServeJSON()
 		return
 	}
 	EndTime := c.GetString("EndTime")
-	endTime, ok := lib.TimeStrToTime(EndTime)
+	_, ok = lib.TimeStrToTime(EndTime)
 	if !ok {
 		c.Data["json"] = lib.JSONS{Code: 202, Msg: "时间格式错误!"}
 		c.ServeJSON()
@@ -1956,7 +2066,10 @@ func (c *TaskDataController) CopyFromPositionAverageSN() {
 		c.ServeJSON()
 		return
 	}
-	CopyEndTime := copyTime.Add(endTime.Sub(startTime)).Format("2006-01-02 15:04:05")
+	//CopyEndTime := copyTime.Add(endTime.Sub(startTime)).Format("2006-01-02 15:04:05")
+
+	T_switch_t, _ := c.GetBool("T_switch_t", true)
+	T_switch_h, _ := c.GetBool("T_switch_h", true)
 
 	SN_List := strings.Split(strings.Trim(c.GetString("SN_List"), "|"), "|")
 	if len(SN_List) != 2 {
@@ -2018,11 +2131,11 @@ func (c *TaskDataController) CopyFromPositionAverageSN() {
 		ct = ct.Add(time.Second * time.Duration(T_saveT))
 	}
 
-	Task.DeleteTaskDataByTimeRange(Task_r.T_task_id, CopySN, CopyID, CopyTime, CopyEndTime)
+	//Task.DeleteTaskDataByTimeRange(Task_r.T_task_id, CopySN, CopyID, CopyTime, CopyEndTime)
 
 	go func(TaskDataList []Task.TaskData_, task_id string) {
 		for _, taskData := range TaskDataList {
-			Task.InsertTaskData(task_id, taskData)
+			Task.InsertTaskData_TH(task_id, T_switch_t, T_switch_h, taskData)
 		}
 	}(list, Task_r.T_task_id)
 
@@ -2723,3 +2836,2096 @@ func (c *TaskDataController) Certificate_List() {
 	c.ServeJSON()
 	return
 }
+
+/*
+===========================
+				自动填写标签
+========================
+*/
+
+// 自动填写标签数据 标签列表
+func (c *TaskDataController) ListJson() {
+	mySlice := []string{ // 20250310
+		//"柜内所有测点",
+		"均匀性布点",
+		"产品存放区域测点",
+		"冷藏柜内部最高温",
+		"冷藏柜内部最低温",
+		"外部环境分割线最高温",
+		"外部环境分割线最低温",
+		"冷藏柜外部环境测点最高温",
+		"冷藏柜外部环境测点最低温",
+		"内部环境分割线最低温",
+		"内部环境分割线最高温",
+		"冰排释冷开始时间",
+		"冰排释冷结束时间",
+		"冰排释冷分割线最高温",
+		"冰排释冷分割线最低温",
+		"静态第一次开箱注释",
+		"静态第二次开箱注释",
+		"静态第三次开箱注释",
+		"动态第一次开箱注释",
+		"动态第二次开箱注释",
+		"动态第三次开箱注释",
+		"保温箱温度设定值",
+		"风机温度设定值",
+		"保温箱准备开始时间",
+		"冰排预冷保温箱准备结束时间",
+		"温度自动监测设备放置位置开始时间",
+		"温度自动监测设备放置位置结束时间",
+		"温度分布特性开始时间",
+		"温度分布特性结束时间",
+		"最长保温时限开始时间",
+		"最长保温时限结束时间",
+		"温度分布特性的测试与分析(满载)开始时间",
+		"温度分布特性的测试与分析(空载)开始时间",
+		"温度分布特性的测试与分析(满载)结束时间",
+		"温度分布特性的测试与分析(空载)结束时间",
+		"温控设备运行参数及使用状况测试(满载)开始时间",
+		"温控设备运行参数及使用状况测试(空载)开始时间",
+		"温控设备运行参数及使用状况测试(满载)结束时间",
+		"温控设备运行参数及使用状况测试(空载)结束时间",
+		"(满载)温度偏差均匀度波动度分析时间区间",
+		"(空载)温度偏差均匀度波动度分析时间区间",
+		"运行确认及偏差处理(满载)开始时间",
+		"运行确认及偏差处理(空载)开始时间",
+		"满载风机启动时间点注释",
+		"满载风机停止时间点注释",
+		"满载测试结束风机停止时间注释",
+		"空载风机启动时间点注释",
+		"空载风机停止时间点注释",
+		"空载测试结束风机停止时间注释",
+		"第一次开门开始时间",
+		"第一次开门结束时间",
+		"满载风机启动时间点",
+		"空载风机启动时间点",
+		"满载风机停止时间点",
+		"空载风机停止时间点",
+		"满载测试结束风机停止时间",
+		"空载测试结束风机停止时间",
+		"满载第一次关门温度恢复时间",
+		"空载第一次关门温度恢复时间",
+		"满载开门最长需要多少分钟恢复",
+		"空载开门最长需要多少分钟恢复",
+		"冷藏库作业口外部环境分割线最低温",
+		"冷藏库作业口外部环境分割线最高温",
+		"冷藏库外部环境测点最高温",
+		"冷藏库外部环境测点最低温",
+		"冷藏库内部最高温",
+		"冷藏库内部最低温",
+	}
+
+	c.Data["json"] = mySlice
+	c.ServeJSON() // 使用 ServeJSON
+}
+
+/*  ----------------------------------------------------------------------------------- */
+
+func (c *TaskDataController) A满载测试结束风机停止时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	均匀性布点 := c.GetString("均匀性布点") //  v26nplogbwt1
+	if len(均匀性布点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 均匀性布点 失败!"})
+		return
+	}
+	产品存放区域测点 := c.GetString("产品存放区域测点") //  v26nplogbwt1
+	if len(产品存放区域测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 产品存放区域测点 失败!"})
+		return
+	}
+	均匀性布点 = 均匀性布点 + "|" + 产品存放区域测点
+
+	开始时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)开始时间") //  v26nplogbwt1
+	if len(开始时间) == 0 || 开始时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)开始时间 失败!"})
+		return
+	}
+	结束时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)结束时间") //  v26nplogbwt1
+	if len(结束时间) == 0 || 结束时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)结束时间 失败!"})
+		return
+	}
+
+	list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, 均匀性布点, 开始时间, 结束时间)
+	fmt.Println("list:", list)
+	CalculateHumps_list := Task.CalculateHumps(list)
+
+	if len(CalculateHumps_list) < 7 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到连续5个循环 !"})
+		return
+	}
+	fmt.Println("CalculateHumps_list:", CalculateHumps_list)
+	//start := CalculateHumps_list[6].Start // 驼峰开始
+	//peak := CalculateHumps_list[0]["peak"].(Task.TaskData) // 驼峰最高
+	end := CalculateHumps_list[4].End // 驼峰结束
+	// .Format("2006-01-02 15:04:05")
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: end.T_time})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A空载测试结束风机停止时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	均匀性布点 := c.GetString("均匀性布点") //  v26nplogbwt1
+	if len(均匀性布点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 均匀性布点 失败!"})
+		return
+	}
+	产品存放区域测点 := c.GetString("产品存放区域测点") //  v26nplogbwt1
+	if len(产品存放区域测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 产品存放区域测点 失败!"})
+		return
+	}
+	均匀性布点 = 均匀性布点 + "|" + 产品存放区域测点
+
+	开始时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)开始时间") //  v26nplogbwt1
+	if len(开始时间) == 0 || 开始时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)开始时间 失败!"})
+		return
+	}
+	结束时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)结束时间") //  v26nplogbwt1
+	if len(结束时间) == 0 || 结束时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)结束时间 失败!"})
+		return
+	}
+
+	list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, 均匀性布点, 开始时间, 结束时间)
+	CalculateHumps_list := Task.CalculateHumps(list)
+
+	if len(CalculateHumps_list) < 7 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到连续5个循环 !"})
+		return
+	}
+	//start := CalculateHumps_list[6].Start // 驼峰开始
+	//peak := CalculateHumps_list[0]["peak"].(Task.TaskData) // 驼峰最高
+	end := CalculateHumps_list[4].End // 驼峰结束// 驼峰结束
+	// .Format("2006-01-02 15:04:05")
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: end.T_time})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A满载风机停止时间点() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	均匀性布点 := c.GetString("均匀性布点") //  v26nplogbwt1
+	if len(均匀性布点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 均匀性布点 失败!"})
+		return
+	}
+	产品存放区域测点 := c.GetString("产品存放区域测点") //  v26nplogbwt1
+	if len(产品存放区域测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 产品存放区域测点 失败!"})
+		return
+	}
+	均匀性布点 = 均匀性布点 + "|" + 产品存放区域测点
+
+	开始时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)开始时间") //  v26nplogbwt1
+	if len(开始时间) == 0 || 开始时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)开始时间 失败!"})
+		return
+	}
+	结束时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)结束时间") //  v26nplogbwt1
+	if len(结束时间) == 0 || 结束时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)结束时间 失败!"})
+		return
+	}
+
+	list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, 均匀性布点, 开始时间, 结束时间)
+	CalculateHumps_list := Task.CalculateHumps(list)
+
+	if len(CalculateHumps_list) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到连续1个循环 !"})
+		return
+	}
+	//start := CalculateHumps_list[0]["start"].(Task.TaskData)  // 驼峰开始
+	//peak := CalculateHumps_list[0]["peak"].(Task.TaskData) // 驼峰最高
+	end := CalculateHumps_list[0].End // 驼峰结束
+	// .Format("2006-01-02 15:04:05")
+	fmt.Println(end)
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: end.T_time})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A空载风机停止时间点() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	均匀性布点 := c.GetString("均匀性布点") //  v26nplogbwt1
+	if len(均匀性布点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 均匀性布点 失败!"})
+		return
+	}
+	产品存放区域测点 := c.GetString("产品存放区域测点") //  v26nplogbwt1
+	if len(产品存放区域测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 产品存放区域测点 失败!"})
+		return
+	}
+	均匀性布点 = 均匀性布点 + "|" + 产品存放区域测点
+
+	开始时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)开始时间") //  v26nplogbwt1
+	if len(开始时间) == 0 || 开始时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)开始时间 失败!"})
+		return
+	}
+	结束时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)结束时间") //  v26nplogbwt1
+	if len(结束时间) == 0 || 结束时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)结束时间 失败!"})
+		return
+	}
+
+	list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, 均匀性布点, 开始时间, 结束时间)
+	CalculateHumps_list := Task.CalculateHumps(list)
+
+	if len(CalculateHumps_list) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到连续1个循环 !"})
+		return
+	}
+	//start := CalculateHumps_list[0]["start"].(Task.TaskData)  // 驼峰开始
+	//peak := CalculateHumps_list[0]["peak"].(Task.TaskData) // 驼峰最高
+	end := CalculateHumps_list[0].End // 驼峰结束
+	// .Format("2006-01-02 15:04:05")
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: end.T_time})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A空载风机启动时间点() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	均匀性布点 := c.GetString("均匀性布点") //  v26nplogbwt1
+	if len(均匀性布点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 均匀性布点 失败!"})
+		return
+	}
+	产品存放区域测点 := c.GetString("产品存放区域测点") //  v26nplogbwt1
+	if len(产品存放区域测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 产品存放区域测点 失败!"})
+		return
+	}
+	均匀性布点 = 均匀性布点 + "|" + 产品存放区域测点
+
+	开始时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)开始时间") //  v26nplogbwt1
+	if len(开始时间) == 0 || 开始时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)开始时间 失败!"})
+		return
+	}
+	结束时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)结束时间") //  v26nplogbwt1
+	if len(结束时间) == 0 || 结束时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)结束时间 失败!"})
+		return
+	}
+
+	list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, 均匀性布点, 开始时间, 结束时间)
+	CalculateHumps_list := Task.CalculateHumps(list)
+
+	if len(CalculateHumps_list) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到连续1个循环 !"})
+		return
+	}
+	//start := CalculateHumps_list[0]["start"].(Task.TaskData)  // 驼峰开始
+	peak := CalculateHumps_list[0].Peak // 驼峰最高
+	//end := CalculateHumps_list[0]["end"].(Task.TaskData)    // 驼峰结束
+	// .Format("2006-01-02 15:04:05")
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: peak.T_time})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A满载风机启动时间点() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	均匀性布点 := c.GetString("均匀性布点") //  v26nplogbwt1
+	if len(均匀性布点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 均匀性布点 失败!"})
+		return
+	}
+	产品存放区域测点 := c.GetString("产品存放区域测点") //  v26nplogbwt1
+	if len(产品存放区域测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 产品存放区域测点 失败!"})
+		return
+	}
+	均匀性布点 = 均匀性布点 + "|" + 产品存放区域测点
+
+	开始时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)开始时间") //  v26nplogbwt1
+	if len(开始时间) == 0 || 开始时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)开始时间 失败!"})
+		return
+	}
+	结束时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)结束时间") //  v26nplogbwt1
+	if len(结束时间) == 0 || 结束时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)结束时间 失败!"})
+		return
+	}
+
+	list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, 均匀性布点, 开始时间, 结束时间)
+	CalculateHumps_list := Task.CalculateHumps(list)
+
+	if len(CalculateHumps_list) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到连续1个循环 !"})
+		return
+	}
+	//start := CalculateHumps_list[0]["start"].(Task.TaskData)  // 驼峰开始
+	peak := CalculateHumps_list[0].Peak // 驼峰最高
+	//end := CalculateHumps_list[0]["end"].(Task.TaskData)    // 驼峰结束
+	// .Format("2006-01-02 15:04:05")
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: peak.T_time})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A冷藏柜内部最高温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("温度控制范围最高值") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最高值 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A冷藏柜内部最低温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("温度控制范围最小值") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最小值 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A第一次开门结束时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("开空结") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		时间 = c.GetString("开满结") //  v26nplogbwt1
+		if len(时间) == 0 || 时间 == "null" {
+			lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 开空结 或 开满结 失败!"})
+			return
+		}
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A第一次开门开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("开空开") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		时间 = c.GetString("开满开") //  v26nplogbwt1
+		if len(时间) == 0 || 时间 == "null" {
+			lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 开空开 或 开满开 失败!"})
+			return
+		}
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A空载测试结束风机停止时间注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("空载测试结束风机停止时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 空载测试结束风机停止时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A空载风机停止时间点注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("空载风机停止时间点") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 空载风机停止时间点 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A空载风机启动时间点注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("空载风机启动时间点") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 空载风机启动时间点 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A满载测试结束风机停止时间注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("满载测试结束风机停止时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 满载测试结束风机停止时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A满载风机停止时间点注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("满载风机停止时间点") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 满载风机停止时间点 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A柜内所有测点() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("均匀性布点") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 均匀性布点 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A均匀性布点() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("柜内所有测点") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 柜内所有测点 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A产品存放区域测点() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("柜内所有测点") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 柜内所有测点 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A满载风机启动时间点注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("满载风机启动时间点") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 满载风机启动时间点 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A运行确认及偏差处理空载开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("现场测试开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试开始时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A运行确认及偏差处理满载开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("现场测试开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试开始时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A空载温度偏差均匀度波动度分析时间区间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间1 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)开始时间") //  v26nplogbwt1
+	if len(时间1) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)开始时间 失败!"})
+		return
+	}
+	时间2 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)结束时间") //  v26nplogbwt1
+	if len(时间2) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)结束时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间1 + "|" + 时间2})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A满载温度偏差均匀度波动度分析时间区间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间1 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)开始时间") //  v26nplogbwt1
+	if len(时间1) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)开始时间 失败!"})
+		return
+	}
+	时间2 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)结束时间") //  v26nplogbwt1
+	if len(时间2) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)结束时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间1 + "|" + 时间2})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A温控设备运行参数及使用状况测试空载结束时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)结束时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)结束时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A温控设备运行参数及使用状况测试满载结束时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)结束时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)结束时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A温控设备运行参数及使用状况测试空载开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)开始时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A温控设备运行参数及使用状况测试满载开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)开始时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A温度分布特性的测试与分析空载结束时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)结束时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)结束时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A温度分布特性的测试与分析满载结束时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)结束时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)结束时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A温度分布特性的测试与分析空载开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(空载)开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(空载)开始时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A温度分布特性的测试与分析满载开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("监测系统配置的测点终端参数及安装位置确认(满载)开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 监测系统配置的测点终端参数及安装位置确认(满载)开始时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A最长保温时限结束时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("温度自动监测设备放置位置结束时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置结束时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A最长保温时限开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("温度自动监测设备放置位置开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置开始时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A温度分布特性结束时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("温度自动监测设备放置位置结束时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置结束时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A温度分布特性开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("温度自动监测设备放置位置开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置开始时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 箱内所有测点|温度自动监测设备放置位置开始时间
+// 1}取 平均值 ,高于等于 [温度范围最高值] 并持续5分钟,取 第一个超标时的时间值
+// 2}[温湿度系统测点] 取最后时间点
+func (c *TaskDataController) A温度自动监测设备放置位置结束时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	箱内所有测点 := c.GetString("箱内所有测点") //  v26nplogbwt1
+	if len(箱内所有测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 箱内所有测点 失败!"})
+		return
+	}
+	温度自动监测设备放置位置开始时间 := c.GetString("温度自动监测设备放置位置开始时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置开始时间 失败!"})
+		return
+	}
+	温度范围最高值_ := c.GetString("温度范围最高值") //  v26nplogbwt1
+	if len(温度范围最高值_) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度范围最高值 失败!"})
+		return
+	}
+	温度范围最高值 := lib.To_float32(温度范围最高值_)
+
+	list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, 箱内所有测点, 温度自动监测设备放置位置开始时间, "")
+	if len(list) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到 箱内所有测点|温度自动监测设备放置位置开始时间 数据!"})
+		return
+	}
+
+	for i := 0; i < (len(list) - 7); i++ {
+		if list[i].T_t >= 温度范围最高值 {
+			if list[i].T_t <= list[i+1].T_t &&
+				list[i+1].T_t <= list[i+2].T_t &&
+				list[i+2].T_t <= list[i+3].T_t &&
+				list[i+3].T_t <= list[i+4].T_t &&
+				list[i+4].T_t <= list[i+5].T_t &&
+				list[i+5].T_t <= list[i+6].T_t {
+				lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: list[i].T_time})
+				return
+			}
+		}
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到 高于等于 [温度范围最高值] 并持续5分钟 数据!"})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 温湿度系统测点 第一条数据时间
+func (c *TaskDataController) A温度自动监测设备放置位置开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	温湿度系统测点 := c.GetString("温湿度系统测点") //  v26nplogbwt1
+	if len(温湿度系统测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温湿度系统测点 失败!"})
+		return
+	}
+
+	list, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, 温湿度系统测点, "", "", "", 0, 1)
+	if len(list) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到 温湿度系统测点 数据!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: list[0].T_time})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A保温箱准备开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("现场测试开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试开始时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 箱内所有测点|现场测试开始时间|温度自动监测设备放置位置开始时间
+// 温度低于(温度范围最高值 - 0.5),= 低于温度当前时的时间点
+func (c *TaskDataController) A冰排预冷保温箱准备结束时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	箱内所有测点 := c.GetString("箱内所有测点") //  v26nplogbwt1
+	if len(箱内所有测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 箱内所有测点 失败!"})
+		return
+	}
+	现场测试开始时间 := c.GetString("现场测试开始时间") //  v26nplogbwt1
+	if len(现场测试开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试开始时间 失败!"})
+		return
+	}
+	温度自动监测设备放置位置开始时间 := c.GetString("温度自动监测设备放置位置开始时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置开始时间 失败!"})
+		return
+	}
+	温度范围最高值_ := c.GetString("温度范围最高值") //  v26nplogbwt1
+	if len(温度范围最高值_) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度范围最高值 失败!"})
+		return
+	}
+	温度范围最高值 := lib.To_float32(温度范围最高值_) - 0.5
+	list, _ := Task.Read_TaskData_ById_List_SQL(Task_r.T_task_id, " AND t_t  <= "+lib.To_string(温度范围最高值)+" ", 箱内所有测点, "", 现场测试开始时间, "", 0, 1)
+	if len(list) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到 温度低于(温度范围最高值 - 0.5) !"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: list[0].T_time})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 保温箱温度设定值 = (温度范围最高值 - 温度范围最低值)/ 2
+func (c *TaskDataController) A保温箱温度设定值() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	温度范围最高值 := c.GetString("温度控制范围最高值") //  v26nplogbwt1
+	if len(温度范围最高值) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最高值 失败!"})
+		return
+	}
+	温度范围最低值 := c.GetString("温度控制范围最小值") //  v26nplogbwt1
+	if len(温度范围最低值) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最小值 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: lib.To_string((lib.To_float32(温度范围最高值) + lib.To_float32(温度范围最低值)) / 2)})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 风机温度设定值=(制冷机组温控设定最低值+制冷机组温控设定最高值)/2
+func (c *TaskDataController) A风机温度设定值() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	制冷机组温控设定最低值 := c.GetString("制冷机组温控设定最低值") //  v26nplogbwt1
+	if len(制冷机组温控设定最低值) != 0 || 制冷机组温控设定最低值 != "null" {
+		if !strings.Contains(制冷机组温控设定最低值, "档") {
+			制冷机组温控设定最高值 := c.GetString("制冷机组温控设定最高值") //  v26nplogbwt1
+			if len(制冷机组温控设定最高值) == 0 {
+				lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 制冷机组温控设定最高值 失败!"})
+				return
+			}
+			制冷机组温控设定最低值_, _ := lib.StringToFloat32(制冷机组温控设定最低值)
+			制冷机组温控设定最高值_, _ := lib.StringToFloat32(制冷机组温控设定最高值)
+
+			lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: lib.To_string((制冷机组温控设定最低值_ + 制冷机组温控设定最高值_) / 2)})
+			return
+
+		}
+	}
+	温度控制范围最高值 := c.GetString("温度控制范围最高值") //  v26nplogbwt1
+	if len(温度控制范围最高值) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最高值 失败!"})
+		return
+	}
+
+	温度控制范围最小值 := c.GetString("温度控制范围最小值") //  v26nplogbwt1
+	if len(温度控制范围最小值) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最小值 失败!"})
+		return
+	}
+	T := (lib.To_float32(温度控制范围最高值) + lib.To_float32(温度控制范围最小值)) / 2
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: lib.To2(T)})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A动态第三次开箱注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("动态三次开箱开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A动态第二次开箱注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("动态二次开箱开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A动态第一次开箱注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("动态第一次开箱开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A静态第三次开箱注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("静态三次开箱开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A静态第二次开箱注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("静态二次开箱开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A静态第一次开箱注释() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	时间 := c.GetString("静态第一次开箱开始时间") //  v26nplogbwt1
+	if len(时间) == 0 || 时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 时间 + "/" + 时间})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 冰排释冷监测设备|冰排释冷开始时间  当前 温度数据
+func (c *TaskDataController) A冰排释冷分割线最低温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	冰排释冷监测设备 := c.GetString("冰排释冷监测设备") //  v26nplogbwt1
+	if len(冰排释冷监测设备) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冰排释冷监测设备 失败!"})
+		return
+	}
+
+	冰排释冷开始时间 := c.GetString("冰排释冷开始时间") //  v26nplogbwt1
+	if len(冰排释冷开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冰排释冷开始时间 失败!"})
+		return
+	}
+
+	list, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, 冰排释冷监测设备, "", 冰排释冷开始时间, 冰排释冷开始时间, 0, 1)
+	if len(list) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冰排释冷监测设备|冰排释冷开始时间  当前 温度数据 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: fmt.Sprintf("%.1f", math.Ceil(float64(list[0].T_t*10))/10)})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 冰排释冷监测设备|冰排释冷结束时间  当前 温度数据
+func (c *TaskDataController) A冰排释冷分割线最高温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	冰排释冷监测设备 := c.GetString("冰排释冷监测设备") //  v26nplogbwt1
+	if len(冰排释冷监测设备) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冰排释冷监测设备 失败!"})
+		return
+	}
+
+	冰排释冷结束时间 := c.GetString("冰排释冷结束时间") //  v26nplogbwt1
+	if len(冰排释冷结束时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冰排释冷结束时间 失败!"})
+		return
+	}
+
+	list, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, 冰排释冷监测设备, "", 冰排释冷结束时间, 冰排释冷结束时间, 0, 1)
+	if len(list) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冰排释冷监测设备|冰排释冷结束时间  当前 温度数据 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: fmt.Sprintf("%.1f", math.Ceil(float64(list[0].T_t*10))/10)})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 冰排释冷监测设备|现场测试开始时间|温度自动监测设备放置位置开始时间
+// [冰排释冷开始时间] 时间后 ,超过 [温度范围最低值 ]度,第一条超标数据点时间
+func (c *TaskDataController) A冰排释冷结束时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	冰排释冷监测设备 := c.GetString("冰排释冷监测设备") //  v26nplogbwt1
+	if len(冰排释冷监测设备) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冰排释冷监测设备 失败!"})
+		return
+	}
+	温度范围最低值 := c.GetString("温度范围最低值") //  v26nplogbwt1
+	if len(温度范围最低值) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度范围最低值 失败!"})
+		return
+	}
+	冰排释冷开始时间 := c.GetString("冰排释冷开始时间") //  v26nplogbwt1
+	if len(冰排释冷开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冰排释冷开始时间 失败!"})
+		return
+	}
+	温度自动监测设备放置位置开始时间 := c.GetString("温度自动监测设备放置位置开始时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置开始时间 失败!"})
+		return
+	}
+
+	list, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, 冰排释冷监测设备, "", 冰排释冷开始时间, 温度自动监测设备放置位置开始时间, 0, 9999)
+	for _, v := range list {
+		if v.T_t >= lib.To_float32(温度范围最低值) {
+			lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: v.T_time})
+			return
+		}
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 [冰排释冷开始时间] 时间后 ,超过 [温度范围最低值]度,第一条超标数据点时间 失败!"})
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 冰排释冷监测设备|现场测试开始时间|温度自动监测设备放置位置开始时间
+// V型数据,下降持续5分钟,持续上升 5 分钟,取上升点的第一条数据
+// 40 2025-02-27 12:08  2025-02-27 14:40
+func (c *TaskDataController) A冰排释冷开始时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	冰排释冷监测设备 := c.GetString("冰排释冷监测设备") //  v26nplogbwt1
+	if len(冰排释冷监测设备) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冰排释冷监测设备 失败!"})
+		return
+	}
+	现场测试开始时间 := c.GetString("现场测试开始时间") //  v26nplogbwt1
+	if len(现场测试开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试开始时间 失败!"})
+		return
+	}
+	温度自动监测设备放置位置开始时间 := c.GetString("温度自动监测设备放置位置开始时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置开始时间 失败!"})
+		return
+	}
+
+	list, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, 冰排释冷监测设备, "", 现场测试开始时间, 温度自动监测设备放置位置开始时间, 0, 9999)
+	list_id, found := Task.FindVTrend(list)
+	if !found {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 V型趋势 失败!,下降持续5分钟,上升持续5分钟"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: list[list_id].T_time})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 保温箱外环境测点|温度自动监测设备放置位置开始时间|温度自动监测设备放置位置结束时间
+// 061 2025-02-27 14:40 2025-02-28 21:46
+func (c *TaskDataController) A外部环境分割线最高温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	保温箱外环境测点 := c.GetString("保温箱外环境测点") //  v26nplogbwt1
+	if len(保温箱外环境测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 保温箱外环境测点 失败!"})
+		return
+	}
+	温度自动监测设备放置位置开始时间 := c.GetString("温度自动监测设备放置位置开始时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置开始时间 失败!"})
+		return
+	}
+	温度自动监测设备放置位置结束时间 := c.GetString("温度自动监测设备放置位置结束时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置结束时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置结束时间 失败!"})
+		return
+	}
+
+	_, maxT := Task.Read_TaskData_T_Min_Max(Task_r.T_task_id, 保温箱外环境测点, "", 温度自动监测设备放置位置开始时间, 温度自动监测设备放置位置结束时间)
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: fmt.Sprintf("%.1f", math.Ceil(float64(maxT*10))/10)})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 保温箱外环境测点|温度自动监测设备放置位置开始时间|温度自动监测设备放置位置结束时间
+func (c *TaskDataController) A外部环境分割线最低温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	保温箱外环境测点 := c.GetString("保温箱外环境测点") //  v26nplogbwt1
+	if len(保温箱外环境测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 保温箱外环境测点 失败!"})
+		return
+	}
+	温度自动监测设备放置位置开始时间 := c.GetString("温度自动监测设备放置位置开始时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置开始时间 失败!"})
+		return
+	}
+	温度自动监测设备放置位置结束时间 := c.GetString("温度自动监测设备放置位置结束时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置结束时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度自动监测设备放置位置结束时间 失败!"})
+		return
+	}
+
+	minT, _ := Task.Read_TaskData_T_Min_Max(Task_r.T_task_id, 保温箱外环境测点, "", 温度自动监测设备放置位置开始时间, 温度自动监测设备放置位置结束时间)
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: fmt.Sprintf("%.1f", math.Ceil(float64(minT*10))/10)})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 保温箱外环境测点|温度自动监测设备放置位置开始时间|温度自动监测设备放置位置结束时间
+// 061 2025-02-27 14:40 2025-02-28 21:46
+func (c *TaskDataController) A冷藏柜外部环境测点最高温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	保温箱外环境测点 := c.GetString("冷藏柜外部环境测点") //  v26nplogbwt1
+	if len(保温箱外环境测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冷藏柜外部环境测点 失败!"})
+		return
+	}
+	温度自动监测设备放置位置开始时间 := c.GetString("现场测试开始时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试开始时间 失败!"})
+		return
+	}
+	温度自动监测设备放置位置结束时间 := c.GetString("现场测试结束时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置结束时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试结束时间 失败!"})
+		return
+	}
+
+	_, maxT := Task.Read_TaskData_T_Min_Max(Task_r.T_task_id, 保温箱外环境测点, "", 温度自动监测设备放置位置开始时间, 温度自动监测设备放置位置结束时间)
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: fmt.Sprintf("%.1f", math.Ceil(float64(maxT*10))/10)})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 保温箱外环境测点|温度自动监测设备放置位置开始时间|温度自动监测设备放置位置结束时间
+func (c *TaskDataController) A冷藏柜外部环境测点最低温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	保温箱外环境测点 := c.GetString("冷藏柜外部环境测点") //  v26nplogbwt1
+	if len(保温箱外环境测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冷藏柜外部环境测点 失败!"})
+		return
+	}
+	温度自动监测设备放置位置开始时间 := c.GetString("现场测试开始时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试开始时间 失败!"})
+		return
+	}
+	温度自动监测设备放置位置结束时间 := c.GetString("现场测试结束时间") //  v26nplogbwt1
+	if len(温度自动监测设备放置位置结束时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试结束时间 失败!"})
+		return
+	}
+
+	minT, _ := Task.Read_TaskData_T_Min_Max(Task_r.T_task_id, 保温箱外环境测点, "", 温度自动监测设备放置位置开始时间, 温度自动监测设备放置位置结束时间)
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: fmt.Sprintf("%.1f", math.Ceil(float64(minT*10))/10)})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A内部环境分割线最低温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	温度范围最低值 := c.GetString("温度控制范围最小值") //  v26nplogbwt1
+	if len(温度范围最低值) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最小值 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 温度范围最低值})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A内部环境分割线最高温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	温度范围最高值 := c.GetString("温度控制范围最高值") //  v26nplogbwt1
+	if len(温度范围最高值) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最高值 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 温度范围最高值})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A满载第一次关门温度恢复时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	柜内所有测点 := c.GetString("柜内所有测点") //  v26nplogbwt1
+	if len(柜内所有测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 柜内所有测点 失败!"})
+		return
+	}
+	温度控制范围最高值_ := c.GetString("温度控制范围最高值") //  v26nplogbwt1
+	if len(温度控制范围最高值_) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最高值 失败!"})
+		return
+	}
+	温度控制范围最高值 := lib.To_float32(温度控制范围最高值_)
+
+	第一次开门结束时间 := c.GetString("第一次开门结束时间") //  v26nplogbwt1
+	if len(第一次开门结束时间) == 0 || 第一次开门结束时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 第一次开门结束时间 失败!"})
+		return
+	}
+	第一次开门结束时间_a, err := time.Parse("2006-01-02 15:04:05", 第一次开门结束时间)
+	第一次开门结束时间_b := 第一次开门结束时间_a
+
+	for x := 0; x < 60; x++ {
+		第一次开门结束时间_b = 第一次开门结束时间_a.Add(time.Minute * 60)
+
+		maps_Time_Min_Max_GROUP := Task.Read_TaskData_T_Min_Max_Time_Min_Max_ListGROUP(Task_r.T_task_id, 柜内所有测点, 第一次开门结束时间_a.Format("2006-01-02 15:04:05"), 第一次开门结束时间_b.Format("2006-01-02 15:04:05"))
+
+		//  判断拐点
+		if maps_Time_Min_Max_GROUP[0].T_max <= maps_Time_Min_Max_GROUP[1].T_max &&
+			maps_Time_Min_Max_GROUP[1].T_max >= maps_Time_Min_Max_GROUP[2].T_max {
+
+			if maps_Time_Min_Max_GROUP[1].T_max > 温度控制范围最高值 {
+				// 情况1:开门有超标的情况:
+				// 柜内所有测点中任意一条数据出现超温度控制范围最高值后所有验证工具下降至温度控制范围最高值减0.5℃此时的时间
+				for _, group := range maps_Time_Min_Max_GROUP {
+					if group.T_max < 温度控制范围最高值-0.5 {
+						lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: group.T_times})
+						return
+					}
+				}
+				lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到 下降至温度控制范围最高值减0.5℃此时的时间 !"})
+				return
+			} else {
+				// 情况2:开门无超标的情况:
+				// 柜内所有测点中温度持续下降连续5分钟内,取第一条时间作为此时间点
+				list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, 柜内所有测点, maps_Time_Min_Max_GROUP[1].T_times, 第一次开门结束时间_a.Add(time.Minute*30).Format("2006-01-02 15:04:05"))
+
+				for i := 0; i < len(list)-6; i++ {
+					if maps_Time_Min_Max_GROUP[i].T_max <= maps_Time_Min_Max_GROUP[i+1].T_max &&
+						maps_Time_Min_Max_GROUP[i+1].T_max >= maps_Time_Min_Max_GROUP[i+2].T_max &&
+						maps_Time_Min_Max_GROUP[i+2].T_max >= maps_Time_Min_Max_GROUP[i+3].T_max &&
+						maps_Time_Min_Max_GROUP[i+3].T_max >= maps_Time_Min_Max_GROUP[i+4].T_max &&
+						maps_Time_Min_Max_GROUP[i+4].T_max >= maps_Time_Min_Max_GROUP[i+5].T_max {
+
+						lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: maps_Time_Min_Max_GROUP[i].T_times})
+						return
+
+					}
+				}
+				lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到 温度持续下降连续5分钟 !"})
+				return
+			}
+
+		}
+
+		第一次开门结束时间_a = 第一次开门结束时间_a.Add(time.Minute * 1)
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到数据拐点 !"})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A空载第一次关门温度恢复时间() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	柜内所有测点 := c.GetString("柜内所有测点") //  v26nplogbwt1
+	if len(柜内所有测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 柜内所有测点 失败!"})
+		return
+	}
+	温度控制范围最高值_ := c.GetString("温度控制范围最高值") //  v26nplogbwt1
+	if len(温度控制范围最高值_) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最高值 失败!"})
+		return
+	}
+	温度控制范围最高值 := lib.To_float32(温度控制范围最高值_)
+
+	第一次开门结束时间 := c.GetString("第一次开门结束时间") //  v26nplogbwt1
+	if len(第一次开门结束时间) == 0 || 第一次开门结束时间 == "null" {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 第一次开门结束时间 失败!"})
+		return
+	}
+	第一次开门结束时间_a, err := time.Parse("2006-01-02 15:04:05", 第一次开门结束时间)
+	第一次开门结束时间_b := 第一次开门结束时间_a
+
+	for x := 0; x < 60; x++ {
+		第一次开门结束时间_b = 第一次开门结束时间_a.Add(time.Minute * 20)
+
+		maps_Time_Min_Max_GROUP := Task.Read_TaskData_T_Min_Max_Time_Min_Max_ListGROUP(Task_r.T_task_id, 柜内所有测点, 第一次开门结束时间_a.Format("2006-01-02 15:04:05"), 第一次开门结束时间_b.Format("2006-01-02 15:04:05"))
+
+		//  判断拐点
+		if maps_Time_Min_Max_GROUP[0].T_max <= maps_Time_Min_Max_GROUP[1].T_max &&
+			maps_Time_Min_Max_GROUP[1].T_max >= maps_Time_Min_Max_GROUP[2].T_max {
+
+			if maps_Time_Min_Max_GROUP[1].T_max > 温度控制范围最高值 {
+				// 情况1:开门有超标的情况:
+				// 柜内所有测点中任意一条数据出现超温度控制范围最高值后所有验证工具下降至温度控制范围最高值减0.5℃此时的时间
+				for _, group := range maps_Time_Min_Max_GROUP {
+					if group.T_max < 温度控制范围最高值-0.5 {
+						lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: group.T_times})
+						return
+					}
+				}
+				lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到 下降至温度控制范围最高值减0.5℃此时的时间 !"})
+				return
+			} else {
+				// 情况2:开门无超标的情况:
+				// 柜内所有测点中温度持续下降连续5分钟内,取第一条时间作为此时间点
+				list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, 柜内所有测点, maps_Time_Min_Max_GROUP[1].T_times, 第一次开门结束时间_a.Add(time.Minute*30).Format("2006-01-02 15:04:05"))
+
+				for i := 0; i < len(list)-6; i++ {
+					if maps_Time_Min_Max_GROUP[i].T_max <= maps_Time_Min_Max_GROUP[i+1].T_max &&
+						maps_Time_Min_Max_GROUP[i+1].T_max >= maps_Time_Min_Max_GROUP[i+2].T_max &&
+						maps_Time_Min_Max_GROUP[i+2].T_max >= maps_Time_Min_Max_GROUP[i+3].T_max &&
+						maps_Time_Min_Max_GROUP[i+3].T_max >= maps_Time_Min_Max_GROUP[i+4].T_max &&
+						maps_Time_Min_Max_GROUP[i+4].T_max >= maps_Time_Min_Max_GROUP[i+5].T_max {
+
+						lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: maps_Time_Min_Max_GROUP[i].T_times})
+						return
+
+					}
+				}
+				lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到 温度持续下降连续5分钟 !"})
+				return
+			}
+
+		}
+
+		第一次开门结束时间_a = 第一次开门结束时间_a.Add(time.Minute * 1)
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "没找到数据拐点 !"})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A满载开门最长需要多少分钟恢复() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	恢复时间_ := c.GetString("满载第一次关门温度恢复时间") //  v26nplogbwt1
+	恢复时间, err := time.Parse("2006-01-02 15:04:05", 恢复时间_)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 满载第一次关门温度恢复时间 失败!"})
+		return
+	}
+
+	结束时间_ := c.GetString("第一次开门结束时间") //  v26nplogbwt1
+	结束时间, err := time.Parse("2006-01-02 15:04:05", 结束时间_)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 第一次开门结束时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: lib.To_string((恢复时间.Unix() - 结束时间.Unix()) / 60)})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A空载开门最长需要多少分钟恢复() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	恢复时间_ := c.GetString("空载第一次关门温度恢复时间") //  v26nplogbwt1
+	恢复时间, err := time.Parse("2006-01-02 15:04:05", 恢复时间_)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 空载第一次关门温度恢复时间 失败!"})
+		return
+	}
+
+	结束时间_ := c.GetString("第一次开门结束时间") //  v26nplogbwt1
+	结束时间, err := time.Parse("2006-01-02 15:04:05", 结束时间_)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 第一次开门结束时间 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: lib.To_string((恢复时间.Unix() - 结束时间.Unix()) / 60)})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A冷藏库作业口外部环境分割线最低温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	作业口外部测点 := c.GetString("作业口外部测点") //  v26nplogbwt1
+	if len(作业口外部测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 作业口外部测点 失败!"})
+		return
+	}
+
+	现场测试开始时间 := c.GetString("现场测试开始时间") //  v26nplogbwt1
+	if len(现场测试开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试开始时间 失败!"})
+		return
+	}
+	现场测试结束时间 := c.GetString("现场测试结束时间") //  v26nplogbwt1
+	if len(现场测试开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试结束时间 失败!"})
+		return
+	}
+
+	minT, _ := Task.Read_TaskData_T_Min_Max(Task_r.T_task_id, 作业口外部测点, "", 现场测试开始时间, 现场测试结束时间)
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: fmt.Sprintf("%.1f", math.Ceil(float64(minT*10))/10)})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A冷藏库作业口外部环境分割线最高温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	作业口外部测点 := c.GetString("作业口外部测点") //  v26nplogbwt1
+	if len(作业口外部测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 作业口外部测点 失败!"})
+		return
+	}
+
+	现场测试开始时间 := c.GetString("现场测试开始时间") //  v26nplogbwt1
+	if len(现场测试开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试开始时间 失败!"})
+		return
+	}
+	现场测试结束时间 := c.GetString("现场测试结束时间") //  v26nplogbwt1
+	if len(现场测试开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试结束时间 失败!"})
+		return
+	}
+
+	_, maxT := Task.Read_TaskData_T_Min_Max(Task_r.T_task_id, 作业口外部测点, "", 现场测试开始时间, 现场测试结束时间)
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: fmt.Sprintf("%.1f", math.Ceil(float64(maxT*10))/10)})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A冷藏库外部环境测点最高温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	冷藏库外部环境测点 := c.GetString("冷藏库外部环境测点") //  v26nplogbwt1
+	if len(冷藏库外部环境测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冷藏库外部环境测点 失败!"})
+		return
+	}
+
+	现场测试开始时间 := c.GetString("现场测试开始时间") //  v26nplogbwt1
+	if len(现场测试开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试开始时间 失败!"})
+		return
+	}
+	现场测试结束时间 := c.GetString("现场测试结束时间") //  v26nplogbwt1
+	if len(现场测试开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试结束时间 失败!"})
+		return
+	}
+
+	_, maxT := Task.Read_TaskData_T_Min_Max(Task_r.T_task_id, 冷藏库外部环境测点, "", 现场测试开始时间, 现场测试结束时间)
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: fmt.Sprintf("%.1f", math.Ceil(float64(maxT*10))/10)})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+func (c *TaskDataController) A冷藏库外部环境测点最低温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	冷藏库外部环境测点 := c.GetString("冷藏库外部环境测点") //  v26nplogbwt1
+	if len(冷藏库外部环境测点) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 冷藏库外部环境测点 失败!"})
+		return
+	}
+
+	现场测试开始时间 := c.GetString("现场测试开始时间") //  v26nplogbwt1
+	if len(现场测试开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试开始时间 失败!"})
+		return
+	}
+	现场测试结束时间 := c.GetString("现场测试结束时间") //  v26nplogbwt1
+	if len(现场测试开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 现场测试结束时间 失败!"})
+		return
+	}
+
+	minT, _ := Task.Read_TaskData_T_Min_Max(Task_r.T_task_id, 冷藏库外部环境测点, "", 现场测试开始时间, 现场测试结束时间)
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: fmt.Sprintf("%.1f", math.Ceil(float64(minT*10))/10)})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A冷藏库内部最低温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	温度控制范围最小值 := c.GetString("温度控制范围最小值") //  v26nplogbwt1
+	if len(温度控制范围最小值) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最小值 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 温度控制范围最小值})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+func (c *TaskDataController) A冷藏库内部最高温() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	温度控制范围最高值 := c.GetString("温度控制范围最高值") //  v26nplogbwt1
+	if len(温度控制范围最高值) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取 温度控制范围最高值 失败!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: 温度控制范围最高值})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}

+ 964 - 0
controllers/TaskHandle.go

@@ -0,0 +1,964 @@
+package controllers
+
+import (
+	"ColdVerify_local/lib"
+	"ColdVerify_local/logs"
+	"ColdVerify_local/models/Device"
+	"ColdVerify_local/models/Task"
+	"ColdVerify_local/models/VerifyTemplate"
+	"fmt"
+	beego "github.com/beego/beego/v2/server/web"
+	"github.com/beego/beego/v2/server/web/context"
+	"math"
+	"net/http"
+	"sort"
+	"strings"
+	"time"
+)
+
+type TaskDataHandleController struct {
+	beego.Controller
+}
+
+/*
+同区域数据缺失
+*/
+
+// 自动添加缺失终端,取关联绑定终端平均复制
+func (c *TaskDataHandleController) SSE_Automatically_add_missing_terminal() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+	println("T_task_id:", T_task_id)
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	DeviceClassList_r := Device.Read_DeviceClassList_List_id(Task_r.T_class)
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "终端总共:" + lib.To_string(len(DeviceClassList_r)) + " 正在检查自检探头..."})
+	for _, class_ := range DeviceClassList_r {
+		_, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, class_.T_sn, class_.T_id, "", "", 0, 1)
+		if cnt == 0 {
+			lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "找到" + class_.T_id + class_.T_remark + " 自检探头"})
+			// 获取 备注 下面关联设备,数量
+			var DeviceClassListT_remark_r_list_MAX int64
+			DeviceClassListT_remark_r_list_MAX = 0 //最大值
+			DeviceClassListT_remark_r := Device.Read_DeviceClassList_List_id_T_remark(class_.T_class, class_.T_remark)
+			for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
+				_, cnt = Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "", "", 0, 9999)
+				logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
+				if DeviceClassListT_remark_r_list_MAX < cnt {
+					DeviceClassListT_remark_r_list_MAX = cnt
+				}
+			}
+			// 筛选 符合的数量 终端
+			SN_List_sn := 9
+			SN_List_s := "" // 2023282551724643,003|2023282534778895,004|
+			SN_List_xn := 9
+			SN_List_x := "" // 2023282551724643,003|2023282534778895,004|
+			SN_List := ""
+			//SN_List_num := 0 // 数量  只能两个
+			CopyTime := ""  //复制的起点 2025-01-07 15:18:00
+			StartTime := "" // 2025-01-07 15:18:00
+			EndTime := ""   //2025-01-07 21:17:00
+			for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
+				List_data, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "", "", 0, 9999)
+				if len(List_data) == 0 {
+					//lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: DeviceClassListT_remark_r_list.T_id+"没有找到对应数据!"})
+					continue
+				}
+				if DeviceClassListT_remark_r_list_MAX == cnt {
+					logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
+					CopyTime = List_data[len(List_data)-1].T_time
+					StartTime = List_data[len(List_data)-1].T_time
+					EndTime = List_data[0].T_time
+
+					absc := int(math.Abs(float64(lib.To_int(DeviceClassListT_remark_r_list.T_id) - lib.To_int(class_.T_id))))
+
+					if absc < SN_List_sn {
+						SN_List_s = DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
+						SN_List_sn = absc
+						continue
+					}
+					if absc < SN_List_xn {
+						SN_List_x = DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
+						SN_List_xn = absc
+						continue
+					}
+
+					//SN_List_num++
+					//if SN_List_num >= 2 {
+					//	break // 数量  只能两个
+					//}
+				}
+			}
+			logs.Println("复制参数:", SN_List, CopyTime, StartTime, EndTime)
+			if len(SN_List_x) == 0 || len(SN_List_s) == 0 {
+				lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "[" + class_.T_remark + "]中没有找到 至少2条 完整可用数据"})
+				return
+			}
+
+			SN_List = SN_List_s + SN_List_x
+
+			lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: class_.T_sn + "|" + class_.T_id + "开始平均复制到" + SN_List})
+
+			// 开始平均复制到
+			CopySN := class_.T_sn
+			CopyID := class_.T_id
+
+			copyTime, _ := lib.TimeStrToTime(CopyTime)
+			endTime, _ := lib.TimeStrToTime(EndTime)
+			startTime, _ := lib.TimeStrToTime(StartTime)
+			// 时间间隔 s
+			T_saveT := 60
+			CopyEndTime := copyTime.Add(endTime.Sub(startTime)).Format("2006-01-02 15:04:05")
+
+			SN_List_Split := strings.Split(strings.Trim(SN_List, "|"), "|")
+			sn_id1 := strings.Split(SN_List_Split[0], ",")
+
+			sn1, id_str1 := sn_id1[0], sn_id1[1]
+			sn_id2 := strings.Split(SN_List_Split[1], ",")
+
+			sn2, id_str2 := sn_id2[0], sn_id2[1]
+			List1, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, sn1, id_str1, StartTime, EndTime, 0, 9999)
+			List2, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, sn2, id_str2, StartTime, EndTime, 0, 9999)
+			num := len(List1)
+			if len(List2) < len(List1) {
+				num = len(List2)
+			}
+			var list []Task.TaskData_
+			ct := copyTime
+			for i := 0; i < num; i++ {
+				if List1[i].T_time != List2[i].T_time {
+					lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: fmt.Sprintf("%s【%s】、%s【%s】时间不一致", List1[i].T_id, List1[i].T_time, List2[i].T_id, List2[i].T_time)})
+					return
+				}
+				T_t := (List1[i].T_t + List2[i].T_t) / 2
+				T_rh := (List1[i].T_rh + List2[i].T_rh) / 2
+				list = append(list, Task.TaskData_{
+					T_sn:   CopySN,
+					T_id:   CopyID,
+					T_t:    T_t,
+					T_rh:   T_rh,
+					T_time: ct.Format("2006-01-02 15:04:05"),
+				})
+				ct = ct.Add(time.Second * time.Duration(T_saveT))
+			}
+			Task.DeleteTaskDataByTimeRange(Task_r.T_task_id, CopySN, CopyID, CopyTime, CopyEndTime)
+			for i, taskData := range list {
+				Task.InsertTaskData(Task_r.T_task_id, taskData)
+
+				if i%100 == 0 {
+					lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", i, len(list))})
+				}
+			}
+
+		}
+
+	}
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 自动添加缺失数据,取关联绑定终端平均复制
+func (c *TaskDataHandleController) SSE_Automatically_add_missing_data() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+	// 时间间隔 s
+	T_saveT := 60
+
+	// 获取 备注 下面关联设备,数量
+	var Devicedata_list_MAX int64
+	Devicedata_list_MAX = 0 //最大值
+	DeviceClassList_list := Device.Read_DeviceClassList_List_id(Task_r.T_class)
+	for _, DeviceClassListT_remark_r_list := range DeviceClassList_list {
+		_, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "", "", 0, 9999)
+
+		if Devicedata_list_MAX < cnt {
+			Devicedata_list_MAX = cnt
+		}
+	}
+	logs.Println("数据标准数量:", Devicedata_list_MAX)
+	// 选择 数据缺失的终端
+	for _, DeviceClassList_r := range DeviceClassList_list {
+		list, cnt := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, DeviceClassList_r.T_sn, DeviceClassList_r.T_id, "", "", 0, 9999)
+		if Devicedata_list_MAX != cnt {
+
+			lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: DeviceClassList_r.T_id + " 终端自检数据 ,自检:" + lib.To_string(Devicedata_list_MAX-cnt) + " "})
+			for i := 0; i < len(list)-1; i++ {
+				current := list[i].T_time
+				next := list[i+1].T_time
+				ct, _ := time.Parse("2006-01-02 15:04:05", current)
+				nt, _ := time.Parse("2006-01-02 15:04:05", next)
+				interval := nt.Unix() - ct.Unix()
+				//logs.Debug("时间间隔:", interval, "保存时间:", saveTime)
+				//fmt.Println("当前:", current, "下一个:", next)
+				if int(interval) > T_saveT {
+					lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "找到自检点 " + current + " ~ " + next + " 开始自检"})
+
+					// -------------------- 开始 平均复制到  --------------------
+
+					// 获取 备注 下面关联设备,数量
+					var DeviceClassListT_remark_r_list_MAX int64
+					DeviceClassListT_remark_r_list_MAX = 0 //最大值
+					DeviceClassListT_remark_r := Device.Read_DeviceClassList_List_id_T_remark(DeviceClassList_r.T_class, DeviceClassList_r.T_remark)
+					for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
+						_, cnt = Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "", "", 0, 9999)
+						logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
+						if DeviceClassListT_remark_r_list_MAX < cnt {
+							DeviceClassListT_remark_r_list_MAX = cnt
+						}
+					}
+					// 筛选 符合的数量 终端
+					SN_List_sn := 9
+					SN_List_s := "" // 2023282551724643,003|2023282534778895,004|
+					SN_List_xn := 9
+					SN_List_x := "" // 2023282551724643,003|2023282534778895,004|
+					SN_List := ""   // 2023282551724643,003|2023282534778895,004|
+					//SN_List_num := 0     // 数量  只能两个
+					CopyTime := current  //复制的起点 2025-01-07 15:18:00
+					StartTime := current // 2025-01-07 15:18:00
+					EndTime := next      //2025-01-07 21:17:00
+					for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
+						List_data, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "", "", 0, 9999)
+						if DeviceClassListT_remark_r_list_MAX == cnt {
+							logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
+							//SN_List += DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
+							//CopyTime = List_data[len(List_data)-1].T_time
+							//StartTime = List_data[len(List_data)-1].T_time
+							EndTime = List_data[0].T_time
+
+							absc := int(math.Abs(float64(lib.To_int(DeviceClassListT_remark_r_list.T_id) - lib.To_int(DeviceClassList_r.T_id))))
+
+							if absc < SN_List_sn {
+								SN_List_s = DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
+								SN_List_sn = absc
+								continue
+							}
+							if absc < SN_List_xn {
+								SN_List_x = DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
+								SN_List_xn = absc
+								continue
+							}
+
+						}
+					}
+					logs.Println("复制参数:", SN_List, CopyTime, StartTime, EndTime)
+					if len(SN_List_x) == 0 || len(SN_List_s) == 0 {
+						lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "[" + DeviceClassList_r.T_remark + "] 中没有找到 至少2条 完整可用数据"})
+						return
+					}
+					SN_List = SN_List_s + SN_List_x
+
+					lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: DeviceClassList_r.T_sn + "|" + DeviceClassList_r.T_id + "开始平均复制到" + SN_List})
+
+					// 开始平均复制到
+					CopySN := DeviceClassList_r.T_sn
+					CopyID := DeviceClassList_r.T_id
+
+					copyTime, _ := lib.TimeStrToTime(CopyTime)
+					endTime, _ := lib.TimeStrToTime(EndTime)
+					startTime, _ := lib.TimeStrToTime(StartTime)
+
+					CopyEndTime := copyTime.Add(endTime.Sub(startTime)).Format("2006-01-02 15:04:05")
+
+					SN_List_Split := strings.Split(strings.Trim(SN_List, "|"), "|")
+					sn_id1 := strings.Split(SN_List_Split[0], ",")
+
+					sn1, id_str1 := sn_id1[0], sn_id1[1]
+					sn_id2 := strings.Split(SN_List_Split[1], ",")
+
+					sn2, id_str2 := sn_id2[0], sn_id2[1]
+					List1, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, sn1, id_str1, StartTime, EndTime, 0, 9999)
+					List2, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, sn2, id_str2, StartTime, EndTime, 0, 9999)
+					num := len(List1)
+					if len(List2) < len(List1) {
+						num = len(List2)
+					}
+					var list []Task.TaskData_
+					ct := copyTime
+					for i := 0; i < num; i++ {
+						if List1[i].T_time != List2[i].T_time {
+							lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: fmt.Sprintf("%s【%s】、%s【%s】时间不一致", List1[i].T_id, List1[i].T_time, List2[i].T_id, List2[i].T_time)})
+							return
+						}
+						T_t := (List1[i].T_t + List2[i].T_t) / 2
+						T_rh := (List1[i].T_rh + List2[i].T_rh) / 2
+						list = append(list, Task.TaskData_{
+							T_sn:   CopySN,
+							T_id:   CopyID,
+							T_t:    T_t,
+							T_rh:   T_rh,
+							T_time: ct.Format("2006-01-02 15:04:05"),
+						})
+						ct = ct.Add(time.Second * time.Duration(T_saveT))
+					}
+					Task.DeleteTaskDataByTimeRange(Task_r.T_task_id, CopySN, CopyID, CopyTime, CopyEndTime)
+					for i, taskData := range list {
+						Task.InsertTaskData(Task_r.T_task_id, taskData)
+
+						if i%100 == 0 {
+							lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", i, len(list))})
+						}
+					}
+
+				}
+			}
+
+		}
+	}
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 数据持续时间    x   分钟 没有变化
+func (c *TaskDataHandleController) SSE_Continuously_unchanged_data() {
+
+	T_task_id := c.GetString("T_task_id")     //  v26nplogbwt1
+	T_timeout, _ := c.GetInt("T_timeout", 30) //  持续时间
+
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	// 获取 备注 下面关联设备,数量
+	var Devicedata_list_MAX int64
+	Devicedata_list_MAX = 0 //最大值
+	DeviceClassList_list := Device.Read_DeviceClassList_List_id(Task_r.T_class)
+	for _, DeviceClassListT_remark_r_list := range DeviceClassList_list {
+		_, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "", "", 0, 9999)
+
+		if Devicedata_list_MAX < cnt {
+			Devicedata_list_MAX = cnt
+		}
+	}
+	logs.Println("数据标准数量:", Devicedata_list_MAX)
+	// 选择 数据缺失的终端
+	for _, DeviceClassList_r := range DeviceClassList_list {
+		TaskData_list, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, DeviceClassList_r.T_sn, DeviceClassList_r.T_id, "", "", 0, 9999)
+
+		var t_data float32
+		t_data = 0
+		t_data_num := 0
+
+		current := ""
+		next := ""
+		for i := 0; i < len(TaskData_list)-1; i++ {
+			if t_data == TaskData_list[i].T_t {
+				if t_data_num == 0 {
+					current = TaskData_list[i].T_time
+
+				}
+				t_data_num += 1
+				continue
+
+			} else {
+				if t_data_num > T_timeout {
+					next = TaskData_list[i].T_time
+
+					CopyFromPositionAverage(c.Ctx.ResponseWriter, Task_r.T_task_id, DeviceClassList_r.T_class, DeviceClassList_r.T_remark, DeviceClassList_r.T_sn, DeviceClassList_r.T_id, current, next)
+				}
+				// 清空标致
+				t_data = TaskData_list[i].T_t
+				t_data_num = 0
+				continue
+			}
+
+		}
+
+	}
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 平均复制到
+func CopyFromPositionAverage(c *context.Response, T_task_id string, T_class int, T_remark, T_sn, T_id, current, next string) {
+	fmt.Println("平均复制到 CopyFromPositionAverage:", T_task_id, T_class, T_remark, T_sn, T_id, current, next)
+
+	lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: "找到 " + T_id + " 无数据变化, 时间 " + current + " ~ " + next})
+
+	// -------------------- 开始 平均复制到  --------------------
+	// 时间间隔 s
+	T_saveT := 60
+	// 获取 备注 下面关联设备,数量
+	var DeviceClassListT_remark_r_list_MAX int64
+	DeviceClassListT_remark_r_list_MAX = 0 //最大值
+	DeviceClassListT_remark_r := Device.Read_DeviceClassList_List_id_T_remark(T_class, T_remark)
+	for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
+		_, cnt := Task.Read_TaskData_ById_List(T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, current, next, 0, 9999)
+		logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
+		if DeviceClassListT_remark_r_list_MAX < cnt {
+			DeviceClassListT_remark_r_list_MAX = cnt
+		}
+	}
+	// 筛选 符合的数量 终端
+	SN_List := ""        // 2023282551724643,003|2023282534778895,004|
+	SN_List_num := 0     // 数量  只能两个
+	CopyTime := current  //复制的起点 2025-01-07 15:18:00
+	StartTime := current // 2025-01-07 15:18:00
+	EndTime := next      //2025-01-07 21:17:00
+	for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
+		_, cnt := Task.Read_TaskData_ById_List(T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, current, next, 0, 9999)
+		if DeviceClassListT_remark_r_list_MAX == cnt {
+			logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
+			SN_List += DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
+			//CopyTime = List_data[len(List_data)-1].T_time
+			//StartTime = List_data[len(List_data)-1].T_time
+			//EndTime = List_data[0].T_time
+			SN_List_num++
+			if SN_List_num >= 2 {
+				break // 数量  只能两个
+			}
+		}
+	}
+	logs.Println("复制参数:", SN_List, CopyTime, StartTime, EndTime)
+	if SN_List_num != 2 {
+		lib.SseWriteJSON(c, lib.JSONSSE{State: 2, Msg: "[" + T_remark + "] 中没有找到 至少2条 完整可用数据"})
+		return
+	}
+	lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: T_sn + "|" + T_id + "开始平均复制到" + SN_List})
+
+	// 开始平均复制到
+	CopySN := T_sn
+	CopyID := T_id
+
+	copyTime, _ := lib.TimeStrToTime(CopyTime)
+	endTime, _ := lib.TimeStrToTime(EndTime)
+	startTime, _ := lib.TimeStrToTime(StartTime)
+
+	CopyEndTime := copyTime.Add(endTime.Sub(startTime)).Format("2006-01-02 15:04:05")
+
+	SN_List_Split := strings.Split(strings.Trim(SN_List, "|"), "|")
+	sn_id1 := strings.Split(SN_List_Split[0], ",")
+
+	sn1, id_str1 := sn_id1[0], sn_id1[1]
+	sn_id2 := strings.Split(SN_List_Split[1], ",")
+
+	sn2, id_str2 := sn_id2[0], sn_id2[1]
+	List1, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn1, id_str1, StartTime, EndTime, 0, 9999)
+	List2, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn2, id_str2, StartTime, EndTime, 0, 9999)
+	num := len(List1)
+	if len(List2) < len(List1) {
+		num = len(List2)
+	}
+
+	fmt.Println("num:", num)
+	var TaskData_list []Task.TaskData_
+	ct := copyTime
+	for TaskData_i := 0; TaskData_i < num; TaskData_i++ {
+		if List1[TaskData_i].T_time != List2[TaskData_i].T_time {
+			lib.SseWriteJSON(c, lib.JSONSSE{State: 2, Msg: fmt.Sprintf("%s【%s】、%s【%s】时间不一致", List1[TaskData_i].T_id, List1[TaskData_i].T_time, List2[TaskData_i].T_id, List2[TaskData_i].T_time)})
+			return
+		}
+		T_t := (List1[TaskData_i].T_t + List2[TaskData_i].T_t) / 2
+		T_rh := (List1[TaskData_i].T_rh + List2[TaskData_i].T_rh) / 2
+		TaskData_list = append(TaskData_list, Task.TaskData_{
+			T_sn:   CopySN,
+			T_id:   CopyID,
+			T_t:    T_t,
+			T_rh:   T_rh,
+			T_time: ct.Format("2006-01-02 15:04:05"),
+		})
+		ct = ct.Add(time.Second * time.Duration(T_saveT))
+	}
+	fmt.Println("TaskData_list:", len(TaskData_list))
+	Task.DeleteTaskDataByTimeRange(T_task_id, CopySN, CopyID, CopyTime, CopyEndTime)
+	for taskData_i, taskData := range TaskData_list {
+		Task.InsertTaskData(T_task_id, taskData)
+
+		if taskData_i%100 == 0 {
+			lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", taskData_i, len(TaskData_list))})
+		}
+	}
+
+}
+
+// 绑定点与终端比对  (绑定点数据自检)
+func (c *TaskDataHandleController) SSE_Comparison_between_binding_points_and_terminals() {
+
+	T_task_id := c.GetString("T_task_id")            //  v26nplogbwt1
+	T_deviation, _ := c.GetFloat("T_deviation", 1.0) //  持续时间
+
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	// -------------------- 温湿度绑定点1 --------------------
+	温湿度绑定点1_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点1")
+	if len(温湿度绑定点1_list) != 1 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温湿度绑定点1 中找到 " + lib.To_string(len(温湿度绑定点1_list)) + "条,只允许 一条数据!"})
+		return
+	}
+	监测终端01_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "监测终端01")
+	if len(监测终端01_list) != 1 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "监测终端01 中找到 " + lib.To_string(len(监测终端01_list)) + "条,只允许 一条数据!"})
+		return
+	}
+	温度分布特性的测试与分析_开始时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)开始时间")
+	温度分布特性的测试与分析_结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)结束时间")
+	if len(温度分布特性的测试与分析_开始时间) == 0 || len(温度分布特性的测试与分析_结束时间) == 0 {
+		温度分布特性的测试与分析_开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)开始时间")
+		温度分布特性的测试与分析_结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)结束时间")
+	}
+	if len(温度分布特性的测试与分析_开始时间) == 0 || len(温度分布特性的测试与分析_结束时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "请检查 温度分布特性的测试与分析时间!"})
+		return
+	}
+	fmt.Println("温湿度绑定点1   数据准备:", 温湿度绑定点1_list[0].T_id, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+
+	var 温湿度绑定点1vga, 监测终端01vga, vgaca float64
+	温湿度绑定点1vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+	监测终端01vga = Task.Read_TaskData_AVG(T_task_id, 监测终端01_list[0].T_sn, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+	vgaca = math.Round((监测终端01vga-温湿度绑定点1vga)*100) / 100.0
+
+	for T_deviation < math.Abs(vgaca) {
+		// 缩放
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!温湿度绑定点1 平均值:" +
+			lib.To_string(温湿度绑定点1vga) + "℃ 监测终端01vga 平均值" + lib.To_string(监测终端01vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
+
+		Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, 0.95)
+
+		// 偏移
+		温湿度绑定点1vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+		监测终端01vga = Task.Read_TaskData_AVG(T_task_id, 监测终端01_list[0].T_sn, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+		vgaca = math.Round((监测终端01vga-温湿度绑定点1vga)*100) / 100.0
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!温湿度绑定点1 平均值:" +
+			lib.To_string(温湿度绑定点1vga) + "℃ 监测终端01vga 平均值" + lib.To_string(监测终端01vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
+		Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, math.Round(((监测终端01vga-温湿度绑定点1vga)*0.8)*100)/100.0)
+
+		温湿度绑定点1vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+		监测终端01vga = Task.Read_TaskData_AVG(T_task_id, 监测终端01_list[0].T_sn, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+		vgaca = math.Round((监测终端01vga-温湿度绑定点1vga)*100) / 100.0
+
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "数据满足要求!温湿度绑定点1 平均值:" + lib.To_string(温湿度绑定点1vga) + "℃ 监测终端01vga 平均值" + lib.To_string(监测终端01vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ !"})
+
+	// -------------------- 温湿度绑定点2 --------------------
+
+	温湿度绑定点2_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点2")
+	if len(温湿度绑定点2_list) != 1 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点2 没找到,跳过 温湿度绑定点2"})
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
+		return
+	}
+	监测终端02_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "监测终端02")
+	if len(监测终端02_list) != 1 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "监测终端02 中找到 " + lib.To_string(len(监测终端02_list)) + "条,布点终端异常!"})
+		return
+	}
+
+	fmt.Println("温湿度绑定点2  数据准备:", 温湿度绑定点2_list[0].T_id, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+
+	var 温湿度绑定点2vga, 监测终端02vga float64
+	温湿度绑定点2vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+	监测终端02vga = Task.Read_TaskData_AVG(T_task_id, 监测终端02_list[0].T_sn, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+	vgaca = math.Round((监测终端02vga-温湿度绑定点2vga)*100) / 100.0
+
+	for T_deviation < math.Abs(vgaca) {
+		// 缩放
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!温湿度绑定点2 平均值:" +
+			lib.To_string(温湿度绑定点2vga) + "℃ 监测终端02vga 平均值" + lib.To_string(监测终端02vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
+
+		Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, 0.95)
+
+		// 偏移
+		温湿度绑定点2vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+		监测终端02vga = Task.Read_TaskData_AVG(T_task_id, 监测终端02_list[0].T_sn, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+		vgaca = math.Round((监测终端02vga-温湿度绑定点2vga)*100) / 100.0
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!温湿度绑定点2 平均值:" +
+			lib.To_string(温湿度绑定点2vga) + "℃ 监测终端02vga 平均值" + lib.To_string(监测终端02vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
+		Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, math.Round(((监测终端02vga-温湿度绑定点2vga)*0.8)*100)/100.0)
+
+		温湿度绑定点2vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+		监测终端02vga = Task.Read_TaskData_AVG(T_task_id, 监测终端02_list[0].T_sn, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+		vgaca = math.Round((监测终端02vga-温湿度绑定点2vga)*100) / 100.0
+
+	}
+	//
+	//lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "数据满足要求!温湿度绑定点2 平均值:" + lib.To_string(温湿度绑定点2vga) + "℃ 监测终端02vga 平均值" + lib.To_string(监测终端02vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ !"})
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 绑定点与冷热点比对  (冷热点数据自检)
+func (c *TaskDataHandleController) SSE_Compare_binding_points_with_cold_and_hot_spots() {
+
+	T_task_id := c.GetString("T_task_id")            //  v26nplogbwt1
+	T_deviation, _ := c.GetFloat("T_deviation", 1.0) //  持续时间
+
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	// ------------------
+	温度分布特性的测试与分析_开始时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)开始时间")
+	温度分布特性的测试与分析_结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)结束时间")
+	if len(温度分布特性的测试与分析_开始时间) == 0 || len(温度分布特性的测试与分析_结束时间) == 0 {
+		温度分布特性的测试与分析_开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)开始时间")
+		温度分布特性的测试与分析_结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)结束时间")
+	}
+	// 均匀性布点   产品存放区域测点
+	部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点")
+	部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...)
+	if len(部点终端_list) <= 2 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"})
+		return
+	}
+	type AVGClassList struct {
+		T_id  string
+		T_vga float64
+	}
+	var AVGClassList_r []AVGClassList
+	for _, i2 := range 部点终端_list {
+		AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_vga: Task.Read_TaskData_AVG(T_task_id, i2.T_sn, i2.T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
+	}
+	// 使用 sort.Slice 对切片进行排序
+	sort.Slice(AVGClassList_r, func(i, j int) bool {
+		return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
+		// 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
+	})
+	fmt.Println("AVGClassList_r:", AVGClassList_r)
+
+	// -------  温湿度绑定点
+	温湿度绑定点1_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点1")
+	if len(温湿度绑定点1_list) != 1 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温湿度绑定点1 中找到 " + lib.To_string(len(温湿度绑定点1_list)) + "条,布点终端异常!"})
+		return
+	}
+	温湿度绑定点2_list_is := true
+	温湿度绑定点2_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点2")
+	if len(温湿度绑定点2_list) != 1 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点2 没找到,将 温湿度绑定点1 设置低点"})
+		温湿度绑定点2_list = 温湿度绑定点1_list
+		温湿度绑定点2_list_is = false
+	}
+	温湿度绑定点1vga := Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+	温湿度绑定点2vga := Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
+
+	if 温湿度绑定点1vga == 温湿度绑定点2vga {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点1 与 温湿度绑定点2 平均值相等,将 进行上下偏移处理!"})
+		温湿度绑定点1vga += T_deviation / 2
+		温湿度绑定点2vga -= T_deviation / 2
+		T_deviation /= 2
+	}
+
+	var 温湿度绑定点vga_H, 温湿度绑定点vga_L AVGClassList
+	if 温湿度绑定点1vga > 温湿度绑定点2vga {
+		温湿度绑定点vga_H.T_id = 温湿度绑定点1_list[0].T_id
+		温湿度绑定点vga_H.T_vga = 温湿度绑定点1vga
+		温湿度绑定点vga_L.T_id = 温湿度绑定点2_list[0].T_id
+		温湿度绑定点vga_L.T_vga = 温湿度绑定点2vga
+	} else {
+		温湿度绑定点vga_L.T_id = 温湿度绑定点1_list[0].T_id
+		温湿度绑定点vga_L.T_vga = 温湿度绑定点1vga
+		温湿度绑定点vga_H.T_id = 温湿度绑定点2_list[0].T_id
+		温湿度绑定点vga_H.T_vga = 温湿度绑定点2vga
+	}
+
+	fmt.Println("温湿度绑定点:", 温湿度绑定点vga_H, 温湿度绑定点vga_L)
+
+	// -------------------- 温湿度绑定点vga_H --------------------
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 进行 高点处理 ------"})
+
+	var vgaca float64
+
+	vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
+
+	for T_deviation < math.Abs(vgaca) {
+		// 缩放
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!热点" + lib.To_string(AVGClassList_r[0].T_id) + " 平均值:" + lib.To_string(AVGClassList_r[0].T_vga) +
+			"℃ 高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_H.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
+
+		Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_r[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, 0.95)
+
+		// 偏移
+		// 均匀性布点   产品存放区域测点
+		AVGClassList_r = AVGClassList_r[:0] // 清空切片
+		for _, i2 := range 部点终端_list {
+			AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_vga: Task.Read_TaskData_AVG(T_task_id, i2.T_sn, i2.T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
+		}
+		// 使用 sort.Slice 对切片进行排序
+		sort.Slice(AVGClassList_r, func(i, j int) bool {
+			return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
+			// 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
+		})
+		fmt.Println("AVGClassList_r:", AVGClassList_r)
+		vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
+
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!热点" + lib.To_string(AVGClassList_r[0].T_id) + " 平均值:" + lib.To_string(AVGClassList_r[0].T_vga) +
+			"℃ 高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_H.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
+
+		Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, math.Round(((vgaca)*0.8)*100)/100.0)
+
+		// 均匀性布点   产品存放区域测点
+		AVGClassList_r = AVGClassList_r[:0] // 清空切片
+		for _, i2 := range 部点终端_list {
+			AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_vga: Task.Read_TaskData_AVG(T_task_id, i2.T_sn, i2.T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
+		}
+		// 使用 sort.Slice 对切片进行排序
+		sort.Slice(AVGClassList_r, func(i, j int) bool {
+			return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
+			// 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
+		})
+		fmt.Println("AVGClassList_r:", AVGClassList_r)
+		vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
+
+	}
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "热点 数据满足要求!热点" + lib.To_string(AVGClassList_r[0].T_id) + " 平均值:" + lib.To_string(AVGClassList_r[0].T_vga) +
+		"℃ 高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_H.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ "})
+
+	// -------------------- 温湿度绑定点vga_L --------------------
+	if !温湿度绑定点2_list_is {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "低点跳过处理!"})
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
+		return
+	}
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 进行 低点处理 ------"})
+
+	vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0
+	for T_deviation < math.Abs(vgaca) {
+		// 缩放
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!冷点" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_id) + " 平均值:" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_vga) +
+			"℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
+
+		Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_r[len(AVGClassList_r)-1].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, 0.95)
+
+		// 偏移
+		// 均匀性布点   产品存放区域测点
+		AVGClassList_r = AVGClassList_r[:0] // 清空切片
+		for _, i2 := range 部点终端_list {
+			AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_vga: Task.Read_TaskData_AVG(T_task_id, i2.T_sn, i2.T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
+		}
+		// 使用 sort.Slice 对切片进行排序
+		sort.Slice(AVGClassList_r, func(i, j int) bool {
+			return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
+			// 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
+		})
+		fmt.Println("AVGClassList_r:", AVGClassList_r)
+		vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0
+
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!冷点" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_id) + " 平均值:" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_vga) +
+			"℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
+
+		Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[len(AVGClassList_r)-1].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, math.Round(((vgaca)*0.8)*100)/100.0)
+
+		// 均匀性布点   产品存放区域测点
+		AVGClassList_r = AVGClassList_r[:0] // 清空切片
+		for _, i2 := range 部点终端_list {
+			AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_vga: Task.Read_TaskData_AVG(T_task_id, i2.T_sn, i2.T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
+		}
+		// 使用 sort.Slice 对切片进行排序
+		sort.Slice(AVGClassList_r, func(i, j int) bool {
+			return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
+			// 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
+		})
+		fmt.Println("AVGClassList_r:", AVGClassList_r)
+		vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0
+
+	}
+	//lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "冷点 数据满足要求!冷点" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_id) + " 平均值:" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_vga) +
+	//	"℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ "})
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 区间数据校正  (布点区域数据自检)
+func (c *TaskDataHandleController) SSE_Interval_data_correction() {
+
+	T_task_id := c.GetString("T_task_id") //  v26nplogbwt1
+
+	c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
+	c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
+	c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
+
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
+
+	Task_r, err := Task.Read_Task(T_task_id)
+	if err != nil {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
+		return
+	}
+
+	// ------------------
+
+	结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开空开")
+	if len(结束时间) == 0 {
+		结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开满开")
+	}
+	if len(结束时间) == 0 {
+		结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)结束时间")
+	}
+	if len(结束时间) == 0 {
+		结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)结束时间")
+	}
+	if len(结束时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到结束时间 标签!"})
+		return
+	}
+	温度控制范围最小值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最小值")))
+	温度控制范围最高值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最高值")))
+	if 温度控制范围最小值 == 0 || 温度控制范围最高值 == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温度控制范围 标签值不正确!"})
+		return
+	}
+	// 均匀性布点   产品存放区域测点
+	部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点")
+	部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...)
+	if len(部点终端_list) <= 2 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"})
+		return
+	}
+
+	//List_data, _ := Task.Read_TaskData_ById_List(Task_r.T_task_id, 部点终端_list[0].T_sn, 部点终端_list[0].T_id, "", "", 0, 9999)
+	//开始时间 := List_data[len(List_data) - 1].T_time
+
+	开始时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)开始时间")
+	if len(开始时间) == 0 {
+		开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)开始时间")
+	}
+	if len(开始时间) == 0 {
+		lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到开始时间 标签!"})
+		return
+	}
+
+	type AVGClassList struct {
+		T_id  string
+		T_max float64
+		T_min float64
+	}
+	var AVGClassList_r []AVGClassList
+	for _, i2 := range 部点终端_list {
+		T_max := Task.Read_TaskData_max(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
+		T_min := Task.Read_TaskData_min(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
+		AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_max: T_max, T_min: T_min})
+	}
+	fmt.Println("AVGClassList_r:", AVGClassList_r)
+
+	fmt.Println("数据准备:", 开始时间, 结束时间, 温度控制范围最小值, 温度控制范围最高值)
+
+	// -------  温湿度绑定点
+	AVGClassList_is := true
+
+	// -------------------- 温湿度绑定点vga_H --------------------
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "--- 进行处理 数据!---"})
+	for AVGClassList_is {
+		AVGClassList_is = false
+		// 准备数据
+		AVGClassList_r = AVGClassList_r[:0]
+		for _, i2 := range 部点终端_list {
+			T_max := Task.Read_TaskData_max(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
+			T_min := Task.Read_TaskData_min(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
+			AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_max: T_max, T_min: T_min})
+		}
+
+		for _, AVGClassList_i := range AVGClassList_r {
+			var vgaca float64
+			if AVGClassList_i.T_max > 温度控制范围最高值 {
+				AVGClassList_is = true
+
+				vgaca = math.Round((温度控制范围最高值-AVGClassList_i.T_max)*100) / 100.0
+				// 缩放
+				lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最大值:" + lib.To_string(AVGClassList_i.T_max) +
+					"℃  " + " 数据偏差: " + lib.To_string(vgaca) + "℃ 设置高:" + lib.To_string(温度控制范围最高值) + "℃"})
+				Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_i.T_id, 开始时间, 结束时间, 0.95)
+				Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[0].T_id, 开始时间, 结束时间, math.Round(((vgaca)*0.8)*100)/100.0)
+
+			}
+			if AVGClassList_i.T_min < 温度控制范围最小值 {
+				AVGClassList_is = true
+
+				vgaca = math.Round((温度控制范围最小值-AVGClassList_i.T_min)*100) / 100.0
+				// 缩放
+				lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最小值:" + lib.To_string(AVGClassList_i.T_min) +
+					"℃  " + " 数据偏差: " + lib.To_string(vgaca) + "℃ 设置小:" + lib.To_string(温度控制范围最小值) + "℃"})
+				Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_i.T_id, 开始时间, 结束时间, 0.95)
+				vgaca += float64(AVGClassList_i.T_min) - (AVGClassList_i.T_min * 0.95)
+
+				Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_i.T_id, 开始时间, 结束时间, math.Round(((vgaca)*1.2)*100)/100.0)
+
+			}
+		}
+		if AVGClassList_is {
+			lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 还有 数据需要修改 ------"})
+		}
+
+	}
+	lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
+
+	// Close the connection
+	c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
+}
+
+// 数据等比咧缩放      温度 湿度比列
+//func DataGeometricScale(T_task_id,SN_List_s,StartTime,EndTime string,Temperature,Humidity float64) {
+//
+//	SN_List := strings.Split(strings.Trim(SN_List_s, "|"), "|")
+//
+//	for _, v := range SN_List {
+//		sn_id := strings.Split(v, ",")
+//		if len(sn_id) != 2 {
+//			continue
+//		}
+//		sn, id := sn_id[0], sn_id[1]
+//
+//
+//
+//	}
+//
+//	return
+//}

+ 1 - 1
go.mod

@@ -1,6 +1,6 @@
 module ColdVerify_local
 
-go 1.19
+go 1.23
 
 require (
 	github.com/astaxie/beego v1.12.3

+ 12 - 0
go.sum

@@ -32,6 +32,7 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 git.sr.ht/~sbinet/cmpimg v0.1.0 h1:E0zPRk2muWuCqSKSVZIWsgtU9pjsw3eKHi8VmQeScxo=
+git.sr.ht/~sbinet/cmpimg v0.1.0/go.mod h1:FU12psLbF4TfNXkKH2ZZQ29crIqoiqTZmeQ7dkp/pxE=
 git.sr.ht/~sbinet/gg v0.4.1 h1:YccqPPS57/TpqX2fFnSRlisrqQ43gEdqVm3JtabPrp0=
 git.sr.ht/~sbinet/gg v0.4.1/go.mod h1:xKrQ22W53kn8Hlq+gzYeyyohGMwR8yGgSMlVpY/mHGc=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@@ -82,6 +83,7 @@ github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt
 github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
 github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
 github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
+github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -89,7 +91,9 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
 github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ=
+github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
 github.com/go-fonts/latin-modern v0.3.1 h1:/cT8A7uavYKvglYXvrdDw4oS5ZLkcOU22fa2HJ1/JVM=
+github.com/go-fonts/latin-modern v0.3.1/go.mod h1:ysEQXnuT/sCDOAONxC7ImeEDVINbltClhasMAqEtRK0=
 github.com/go-fonts/liberation v0.3.1 h1:9RPT2NhUpxQ7ukUvz3jeUckmN42T9D9TpjtQcqK/ceM=
 github.com/go-fonts/liberation v0.3.1/go.mod h1:jdJ+cqF+F4SUL2V+qxBth8fvBpBDS7yloUL5Fi8GTGY=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -165,6 +169,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -211,11 +216,13 @@ github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDu
 github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ=
+github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
 github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
+github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
 github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
 github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -228,6 +235,7 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/nats-io/jwt/v2 v2.4.1 h1:Y35W1dgbbz2SQUYDPCaclXcuqleVmpbRa7646Jf2EX4=
+github.com/nats-io/jwt/v2 v2.4.1/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI=
 github.com/nats-io/nats-server/v2 v2.9.20 h1:bt1dW6xsL1hWWwv7Hovm+EJt5L6iplyqlgEFkoEUk0k=
 github.com/nats-io/nats-server/v2 v2.9.20/go.mod h1:aTb/xtLCGKhfTFLxP591CMWfkdgBmcUUSkiSOe5A3gw=
 github.com/nats-io/nats.go v1.27.0 h1:3o9fsPhmoKm+yK7rekH2GtWoE+D9jFbw8N3/ayI1C00=
@@ -366,6 +374,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
 golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
 golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea h1:vLCWI/yYrdEHyN2JzIzPO3aaQJHQdp89IZBA/+azVC4=
+golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20220902085622-e7cb96979f69/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
@@ -519,6 +528,7 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
+golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -567,6 +577,7 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM=
+gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU=
 gonum.org/v1/plot v0.13.0 h1:yb2Z/b8bY5h/xC4uix+ujJ+ixvPUvBmUOtM73CJzpsw=
 gonum.org/v1/plot v0.13.0/go.mod h1:mV4Bpu4PWTgN2CETURNF8hCMg7EtlZqJYCcmYo/t4Co=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
@@ -679,5 +690,6 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
 honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
 rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

+ 53 - 0
lib/lib.go

@@ -7,6 +7,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"github.com/beego/beego/v2/server/web/context"
 	"github.com/nats-io/nats.go"
 	"github.com/signintech/gopdf"
 	"io/ioutil"
@@ -19,6 +20,7 @@ import (
 	"strconv"
 	"strings"
 	"time"
+	"unicode"
 )
 
 var Nats *nats.Conn
@@ -30,6 +32,11 @@ type JSONS struct {
 	Data interface{} // 泛型
 }
 
+type JSONSSE struct {
+	State int8   // 状态  0 进行中   1 成功    2 失败
+	Msg   string // 内容
+}
+
 type R_JSONS struct {
 	//必须的大写开头
 	List      interface{}
@@ -268,6 +275,30 @@ func To_float32(value interface{}) float32 {
 	return key
 }
 
+// StringToFloat32 将字符串转换为 float32,支持数字、小数点和负数
+func StringToFloat32(s string) (float32, error) {
+	cleanedStr := ""
+	for i, char := range s {
+		// 允许数字、小数点,以及第一个字符是负号
+		if unicode.IsDigit(char) || char == '.' || (char == '-' && i == 0) {
+			cleanedStr += string(char)
+		}
+	}
+
+	// 检查字符串是否为空(例如输入是 "abc")
+	if cleanedStr == "" {
+		return 0, fmt.Errorf("无效的数字格式: %s", s)
+	}
+
+	// 转换为 float32
+	f, err := strconv.ParseFloat(cleanedStr, 32)
+	if err != nil {
+		return 0, fmt.Errorf("转换失败: %v", err)
+	}
+
+	return float32(f), nil
+}
+
 func To_string(value interface{}) string {
 	var key string
 	if value == nil {
@@ -488,3 +519,25 @@ func FuncName() string {
 	f := runtime.FuncForPC(pc[0])
 	return f.Name()
 }
+
+// 发送 数据
+func SseWriteJSON(client *context.Response, msg JSONSSE) error {
+	datajson, _ := json.Marshal(msg)
+	// Send data to the client
+	client.Write(append(append([]byte("data: "), datajson...), []byte("\n\n")...))
+	//client.Write([]byte("\n"))
+	logs.Println("SseWriteJSON:", string(datajson))
+	// Flush the response writer to send the data immediately
+	client.Flush()
+
+	return nil
+}
+
+// 格式化为保留两位小数的字符串
+func To2(number float32) string {
+
+	formatted := fmt.Sprintf("%.2f", number)
+	//fmt.Println(formatted) // 输出: 3.14
+	return formatted
+
+}

+ 2 - 0
logs/LogPrintln.go

@@ -2,6 +2,7 @@ package logs
 
 import (
 	"ColdVerify_local/conf"
+	"fmt"
 	"github.com/astaxie/beego/logs"
 )
 
@@ -23,6 +24,7 @@ func Println(format string, v ...interface{}) {
 		format += " %v"
 	}
 	Logx.Info(format, v...)
+	fmt.Println(v)
 }
 
 // Debug Log DEBUG level message.

+ 344 - 1
models/Device/DeviceClassList.go

@@ -1,6 +1,20 @@
 package Device
 
-import "time"
+import (
+	"ColdVerify_local/conf"
+	"ColdVerify_local/lib"
+	"ColdVerify_local/logs"
+	"encoding/json"
+	"fmt"
+	"github.com/astaxie/beego/cache"
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"strconv"
+	"strings"
+	"time"
+)
 
 // 模板
 type DeviceClassList struct {
@@ -18,3 +32,332 @@ type DeviceClassList struct {
 	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
 	UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
 }
+
+func (t *DeviceClassList) TableName() string {
+	return "device_class_list" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+var redisCache_DeviceClassList cache.Cache
+
+func init() {
+
+	//注册模型
+	orm.RegisterModel(new(DeviceClassList))
+
+	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
+		"redis_"+"DeviceClassList", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
+	logs.Println(config)
+	var err error
+	redisCache_DeviceClassList, err = cache.NewCache("redis", config)
+	if err != nil || redisCache_DeviceClassList == nil {
+		errMsg := "failed to init redis"
+		logs.Println(errMsg, err)
+
+	}
+}
+
+// ---------------- Redis -------------------
+// Redis_Set(m.T_sn,m) // Redis 更新缓存
+func Redis_DeviceClassList_Set(key string, r DeviceClassList) (err error) {
+	//json序列化
+	str, err := json.Marshal(r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	err = redisCache_DeviceClassList.Put(key, str, 24*time.Hour)
+	if err != nil {
+		logs.Println("set key:", key, ",value:", str, err)
+	}
+	return
+}
+
+// if r,is :=Redis_Get(T_sn);is{
+// return r,nil
+// }
+func Redis_DeviceClassList_Get(key string) (r DeviceClassList, is bool) {
+	if redisCache_DeviceClassList.IsExist(key) {
+		logs.Println("找到key:", key)
+		v := redisCache_DeviceClassList.Get(key)
+		json.Unmarshal(v.([]byte), &r)
+		return r, true
+	}
+	logs.Println("没有 找到key:", key)
+	return DeviceClassList{}, false
+}
+func Redis_DeviceClassList_DelK(key string) (err error) {
+	err = redisCache_DeviceClassList.Delete(key)
+	return
+}
+
+// ---------------- 特殊方法 -------------------
+
+// 获取 ById
+func Read_DeviceClassList_ById(id int) (r DeviceClassList, is bool) {
+	o := orm.NewOrm()
+	r = DeviceClassList{Id: id}
+	err := o.Read(&r) // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, false
+	}
+	return r, true
+}
+
+// 获取 By
+func Read_DeviceClassList(T_sn string) (r DeviceClassList, is bool) {
+	if r, is = Redis_DeviceClassList_Get(T_sn); is == true {
+		return r, true
+	}
+
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(DeviceClassList))
+	err := qs.Filter("T_sn", T_sn).One(&r)
+	if err != nil {
+		logs.Println(lib.FuncName(), err)
+		return r, false
+	}
+
+	Redis_DeviceClassList_Set(T_sn, r)
+	return r, true
+}
+
+
+// 添加
+func Read_DeviceClassList_T_class_T_sn(T_class int, T_sn string) (r DeviceClassList, is bool) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(DeviceClassList))
+	err := qs.Filter("T_sn", T_sn).Filter("T_class", T_class).One(&r)
+	if err != nil {
+		logs.Println(lib.FuncName(), err)
+		return r, false
+	}
+	return r, true
+}
+
+func Read_DeviceClassList_T_class_T_id(T_class int, T_id string) (r DeviceClassList, is bool) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(DeviceClassList))
+	err := qs.Filter("T_id", T_id).Filter("T_class", T_class).Filter("T_State", 1).One(&r)
+	if err != nil {
+		logs.Println(lib.FuncName(), err)
+		return r, false
+	}
+	return r, true
+}
+
+// 添加
+func Add_DeviceClassList(r DeviceClassList) (id int64, is bool) {
+	o := orm.NewOrm()
+	//r.T_State = 1
+	//err := o.Read(&r, "T_class", "T_sn", "T_State") // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	//if err == nil {
+	//	if r.Id > 0 {
+	//		logs.Println("重复添加", r.T_class, r.T_sn)
+	//		return 0, false
+	//	}
+	//}
+
+	id, err := o.Insert(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return 0, false
+	}
+
+	Redis_DeviceClassList_Set(r.T_sn, r)
+	return id, true
+}
+
+// 删除
+func Delete_DeviceClassList(v DeviceClassList) bool {
+	o := orm.NewOrm()
+	if num, err := o.Delete(&v); err == nil {
+		logs.Println("Number of records deleted in database:", num)
+	} else {
+		logs.Println(lib.FuncName(), err)
+		return false
+	}
+
+	Redis_DeviceClassList_DelK(v.T_sn)
+	return true
+}
+
+// 删除
+func Delete_DeviceClassList_(v DeviceClassList) bool {
+	o := orm.NewOrm()
+	v.T_State = 0
+	if num, err := o.Update(&v, "T_State"); err == nil {
+		logs.Println("Number of records updated in database:", num)
+	} else {
+		logs.Println(lib.FuncName(), err)
+		return false
+	}
+
+	Redis_DeviceClassList_DelK(v.T_sn)
+	return true
+}
+
+// 修改
+func Update_DeviceClassList(m DeviceClassList, cols ...string) bool {
+	o := orm.NewOrm()
+	if num, err := o.Update(&m, cols...); err == nil {
+		logs.Println("Number of records updated in database:", num)
+		Redis_DeviceClassList_Set(m.T_sn, m)
+		return true
+	} else {
+		logs.Println(lib.FuncName(), err)
+	}
+	return false
+}
+
+// 获取列表
+func Read_DeviceClassList_List(T_class int, T_sn string, page int, page_z int) (r []DeviceClassList, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceClassList))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_class", T_class).And("T_sn__icontains", T_sn).And("T_State", 1) // .AndNot("status__in", 1).Or("profile__age__gt", 2000)
+	if page_z == 9999 {
+		qs.SetCond((*orm2.Condition)(cond1)).OrderBy("T_id").All(&r)
+	} else {
+		qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("T_id").All(&r)
+	}
+	cnt, _ = qs.SetCond((*orm2.Condition)(cond1)).Count()
+	return r, cnt
+}
+func Read_DeviceClassList_OrderList(T_class int, T_sn, T_id, T_remark string, page int, page_z int) (r []DeviceClassList, cnt int64) {
+
+	o := orm.NewOrm()
+	var maps_z []orm2.ParamsList
+	pagez := page_z
+
+	var offset int
+	if page <= 1 {
+		offset = 0
+	} else {
+		page -= 1
+		offset = page * pagez
+	}
+
+	sqlWhere := "t_class = " + strconv.Itoa(T_class) + " AND t__state = 1"
+	if len(T_sn) > 1 {
+		sqlWhere += " AND t_sn like \"%" + T_sn + "%\""
+	}
+	if len(T_id) > 1 {
+		sqlWhere += " AND T_id like \"%" + T_id + "%\""
+	}
+	if len(T_remark) > 0 {
+		sqlWhere += " AND t_remark like \"%" + T_remark + "%\""
+	}
+
+	sql := "SELECT COUNT(ID) FROM device_class_list WHERE " + sqlWhere
+	logs.Println(sql)
+	_, err := o.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		return r, 0
+	}
+	if len(maps_z) == 0 {
+		return r, 0
+	}
+	//logs.Println("maps_z;",maps_z[0][0])
+	sql = "SELECT *  FROM device_class_list WHERE " + sqlWhere + " ORDER BY t_id+0 "
+	if page_z != 9999 {
+		sql = sql + " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(pagez)
+	}
+
+	logs.Println(sql)
+	_, err = o.Raw(sql).QueryRows(&r)
+	if err != nil {
+		logs.Println(lib.FuncName(), err)
+		return r, 0
+	}
+
+	//value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", cnt), 64)
+	key, _ := strconv.Atoi(maps_z[0][0].(string))
+	return r, int64(key)
+}
+
+// 获取列表
+func Read_DeviceClassList_List_id(T_class_Id int) (r []DeviceClassList) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceClassList))
+
+	qs.Filter("T_class", T_class_Id).Filter("T_State", 1).All(&r)
+
+	return r
+}
+
+// 获取列表
+func Read_DeviceClassList_List_id_T_remark(T_class_Id int,T_remark string) (r []DeviceClassList) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceClassList))
+	T_remark_s := strings.Split(T_remark,"|")
+	cond := orm.NewCondition()
+	cond1 := orm.NewCondition()
+
+	for _,v := range T_remark_s{
+		if len(T_remark_s) > 0 {
+			cond1 = cond1.Or("T_remark__icontains", v) // .AndNot("status__in", 1).Or("profile__age__gt", 2000)
+
+		}
+
+	}
+	cond = cond.And("T_class", T_class_Id).And("T_State", 1).AndCond(cond1)
+
+	qs.SetCond((*orm2.Condition)(cond)).All(&r)
+
+	//qs.Filter("T_class", T_class_Id).Filter("T_remark", T_remark).Filter("T_State", 1).All(&r)
+
+	return r
+}
+
+// 获取列表
+func Read_DeviceClassList_List_id_T_sn(T_class_Id int,T_sn string) (r []DeviceClassList) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceClassList))
+
+	qs.Filter("T_class", T_class_Id).Filter("T_sn", T_sn).All(&r)
+
+	return r
+}
+
+// 删除重复设备列表
+func Del_DeviceClassList_Duplication(T_class int) error {
+
+	o := orm.NewOrm()
+
+	// 开始插入数据 UPDATE `cold_verify`.`Z_TaskData_d8qMyeXLzIxn` SET `t_t` = 20.2 WHERE `ID` = 69
+	sql := "DELETE FROM device_class_list WHERE ID NOT IN (" +
+		"SELECT * FROM (SELECT MIN(ID) FROM device_class_list WHERE t__state = 1 AND t_class = " + strconv.Itoa(T_class) +
+		" GROUP BY t_class, t_id, t_sn) AS keep_ids) " +
+		" AND t__state = 1 AND t_class = " + strconv.Itoa(T_class)
+
+	//  这里有时间优化  用于一次 prepare 多次 exec,以提高批量执行的速度
+	logs.Debug(sql)
+	res, err := o.Raw(sql).Exec()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	num, _ := res.RowsAffected()
+
+	logs.Debug("删除重复设备列表: ", num)
+	return nil
+}

+ 506 - 2
models/Task/TaskData.go

@@ -12,6 +12,7 @@ import (
 	orm2 "github.com/beego/beego/v2/client/orm"
 	"github.com/go-sql-driver/mysql"
 	_ "github.com/go-sql-driver/mysql"
+	"math"
 	"strconv"
 	"strings"
 	"time"
@@ -22,7 +23,7 @@ const (
 	Humidity    = "Humidity"
 )
 
-// 模板
+// 模板  func TestBeego(t *testing.T) {
 type TaskData struct {
 	Id int `orm:"column(ID);size(11);auto;pk"`
 
@@ -33,6 +34,14 @@ type TaskData struct {
 
 	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间 UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`   //auto_now 每次 model 保存时都会对时间自动更新
 }
+type TaskData_Time_Min_Max_GROUP struct {
+	T_max    float32 // 温度
+	T_max_id string  // 温度
+	T_min    float32 // 湿度
+	T_min_id string  // 湿度
+	T_times  string  // 采集时间
+
+}
 
 func (t *TaskData) TableName() string {
 	return "task_data" // 数据库名称   // ************** 替换 FormulaList **************
@@ -158,6 +167,10 @@ type TaskDataClass_ struct {
 	T_sn string `orm:"column(t_sn);size(256);null"` // 标题
 	T_id string `orm:"column(t_id);size(256);null"` // 名称
 }
+type TaskData_AVG struct {
+	T_t    float32 `orm:"column(t_t);size(10);null"` // 温度
+	T_time string  `orm:"column(t_times);null;"`     // 采集时间
+}
 
 func Read_TaskData_ById_List(T_task_id string, SN string, T_id string, Time_start_ string, Time_end_ string, page int, page_z int) ([]TaskData_, int64) {
 	o := orm.NewOrm()
@@ -219,6 +232,7 @@ func Read_TaskData_ById_List(T_task_id string, SN string, T_id string, Time_star
 	key, _ := strconv.Atoi(maps_z[0][0].(string))
 	return maps, int64(key)
 }
+
 func Read_TaskData_ById_List_AES(T_task_id string, SN string, T_id string, Time_start_ string, Time_end_ string, page int, page_z int) ([]TaskData_, int64) {
 	o := orm.NewOrm()
 	var maps []TaskData_
@@ -246,7 +260,105 @@ func Read_TaskData_ById_List_AES(T_task_id string, SN string, T_id string, Time_
 		sql_condition += " AND t_id = '" + T_id + "'"
 	}
 	if len(SN) > 0 {
-		sql_condition += " AND t_sn = '" + SN + "'"
+		if strings.Contains(SN, "|") {
+			// 将字符串按 | 分割
+			ids := strings.Split(strings.TrimSuffix(SN, "|"), "|")
+
+			// 构建 SQL 查询
+			query := " AND t_sn IN ("
+			// 动态添加每个 id
+			for i, id := range ids {
+				query += "'" + id + "'"
+				if i < len(ids)-1 {
+					query += ", " // 添加逗号分隔
+				}
+			}
+			query += ") " // 结束 SQL 查询
+
+		} else {
+			sql_condition += " AND t_sn = '" + SN + "'"
+		}
+	}
+	if len(sql_condition) > 0 {
+		sql_condition = " WHERE " + strings.TrimLeft(sql_condition, " AND ")
+	}
+
+	sql := "SELECT COUNT(ID) FROM z_task_data_" + T_task_id + sql_condition
+
+	fmt.Println(sql)
+	_, err := o.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		return maps, 0
+	}
+	if len(maps_z) == 0 {
+		return maps, 0
+	}
+
+	//fmt.Println("maps_z;",maps_z[0][0])
+	sql = "SELECT ID,t_sn,t_id,t_t,t_rh,DATE_FORMAT(t_time,'%Y-%m-%d %H:%i:%s') AS t_times,t_time FROM z_task_data_" + T_task_id + sql_condition + " ORDER BY t_time"
+	if page_z != 9999 {
+		sql = sql + " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(pagez)
+	}
+
+	fmt.Println(sql)
+	_, err = o.Raw(sql).QueryRows(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+
+	//value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", cnt), 64)
+	key, _ := strconv.Atoi(maps_z[0][0].(string))
+	return maps, int64(key)
+}
+
+func Read_TaskData_ById_List_SQL(T_task_id string, SQL, SN string, T_id string, Time_start_ string, Time_end_ string, page int, page_z int) ([]TaskData_, int64) {
+	o := orm.NewOrm()
+	var maps []TaskData_
+	var maps_z []orm2.ParamsList
+	pagez := page_z
+
+	var offset int
+	if page <= 1 {
+		offset = 0
+	} else {
+		page -= 1
+		offset = page * pagez
+	}
+
+	sql_condition := ""
+	if len(Time_start_) > 1 {
+		sql_condition += " AND t_time >= '" + Time_start_ + "'"
+	}
+
+	if len(Time_end_) > 1 {
+		sql_condition += " AND t_time <= '" + Time_end_ + "'"
+	}
+
+	if len(T_id) > 0 {
+		sql_condition += " AND t_id = '" + T_id + "'"
+	}
+	if len(SQL) > 0 {
+		sql_condition += SQL
+	}
+	if len(SN) > 0 {
+		if strings.Contains(SN, "|") {
+			// 将字符串按 | 分割
+			ids := strings.Split(strings.TrimSuffix(SN, "|"), "|")
+
+			// 构建 SQL 查询
+			query := " AND t_sn IN ("
+			// 动态添加每个 id
+			for i, id := range ids {
+				query += "'" + id + "'"
+				if i < len(ids)-1 {
+					query += ", " // 添加逗号分隔
+				}
+			}
+			query += ") " // 结束 SQL 查询
+
+		} else {
+			sql_condition += " AND t_sn = '" + SN + "'"
+		}
 	}
 	if len(sql_condition) > 0 {
 		sql_condition = " WHERE " + strings.TrimLeft(sql_condition, " AND ")
@@ -301,6 +413,50 @@ func Read_TaskData_ById_List_(T_task_id string, SN string) []TaskData_ {
 	return maps
 }
 
+func Read_TaskData_ById_AVG(T_task_id string, SN string, Time_start_ string, Time_end_ string) []TaskData_AVG {
+	o := orm.NewOrm()
+	var maps []TaskData_AVG
+
+	sql_condition := ""
+	if len(Time_start_) > 1 {
+		sql_condition += " AND t_time >= '" + Time_start_ + "'"
+	}
+
+	if len(Time_end_) > 1 {
+		sql_condition += " AND t_time <= '" + Time_end_ + "'"
+	}
+
+	if len(SN) > 0 {
+		if strings.Contains(SN, "|") {
+			// 将字符串按 | 分割
+			ids := strings.Split(strings.TrimSuffix(SN, "|"), "|")
+
+			// 构建 SQL 查询
+			query := " AND t_sn IN ("
+			// 动态添加每个 id
+			for i, id := range ids {
+				query += "'" + id + "'"
+				if i < len(ids)-1 {
+					query += ", " // 添加逗号分隔
+				}
+			}
+			query += ") " // 结束 SQL 查询
+
+		} else {
+			sql_condition += " AND t_sn = '" + SN + "'"
+		}
+	}
+	if len(sql_condition) > 0 {
+		sql_condition = " WHERE " + strings.TrimLeft(sql_condition, " AND ")
+	}
+
+	sql := "SELECT DATE_FORMAT(t_time,'%Y-%m-%d %H:%i:%s') AS t_times, AVG(t_t) AS t_t FROM z_task_data_" + T_task_id + sql_condition + "  GROUP BY t_time  ORDER BY t_time"
+
+	fmt.Println(sql)
+	o.Raw(sql).QueryRows(&maps)
+
+	return maps
+}
 func Read_TaskData_ById_ClassList(T_task_id string) []TaskDataClass_ {
 	o := orm.NewOrm()
 	var maps []TaskDataClass_
@@ -775,6 +931,41 @@ func InsertTaskData(T_task_id string, d TaskData_) {
 
 }
 
+// InsertTaskData 添加设备数据
+func InsertTaskData_TH(T_task_id string, T_switch_t, T_switch_h bool, d TaskData_) {
+
+	o := orm.NewOrm()
+	var maps TaskData_
+	sql := fmt.Sprintf("SELECT * FROM z_task_data_%s where t_time='%s' and t_id = '%s' and t_sn = '%s'", T_task_id, d.T_time, d.T_id, d.T_sn)
+	err := o.Raw(sql).QueryRow(&maps)
+	if err != nil && err.Error() != orm.ErrNoRows.Error() {
+		logs.Error(lib.FuncName(), err)
+	}
+	// 添加
+	if maps.ID == 0 {
+		sqlStatement := fmt.Sprintf("insert into z_task_data_%s(t_sn, t_id, t_t, t_rh, t_time) value('%s','%s',%f,%f,'%s')", T_task_id, d.T_sn, d.T_id, d.T_t, d.T_rh, d.T_time)
+		_, err = o.Raw(sqlStatement).Exec()
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+		}
+		return
+	}
+
+	//已经存在该条目,更新
+	sqlStatement := fmt.Sprintf("update z_task_data_%s set t_t = %f,t_rh = %f where t_time= '%s' and t_id = '%s' and t_sn = '%s'", T_task_id, d.T_t, d.T_rh, d.T_time, d.T_id, d.T_sn)
+	if T_switch_t && !T_switch_h {
+		sqlStatement = fmt.Sprintf("update z_task_data_%s set t_t = %f where t_time= '%s' and t_id = '%s' and t_sn = '%s'", T_task_id, d.T_t, d.T_time, d.T_id, d.T_sn)
+	}
+	if !T_switch_t && T_switch_h {
+		sqlStatement = fmt.Sprintf("update z_task_data_%s set t_rh = %f where t_time= '%s' and t_id = '%s' and t_sn = '%s'", T_task_id, d.T_rh, d.T_time, d.T_id, d.T_sn)
+	}
+	_, err = o.Raw(sqlStatement).Exec()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+
+}
+
 // DeleteTaskDataByTimeRange 删除时间范围内的数据
 func DeleteTaskDataByTimeRange(T_task_id, sn string, id string, start, end string) {
 	sqlStatement := fmt.Sprintf("delete from z_task_data_%s where t_time between '%s' and '%s' and t_id = '%s' and t_sn = '%s'", T_task_id, start, end, id, sn)
@@ -866,7 +1057,48 @@ func Read_TaskData_T_Min_Max(T_task_id string, SN string, T_id string, Time_star
 
 // UpdateTaskDataTemperatureAndHumidityByGeometric 更新设备探头数据温湿度 等比缩放
 func UpdateTaskDataTemperatureAndHumidityByGeometric(T_task_id, sn, id, startTime, endTime string, temperature, humidity float64) {
+
 	sqlStatement := fmt.Sprintf("update z_task_data_%s set t_t = t_t * %f , t_rh = t_rh * %f where t_id = '%s' and  t_sn = '%s' and t_time BETWEEN '%s' and '%s'", T_task_id, temperature, humidity, id, sn, startTime, endTime)
+
+	o := orm.NewOrm()
+
+	exec, err := o.Raw(sqlStatement).Exec()
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	affected, err := exec.RowsAffected()
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	fmt.Printf("影响了%d行\n", affected)
+}
+func UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, id, startTime, endTime string, temperature float64) {
+
+	sqlStatement := fmt.Sprintf("update z_task_data_%s set t_t = t_t * %f where t_id = '%s' and t_time BETWEEN '%s' and '%s'", T_task_id, temperature, id, startTime, endTime)
+
+	o := orm.NewOrm()
+
+	exec, err := o.Raw(sqlStatement).Exec()
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	affected, err := exec.RowsAffected()
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	fmt.Printf("影响了%d行\n", affected)
+}
+
+// UpdateTaskDataTemperatureAndHumidityByGeometric 更新设备探头数据温湿度 等比缩放
+func UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, id, startTime, endTime string, temperature float64) {
+
+	sqlStatement := ""
+	if temperature > 0 {
+		sqlStatement = fmt.Sprintf("update z_task_data_%s set t_t = t_t + %f  where t_id = '%s' and t_time BETWEEN '%s' and '%s'", T_task_id, temperature, id, startTime, endTime)
+	} else {
+		sqlStatement = fmt.Sprintf("update z_task_data_%s set t_t = t_t %f  where t_id = '%s' and t_time BETWEEN '%s' and '%s'", T_task_id, temperature, id, startTime, endTime)
+
+	}
 	o := orm.NewOrm()
 
 	exec, err := o.Raw(sqlStatement).Exec()
@@ -975,6 +1207,83 @@ func Read_TaskData_ByIds_List(T_task_id string, SN []string, T_id []string, Time
 	return maps
 }
 
+func Read_TaskData_T_Min_Max_Time_Min_Max_ListGROUP(T_task_id string, SN string, Time_start_ string, Time_end_ string) []TaskData_Time_Min_Max_GROUP {
+	o := orm.NewOrm()
+	var maps_Time_Min_Max_GROUP []TaskData_Time_Min_Max_GROUP
+
+	时间_a, _ := time.Parse("2006-01-02 15:04:05", Time_start_)
+	时间_b, _ := time.Parse("2006-01-02 15:04:05", Time_end_)
+
+	for 时间_a.Unix() <= 时间_b.Unix() {
+
+		var maps []TaskData_
+		maps_Time_Min_Max_GROUP_ := TaskData_Time_Min_Max_GROUP{
+			T_max:   -100,
+			T_min:   100,
+			T_times: 时间_a.Format("2006-01-02 15:04:05"),
+		}
+		sql_condition := ""
+		Time_start_ = 时间_a.Format("2006-01-02 15:04:05")
+		Time_end_ = 时间_b.Format("2006-01-02 15:04:05")
+		if len(Time_start_) > 1 {
+			sql_condition += " AND t_time >= '" + Time_start_ + "'"
+		}
+		if len(Time_end_) > 1 {
+			sql_condition += " AND t_time <= '" + Time_end_ + "'"
+		}
+
+		if len(SN) > 0 {
+			if strings.Contains(SN, "|") {
+				// 将字符串按 | 分割
+				ids := strings.Split(strings.TrimSuffix(SN, "|"), "|")
+
+				// 构建 SQL 查询
+				query := " AND t_sn IN ("
+				// 动态添加每个 id
+				for i, id := range ids {
+					query += "'" + id + "'"
+					if i < len(ids)-1 {
+						query += ", " // 添加逗号分隔
+					}
+				}
+				query += ") " // 结束 SQL 查询
+
+			} else {
+				sql_condition += " AND t_sn = '" + SN + "'"
+			}
+		}
+		if len(sql_condition) > 0 {
+			sql_condition = " WHERE " + strings.TrimLeft(sql_condition, " AND ")
+		}
+
+		//fmt.Println("maps_z;",maps_z[0][0])
+		sql := "SELECT ID,t_sn,t_id,t_t,t_rh,DATE_FORMAT(t_time,'%Y-%m-%d %H:%i:%s') AS t_times,t_time FROM z_task_data_" + T_task_id + sql_condition + " ORDER BY t_time DESC"
+
+		fmt.Println(sql)
+		_, err := o.Raw(sql).QueryRows(&maps)
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+		}
+
+		for _, data := range maps {
+			if data.T_t > maps_Time_Min_Max_GROUP_.T_max {
+				maps_Time_Min_Max_GROUP_.T_max = data.T_t
+				maps_Time_Min_Max_GROUP_.T_max_id = data.T_id
+			}
+			if data.T_t < maps_Time_Min_Max_GROUP_.T_max {
+				maps_Time_Min_Max_GROUP_.T_min = data.T_t
+				maps_Time_Min_Max_GROUP_.T_min_id = data.T_id
+			}
+		}
+		maps_Time_Min_Max_GROUP = append(maps_Time_Min_Max_GROUP, maps_Time_Min_Max_GROUP_)
+
+		时间_a = 时间_a.Add(time.Minute * 10)
+
+	}
+
+	return maps_Time_Min_Max_GROUP
+}
+
 // 按照 t_id 分组数据
 func GroupDataByTID(data []TaskData) map[string][]TaskData {
 	groupedData := make(map[string][]TaskData)
@@ -1046,3 +1355,198 @@ func UpdateAUTO_INCREMENT(alias_name, T_task_id string) error {
 	}
 	return nil
 }
+
+// 修改auto_increment的初始值
+func Read_TaskData_AVG(T_task_id, T_sn, T_id, startTime, endTime string) float64 {
+	o := orm.NewOrm()
+	var v float64
+	sql := fmt.Sprintf("select AVG(t_t) FROM z_task_data_%s where t_id = '%s' and t_time BETWEEN '%s' and '%s'", T_task_id, T_id, startTime, endTime)
+
+	err := o.Raw(sql).QueryRow(&v)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return 0
+	}
+
+	return v
+}
+
+// 修改auto_increment的初始值
+func Read_TaskData_max(T_task_id, T_sn, T_id, startTime, endTime string) float64 {
+	o := orm.NewOrm()
+	var v float64
+	sql := fmt.Sprintf("select MAX(t_t) FROM z_task_data_%s where t_id = '%s' and t_time BETWEEN '%s' and '%s'", T_task_id, T_id, startTime, endTime)
+
+	err := o.Raw(sql).QueryRow(&v)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return 0
+	}
+
+	return v
+}
+
+// 修改auto_increment的初始值
+func Read_TaskData_min(T_task_id, T_sn, T_id, startTime, endTime string) float64 {
+	o := orm.NewOrm()
+	var v float64
+	sql := fmt.Sprintf("select MIN(t_t) FROM z_task_data_%s where t_id = '%s' and t_time BETWEEN '%s' and '%s'", T_task_id, T_id, startTime, endTime)
+
+	err := o.Raw(sql).QueryRow(&v)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return 0
+	}
+
+	return v
+}
+
+// 重置 SN数据
+
+func Import_TaskData_Back(Sn string, T_id string, T_task_id string, Time_start string, Time_end string) error {
+	o := orm.NewOrm()
+	// 开始插入数据
+	sql := "insert into z_task_data_" + T_task_id + "(t_sn,t_id,t_t,t_rh,t_time) select '" + Sn + "','" + T_id + "',t_t,t_rh,t_time from z_devicedata_" + Sn
+	if len(Time_start) > 0 && len(Time_end) > 0 {
+		sql = sql + " WHERE t_time >= '" + Time_start + "' AND t_time <= '" + Time_end + "'"
+	}
+	logs.Println(sql)
+	_, err := o.Raw(sql).Exec()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+
+	return nil
+}
+
+func Import_Task_Back(Sn string, T_id string, T_task_id, To_T_task_id string, Time_start string, Time_end string) error {
+	o := orm.NewOrm()
+	// 开始插入数据
+	sql := "insert into z_task_data_" + To_T_task_id + "(t_sn,t_id,t_t,t_rh,t_time) select t_sn,t_id,t_t,t_rh,t_time from z_task_data_" + T_task_id
+	if len(Time_start) > 0 && len(Time_end) > 0 {
+		sql = sql + " WHERE t_sn = '" + Sn + "' AND t_id  = '" + T_id + "' AND t_time >= '" + Time_start + "' AND t_time <= '" + Time_end + "'"
+	}
+	logs.Println(sql)
+	_, err := o.Raw(sql).Exec()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+
+	return nil
+}
+
+/* ==============================================================================================================
+	                 V型数据,下降持续5分钟,持续上升 5 分钟,取上升点的第一条数据
+==============================================================================================================
+*/
+// isDescending checks if the given data points are strictly descending.
+func isDescending(data []TaskData_) bool {
+	if len(data) < 2 {
+		return false // Not enough data to determine a trend.
+	}
+	for i := 1; i < len(data); i++ {
+		if data[i].T_t >= data[i-1].T_t {
+			return false // Not strictly descending.
+		}
+	}
+	return true
+}
+
+// isAscending checks if the given data points are strictly ascending.
+func isAscending(data []TaskData_) bool {
+	if len(data) < 2 {
+		return false // Not enough data to determine a trend.
+	}
+	for i := 1; i < len(data); i++ {
+		if data[i].T_t <= data[i-1].T_t {
+			return false // Not strictly ascending.
+		}
+	}
+	return true
+}
+
+// findVTrend identifies a V-shaped trend in the data and returns the time of the lowest point.
+// It looks for a sequence of at least 5 descending points followed by at least 5 ascending points.
+func FindVTrend(data []TaskData_) (int, bool) {
+	if len(data) < 10 {
+		return -1, false // Not enough data to find a V-trend.
+	}
+
+	for i := 5; i < len(data)-5; i++ { // Adjust loop for index out of bounds error
+		descendingData := data[i-5 : i] // Get 5 descending point
+		ascendingData := data[i : i+5]  // get 5 ascending point
+
+		if isDescending(descendingData) && isAscending(ascendingData) {
+			// Found a V-trend.  Return the time of the lowest point (data[i]).
+			return i, true
+		}
+	}
+
+	return -1, false // No V-trend found.
+}
+
+type CalculateHumps_R struct {
+	Start TaskData_AVG
+	Peak  TaskData_AVG
+	End   TaskData_AVG
+}
+
+// 计算驼峰趋势
+func CalculateHumps(data []TaskData_AVG) []CalculateHumps_R {
+	var humps []CalculateHumps_R
+	n := len(data)
+	if n < 3 {
+		return humps
+	}
+
+	i := 0
+	for i < n-5 {
+		// 寻找开始的最低点
+		for !(data[i].T_t <= data[i+1].T_t && data[i+1].T_t <= data[i+2].T_t) {
+			i++
+			if i > n-5 {
+				break
+			}
+		}
+		start := i
+
+		// 寻找最高点
+		for !(data[i].T_t >= data[i+1].T_t && data[i+1].T_t > data[i+2].T_t && data[i+2].T_t > data[i+3].T_t) {
+			i++
+			if i > n-5 {
+				break
+			}
+		}
+		peak := i
+		Abs_peak := math.Abs(float64(data[start].T_t - data[peak].T_t))
+		if Abs_peak < 0.2 {
+			continue
+		}
+
+		// 寻找结束的最低点
+		for !(data[i].T_t <= data[i+1].T_t && data[i+1].T_t < data[i+2].T_t && data[i+2].T_t < data[i+3].T_t) {
+			i++
+			if i > n-5 {
+				break
+			}
+		}
+		end := i
+		Abs_end := math.Abs(float64(data[end].T_t - data[peak].T_t))
+		if Abs_end < 0.3 {
+			continue
+		}
+		// 如果找到了一个完整的驼峰
+		if start < peak && peak < end {
+			CalculateHumps_ := CalculateHumps_R{
+				Start: data[start],
+				Peak:  data[peak],
+				End:   data[end],
+			}
+			humps = append(humps, CalculateHumps_)
+		}
+	}
+
+	return humps
+}

+ 183 - 0
models/VerifyTemplate/VerifyTemplate.go

@@ -0,0 +1,183 @@
+package VerifyTemplate
+
+import (
+	"ColdVerify_local/lib"
+	"ColdVerify_local/logs"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"time"
+)
+
+// 模板
+type VerifyTemplate struct {
+	Id      int `orm:"column(ID);size(11);auto;pk"`
+	T_class int `orm:"size(8);default(0)"` // 分类
+
+	T_VerifyTemplate_id string `orm:"size(256);null"`     // 标题
+	T_name              string `orm:"size(256);null"`     // 标题
+	T_sort              int    `orm:"size(2);default(1)"` // 排
+
+	T_scheme    string `orm:"size(256);null"` // 方案模板
+	T_reporting string `orm:"size(256);null"` // 报告模板
+	T_marking   string `orm:"size(256);null"` // 标识模板
+	T_inspect   string `orm:"size(256);null"` // 自检
+	T_cover     string `orm:"size(256);null"` // 封面
+
+	T_deploy  string   `orm:"type(text);null"` // 部点选项  格式 布点内容1|布点内容2|布点内容3
+
+	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
+	UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
+}
+
+type VerifyTemplate_R struct {
+	T_VerifyTemplate_id string `orm:"size(256);null"` // 标题
+	T_name              string `orm:"size(256);null"` // 标题
+	T_sort              int    `orm:"size(200);null"` // 分类
+
+	T_scheme    string // 方案模板
+	T_reporting string // 报告模板
+	T_inspect   string // 自检
+	T_marking   string // 标识模板
+	T_cover     string // 封面
+	T_deploy  string  // 部点选项  格式 布点内容1|布点内容2|布点内容3
+}
+
+func (t *VerifyTemplate) TableName() string {
+	return "verify_template" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+
+	//注册模型
+	orm.RegisterModel(new(VerifyTemplate))
+
+}
+
+// -------------------------------------------------------------
+func VerifyTemplateToVerifyTemplate_R(T VerifyTemplate) (T_r VerifyTemplate_R) {
+	T_r.T_VerifyTemplate_id = T.T_VerifyTemplate_id
+	T_r.T_name = T.T_name
+	T_r.T_sort = T.T_sort
+	T_r.T_scheme = T.T_scheme
+	T_r.T_reporting = T.T_reporting
+	T_r.T_inspect = T.T_inspect
+	T_r.T_marking = T.T_marking
+	T_r.T_cover = T.T_cover
+	T_r.T_deploy = T.T_deploy
+
+	return T_r
+}
+
+// ---------------- 特殊方法 -------------------
+
+// 获取 ById
+func Read_VerifyTemplate_ById(id int) (r VerifyTemplate, is bool) {
+	o := orm.NewOrm()
+	r = VerifyTemplate{Id: id}
+	err := o.Read(&r) // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, false
+	}
+	return r, true
+}
+
+// 获取 By
+func Read_VerifyTemplate(T_VerifyTemplate_id string) (r VerifyTemplate, is bool) {
+
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(VerifyTemplate))
+	err := qs.Filter("T_VerifyTemplate_id", T_VerifyTemplate_id).One(&r)
+	if err != nil {
+		return r, false
+	}
+
+	return r, true
+}
+
+func Read_VerifyTemplate_T_name(T_name string) (r VerifyTemplate, is bool) {
+
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(VerifyTemplate))
+	err := qs.Filter("T_name", T_name).One(&r)
+	if err != nil {
+		return r, false
+	}
+
+	return r, true
+}
+
+// 添加
+func Add_VerifyTemplate(r VerifyTemplate) (T_VerifyTemplate_id string, is bool) {
+	o := orm.NewOrm()
+
+	// 生成编号
+	rand_x := 0
+	for true {
+		r.T_VerifyTemplate_id = lib.GetRandstring(4, "", int64(rand_x)) // 1,336,336
+		err := o.Read(&r, "T_VerifyTemplate_id")                        // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+		if err != nil {
+			break
+		}
+		rand_x += 1
+	}
+
+	_, err := o.Insert(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return "", false
+	}
+
+	return r.T_VerifyTemplate_id, true
+}
+
+// 删除
+func Delete_VerifyTemplate(v VerifyTemplate) bool {
+	o := orm.NewOrm()
+	if num, err := o.Delete(&v); err == nil {
+		logs.Println("Number of records deleted in database:", num)
+	} else {
+		return false
+	}
+
+	return true
+}
+
+// 修改
+func Update_VerifyTemplate(m VerifyTemplate, cols ...string) bool {
+	o := orm.NewOrm()
+	if num, err := o.Update(&m, cols...); err == nil {
+		logs.Println("Number of records updated in database:", num)
+		return true
+	}
+	return false
+}
+
+// 获取列表
+func Read_VerifyTemplate_List(T_class int, T_name string, page int, page_z int) ([]VerifyTemplate_R, int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []VerifyTemplate
+	qs := o.QueryTable(new(VerifyTemplate))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_class", T_class).And("T_name__icontains", T_name) // .AndNot("status__in", 1).Or("profile__age__gt", 2000)
+
+	qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("T_name").All(&r)
+	cnt, _ := qs.SetCond((*orm2.Condition)(cond1)).Count()
+	// 转换
+	var VerifyTemplate_r []VerifyTemplate_R
+	for _, v := range r {
+		VerifyTemplate_r = append(VerifyTemplate_r, VerifyTemplateToVerifyTemplate_R(v))
+	}
+
+	return VerifyTemplate_r, cnt
+}

+ 153 - 0
models/VerifyTemplate/VerifyTemplateClass.go

@@ -0,0 +1,153 @@
+package VerifyTemplate
+
+import (
+	"ColdVerify_local/lib"
+	"ColdVerify_local/logs"
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"strconv"
+)
+
+// 模板
+type VerifyTemplateClass struct {
+	Id     int    `orm:"column(ID);size(11);auto;pk"`
+	T_fid  int    `orm:"size(200);null"` // 父级分类ID,主类 为 0
+	T_name string `orm:"size(256);null"` // 标题
+	T_path string `orm:"size(256);null"` // 路径
+
+	T_State int `orm:"size(2);default(1)"` // 0 删除(伪删除)   1 正常
+
+	Children []VerifyTemplateClass `orm:"-"`
+}
+
+func (t *VerifyTemplateClass) TableName() string {
+	return "verify_template_class" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(VerifyTemplateClass))
+}
+
+type VerifyTemplateClass_R struct {
+	Id       int
+	T_fid    int                   // 项目 id, VerifyTemplateClass.ID
+	T_name   string                // 名称
+	T_State  int                   // 0 删除(伪删除)   1 正常(已交付)     2 开发中
+	Children []VerifyTemplateClass `orm:"-"`
+}
+
+// 获取 ById
+func Read_VerifyTemplateClass_ById(id int) (r VerifyTemplateClass, err error) {
+	o := orm.NewOrm()
+	r = VerifyTemplateClass{Id: id, T_State: 1}
+	err = o.Read(&r, "Id", "T_State")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, err
+	}
+	return r, err
+}
+
+// 添加
+func Add_VerifyTemplateClass(var_ VerifyTemplateClass) (id int64, err error) {
+	o := orm.NewOrm()
+	o.Begin()
+	id, err = o.Insert(&var_)
+	if err != nil {
+		o.Rollback()
+		return id, err
+	}
+
+	T_Path := "/0/" + strconv.Itoa(int(id)) + "/"
+	if var_.T_fid != 0 {
+		class_r, err := Read_VerifyTemplateClass_ById(var_.T_fid)
+		if err != nil {
+			o.Rollback()
+			return id, err
+		}
+		T_Path = class_r.T_path + strconv.Itoa(int(id)) + "/"
+	}
+
+	var_.Id = int(id)
+	var_.T_path = T_Path
+	_, err = o.Update(&var_, "T_path")
+	if err != nil {
+		o.Rollback()
+		return id, err
+	}
+	o.Commit()
+
+	return id, err
+}
+
+// 修改
+func Update_VerifyTemplateClass(r VerifyTemplateClass, cols ...string) bool {
+	o := orm.NewOrm()
+	if num, err := o.Update(&r, cols...); err == nil {
+		logs.Println("Number of records updated in database:", num)
+		return true
+	}
+	return false
+}
+
+// 批量删除
+func Delete_VerifyTemplateClass_ByIds(ids []int) bool {
+	o := orm.NewOrm()
+	o.Begin()
+	for _, id := range ids {
+		v := VerifyTemplateClass{Id: id, T_State: 0}
+		if _, err := o.Update(&v, "T_State"); err != nil {
+			o.Rollback()
+			return false
+		}
+	}
+
+	o.Commit()
+	return true
+}
+
+// 获取列表
+func Read_VerifyTemplateClass_List() (r []VerifyTemplateClass) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var map_r []VerifyTemplateClass
+	qs := o.QueryTable(new(VerifyTemplateClass))
+
+	cond := orm.NewCondition()
+
+	cond1 := cond.And("T_State", 1)
+
+	qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&map_r)
+
+	r = VerifyTemplateClass_Call(map_r, 0)
+
+	return r
+
+}
+
+func VerifyTemplateClass_Call(list []VerifyTemplateClass, parentId int) []VerifyTemplateClass {
+	res := make([]VerifyTemplateClass, 0)
+	for _, v := range list {
+		if v.T_fid == parentId {
+			v.Children = VerifyTemplateClass_Call(list, v.Id)
+			res = append(res, v)
+		}
+	}
+	return res
+}
+
+// 通过T_pid查询所有子id
+func ReadVerifyTemplateClassIds_T_path(T_path string) (VerifyTemplateClassIds []int) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(VerifyTemplateClass))
+	var VerifyTemplateClassList []VerifyTemplateClass
+	qs.Filter("T_path__startswith", T_path).Filter("T_State", 1).All(&VerifyTemplateClassList)
+	for _, v := range VerifyTemplateClassList {
+		VerifyTemplateClassIds = append(VerifyTemplateClassIds, v.Id)
+	}
+	return VerifyTemplateClassIds
+}

+ 251 - 0
models/VerifyTemplate/VerifyTemplateMap.go

@@ -0,0 +1,251 @@
+package VerifyTemplate
+
+import (
+	"ColdVerify_local/conf"
+	"ColdVerify_local/lib"
+	"ColdVerify_local/logs"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"log"
+	"time"
+)
+
+// 模板
+type VerifyTemplateMap struct {
+	Id int `orm:"column(ID);size(11);auto;pk"`
+
+	T_id                string `orm:"size(256);null"`     // 标题
+	T_VerifyTemplate_id string `orm:"size(256);null"`     // 标题
+	T_label             int    `orm:"size(2);default(1)"` // 数据类型
+	T_source            int    `orm:"size(2);default(0)"` // 来源 0-所有 1-方案 2-报告 3-表单
+
+	//1:文本
+	//2:数值
+	//3:设备多选 (1|2|3|4|5|6|)
+	//4:设备单选选 (1)
+	//7:当期时间(2022年01月19日)
+	//9:当期时间(开始与结束时间)(2022-01-01 13:08|2022-01-02 13:08)
+	//10:图片
+	//11:CAD
+	T_name string `orm:"size(256);null"`     // 标签名称
+	T_text string `orm:"size(256);null"`     // 描述
+	T_sort int    `orm:"size(2);default(1)"` // 排序
+	T_Required int    `orm:"size(2);default(0)"` // 必填项  1 必填   0 非必填
+	T_Construction int    `orm:"size(2);default(0)"` // 实施(是否在APP 上显示)  1 显示   0 不显示
+
+	// 验证流程
+	T_flow_sort int `orm:"size(2);default(0)"` // 验证流程排序
+	T_max_time  int `orm:"size(256);null"`     // 验证流程最大时间
+	T_min_time  int `orm:"size(256);null"`     // 验证流程最小时间
+
+	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
+	UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
+}
+
+type VerifyTemplateMap_R struct {
+	T_id         string
+	T_source     int    // 数据类型
+	T_label      int    // 来源
+	T_name       string // 标签名称
+	T_text       string // 描述
+	T_sort       int    // 排序
+	T_Required       int    // 必填项  1 必填   0 非必填
+	T_Construction       int   // 实施(是否在APP 上显示)  1 显示   0 不显示
+	T_flow_sort  int    // 验证流程排序
+	T_max_time   int    // 验证流程最大时间
+	T_min_time   int    // 验证流程最小时间
+	T_start_time int    // 任务开始时间 app
+}
+
+func (t *VerifyTemplateMap) TableName() string {
+	return "verify_template_map" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+
+	//注册模型
+	orm.RegisterModel(new(VerifyTemplateMap))
+
+}
+
+// -------------------------------------------------------------
+func VerifyTemplateMapToVerifyTemplateMap_R(T VerifyTemplateMap) (T_r VerifyTemplateMap_R) {
+	T_r.T_id = T.T_id
+	T_r.T_source = T.T_source
+	T_r.T_label = T.T_label
+	T_r.T_name = T.T_name
+	T_r.T_text = T.T_text
+	T_r.T_sort = T.T_sort
+	T_r.T_Required = T.T_Required
+	T_r.T_Construction = T.T_Construction
+	T_r.T_flow_sort = T.T_flow_sort
+	T_r.T_max_time = T.T_max_time
+	T_r.T_min_time = T.T_min_time
+	return T_r
+}
+
+// ---------------- 特殊方法 -------------------
+
+// 获取 ById
+func Read_VerifyTemplateMap_ById(id int) (r VerifyTemplateMap, is bool) {
+	o := orm.NewOrm()
+	r = VerifyTemplateMap{Id: id}
+	err := o.Read(&r) // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, false
+	}
+	return r, true
+}
+
+// 获取 By
+func Read_VerifyTemplateMap(T_id string) (r VerifyTemplateMap, is bool) {
+
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(VerifyTemplateMap))
+	err := qs.Filter("T_id", T_id).One(&r)
+	if err != nil {
+		return r, false
+	}
+
+	return r, true
+}
+
+// 添加
+func Add_VerifyTemplateMap(r VerifyTemplateMap) (id int64, is bool) {
+	o := orm.NewOrm()
+
+	// 生成编号
+	rand_x := 0
+	for true {
+		r.T_id = lib.GetRandstring(4, "", int64(rand_x)) // 1,336,336
+		err := o.Read(&r, "T_id")                        // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+		if err != nil {
+			break
+		}
+		rand_x += 1
+	}
+
+	id, err := o.Insert(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return 0, false
+	}
+
+	return id, true
+}
+
+// 添加
+func Add_VerifyTemplateMapMulti(r []VerifyTemplateMap) (id int64, is bool) {
+	o := orm.NewOrm()
+	n, err := o.InsertMulti(len(r), r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return n, false
+	}
+
+	return n, true
+}
+
+// 删除
+func Delete_VerifyTemplateMap(v VerifyTemplateMap) bool {
+	o := orm.NewOrm()
+	if num, err := o.Delete(&v); err == nil {
+		logs.Println("Number of records deleted in database:", num)
+	} else {
+		return false
+	}
+
+	return true
+}
+
+// 修改
+func Update_VerifyTemplateMap(m VerifyTemplateMap, cols ...string) bool {
+	o := orm.NewOrm()
+	if num, err := o.Update(&m, cols...); err == nil {
+		log.Println("Number of records updated in database:", num)
+		return true
+	}
+	return false
+}
+
+// 获取列表
+func Read_VerifyTemplateMap_List(T_VerifyTemplate_id string, T_sort, T_flow_sort int) ([]VerifyTemplateMap_R, int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []VerifyTemplateMap
+	qs := o.QueryTable(new(VerifyTemplateMap))
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_VerifyTemplate_id", T_VerifyTemplate_id) // .AndNot("status__in", 1).Or("profile__age__gt", 2000)
+	// 排序 默认升序
+
+	if T_sort == 2 {
+		qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-T_sort").All(&r)
+	} else if T_flow_sort == 1 {
+		qs.SetCond((*orm2.Condition)(cond1)).OrderBy("T_flow_sort").All(&r)
+	} else if T_flow_sort == 2 {
+		qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-T_flow_sort").All(&r)
+	} else {
+		qs.SetCond((*orm2.Condition)(cond1)).OrderBy("T_sort").All(&r)
+	}
+	cnt, _ := qs.SetCond((*orm2.Condition)(cond1)).Count()
+
+	// 转换
+	var VerifyTemplateMap_r []VerifyTemplateMap_R
+	for _, v := range r {
+		VerifyTemplateMap_r = append(VerifyTemplateMap_r, VerifyTemplateMapToVerifyTemplateMap_R(v))
+	}
+
+	return VerifyTemplateMap_r, cnt
+}
+
+func Read_VerifyTemplateMap_List_For_Data(T_VerifyTemplate_id string, T_source, T_flow int) []VerifyTemplateMap {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []VerifyTemplateMap
+	qs := o.QueryTable(new(VerifyTemplateMap))
+	source := []int{T_source}
+	if T_source == 2 {
+		source = append(source, 3)
+	}
+	if T_source != 3 {
+		source = append(source, 0)
+	}
+
+	cond := orm.NewCondition()
+	if T_flow == 1 {
+		// app时间流程 排序id不等于0
+		cond = cond.AndNot("T_flow_sort", 0).And("T_VerifyTemplate_id", T_VerifyTemplate_id)
+		qs.SetCond((*orm2.Condition)(cond)).OrderBy("T_flow_sort").All(&r)
+	} else {
+		cond = cond.And("T_source__in", source).And("T_VerifyTemplate_id", T_VerifyTemplate_id)
+		qs.SetCond((*orm2.Condition)(cond)).OrderBy("T_sort").All(&r)
+	}
+
+	return r
+}
+
+func VerifyTemplateMap_RToMap(T []VerifyTemplateMap_R) map[string]string {
+	maps := make(map[string]string, len(T))
+	for _, v := range T {
+		maps[v.T_id] = v.T_name
+	}
+	return maps
+}
+
+func Read_VerifyTemplateMap_T_name(T_VerifyTemplate_id, T_name string) (r VerifyTemplateMap, err error) {
+
+	serverOrm := orm2.NewOrmUsingDB(conf.Server_AliasName)
+
+	qs := serverOrm.QueryTable(new(VerifyTemplateMap))
+	//err := qs.Filter("T_task_id", T_task_id).Filter("T_State", 1).One(&r)
+	err = qs.Filter("T_VerifyTemplate_id", T_VerifyTemplate_id).Filter("T_name__icontains", T_name).One(&r)
+	if err != nil {
+		return r, err
+	}
+
+	return r, nil
+}

+ 334 - 0
models/VerifyTemplate/VerifyTemplateMapData.go

@@ -0,0 +1,334 @@
+package VerifyTemplate
+
+import (
+	"ColdVerify_local/conf"
+	"ColdVerify_local/lib"
+	"ColdVerify_local/logs"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"time"
+)
+
+// 模板
+type VerifyTemplateMapData struct {
+	Id                     int    `orm:"column(ID);size(11);auto;pk"`
+	T_source               int    `orm:"size(2);"`             // 来源 0-所有 1-方案 2-报告 3-表单
+	T_task_id              string `orm:"index,size(256);null"` // 任务id
+	T_VerifyTemplate_id    string `orm:"index,size(256);null"` // 模板id
+	T_VerifyTemplateMap_id string `orm:"index,size(256);null"` // 标签id
+	T_value                string `orm:"size(1024);null"`      // 内容
+	T_Required             int    `orm:"size(2);default(0)"`   // 必填项  1 必填   0 非必填
+	T_Construction         int    `orm:"size(2);default(0)"`   // 实施(是否在APP 上显示)  1 显示   0 不显示
+
+	// 验证流程
+	T_flow_sort int `orm:"size(2);default(0)"` // 验证流程排序
+	T_max_time  int `orm:"size(256);null"`     // 验证流程最大时间
+	T_min_time  int `orm:"size(256);null"`     // 验证流程最小时间
+
+	T_start_time int64 `orm:"size(256);null"` // 开始时间 app
+
+	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
+	UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
+}
+
+type VerifyTemplateMapData_R struct {
+	T_id                   int
+	T_VerifyTemplateMap_id string // 标签id
+	T_source               int
+	T_label                int    //
+	T_name                 string // 标题
+	T_text                 string // 标题
+	T_value                string //
+	T_Required             int    //
+	T_Construction             int    //
+	// 验证流程
+	T_flow_sort int // 验证流程排序
+	T_max_time  int // 验证流程最大时间
+	T_min_time  int // 验证流程最小时间
+
+	T_start_time int64 // 开始时间 app
+}
+
+func (t *VerifyTemplateMapData) TableName() string {
+	return "verify_template_map_data" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(VerifyTemplateMapData))
+
+}
+
+// -------------------------------------------------------------
+func VerifyTemplateMapToVerifyTemplateMapData_R(T VerifyTemplateMap) (T_r VerifyTemplateMapData_R) {
+	T_r.T_VerifyTemplateMap_id = T.T_id
+	T_r.T_source = T.T_source
+	T_r.T_label = T.T_label
+	T_r.T_name = T.T_name
+	T_r.T_text = T.T_text
+	T_r.T_Required = T.T_Required
+	T_r.T_Construction = T.T_Construction
+
+	T_r.T_flow_sort = T.T_flow_sort
+	T_r.T_max_time = T.T_max_time
+	T_r.T_min_time = T.T_min_time
+
+	T_r.T_value = ""
+	return T_r
+}
+
+func VerifyTemplateMapDataToVerifyTemplateMapData_R(T VerifyTemplateMap, VerifyTemplateMapData map[string]VerifyTemplateMapData) (T_r VerifyTemplateMapData_R) {
+	T_r.T_VerifyTemplateMap_id = T.T_id
+	T_r.T_source = T.T_source
+	T_r.T_label = T.T_label
+	T_r.T_name = T.T_name
+	T_r.T_text = T.T_text
+	T_r.T_Required = T.T_Required
+	T_r.T_Construction = T.T_Construction
+
+	T_r.T_flow_sort = T.T_flow_sort
+	T_r.T_max_time = T.T_max_time
+	T_r.T_min_time = T.T_min_time
+
+	T_r.T_value = ""
+	if v, ok := VerifyTemplateMapData[T.T_id]; ok {
+		T_r.T_value = v.T_value
+		T_r.T_start_time = v.T_start_time
+	}
+	return T_r
+}
+
+// 添加或更新模板数据 并添加历史数据
+func AddOrUpdate_VerifyTemplateMapData_ADD_History(List []VerifyTemplateMapData, T_source int, T_uuid string) (ids []int64, is bool) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(VerifyTemplateMapData))
+	o.Begin()
+	T_time := time.Now().Format("2006-01-02 15:04:05")
+	for _, v := range List {
+		var r VerifyTemplateMapData
+		// 创建验证模版数据,有则更新,没有则创建
+		err := qs.Filter("T_task_id", v.T_task_id).Filter("T_VerifyTemplate_id", v.T_VerifyTemplate_id).Filter("T_VerifyTemplateMap_id", v.T_VerifyTemplateMap_id).One(&r)
+		if err != nil {
+			if err.Error() == orm.ErrNoRows.Error() {
+				id, err := o.Insert(&v)
+				if err != nil {
+					logs.Error(lib.FuncName(), err)
+					o.Rollback()
+					return ids, false
+				}
+				ids = append(ids, id)
+			} else {
+				logs.Error(lib.FuncName(), err)
+				o.Rollback()
+				return ids, false
+			}
+		}
+
+		// 更新验证模版数据
+		if r.Id > 0 && (len(v.T_value) > 0 || v.T_start_time > 0) {
+			if v.T_start_time == 1 {
+				v.T_start_time = 0
+			}
+			v.Id = r.Id
+			//_, err = o.Update(&v, "T_flow_sort", "T_max_time", "T_min_time", "T_value")
+			_, err = o.QueryTable(new(VerifyTemplateMapData)).Filter("T_task_id", v.T_task_id).Filter("T_VerifyTemplate_id", v.T_VerifyTemplate_id).
+				Filter("T_VerifyTemplateMap_id", v.T_VerifyTemplateMap_id).Update(orm2.Params{
+				"T_flow_sort": v.T_flow_sort, "T_max_time": v.T_max_time, "T_min_time": v.T_min_time, "T_value": v.T_value, "T_start_time": v.T_start_time,
+			})
+			if err != nil {
+				logs.Error(lib.FuncName(), err)
+				o.Rollback()
+				return ids, false
+			}
+			ids = append(ids, int64(r.Id))
+		}
+
+		// 添加历史记录
+		_, err = o.Insert(&VerifyTemplateMapDataHistory{
+			T_source:               v.T_source,
+			T_task_id:              v.T_task_id,
+			T_time:                 T_time,
+			T_uuid:                 T_uuid,
+			T_submit_source:        T_source,
+			T_VerifyTemplate_id:    v.T_VerifyTemplate_id,
+			T_VerifyTemplateMap_id: v.T_VerifyTemplateMap_id,
+			T_value:                v.T_value,
+			T_Required:             v.T_Required,
+			T_flow_sort:            v.T_flow_sort,
+			T_max_time:             v.T_max_time,
+			T_min_time:             v.T_min_time,
+		})
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+			o.Rollback()
+			return ids, false
+		}
+	}
+
+	o.Commit()
+
+	return ids, true
+}
+
+// ---------------- 特殊方法 -------------------
+// 添加
+func AddOrUpdate_VerifyTemplateMapData(List []VerifyTemplateMapData) (ids []int64, is bool) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(VerifyTemplateMapData))
+	o.Begin()
+	for _, v := range List {
+		var r VerifyTemplateMapData
+		// 创建验证模版数据,有则更新,没有则创建
+		err := qs.Filter("T_task_id", v.T_task_id).Filter("T_VerifyTemplate_id", v.T_VerifyTemplate_id).Filter("T_VerifyTemplateMap_id", v.T_VerifyTemplateMap_id).One(&r)
+		if err != nil {
+			if err.Error() == orm.ErrNoRows.Error() {
+				id, err := o.Insert(&v)
+				if err != nil {
+					logs.Error(lib.FuncName(), err)
+					o.Rollback()
+					return ids, false
+				}
+				ids = append(ids, id)
+			} else {
+				logs.Error(lib.FuncName(), err)
+				o.Rollback()
+				return ids, false
+			}
+		}
+
+		// 更新验证模版数据
+		if r.Id > 0 && (len(v.T_value) > 0 || v.T_start_time > 0) {
+			if v.T_start_time == 1 {
+				v.T_start_time = 0
+			}
+			v.Id = r.Id
+			//_, err = o.Update(&v, "T_flow_sort", "T_max_time", "T_min_time", "T_value")
+			_, err = o.QueryTable(new(VerifyTemplateMapData)).Filter("T_task_id", v.T_task_id).Filter("T_VerifyTemplate_id", v.T_VerifyTemplate_id).
+				Filter("T_VerifyTemplateMap_id", v.T_VerifyTemplateMap_id).Update(orm2.Params{
+				"T_flow_sort": v.T_flow_sort, "T_max_time": v.T_max_time, "T_min_time": v.T_min_time, "T_value": v.T_value, "T_start_time": v.T_start_time,
+			})
+			if err != nil {
+				logs.Error(lib.FuncName(), err)
+				o.Rollback()
+				return ids, false
+			}
+			ids = append(ids, int64(r.Id))
+		}
+
+	}
+
+	o.Commit()
+
+	return ids, true
+}
+
+// 获取列表
+func Read_VerifyTemplateMapData_List(T_source int, T_task_id, T_VerifyTemplate_id string, Map_List []VerifyTemplateMap) []VerifyTemplateMapData_R {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []VerifyTemplateMapData
+	qs := o.QueryTable(new(VerifyTemplateMapData))
+	cond := orm.NewCondition()
+
+	cond1 := cond.And("T_task_id", T_task_id).And("T_VerifyTemplate_id", T_VerifyTemplate_id)
+
+	qs.SetCond((*orm2.Condition)(cond1)).All(&r)
+
+	if len(r) == 0 {
+		// 转换
+		var VerifyTemplateMapData_r []VerifyTemplateMapData_R
+		for k, v := range Map_List {
+			Data_r := VerifyTemplateMapToVerifyTemplateMapData_R(v)
+			Data_r.T_id = k
+			VerifyTemplateMapData_r = append(VerifyTemplateMapData_r, Data_r)
+		}
+
+		return VerifyTemplateMapData_r
+	}
+
+	// 转换
+	var VerifyTemplateMapData_r []VerifyTemplateMapData_R
+	for k, v := range Map_List {
+		Data_r := VerifyTemplateMapDataToVerifyTemplateMapData_R(v, VerifyTemplateMapDataToMap(r))
+		Data_r.T_id = k
+		VerifyTemplateMapData_r = append(VerifyTemplateMapData_r, Data_r)
+	}
+	return VerifyTemplateMapData_r
+}
+
+// 获取列表
+func Read_MapData_List(T_source int, T_task_id, T_VerifyTemplate_id string) []VerifyTemplateMapData {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []VerifyTemplateMapData
+	qs := o.QueryTable(new(VerifyTemplateMapData))
+	cond := orm.NewCondition()
+
+	source := []int{T_source}
+	if T_source == 2 {
+		source = append(source, 3)
+	}
+	if T_source != 3 {
+		source = append(source, 0)
+	}
+
+	cond1 := cond.And("T_source__in", source).And("T_task_id", T_task_id).And("T_VerifyTemplate_id", T_VerifyTemplate_id)
+
+	qs.SetCond((*orm2.Condition)(cond1)).All(&r)
+
+	return r
+}
+
+func VerifyTemplateMapDataToMap(T []VerifyTemplateMapData) map[string]VerifyTemplateMapData {
+	maps := make(map[string]VerifyTemplateMapData, len(T))
+	for _, v := range T {
+		if _, ok := maps[v.T_VerifyTemplateMap_id]; ok {
+			continue
+		}
+		maps[v.T_VerifyTemplateMap_id] = v
+	}
+	return maps
+}
+
+// 清除T_value数据
+func Clear_VerifyTemplateMapData_T_value(T_task_id, T_VerifyTemplate_id, T_VerifyTemplateMap_id string) (err error) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(VerifyTemplateMapData))
+
+	var r VerifyTemplateMapData
+	// 创建验证模版数据,有则更新,没有则创建
+	err = qs.Filter("T_task_id", T_task_id).Filter("T_VerifyTemplate_id", T_VerifyTemplate_id).Filter("T_VerifyTemplateMap_id", T_VerifyTemplateMap_id).One(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	r.T_value = ""
+	_, err = o.Update(&r, "T_value")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	return nil
+}
+
+func Read_VerifyTemplateMapData_T_name(T_task_id,T_VerifyTemplate_id, T_name string) string {
+
+	a_time, err := Read_VerifyTemplateMap_T_name(T_VerifyTemplate_id, T_name)
+	if err != nil {
+		return ""
+	}
+
+	serverOrm := orm2.NewOrmUsingDB(conf.Server_AliasName)
+	var r VerifyTemplateMapData
+	qs := serverOrm.QueryTable(new(VerifyTemplateMapData))
+	//err := qs.Filter("T_task_id", T_task_id).Filter("T_State", 1).One(&r)
+	err = qs.Filter("T_VerifyTemplateMap_id", a_time.T_id).Filter("T_task_id", T_task_id).One(&r)
+	if err != nil {
+		return ""
+	}
+
+	return r.T_value
+}

+ 193 - 0
models/VerifyTemplate/VerifyTemplateMapDataHistory.go

@@ -0,0 +1,193 @@
+package VerifyTemplate
+
+import (
+	"ColdVerify_local/lib"
+	"ColdVerify_local/logs"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"time"
+)
+
+// 模板
+type VerifyTemplateMapDataHistory struct {
+	Id                     int    `orm:"column(ID);size(11);auto;pk"`
+	T_source               int    `orm:"size(4);"`             // 来源 0-所有 1-方案 2-报告 3-表单
+	T_task_id              string `orm:"index,size(256);null"` // 任务id
+	T_VerifyTemplate_id    string `orm:"size(256);null"`       // 模板id
+	T_VerifyTemplateMap_id string `orm:"size(256);null"`       // 标签id
+	T_value                string `orm:"type(text);null"`      // 内容
+	T_Required             int    `orm:"size(2);default(0)"`   // 必填项  1 必填   0 非必填
+	T_Construction         int    `orm:"size(2);default(0)"`   // 实施(是否在APP 上显示)  1 显示   0 不显示
+
+	T_uuid          string `orm:"index,size(256);null"` // 提交人
+	T_time          string `orm:"index,size(256);null"` // 提交时间
+	T_submit_source int    `orm:"size(4);"`             // 提交来源
+	// 验证流程
+	T_flow_sort int `orm:"size(2);default(0)"` // 验证流程排序
+	T_max_time  int `orm:"size(256);null"`     // 验证流程最大时间
+	T_min_time  int `orm:"size(256);null"`     // 验证流程最小时间
+
+	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
+	UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
+}
+
+type VerifyTemplateMapDataHistory_R struct {
+	T_id                   int
+	T_VerifyTemplateMap_id string // 标签id
+	T_source               int
+	T_label                int    //
+	T_name                 string // 标题
+	T_text                 string // 标题
+	T_value                string //
+	T_Required             int    //
+	T_Construction         int    //
+	// 验证流程
+	T_flow_sort int // 验证流程排序
+	T_max_time  int // 验证流程最大时间
+	T_min_time  int // 验证流程最小时间
+}
+
+func (t *VerifyTemplateMapDataHistory) TableName() string {
+	return "verify_template_map_data_history" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(VerifyTemplateMapDataHistory))
+
+}
+
+// -------------------------------------------------------------
+func VerifyTemplateMapToVerifyTemplateMapDataHistory_R(T VerifyTemplateMap) (T_r VerifyTemplateMapDataHistory_R) {
+	T_r.T_VerifyTemplateMap_id = T.T_id
+	T_r.T_source = T.T_source
+	T_r.T_label = T.T_label
+	T_r.T_name = T.T_name
+	T_r.T_text = T.T_text
+	T_r.T_Required = T.T_Required
+	T_r.T_Construction = T.T_Construction
+
+	T_r.T_flow_sort = T.T_flow_sort
+	T_r.T_max_time = T.T_max_time
+	T_r.T_min_time = T.T_min_time
+
+	T_r.T_value = ""
+	return T_r
+}
+
+func VerifyTemplateMapDataToVerifyTemplateMapDataHistory_R(T VerifyTemplateMap, VerifyTemplateMapDataHistory map[string]string) (T_r VerifyTemplateMapDataHistory_R) {
+	T_r.T_VerifyTemplateMap_id = T.T_id
+	T_r.T_source = T.T_source
+	T_r.T_label = T.T_label
+	T_r.T_name = T.T_name
+	T_r.T_text = T.T_text
+	T_r.T_Required = T.T_Required
+	T_r.T_Construction = T.T_Construction
+
+	T_r.T_flow_sort = T.T_flow_sort
+	T_r.T_max_time = T.T_max_time
+	T_r.T_min_time = T.T_min_time
+
+	T_r.T_value = ""
+	if v, ok := VerifyTemplateMapDataHistory[T.T_id]; ok {
+		T_r.T_value = v
+	}
+	return T_r
+}
+
+// 获取列表
+func Read_VerifyTemplateMapDataHistory_List(T_source int, T_task_id, T_VerifyTemplate_id, T_time string,
+	Map_List []VerifyTemplateMap) []VerifyTemplateMapDataHistory_R {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []VerifyTemplateMapDataHistory
+	qs := o.QueryTable(new(VerifyTemplateMapDataHistory))
+	cond := orm.NewCondition()
+
+	cond1 := cond.And("T_task_id", T_task_id).And("T_VerifyTemplate_id", T_VerifyTemplate_id).And("T_time", T_time)
+
+	qs.SetCond((*orm2.Condition)(cond1)).All(&r)
+
+	if len(r) == 0 {
+		// 转换
+		var VerifyTemplateMapData_r []VerifyTemplateMapDataHistory_R
+		for k, v := range Map_List {
+			Data_r := VerifyTemplateMapToVerifyTemplateMapDataHistory_R(v)
+			Data_r.T_id = k
+			VerifyTemplateMapData_r = append(VerifyTemplateMapData_r, Data_r)
+		}
+
+		return VerifyTemplateMapData_r
+	}
+
+	// 转换
+	var VerifyTemplateMapDataHistory_r []VerifyTemplateMapDataHistory_R
+	for k, v := range Map_List {
+		Data_r := VerifyTemplateMapDataToVerifyTemplateMapDataHistory_R(v, VerifyTemplateMapDataHistoryToMap(r))
+		Data_r.T_id = k
+		VerifyTemplateMapDataHistory_r = append(VerifyTemplateMapDataHistory_r, Data_r)
+	}
+	return VerifyTemplateMapDataHistory_r
+}
+
+// 获取列表
+func Read_MapDataHistory_List(T_source int, T_task_id, T_VerifyTemplate_id, T_time string) []VerifyTemplateMapDataHistory {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []VerifyTemplateMapDataHistory
+	qs := o.QueryTable(new(VerifyTemplateMapDataHistory))
+	cond := orm.NewCondition()
+
+	source := []int{T_source}
+	if T_source == 2 {
+		source = append(source, 3)
+	}
+	if T_source != 3 {
+		source = append(source, 0)
+	}
+
+	cond1 := cond.And("T_source__in", source).And("T_task_id", T_task_id).And("T_VerifyTemplate_id", T_VerifyTemplate_id).And("T_time", T_time)
+
+	qs.SetCond((*orm2.Condition)(cond1)).All(&r)
+
+	return r
+}
+
+func VerifyTemplateMapDataHistoryToMap(T []VerifyTemplateMapDataHistory) map[string]string {
+	maps := make(map[string]string, len(T))
+	for _, v := range T {
+		if _, ok := maps[v.T_VerifyTemplateMap_id]; ok {
+			continue
+		}
+		maps[v.T_VerifyTemplateMap_id] = v.T_value
+	}
+	return maps
+}
+
+type VerifyTemplateMapDataHistory_History_List_Res struct {
+	T_uuid      string
+	T_time      string
+	T_uuid_name string
+}
+
+// 获取列表
+func Read_VerifyTemplateMapDataHistory_History_List(T_task_id string, T_source int, AdminMap map[string]string) (lists []VerifyTemplateMapDataHistory_History_List_Res) {
+	o := orm.NewOrm()
+
+	var pl_lists []VerifyTemplateMapDataHistory_History_List_Res
+	_, err := o.Raw("SELECT DISTINCT t_uuid,t_time FROM verify_template_map_data_history where t_task_id = ? and t_submit_source = ? order by t_time desc LIMIT 0,1000 ", T_task_id, T_source).
+		QueryRows(&pl_lists)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return pl_lists
+	}
+
+	for i := 0; i < len(pl_lists); i++ {
+		pl_lists[i].T_uuid_name = AdminMap[pl_lists[i].T_uuid]
+	}
+
+	return pl_lists
+}

+ 80 - 7
routers/TaskData.go

@@ -28,9 +28,19 @@ func init() {
 	beego.Router("/TaskData/Check", &controllers.TaskDataController{}, "*:Check_Asyn") // 设置 设备参数
 
 	beego.Router("/TaskData/Import_TaskData", &controllers.TaskDataController{}, "*:TaskData_Import_TaskData") // 打包本地数据
+	beego.Router("/TaskData/Import_TaskData_SN", &controllers.TaskDataController{}, "*:Import_TaskData_SN")    // 重置 SN数据
 	beego.Router("/TaskData/Up_TaskData", &controllers.TaskDataController{}, "*:TaskData_Up_TaskData_Back")    // 更新线上数据
 	//beego.Router("/TaskData/Up_TaskData_Back", &controllers.TaskDataController{}, "*:TaskData_Up_TaskData_Back") // 更新线上数据
 
+	beego.Router("/TaskDataCopy/List", &controllers.TaskDataController{}, "*:TaskDataCopy_List")       // 数据存档列表
+	beego.Router("/TaskDataCopy/Add", &controllers.TaskDataController{}, "*:TaskDataCopy_Add")         // 添加数据存档
+	beego.Router("/TaskDataCopy/Del", &controllers.TaskDataController{}, "*:TaskDataCopy_Del")         // 删除数据存档
+	beego.Router("/TaskDataCopy/Recover", &controllers.TaskDataController{}, "*:TaskDataCopy_Recover") // 数据存档恢复
+
+	beego.Router("/TaskData/jpg", &controllers.TaskDataController{}, "*:TaskData_JPG")            // 任务生成图片
+	beego.Router("/TaskData/JPG/State", &controllers.TaskDataController{}, "*:TaskData_JPGState") // 任务 图片生成状态
+	beego.Router("/Certificate/List", &controllers.TaskDataController{}, "*:Certificate_List")    // 设计编辑 添加终端列表
+
 	// 数据处理
 	beego.Router("/TaskData/CopyFromPosition", &controllers.TaskDataController{}, "*:CopyFromPosition")                   // 数据复制
 	beego.Router("/TaskData/RepairSensorData", &controllers.TaskDataController{}, "*:RepairSensorData")                   // 数据补漏
@@ -39,19 +49,82 @@ func init() {
 	beego.Router("/TaskData/UpdateFix", &controllers.TaskDataController{}, "*:UpdateFix")                                 // 更新固定值
 	beego.Router("/TaskData/DataSensorDataSmooth", &controllers.TaskDataController{}, "*:DataSensorDataSmooth")           // 数据平滑
 	beego.Router("/TaskData/CopyFromPositionAverageSN", &controllers.TaskDataController{}, "*:CopyFromPositionAverageSN") // 平均复制到
+	beego.Router("/TaskData/CopyTaskDataSN", &controllers.TaskDataController{}, "*:CopyTaskDataSN")                       // 复制任务 数据到
 	beego.Router("/TaskData/CopyFromPositionSN", &controllers.TaskDataController{}, "*:CopyFromPositionSN")               // 增加复制到某测点
 	beego.Router("/TaskData/DataSkewingInterval", &controllers.TaskDataController{}, "*:DataSkewingInterval")             // 数据偏移到给定区间内
 	beego.Router("/TaskData/DataGeometricScale", &controllers.TaskDataController{}, "*:DataGeometricScale")               // 数据等比咧缩放
 	beego.Router("/TaskData/DataRemoveDuplicates", &controllers.TaskDataController{}, "*:DataRemoveDuplicates")           // 数据去重
 	beego.Router("/TaskData/DataBatchDelete", &controllers.TaskDataController{}, "*:DataBatchDelete")                     // 批量删除
 
-	beego.Router("/TaskDataCopy/List", &controllers.TaskDataController{}, "*:TaskDataCopy_List")       // 数据存档列表
-	beego.Router("/TaskDataCopy/Add", &controllers.TaskDataController{}, "*:TaskDataCopy_Add")         // 添加数据存档
-	beego.Router("/TaskDataCopy/Del", &controllers.TaskDataController{}, "*:TaskDataCopy_Del")         // 删除数据存档
-	beego.Router("/TaskDataCopy/Recover", &controllers.TaskDataController{}, "*:TaskDataCopy_Recover") // 数据存档恢复
+	beego.Router("/TaskData/SSE_Automatically_add_missing_terminal", &controllers.TaskDataHandleController{}, "*:SSE_Automatically_add_missing_terminal")                           // 自动添加缺失终端,取关联绑定终端平均复制
+	beego.Router("/TaskData/SSE_Automatically_add_missing_data", &controllers.TaskDataHandleController{}, "*:SSE_Automatically_add_missing_data")                                   // 自动添加缺失终端,取关联绑定终端平均复制
+	beego.Router("/TaskData/SSE_Continuously_unchanged_data", &controllers.TaskDataHandleController{}, "*:SSE_Continuously_unchanged_data")                                         // 数据持续时间       分钟 没有变化
+	beego.Router("/TaskData/SSE_Interval_data_correction", &controllers.TaskDataHandleController{}, "*:SSE_Interval_data_correction")                                               // 区间数据校正  (布点区域数据自检)
+	beego.Router("/TaskData/SSE_Comparison_between_binding_points_and_terminals", &controllers.TaskDataHandleController{}, "*:SSE_Comparison_between_binding_points_and_terminals") // 绑定点与终端比对  (绑定点数据自检)
+	beego.Router("/TaskData/SSE_Compare_binding_points_with_cold_and_hot_spots", &controllers.TaskDataHandleController{}, "*:SSE_Compare_binding_points_with_cold_and_hot_spots")   // 绑定点与冷热点比对  (冷热点数据自检)
 
-	beego.Router("/TaskData/jpg", &controllers.TaskDataController{}, "*:TaskData_JPG")            // 任务生成图片
-	beego.Router("/TaskData/JPG/State", &controllers.TaskDataController{}, "*:TaskData_JPGState") // 任务 图片生成状态
-	beego.Router("/Certificate/List", &controllers.TaskDataController{}, "*:Certificate_List")    // 设计编辑 添加终端列表
+	// 自动处理
+	beego.Router("/TaskDataContent/ListJson", &controllers.TaskDataController{}, "*:ListJson") // 根据id删除任务数据
+	beego.Router("/TaskDataContent/SSE_冷藏柜内部最高温", &controllers.TaskDataController{}, "*:A冷藏柜内部最高温")
+	beego.Router("/TaskDataContent/SSE_冷藏柜内部最低温", &controllers.TaskDataController{}, "*:A冷藏柜内部最低温")
+	beego.Router("/TaskDataContent/SSE_柜内所有测点", &controllers.TaskDataController{}, "*:A柜内所有测点")
+	beego.Router("/TaskDataContent/SSE_均匀性布点", &controllers.TaskDataController{}, "*:A均匀性布点")
+	beego.Router("/TaskDataContent/SSE_产品存放区域测点", &controllers.TaskDataController{}, "*:A产品存放区域测点")
+	beego.Router("/TaskDataContent/SSE_外部环境分割线最高温", &controllers.TaskDataController{}, "*:A外部环境分割线最高温")
+	beego.Router("/TaskDataContent/SSE_外部环境分割线最低温", &controllers.TaskDataController{}, "*:A外部环境分割线最低温")
+	beego.Router("/TaskDataContent/SSE_冷藏柜外部环境测点最高温", &controllers.TaskDataController{}, "*:A冷藏柜外部环境测点最高温")
+	beego.Router("/TaskDataContent/SSE_冷藏柜外部环境测点最低温", &controllers.TaskDataController{}, "*:A冷藏柜外部环境测点最低温")
+	beego.Router("/TaskDataContent/SSE_内部环境分割线最低温", &controllers.TaskDataController{}, "*:A内部环境分割线最低温")
+	beego.Router("/TaskDataContent/SSE_内部环境分割线最高温", &controllers.TaskDataController{}, "*:A内部环境分割线最高温")
+	beego.Router("/TaskDataContent/SSE_冰排释冷开始时间", &controllers.TaskDataController{}, "*:A冰排释冷开始时间")
+	beego.Router("/TaskDataContent/SSE_冰排释冷结束时间", &controllers.TaskDataController{}, "*:A冰排释冷结束时间")
+	beego.Router("/TaskDataContent/SSE_冰排释冷分割线最高温", &controllers.TaskDataController{}, "*:A冰排释冷分割线最高温")
+	beego.Router("/TaskDataContent/SSE_冰排释冷分割线最低温", &controllers.TaskDataController{}, "*:A冰排释冷分割线最低温")
+	beego.Router("/TaskDataContent/SSE_静态第一次开箱注释", &controllers.TaskDataController{}, "*:A静态第一次开箱注释")
+	beego.Router("/TaskDataContent/SSE_静态第二次开箱注释", &controllers.TaskDataController{}, "*:A静态第二次开箱注释")
+	beego.Router("/TaskDataContent/SSE_静态第三次开箱注释", &controllers.TaskDataController{}, "*:A静态第三次开箱注释")
+	beego.Router("/TaskDataContent/SSE_动态第一次开箱注释", &controllers.TaskDataController{}, "*:A动态第一次开箱注释")
+	beego.Router("/TaskDataContent/SSE_动态第二次开箱注释", &controllers.TaskDataController{}, "*:A动态第二次开箱注释")
+	beego.Router("/TaskDataContent/SSE_动态第三次开箱注释", &controllers.TaskDataController{}, "*:A动态第三次开箱注释")
+	beego.Router("/TaskDataContent/SSE_保温箱温度设定值", &controllers.TaskDataController{}, "*:A保温箱温度设定值")
+	beego.Router("/TaskDataContent/SSE_风机温度设定值", &controllers.TaskDataController{}, "*:A风机温度设定值")
+	beego.Router("/TaskDataContent/SSE_保温箱准备开始时间", &controllers.TaskDataController{}, "*:A保温箱准备开始时间")
+	beego.Router("/TaskDataContent/SSE_冰排预冷保温箱准备结束时间", &controllers.TaskDataController{}, "*:A冰排预冷保温箱准备结束时间")
+	beego.Router("/TaskDataContent/SSE_温度自动监测设备放置位置开始时间", &controllers.TaskDataController{}, "*:A温度自动监测设备放置位置开始时间")
+	beego.Router("/TaskDataContent/SSE_温度自动监测设备放置位置结束时间", &controllers.TaskDataController{}, "*:A温度自动监测设备放置位置结束时间")
+	beego.Router("/TaskDataContent/SSE_温度分布特性开始时间", &controllers.TaskDataController{}, "*:A温度分布特性开始时间")
+	beego.Router("/TaskDataContent/SSE_温度分布特性结束时间", &controllers.TaskDataController{}, "*:A温度分布特性结束时间")
+	beego.Router("/TaskDataContent/SSE_最长保温时限开始时间", &controllers.TaskDataController{}, "*:A最长保温时限开始时间")
+	beego.Router("/TaskDataContent/SSE_最长保温时限结束时间", &controllers.TaskDataController{}, "*:A最长保温时限结束时间")
+	beego.Router("/TaskDataContent/SSE_温度分布特性的测试与分析满载开始时间", &controllers.TaskDataController{}, "*:A温度分布特性的测试与分析满载开始时间")
+	beego.Router("/TaskDataContent/SSE_温度分布特性的测试与分析空载开始时间", &controllers.TaskDataController{}, "*:A温度分布特性的测试与分析空载开始时间")
+	beego.Router("/TaskDataContent/SSE_温度分布特性的测试与分析满载结束时间", &controllers.TaskDataController{}, "*:A温度分布特性的测试与分析满载结束时间")
+	beego.Router("/TaskDataContent/SSE_温度分布特性的测试与分析空载结束时间", &controllers.TaskDataController{}, "*:A温度分布特性的测试与分析空载结束时间")
+	beego.Router("/TaskDataContent/SSE_温控设备运行参数及使用状况测试满载开始时间", &controllers.TaskDataController{}, "*:A温控设备运行参数及使用状况测试满载开始时间")
+	beego.Router("/TaskDataContent/SSE_温控设备运行参数及使用状况测试空载开始时间", &controllers.TaskDataController{}, "*:A温控设备运行参数及使用状况测试空载开始时间")
+	beego.Router("/TaskDataContent/SSE_温控设备运行参数及使用状况测试满载结束时间", &controllers.TaskDataController{}, "*:A温控设备运行参数及使用状况测试满载结束时间")
+	beego.Router("/TaskDataContent/SSE_温控设备运行参数及使用状况测试空载结束时间", &controllers.TaskDataController{}, "*:A温控设备运行参数及使用状况测试空载结束时间")
+	beego.Router("/TaskDataContent/SSE_满载温度偏差均匀度波动度分析时间区间", &controllers.TaskDataController{}, "*:A满载温度偏差均匀度波动度分析时间区间")
+	beego.Router("/TaskDataContent/SSE_空载温度偏差均匀度波动度分析时间区间", &controllers.TaskDataController{}, "*:A空载温度偏差均匀度波动度分析时间区间")
+	beego.Router("/TaskDataContent/SSE_运行确认及偏差处理满载开始时间", &controllers.TaskDataController{}, "*:A运行确认及偏差处理满载开始时间")
+	beego.Router("/TaskDataContent/SSE_运行确认及偏差处理空载开始时间", &controllers.TaskDataController{}, "*:A运行确认及偏差处理空载开始时间")
+	beego.Router("/TaskDataContent/SSE_满载风机启动时间点注释", &controllers.TaskDataController{}, "*:A满载风机启动时间点注释")
+	beego.Router("/TaskDataContent/SSE_满载风机停止时间点注释", &controllers.TaskDataController{}, "*:A满载风机停止时间点注释")
+	beego.Router("/TaskDataContent/SSE_满载测试结束风机停止时间注释", &controllers.TaskDataController{}, "*:A满载测试结束风机停止时间注释")
+	beego.Router("/TaskDataContent/SSE_空载风机启动时间点注释", &controllers.TaskDataController{}, "*:A空载风机启动时间点注释")
+	beego.Router("/TaskDataContent/SSE_空载风机停止时间点注释", &controllers.TaskDataController{}, "*:A空载风机停止时间点注释")
+	beego.Router("/TaskDataContent/SSE_空载测试结束风机停止时间注释", &controllers.TaskDataController{}, "*:A空载测试结束风机停止时间注释")
+	beego.Router("/TaskDataContent/SSE_第一次开门开始时间", &controllers.TaskDataController{}, "*:A第一次开门开始时间")
+	beego.Router("/TaskDataContent/SSE_第一次开门结束时间", &controllers.TaskDataController{}, "*:A第一次开门结束时间")
+	beego.Router("/TaskDataContent/SSE_满载风机启动时间点", &controllers.TaskDataController{}, "*:A满载风机启动时间点")
+	beego.Router("/TaskDataContent/SSE_空载风机启动时间点", &controllers.TaskDataController{}, "*:A空载风机启动时间点")
+	beego.Router("/TaskDataContent/SSE_满载风机停止时间点", &controllers.TaskDataController{}, "*:A满载风机停止时间点")
+	beego.Router("/TaskDataContent/SSE_空载风机停止时间点", &controllers.TaskDataController{}, "*:A空载风机停止时间点")
+	beego.Router("/TaskDataContent/SSE_满载测试结束风机停止时间", &controllers.TaskDataController{}, "*:A满载测试结束风机停止时间")
+	beego.Router("/TaskDataContent/SSE_空载测试结束风机停止时间", &controllers.TaskDataController{}, "*:A空载测试结束风机停止时间")
+	beego.Router("/TaskDataContent/SSE_满载第一次关门温度恢复时间", &controllers.TaskDataController{}, "*:A满载第一次关门温度恢复时间")
+	beego.Router("/TaskDataContent/SSE_空载第一次关门温度恢复时间", &controllers.TaskDataController{}, "*:A空载第一次关门温度恢复时间")
+	beego.Router("/TaskDataContent/SSE_满载开门最长需要多少分钟恢复", &controllers.TaskDataController{}, "*:A满载开门最长需要多少分钟恢复")
+	beego.Router("/TaskDataContent/SSE_空载开门最长需要多少分钟恢复", &controllers.TaskDataController{}, "*:A空载开门最长需要多少分钟恢复")
 
 }

二進制
tests/Fhumptrend/20250314134901.xlsx


+ 16 - 0
tests/Fhumptrend/chat

@@ -0,0 +1,16 @@
+
+type TaskData struct {
+	T_t    float32   // 温度℃
+	T_time time.Time // 记录时间
+}
+使用 goland语言实现:
+1、加载 20250314134901.xlsx表格数据,以上是数据结构体
+2、根据数据计算出每一个驼峰 趋势 ,一个完整的驼峰是从 开始的最低点到最高点到结束的最低点,记录计算出开始的最低点,最高点,结束的最低点
+3、将 main() 改成func TestBeego(t *testing.T)
+
+
+高与低 必须相差1以上,10条数据以上。
+1、连续5个循环的第1个循环温度最高点时间
+2、连续5个循环的第1个循环温度最低点时间
+3、连续5个循环的第5个循环温度最低点时间
+20250314134901.xlsx

+ 147 - 0
tests/Fhumptrend/default_test.go

@@ -0,0 +1,147 @@
+package Fhumptrend
+
+import (
+	"fmt"
+	"github.com/xuri/excelize/v2"
+	"math"
+	"strconv"
+	"testing"
+	"time"
+)
+
+// TaskData 结构体
+type TaskData struct {
+	T_t    float32   // 温度℃
+	T_time time.Time // 记录时间
+}
+
+// 加载 Excel 数据
+func loadExcelData(filePath string) ([]TaskData, error) {
+	f, err := excelize.OpenFile(filePath)
+	if err != nil {
+		return nil, err
+	}
+
+	rows, err := f.GetRows("Sheet1")
+	if err != nil {
+		return nil, err
+	}
+
+	var data []TaskData
+	for _, row := range rows {
+		if len(row) < 2 {
+			continue
+		}
+
+		temp := row[0]
+		timeStr := row[1]
+
+		tempFloat, err := parseFloat32(temp)
+		if err != nil {
+			continue
+		}
+
+		// 修改时间格式为 "2006-01-02 15:04:05"
+		timeTime, err := time.Parse("2006-01-02 15:04:05", timeStr)
+		if err != nil {
+			continue
+		}
+
+		data = append(data, TaskData{
+			T_t:    tempFloat,
+			T_time: timeTime,
+		})
+	}
+
+	return data, nil
+}
+
+// 解析字符串为 float32
+func parseFloat32(s string) (float32, error) {
+	f, err := strconv.ParseFloat(s, 64)
+	if err != nil {
+		return 0, err
+	}
+	// 四舍五入到1位小数
+	rounded := math.Round(f*10) / 10
+	return float32(rounded), nil
+}
+
+// 计算驼峰趋势
+func calculateHumps(data []TaskData) []map[string]interface{} {
+	var humps []map[string]interface{}
+	n := len(data)
+	if n < 3 {
+		return humps
+	}
+
+	i := 0
+	for i < n-5 {
+		// 寻找开始的最低点
+		for !(data[i].T_t <= data[i+1].T_t && data[i+1].T_t <= data[i+2].T_t) {
+			i++
+			if i > n-5 {
+				break
+			}
+		}
+		start := i
+
+		// 寻找最高点
+		for !(data[i].T_t >= data[i+1].T_t && data[i+1].T_t > data[i+2].T_t && data[i+2].T_t > data[i+3].T_t) {
+			i++
+			if i > n-5 {
+				break
+			}
+		}
+		peak := i
+		Abs_peak := math.Abs(float64(data[start].T_t - data[peak].T_t))
+		if Abs_peak < 0.2 {
+			continue
+		}
+
+		// 寻找结束的最低点
+		for !(data[i].T_t <= data[i+1].T_t && data[i+1].T_t < data[i+2].T_t && data[i+2].T_t < data[i+3].T_t) {
+			i++
+			if i > n-5 {
+				break
+			}
+		}
+		end := i
+		Abs_end := math.Abs(float64(data[end].T_t - data[peak].T_t))
+		if Abs_end < 0.3 {
+			continue
+		}
+
+		// 如果找到了一个完整的驼峰
+		if start < peak && peak < end {
+			humps = append(humps, map[string]interface{}{
+				"start": data[start],
+				"peak":  data[peak],
+				"end":   data[end],
+			})
+		}
+		i = peak //
+	}
+
+	return humps
+}
+
+// 测试函数
+func TestBeego(t *testing.T) {
+	filePath := "20250314134901.xlsx"
+	data, err := loadExcelData(filePath)
+	if err != nil {
+		t.Fatalf("Failed to load Excel data: %v", err)
+	}
+
+	humps := calculateHumps(data)
+	for _, hump := range humps {
+		start := hump["start"].(TaskData)
+		peak := hump["peak"].(TaskData)
+		end := hump["end"].(TaskData)
+		fmt.Printf("Hump: Start(T_t: %.2f, T_time: %s) -> Peak(T_t: %.2f, T_time: %s) -> End(T_t: %.2f, T_time: %s)\n",
+			start.T_t, start.T_time.Format("2006-01-02 15:04:05"),
+			peak.T_t, peak.T_time.Format("2006-01-02 15:04:05"),
+			end.T_t, end.T_time.Format("2006-01-02 15:04:05"))
+	}
+}

二進制
tests/Fhumptrend/~$20250314134901.xlsx


+ 9 - 44
tests/default_test.go

@@ -1,52 +1,17 @@
-package test
+package main
 
 import (
+	"ColdVerify_local/lib"
 	"fmt"
 	"testing"
-	"time"
 )
 
+// 测试函数
 func TestBeego(t *testing.T) {
-	formatTimeStr := "2022-05-25 18:58"
-	formatTime,err:=time.Parse("2006-01-02 15:04",formatTimeStr)
-	if err!=nil{
-		fmt.Println(err)
-	}
-	fmt.Println(formatTime) //打印结果:2017-04-11 13:33:37 +0000 UTC
-	//// Read from docx file
-	//r, err := docx.ReadDocxFile("./template.docx")
-	//// Or read from memory
-	//// r, err := docx.ReadDocxFromMemory(data io.ReaderAt, size int64)
-	//
-	//// Or read from a filesystem object:
-	//// r, err := docx.ReadDocxFromFS(file string, fs fs.FS)
-	//
-	//if err != nil {
-	//	panic(err)
-	//}
-	//docx1 := r.Editable()
-	//// Replace like https://golang.org/pkg/strings/#Replace
-	//docx1.Replace("old_1_1", "new_1_1", -1)
-	//docx1.Replace("old_1_2", "new_1_2", -1)
-	////docx1.ReplaceLink("http://example.com/", "https://github.com/nguyenthenguyen/docx", 1)
-	////docx1.ReplaceHeader("out with the old", "in with the new")
-	////docx1.ReplaceFooter("Change This Footer", "new footer")
-	//docx1.WriteToFile("./new_result_1.docx")
-	//
-	//docx2 := r.Editable()
-	//docx2.Replace("old_2_1", "new_2_1", -1)
-	//docx2.Replace("old_2_2", "new_2_2", -1)
-	//docx2.WriteToFile("./new_result_2.docx")
+	制冷机组温控设定最低值_, _ := lib.StringToFloat32("-25")
+	制冷机组温控设定最高值_, _ := lib.StringToFloat32("-25")
 
-	//// Or write to ioWriter
-	//// docx2.Write(ioWriter io.Writer)
-
-	//docx3 := r.Editable()
-
-	////Currently only swaps apples for apples i.e. png to png, and not png to jpeg etc.
-	////d.ReplaceImage("word/media/image1.png", "./new.png")
-	//docx3.WriteToFile("./new_result_3.docx")
-
-
-
-}
+	T := (lib.To_float32(制冷机组温控设定最低值_) + lib.To_float32(制冷机组温控设定最高值_)) / 2
+	// 输出结果
+	fmt.Printf("转换后的 float32 值: %s\n", lib.To2(T))
+}

+ 0 - 0
nohup.out → tests/logs/Logx/Logx.log


+ 20 - 0
tests/main.py

@@ -0,0 +1,20 @@
+import pandas as pd
+import matplotlib.pyplot as plt
+
+# Read the CSV file
+df = pd.read_csv("temperature_data.csv")
+
+# Convert the timestamp column to datetime
+df['T_time'] = pd.to_datetime(df['T_time'])
+
+# Plot the data
+plt.figure(figsize=(12, 6))
+plt.plot(df['T_time'], df['T_t'], label='Temperature (°C)')
+plt.xlabel('Time')
+plt.ylabel('Temperature (°C)')
+plt.title('Temperature Over Time')
+plt.legend()
+plt.grid(True)
+plt.xticks(rotation=45)
+plt.tight_layout()
+plt.show()