huangyan 8 miesięcy temu
rodzic
commit
c48a4aa384

+ 180 - 4
controllers/DeviceController.go

@@ -12,7 +12,9 @@ import (
 	beego "github.com/beego/beego/v2/server/web"
 	"io"
 	"io/ioutil"
+	"log"
 	"math"
+	"strconv"
 	"strings"
 	"time"
 )
@@ -252,7 +254,7 @@ func (c *DeviceController) ReadSensor() {
 	return
 }
 
-// WriteDeviation 设置偏差值
+// WriteSensor WriteDeviation 设置偏差值
 func (c *DeviceController) WriteSensor() {
 	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
 	if !b_ {
@@ -324,20 +326,60 @@ func (c *DeviceController) DeviceWarning_List_html() {
 	//if Class_1 > 0 {
 	//	T_Title = Device.Read_DeviceWarningList_ById(Class_1).T_name
 	//}
+	var pageSizes struct {
+		PageSize string `json:"pageSize"`
+	}
+	json.Unmarshal(c.Ctx.Input.RequestBody, &pageSizes)
+
+	pageSize := c.GetString("pageSize", "10")
+	pageSizeInt, _ := strconv.Atoi(pageSize)
+	atoi, _ := strconv.Atoi(pageSizes.PageSize)
+	if atoi == 0 {
+		atoi = pageSizeInt
+	} else {
+		pageSizeInt = atoi
+	}
 
 	var cnt int64
-	DeviceWarning_List, cnt := Warning.Read_Warning_List(admin_r.T_pid, bindSN, tpList, Time_start, Time_end, page, 10)
+	DeviceWarning_List, cnt := Warning.Read_Warning_List(admin_r.T_pid, bindSN, tpList, Time_start, Time_end, page, pageSizeInt)
 
 	c.Data["List"] = DeviceWarning_List
-	page_size := math.Ceil(float64(cnt) / float64(conf.Page_size))
+	page_size := math.Ceil(float64(cnt) / float64(pageSizeInt))
 	c.Data["Page"] = page
 	c.Data["Page_size"] = page_size
 	c.Data["Pages"] = lib.Func_page(int64(page), int64(page_size))
 	c.Data["cnt"] = cnt
+	// 将sync.Map中的数据转存到切片中
 
 	c.TplName = "Device/DeviceWarning.html"
 }
-
+func (c *DeviceController) GetWarningtype() {
+	var results []struct {
+		Key   int
+		Value string
+	}
+	Warning.WarningType_list.Range(func(key, value any) bool {
+		// 确保类型断言成功
+		if k, ok := key.(int); ok {
+			if v, ok := value.(string); ok {
+				// 创建匿名结构体实例并添加到切片
+				// 注意:确保结构体定义与切片元素类型匹配,且无需在字面量中重复标签
+				results = append(results, struct {
+					Key   int
+					Value string
+				}{Key: k, Value: v})
+			} else {
+				fmt.Println("Value is not of type string")
+			}
+		} else {
+			fmt.Println("Key is not of type int")
+		}
+		return true // 继续遍历
+	})
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: results}
+	c.ServeJSON()
+	log.Println(results)
+}
 func (c *DeviceController) DeviceWarning_() {
 	// 验证登录
 	//b_, admin_r := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
@@ -414,3 +456,137 @@ func (c *DeviceController) DeviceWarning_Del() {
 	c.ServeJSON()
 	return
 }
+
+// 批量删除
+func (c *DeviceController) DeviceWarning_DelS() {
+	// 验证登录
+	b_, admin_r := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Ctx.Redirect(302, "Login")
+		return
+	}
+	type SelectedItem struct {
+		Id string `json:"id"`
+		Ut string `json:"ut"` // 假设"ut"字段是时间戳字符串
+	}
+
+	type SelectedItems struct {
+		SelectedIds []SelectedItem `json:"selectedIds"`
+	}
+	var SelectedIds SelectedItems
+	//var selectedIds map[string]any
+
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &SelectedIds)
+	log.Println(SelectedIds.SelectedIds)
+	for _, v := range SelectedIds.SelectedIds {
+		Warning.Delete_Warning_List(v.Id, v.Ut, admin_r.T_pid)
+	}
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "E!", Data: "数据格式错误!!!"}
+		c.ServeJSON()
+	} else {
+		c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+		c.ServeJSON()
+	}
+}
+
+// Device_Copy 复制并添加
+func (c *DeviceController) Device_Copy() {
+	// 验证登录
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Ctx.Redirect(302, "Login")
+		return
+	}
+	type T_data struct {
+		T_sn       string `json:"t_sn"`
+		T_id       int    `json:"t_id"`
+		T_Rh       any    `json:"t_rh"`
+		T_Site     string `json:"t_site"`
+		T_T        any    `json:"t_t"`
+		CreateTime string `json:"createTime"`
+	}
+	var data T_data
+	json.Unmarshal(c.Ctx.Input.RequestBody, &data)
+	r := Device.Read_DeviceParameter_SNNo(data.T_sn)
+	parse, _ := time.Parse("2006-01-02 15:04:05", data.CreateTime)
+	data.CreateTime = parse.Add(time.Duration(r[0].T_saveT) * time.Second).Format("2006-01-02 15:04:05")
+	itoa := strconv.Itoa(data.T_id)
+	Device.Copy_DeviceData(data.T_sn, itoa, data.T_Rh, data.T_T, data.T_Site, data.CreateTime)
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "设置成功", Data: data}
+	c.ServeJSON()
+}
+
+// DeviceWarningUpdate 修改报警
+func (c *DeviceController) DeviceWarningUpdate() {
+	// 验证登录
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Ctx.Redirect(302, "Login")
+		return
+	}
+	var data struct {
+		ColumnName string `json:"columnName"`
+		NewValue   string `json:"newValue"`
+		RowId      string `json:"rowId"`
+		T_Ut       string `json:"T_Ut"`
+	}
+	json.Unmarshal(c.Ctx.Input.RequestBody, &data)
+	Warning.Update_DeviceParameter_Warning(data.ColumnName, data.NewValue, data.RowId, data.T_Ut)
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "设置成功", Data: data}
+	c.ServeJSON()
+}
+
+// DeviceWarningAdd 复制添加报警
+func (c *DeviceController) DeviceWarningAdd() {
+	// 验证登录
+	b_, admin_r := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Ctx.Redirect(302, "Login")
+		return
+	}
+	var data struct {
+		T_tp_name string `json:"column1"`
+		T__d_name string `json:"column2"`
+		T_DS_name string `json:"column3"`
+		T_Remark  string `json:"column4"`
+		T_State   string `json:"column5"`
+		T_Ut      string `json:"column6"`
+		RowId     string `json:"rowId"`
+		SN        string `json:"sn"`
+		T_id      string `json:"t_id"`
+	}
+
+	json.Unmarshal(c.Ctx.Input.RequestBody, &data)
+	atoi, _ := strconv.Atoi(data.T_id)
+	r_Device, err := Device.Read_Device_ByT_sn(data.SN)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "E!", Data: "SN 错误!!!"}
+		c.ServeJSON()
+		return
+	}
+	// 获取 传感器 参数
+	//DeviceSensor_r, is := Device.Read_DeviceSensor_ByT_sn(r_Device.T_sn, atoi)
+	//if !is {
+	//	c.Data["json"] = lib.JSONS{Code: 201, Msg: "E!", Data: "编号 错误!!!"}
+	//	c.ServeJSON()
+	//	return
+	//}
+	T_tp := Warning.Read_WarningType(data.T_tp_name)
+	t1, _ := time.ParseInLocation("2006-01-02 15:04:05", data.T_Ut, time.Local) // +8  时差
+	t_c := Warning.Warning{
+		T_pid:     admin_r.T_pid,
+		T_tp:      T_tp,
+		T_sn:      data.SN,
+		T_D_name:  r_Device.T_devName,
+		T_id:      atoi,
+		T_DS_name: data.T_DS_name,
+		T_Ut:      t1,
+		T_State:   1,
+		T_Remark:  data.T_Remark,
+	}
+	Warning.Add_Warning(t_c)
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}

+ 1 - 1
lastupdate.tmp

@@ -1 +1 @@
-{"E:\\WebstormProjects\\ColdP_server\\controllers":1718181669847005500}
+{"E:\\WebstormProjects\\ColdP_server\\controllers":1718637940538532800}

+ 148 - 0
logs/logx/logx.log

@@ -28,3 +28,151 @@
 2024/06/12 16:30:53.407 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
 2024/06/12 16:36:50.751 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
 2024/06/12 16:41:18.504 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/12 17:09:48.112 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/12 17:11:26.352 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/13 08:57:26.385 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/13 09:57:48.736 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/13 15:16:33.383 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/13 15:39:34.907 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/13 15:43:48.041 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 09:04:07.887 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 09:30:02.367 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 09:35:02.086 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 09:57:34.625 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 10:04:25.129 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 10:28:45.721 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 10:32:15.814 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 10:52:24.007 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 11:02:24.472 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 11:04:36.375 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 11:06:05.791 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 11:09:40.677 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 11:11:01.423 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 11:35:17.393 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 11:42:04.266 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 11:51:22.696 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 13:34:50.649 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 14:50:53.630 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 14:51:36.225 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 14:57:59.087 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:01:25.268 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:09:10.899 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:11:24.610 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:12:47.115 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:17:52.453 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:29:38.586 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:38:54.548 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:41:56.684 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:46:11.921 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:47:50.958 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:50:12.549 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:51:29.300 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:53:16.245 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 15:58:38.479 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 16:17:31.758 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 16:28:11.505 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 16:46:50.393 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 16:47:30.342 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 16:52:23.943 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 16:54:34.108 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 16:59:14.674 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 17:01:13.018 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/14 21:03:20.806 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 10:02:38.275 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 14:59:35.880 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 15:44:56.292 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:19:19.601 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:21:22.472 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:24:42.987 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:35:49.234 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:41:07.406 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:42:53.212 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:45:24.989 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:46:46.387 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:49:34.641 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:50:26.823 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:53:03.737 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:56:44.282 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 16:58:12.734 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 17:00:26.833 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 17:01:20.038 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 17:02:24.848 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 17:03:04.942 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 17:04:05.237 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 17:04:25.822 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 17:05:38.297 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 17:06:27.398 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 17:29:47.756 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 17:36:46.449 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 19:19:48.660 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 19:33:27.245 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 19:57:13.645 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 21:01:26.644 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 21:14:20.924 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 21:14:37.033 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 21:15:40.946 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 21:26:39.381 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 21:28:03.395 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 21:31:40.454 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/15 21:58:21.243 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 09:30:49.017 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 15:24:26.908 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 15:41:27.315 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 15:42:17.810 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 15:44:39.185 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 16:45:45.267 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 16:49:05.498 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 16:52:12.583 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 21:00:46.305 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 21:10:42.226 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 21:12:34.167 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 21:14:02.041 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 21:35:19.689 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 22:07:34.568 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 22:27:07.613 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 22:31:08.938 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 22:31:55.056 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 22:33:56.119 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 22:36:28.732 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 22:40:54.633 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 22:44:38.148 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 22:53:56.905 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/16 23:05:11.333 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 11:48:34.798 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 12:32:39.818 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 13:42:07.645 [E] [WarningType.go:201]  ColdP_server/models/Warning.Read_WarningType_All_Maps invalid connection
+2024/06/17 13:54:17.917 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 14:40:53.263 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 14:45:11.001 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 14:54:50.827 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 15:09:44.042 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 15:15:30.725 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 16:08:35.957 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 16:08:54.413 [E] [DeviceSensor.go:324]  ColdP_server/models/Device.Read_DeviceSensor_ByT_sn <QuerySeter> no row found
+2024/06/17 16:09:35.089 [E] [DeviceSensor.go:324]  ColdP_server/models/Device.Read_DeviceSensor_ByT_sn <QuerySeter> no row found
+2024/06/17 16:10:33.378 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 16:11:07.014 [E] [DeviceSensor.go:324]  ColdP_server/models/Device.Read_DeviceSensor_ByT_sn <QuerySeter> no row found
+2024/06/17 16:12:46.908 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 16:14:55.230 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 16:31:42.322 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 16:33:33.629 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/06/17 16:38:29.705 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 16:43:54.838 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 16:47:57.510 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 17:03:13.710 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 17:06:59.215 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 20:53:59.601 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 21:54:31.876 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 21:58:51.964 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 21:59:58.219 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 22:00:48.142 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 22:02:27.310 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 22:08:30.262 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 22:18:57.009 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 22:19:39.151 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 22:27:08.306 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 22:28:32.735 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 22:30:30.111 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 22:33:28.712 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 22:50:45.648 [I] [WarningType.go:193]  =========== 初始化报警类型 =========
+2024/06/17 23:24:14.910 [I] [WarningType.go:193]  =========== 初始化报警类型 =========

+ 12 - 0
models/Device/DeviceData.go

@@ -11,6 +11,7 @@ import (
 	orm2 "github.com/beego/beego/v2/client/orm"
 	_ "github.com/go-sql-driver/mysql"
 	"github.com/xuri/excelize/v2"
+	"log"
 	"strconv"
 	"strings"
 	"time"
@@ -461,6 +462,17 @@ func Update_DeviceSensorData(v DeviceData_R, fieldName, val string) {
 	}
 }
 
+// 复制添加数据
+func Copy_DeviceData(T_sn, T_id string, T_Rh, T_T any, T_Site, CreateTime string) {
+	T_sp := Read_device_sensor_parameter(T_sn, T_id)
+	o := orm.NewOrm()
+	sprintf := fmt.Sprintf("insert into z_device_data_%s(t_id,t_sp,t_time,t_t,t_rh,t_site,create_time) values (?,?,?,?,?,?,?)", T_sn)
+	log.Println(sprintf)
+	_, err := o.Raw(sprintf, T_id, T_sp, CreateTime, T_T, T_Rh, T_Site, CreateTime).Exec()
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+}
 func Read_DeviceData_ById_Year_List(SN string) []orm2.ParamsList {
 	o := orm.NewOrm()
 

+ 16 - 0
models/Device/DeviceParameter.go

@@ -1,6 +1,8 @@
 package Device
 
 import (
+	"ColdP_server/controllers/lib"
+	"ColdP_server/logs"
 	"fmt"
 	"github.com/beego/beego/v2/adapter/orm"
 	orm2 "github.com/beego/beego/v2/client/orm"
@@ -224,3 +226,17 @@ func ReadDeviceParameterByTsn(tSn string) DeviceParameter {
 	query.Filter("t_sn", tSn).OrderBy("-update_time").One(&deviceParameter)
 	return deviceParameter
 }
+
+// Read_DeviceParameter_SNNo 获取设备参数
+func Read_DeviceParameter_SNNo(T_sn string) (r []DeviceParameter) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceParameter))
+	_, err := qs.Limit(1, 0).Filter("T_sn", T_sn).Filter("T_State", 1).OrderBy("-Id").All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return r
+}

+ 47 - 0
models/Warning/Warning.go

@@ -282,6 +282,53 @@ func Delete_Warning(t_pid, Id int) (err error) {
 	return
 }
 
+// Delete_Warning_List 批量删除
+func Delete_Warning_List(id, ut string, pid int) (err error) {
+	o := orm.NewOrm()
+	atoi, _ := strconv.Atoi(id)
+	layout := "2006-01-02 15:04:05"
+	parse, _ := time.Parse(layout, ut)
+	year := parse.Year()
+	formatMonth := parse.Format("01")
+	years := strconv.Itoa(year)
+	Wtab := "warning_" + years + "_" + formatMonth
+	//在更新状态时需要计算间隔时间,如果T_ut时间和当前时间间隔超过40天就不用更新warning表,反之
+	//获得当前之间计算两个时间之间的间隔
+	now := time.Now()
+	interval := now.Sub(parse)
+	if interval.Hours() > 40*24 {
+		o.Raw("UPDATE warning SET t__state = 0 WHERE t_pid = ? AND ID = ?", pid, atoi).Exec()
+	} else {
+		o.Raw("UPDATE "+Wtab+"  SET t__state = 0  WHERE t_pid = ? AND ID = ?", pid, atoi).Exec()
+		o.Raw("UPDATE warning SET t__state = 0 WHERE t_pid = ? AND ID = ?", pid, atoi).Exec()
+	}
+	return
+}
+
+// Update_DeviceParameter_Warning更新
+func Update_DeviceParameter_Warning(columnName, newValue, rowId, T_Ut string) {
+	o := orm.NewOrm()
+	layout := "2006-01-02 15:04:05"
+	parse, _ := time.Parse(layout, T_Ut)
+	year := parse.Year()
+	formatMonth := parse.Format("01")
+	years := strconv.Itoa(year)
+	Wtab := "warning_" + years + "_" + formatMonth
+	//在更新状态时需要计算间隔时间,如果T_ut时间和当前时间间隔超过40天就不用更新warning表,反之
+	//获得当前之间计算两个时间之间的间隔
+	if columnName == "T_tp_name" {
+		columnName = "t_tp"
+	}
+	now := time.Now()
+	interval := now.Sub(parse)
+	if interval.Hours() > 40*24 {
+		o.Raw("UPDATE "+Wtab+" SET `"+columnName+"` = ? WHERE `ID` = ?", newValue, rowId).Exec()
+	} else {
+		o.Raw("UPDATE "+Wtab+" SET `"+columnName+"` = ? WHERE `ID` = ?", newValue, rowId).Exec()
+		o.Raw("UPDATE warning SET `"+columnName+"` = ? WHERE `ID` = ?", newValue, rowId).Exec()
+	}
+}
+
 // 修改
 func Update_Warning_Backups(r Warning, T_year string, T_month string) bool {
 	o := orm.NewOrm()

+ 19 - 0
models/Warning/WarningType.go

@@ -3,6 +3,7 @@ package Warning
 import (
 	"ColdP_server/controllers/lib"
 	"ColdP_server/logs"
+	"fmt"
 	_ "github.com/astaxie/beego/cache/redis"
 	"github.com/beego/beego/v2/adapter/orm"
 	_ "github.com/go-sql-driver/mysql"
@@ -216,3 +217,21 @@ func Read_WarningType_Get(id int) string {
 		return "未知类型"
 	}
 }
+
+// 报警类型
+func Read_WarningType(id string) int {
+	var r int
+	WarningType_list.Range(func(key, value any) bool {
+		if value.(string) == id {
+			r = key.(int)
+			return false // 找到匹配后立即结束遍历
+		}
+		return true // 继续遍历
+	})
+	// 如果没有找到匹配项,在遍历结束后返回默认值或其他处理
+	if r == 0 {
+		// 这里可以根据需要处理未找到的情况,比如返回一个错误码或特定值
+		fmt.Println("No matching key found for the given ID")
+	}
+	return r
+}

+ 10 - 1
routers/DeviceRouter.go

@@ -22,7 +22,16 @@ func init() {
 	beego.Router("/Device/ReadSensor", &controllers.DeviceController{}, "POST:ReadSensor")
 	//数据偏差值写入
 	beego.Router("/Device/WriteSensor", &controllers.DeviceController{}, "POST:WriteSensor")
-
+	//分页
+	beego.Router("/Device/DeviceWarning_page", &controllers.DeviceController{}, "*:DeviceWarning_List_html")
+	beego.Router("/Device/DeviceWarning_waraning", &controllers.DeviceController{}, "*:GetWarningtype")
+	//批量删除
+	beego.Router("/Device/DeviceWarning_dels", &controllers.DeviceController{}, "*:DeviceWarning_DelS")
+	//修改报警
+	beego.Router("/Device/DeviceWarningUpdate", &controllers.DeviceController{}, "*:DeviceWarningUpdate")
+	beego.Router("/Device/DeviceWarningAdd", &controllers.DeviceController{}, "*:DeviceWarningAdd")
+	//复制添加
+	beego.Router("/Device/Device_Copy", &controllers.DeviceController{}, "*:Device_Copy")
 	beego.Router("/Device/DeviceWarning_List_html", &controllers.DeviceController{}, "*:DeviceWarning_List_html") // 获取未读消息
 	//beego.Router("/Device/DeviceWarning_List", &controllers.DeviceController{}, "*:DeviceWarning_List")                   // 获取未读消息
 	beego.Router("/Device/DeviceWarning_", &controllers.DeviceController{}, "*:DeviceWarning_") // 获取未读消息

+ 100 - 32
views/Data/DataList.html

@@ -63,9 +63,6 @@
                     <hr>
                 </div>
                 <div class="layui-card-body " style="margin-top: -20px">
-                    <!--                    <div class="layui-progress " >-->
-                    <!--                        <div id="progress" class="layui-progress-bar layui-bg-blue" lay-percent="80%"></div>-->
-                    <!--                    </div>-->
                     <div id="DeviceSensor_list" style="width: 98%; overflow: hidden;max-height: 616px;overflow-y: auto">
                         <div style="color: #1E9FFF;text-align: center;font-size: 15px;margin-top: 150px">加载中...</div>
                     </div>
@@ -94,22 +91,6 @@
                                     <i class="layui-icon">反选</i>
                                 </div>
                             </div>
-                            <!--                            <div class="page">-->
-                            <!--                                <div id="DeviceSensor_list_Pages">-->
-
-
-                            <!--                                    &lt;!&ndash;                                    <a class="prev" href="">&lt;&lt;</a>&ndash;&gt;-->
-
-                            <!--                                    &lt;!&ndash;                                    <a class="num" href="">1222</a>&ndash;&gt;-->
-
-                            <!--                                    &lt;!&ndash;                                    <span class="current">111</span>&ndash;&gt;-->
-
-                            <!--                                    &lt;!&ndash;                                    <a class="num" href="">444</a>&ndash;&gt;-->
-                            <!--                                    &lt;!&ndash;                                    <a class="next" href="">&gt;&gt;</a>&ndash;&gt;-->
-
-                            <!--                                </div>-->
-
-                            <!--                            </div>-->
                             <div style="color: #1E9FFF;text-align: center" id="DeviceSensor_list_Pages_x"></div>
                         </div>
                     </div>
@@ -120,7 +101,6 @@
 
         <div style="padding-left: 15px; height: 100%;flex:1;">
             <div class="layui-card">
-
                 <!-- 传感器数据时间选择 选择 start-->
                 <div class="layui-card-body ">
                     <div class="layui-form layui-col-space5" οnsubmit="return false;">
@@ -176,7 +156,7 @@
                     <hr>
                 </div>
                 <!-- 传感器数据时间选择 选择 end-->
-                <div class="layui-card-body" style="height: 540px;">
+                <div class="layui-card-body" >
                     <table class="layui-table ">
                         <colgroup>
                             <col width="100">
@@ -216,6 +196,16 @@
                     <div id="pageTool">
 
                     </div>
+                    <select id="perPageSelect">
+                        <option value="10">10条/页</option>
+                        <option value="100">100条/页</option>
+                        <option value="300">300条/页</option>
+                        <option value="500">500条/页</option>
+                        <option value="800">800条/页</option>
+                        <option value="1000">1000条/页</option>
+                    </select>
+<!--                    <input type="number" id="perPageInput" min="1" value="10">-->
+
                     <!--分页部分 end-->
                 </div>
             </div>
@@ -612,9 +602,24 @@
         }
 
     }
+    $('#perPageSelect').on('change', function() {
+        let itemsPerPage = $(this).val();
+        get_DeviceSensor_data(0, itemsPerPage); // 调用获取数据函数,传入新的每页条数
+    });
+
+    // 如果是输入框,则可能需要验证用户输入并做相应的处理
+    $('#perPageInput').on('input', function() {
+        let itemsPerPage = parseInt($(this).val());
+        if (!isNaN(itemsPerPage)) {
+            get_DeviceSensor_data(0, itemsPerPage);
+        } else {
+            alert('请输入有效的数字!');
+            $(this).val('10'); // 重置为默认值
+        }
+    });
 
 
-    function get_DeviceSensor_data(page) {
+    function get_DeviceSensor_data(page,itemsPerPage) {
 
         if ($("#Time_start").val().length > 0) {
             Time_start = $("#Time_start").val();
@@ -643,7 +648,7 @@
                 Time_end: Time_end,
                 T_snid: DeviceSensor_snid_list,
                 page: page,
-                page_z: 10,
+                page_z: itemsPerPage,
             },
             success: function (result) {
                 console.log(result)
@@ -658,7 +663,7 @@
                         return
                     }
                     addDeviceSensorData(result.Data.list)
-                    addDeviceSensorDataPage(result.Data)
+                    addDeviceSensorDataPage(result.Data,itemsPerPage)
 
                 } else {
 
@@ -736,7 +741,7 @@
     }
 
     //分页添加
-    function addDeviceSensorDataPage(pageInfo) {
+    function addDeviceSensorDataPage(pageInfo,itemsPerPage) {
         let start, end
         start = pageInfo.currentPage - 5 < 1 ? 1 : pageInfo.currentPage - 5
         end = pageInfo.currentPage + 5 > pageInfo.totalPage ? pageInfo.totalPage : pageInfo.currentPage + 5
@@ -745,7 +750,7 @@
         $('#pageTool').append(`<span style="padding: 0 10px;color: #0bace6">共${pageInfo.totalPage}页 / 当前${pageInfo.currentPage}页 共${pageInfo.totalCount}条数据</span>`)
         //上一页
         if (pageInfo.previousPage) {
-            $('#pageTool').append(`<button class="layui-btn  layui-btn-primary layui-btn-sm" onclick="get_DeviceSensor_data(${pageInfo.currentPage - 1})">上一页</button>`)
+            $('#pageTool').append(`<button class="layui-btn  layui-btn-primary layui-btn-sm" onclick="get_DeviceSensor_data(${pageInfo.currentPage - 1},${itemsPerPage})">上一页</button>`)
         } else {
             $('#pageTool').append(`<button class="layui-btn layui-btn-disabled layui-btn-primary layui-btn-sm">上一页</button>`)
         }
@@ -754,12 +759,12 @@
             if (start == pageInfo.currentPage) {
                 $('#pageTool').append(`<button class="layui-btn layui-btn-disabled layui-btn-primary layui-btn-sm">${start}</button>`)
             } else {
-                $('#pageTool').append(`<button class="layui-btn layui-btn-primary layui-btn-sm" onclick="get_DeviceSensor_data(${start})">${start}</button>`)
+                $('#pageTool').append(`<button class="layui-btn layui-btn-primary layui-btn-sm" onclick="get_DeviceSensor_data(${start},${itemsPerPage})">${start}</button>`)
             }
         }
         //下一页
         if (pageInfo.nextPage) {
-            $('#pageTool').append(`<button class="layui-btn  layui-btn-primary layui-btn-sm" onclick="get_DeviceSensor_data(${pageInfo.currentPage + 1})">下一页</button>`)
+            $('#pageTool').append(`<button class="layui-btn  layui-btn-primary layui-btn-sm" onclick="get_DeviceSensor_data(${pageInfo.currentPage + 1},${itemsPerPage})">下一页</button>`)
         } else {
             $('#pageTool').append(`<button class="layui-btn layui-btn-disabled layui-btn-primary layui-btn-sm">下一页</button>`)
         }
@@ -785,8 +790,8 @@
                 <td ondblclick="changeData(this)" data-type="create_time">${v.create_time}</td>
                 <td>
                     <button class="layui-btn layui-btn-danger layui-btn-sm" onclick="deleteOne(this)">删除</button>
-                    <button class="layui-btn layui-bg-blue layui-btn-sm" onclick="deleteOne(this)">复制添加</button>
-                </td>
+                    <button class="layui-btn layui-bg-blue layui-btn-sm" onclick="copyAndAdds(this, '${v.t_sn}', ${v.t_id}, ${v.t_t}, ${v.t_rh}, '${v.t_site}', '${v.create_time}')">复制添加</button>
+                    </td>
             </tr>
             `)
             /*
@@ -795,7 +800,71 @@
             */
         }
     }
-
+    // 新增copyAndAdd函数实现复制并添加新行
+    function copyAndAdds(button, t_sn, t_id, t_t, t_rh, t_site, create_time) {
+        // 准备发送给后端的数据对象
+        let dataToSend = {
+            t_sn: t_sn,
+            t_id: t_id,
+            t_t: t_t,
+            t_rh: t_rh,
+            t_site: t_site,
+            createTime: create_time
+        };
+
+        // 提交数据到后端
+        $.ajax({
+            url: '/Device/Device_Copy', // 替换为你的后端接口地址
+            type: 'POST',
+            contentType: 'application/json',
+            data: JSON.stringify(dataToSend),
+            success: function(response) {
+                console.log("数据提交成功,响应:", response.Data);
+
+                // 假设后端返回了新行ID或者其他需要的数据,这里可以根据需要处理response
+                let newRowId = response.id; // 假设后端返回了新行的唯一ID
+
+                // 根据后端返回的数据(如果有的话)来构造新行的HTML
+                let newRowHtml = `
+    <tr class="new-row" data-id="${response.id}" style="background-color: #f0f8ff; border-left: 4px solid #007bff;">
+        <td>
+            <input
+                type="checkbox"
+                class="layui-form-checkbox"
+                data-sn="${response.Data.t_sn}"
+                data-id="${response.Data.t_id}"
+                data-tt="${response.Data.t_t}"
+                data-trh="${response.Data.t_rh}"
+                data-site="${response.Data.t_site}"
+                data-createTime="${response.Data.createTime}"
+            />
+        </td>
+        <td ondblclick="changeData(this)" data-type="t_time" style="color: #007bff;">${response.Data.createTime}</td>
+        <td ondblclick="changeData(this)" data-type="t_t" style="color: #007bff;">${response.Data.t_t}</td>
+        <td ondblclick="changeData(this)" data-type="t_rh" style="color: #007bff;">${response.Data.t_rh}</td>
+        <td ondblclick="changeData(this)" data-type="t_site" style="color: #007bff;">${response.Data.t_site}</td>
+        <td ondblclick="changeData(this)" data-type="create_time" style="color: #007bff;">${response.Data.createTime}</td>
+        <td>
+            <button class="layui-btn layui-btn-danger layui-btn-sm" onclick="deleteOne(this)">删除</button>
+                            <button class="layui-btn layui-bg-blue layui-btn-sm" onclick="copyAndAdds(this, '${t_sn}', ${t_id}, ${t_t}, ${t_rh}, '${t_site}', '${create_time}')">复制添加</button>
+
+            <!-- 注意:此处可能不需要再提供复制添加按钮,因为数据已持久化 -->
+        </td>
+    </tr>
+`;
+
+                // 在当前行的下一行兄弟元素(下一行)之前插入新行
+                $(button).closest('tr').after(newRowHtml);
+
+                // 这里可以添加成功后的其他操作,如提示用户、更新界面等
+            },
+            error: function(jqXHR, textStatus, errorThrown) {
+                console.error("数据提交失败:", textStatus, errorThrown);
+                // 处理错误情况,比如提示用户
+                alert("数据提交失败,请重试!");
+            }
+        });
+    }
     function showRecord(e) {
         e = $(e).parent().prevAll()
         e = e[e.length - 1]
@@ -895,7 +964,6 @@
             }
             , field: 'file'
             , done: function (res) {
-                layui.layer.success(res.Msg)
                 layui.layer.msg(res.Msg)
                 // layui.layer.close(index)
             }

+ 419 - 105
views/Device/DeviceWarning.html

@@ -1,97 +1,130 @@
 <!DOCTYPE html>
 <html class="x-admin-sm">
-    
-    <head>
-        <meta charset="UTF-8">
-        <meta name="renderer" content="webkit">
-        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-        <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
-        <link rel="shortcut icon" href="https://osscold.baozhida.cn/favicon.ico">
-        <link rel="bookmark" href="https://osscold.baozhida.cn/favicon.ico">
-        <link rel="stylesheet" href="https://osscold.baozhida.cn/css/font.css">
-        <link rel="stylesheet" href="https://osscold.baozhida.cn/css/xadmin.css">
-        <script src="https://osscold.baozhida.cn/lib/layui/layui.js" charset="utf-8"></script>
-        <script type="text/javascript" src="https://osscold.baozhida.cn/js/xadmin.js"></script>
-    </head>
-    
-    <body>
-        <div class="x-nav">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport"
+          content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi"/>
+    <link rel="shortcut icon" href="https://osscold.baozhida.cn/favicon.ico">
+    <link rel="bookmark" href="https://osscold.baozhida.cn/favicon.ico">
+    <link rel="stylesheet" href="https://osscold.baozhida.cn/css/font.css">
+    <link rel="stylesheet" href="https://osscold.baozhida.cn/css/xadmin.css">
+    <script src="https://osscold.baozhida.cn/lib/layui/layui.js" charset="utf-8"></script>
+    <script type="text/javascript" src="https://osscold.baozhida.cn/js/xadmin.js"></script>
+</head>
+
+<body>
+<div class="x-nav">
             <span class="layui-breadcrumb">
                 <a href="">首页</a>
                 <a><cite>宝智达</cite></a>
             </span>
-            <a class="layui-btn layui-btn-normal" style="line-height:1.6em;margin-top:3px;float:right" onclick="location.reload()" title="刷新">
-                <i class="layui-icon layui-icon-refresh" style="line-height:30px"></i>
-            </a>
-        </div>
-        <div class="layui-fluid">
-            <div class="layui-row layui-col-space15">
-                <div class="layui-col-md12">
-                    <div class="layui-card">
-                        <div class="layui-card-body ">
-                            <form class="layui-form layui-col-space5">
-                                <div class="layui-inline layui-show-xs-block">
-                                    <input class="layui-input" autocomplete="off" placeholder="开始日" name="Time_start" id="Time_start" lay-key="1"></div>
-                                <div class="layui-inline layui-show-xs-block">
-                                    <input class="layui-input" autocomplete="off" placeholder="截止日" name="Time_end" id="Time_end" lay-key="2"></div>
-
-                                <div class="layui-input-inline layui-show-xs-block">
-                                    <input value="{{.T_sn}}" type="text" name="T_sn" style="width: 200px" placeholder="请输入 Sn (支持模糊搜索)" autocomplete="off" class="layui-input"></div>
-                                <div class="layui-input-inline layui-show-xs-block">
-                                    <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="sreach">
-                                        <i class="layui-icon">&#xe615;</i></button>
-                                </div>
-                                <button type="button" style="float: right" class="layui-btn layui-btn-normal layui-btn-xs"  onclick="xadmin.open('添加','/Device/DeviceWarning_',400,450)" ><i class="layui-icon">&#xe61f;</i>添加报警</button>
-
-                            </form>
-
+    <a class="layui-btn layui-btn-normal" style="line-height:1.6em;margin-top:3px;float:right"
+       onclick="location.reload()" title="刷新">
+        <i class="layui-icon layui-icon-refresh" style="line-height:30px"></i>
+    </a>
+</div>
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15">
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-body ">
+                    <form class="layui-form layui-col-space5">
+                        <div class="layui-inline layui-show-xs-block">
+                            <input class="layui-input" autocomplete="off" placeholder="开始日" name="Time_start"
+                                   id="Time_start" lay-key="1"></div>
+                        <div class="layui-inline layui-show-xs-block">
+                            <input class="layui-input" autocomplete="off" placeholder="截止日" name="Time_end"
+                                   id="Time_end" lay-key="2"></div>
+
+                        <div class="layui-input-inline layui-show-xs-block">
+                            <input value="{{.T_sn}}" type="text" name="T_sn" style="width: 200px"
+                                   placeholder="请输入 Sn (支持模糊搜索)" autocomplete="off" class="layui-input"></div>
+                        <div class="layui-input-inline layui-show-xs-block">
+                            <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="sreach">
+                                <i class="layui-icon">&#xe615;</i></button>
                         </div>
+                        <button type="button" style="float: right" class="layui-btn layui-btn-normal layui-btn-xs"
+                                onclick="xadmin.open('添加','/Device/DeviceWarning_',400,450)"><i class="layui-icon">&#xe61f;</i>添加报警
+                        </button>
 
-                        <div class="layui-card-body ">
-                            <table class="layui-table layui-form">
-                                <thead>
-                                    <tr>
-                                        <th>报警类型</th>
-                                        <th>主机</th>
-                                        <th>设备</th>
-                                        <th>采集内容</th>
-                                        <th>状态</th>
-                                        <th>采集时间</th>
-                                        <th>操作</th>
-                                    </tr>
-                                </thead>
-                                <tbody>
-                                {{range $index, $elem := .List}}
-                                    <tr {{if eq $elem.T_State 0 }} style="background-color: rgba(0,0,0,0.26)" {{end}} >
-                                        <td>{{$elem.T_tp_name}}</td>
-                                        <td>{{$elem.T_D_name}} 【{{$elem.T_sn}}】</td>
-                                        <td>{{$elem.T_DS_name}} 【{{$elem.T_id}}】</td>
-                                        <td>{{$elem.T_Remark}}</td>
-                                        <td>
-                                            {{if eq $elem.T_State 1}}
-                                                不处理
-                                            {{else if eq $elem.T_State 2}}
-                                                已处理
-                                            {{else if eq $elem.T_State 3}}
-                                                未处理
-                                            {{else}}
-                                                删除
-                                            {{end}}
-                                        </td>
-                                        <td>{{$elem.T_Ut}}</td>
-                                        <td>
-                                            <button class="layui-btn-danger layui-btn layui-btn-xs"  onclick="member_del(this,'{{$elem.Id}}')" href="javascript:;" ><i class="layui-icon" >&#xe640;</i>删除</button>
-
-                                        </td>
-                                    </tr>
+                    </form>
 
+                </div>
+
+                <div class="layui-card-body ">
+                    <table class="layui-table layui-form">
+                        <thead>
+                        <tr>
+                            <th>选择</th>
+                            <th>报警类型</th>
+                            <th>主机</th>
+                            <th>设备</th>
+                            <th>采集内容</th>
+                            <th>状态</th>
+                            <th>采集时间</th>
+                            <th>操作</th>
+                        </tr>
+                        </thead>
+                        <tbody>
+                        {{range $index, $elem := .List}}
+                        <tr {{if eq $elem.T_State 0 }} style="background-color: rgba(0,0,0,0.26)" {{end}}>
+                            <td><input type="checkbox" class="layui-checkbox" name="checkbox" lay-skin="primary"
+                                       value="{{$elem.Id}}"></td>
+
+                            <td type="text" name="T_tp_name">{{$elem.T_tp_name}}
+                            </td>
+                            <td name="t__d_name,t_sn" sn="{{$elem.T_sn}}">{{$elem.T_D_name}}【{{$elem.T_sn}}】</td>
+                            <td name="t__d_s_name,t_id" t_id="{{$elem.T_id}}">{{$elem.T_DS_name}} 【{{$elem.T_id}}】</td>
+                            <td name="t__remark">{{$elem.T_Remark}}</td>
+
+                            <td name="t__state">
+                                {{if eq $elem.T_State 1}}
+                                不处理
+                                {{else if eq $elem.T_State 2}}
+                                已处理
+                                {{else if eq $elem.T_State 3}}
+                                未处理
+                                {{else}}
+                                删除
                                 {{end}}
 
+                            </td>
+                            <td name="t__ut">{{$elem.T_Ut}}</td>
+                            <td>
+                                <button class="layui-btn-danger layui-btn layui-btn-xs"
+                                        onclick="member_del(this,'{{$elem.Id}}','{{$elem.T_Ut}}')" href="javascript:;">
+                                    <i class="layui-icon">&#xe640;</i>删除
+                                </button>
+                                <button class="layui-btn-normal layui-btn layui-btn-xs copy-add-btn" id="copy-add-btn"
+                                        data-id="{{$elem.Id}},{{$elem.T_Ut}}" >复制添加
+                                </button>
+
+
+                            </td>
+                        </tr>
+
+                        {{end}}
+
 
                                 </tbody>
+                        <div class="layui-form layui-border-box layui-row layui-col-space10 layui-form-item">
+                            <button class="layui-btn layui-btn-sm" id="selectAll">全选</button>
+                            <button class="layui-btn layui-btn-sm" id="unselectAll">全不选</button>
+                            <button class="layui-btn layui-btn-sm" id="invertSelect">反选</button>
+                            <button class="layui-btn layui-btn-sm layui-btn-danger" id="batchDelete">批量删除</button>
+                        </div>
                             </table>
                         </div>
                         <div class="layui-card-body ">
+                            <select id="pageSizeSelector">
+                                <option value="10">10 条/页</option>
+                                <option value="20">20 条/页</option>
+                                <option value="50">50 条/页</option>
+                                <option value="100">100 条/页</option>
+                            </select>
                             <div class="page">
                                 <div>
 
@@ -119,30 +152,315 @@
 
 
                                 </div>
-                                Page:{{.Page}}-
-                                Page_size:{{.Page_size}}-
-                                cnt:{{.cnt}}
+                                当前页:{{.Page}}-
+                                总页数:{{.Page_size}}-
+                                总条数:{{.cnt}}
                             </div>
                         </div>
 
 
-                    </div>
-                </div>
             </div>
         </div>
+    </div>
+</div>
+
+</body>
+<script>
+    document.addEventListener('DOMContentLoaded', function() {
+        // 初始化pageSize,先从localStorage读取,如果没有则使用默认值
+        var pageSize = localStorage.getItem('pageSize') || 10;
+        document.getElementById('pageSizeSelector').value = pageSize; // 设置选择框的默认选中项
+        // 监听选择框变化
+        document.getElementById('pageSizeSelector').addEventListener('change', function(event) {
+            var newPageSize = event.target.value;
+            localStorage.setItem('pageSize', newPageSize); // 更新localStorage中的pageSize
+
+            // 调用函数更新分页链接
+            updatePageLinks(newPageSize);
+            sendPageSizeToBackend(newPageSize);
+        });
+        // 页面加载时执行一次,确保初始状态正确
+        updatePageLinks(pageSize);
+    });
+
+    // 更新所有分页链接的函数
+    function updatePageLinks(pageSize) {
+        console.log("Updating page links with pageSize:", pageSize);
+        var links = document.querySelectorAll('.num');
+        for (var i = 0; i < links.length; i++) {
+            var href = links[i].getAttribute('href');
+            href = href.replace(/pageSize\s*=\s*\d+/, 'pageSize=' + encodeURIComponent(pageSize)); // 替换pageSize参数
+            links[i].setAttribute('href', href+"&pageSize="+pageSize);
+        }
+    }
+    // 新增函数:向后端发送pageSize
+    function sendPageSizeToBackend(pageSize) {
+        fetch('/Device/DeviceWarning_page', { // 替换为你的后端接口地址
+            method: 'POST', // 或者根据你的后端接口要求使用'PUT'、'PATCH'等
+            headers: {
+                'Content-Type': 'application/json',
+            },
+            body: JSON.stringify({ pageSize: pageSize }), // 将pageSize作为JSON对象发送
+        })
+            .then(response => {
+                console.log('Sending pageSize to the server:', response);
+                if (!response.ok) {
+                    throw new Error(`Network response was not ok: ${response.statusText}`);
+                }
+            })
+    }
+
+    layui.use(['layer', 'laydate', 'form'],
+        function () {
+            var laydate = layui.laydate;
+            var $ = layui.jquery,
+                layer = layui.layer; //独立版的layer无需执行这一句
+            $("#selectAll").on("click", function () {
+                $(":checkbox[name='checkbox']").prop("checked", true);
+                $(".layui-form-checkbox").addClass("layui-form-checked"); // 通过类名设置全选
+                // form.render('checkbox'); // 渲染以显示变化
+            });
+            $("#unselectAll").on("click", function () {
+                $(":checkbox[name='checkbox']").prop("checked", false);
+                $(".layui-form-checkbox").removeClass("layui-form-checked"); // 通过类名设置全不选
+                // form.render('checkbox');
+            });
+            $("#invertSelect").on("click", function () {
+                $(":checkbox[name='checkbox']").each(function () {
+                    this.checked = !this.checked; // 切换每个复选框的选中状态
+                });
+                $(".layui-form-checkbox").each(function () {
+                    if ($(this).hasClass("layui-form-checked")) {
+                        $(this).removeClass("layui-form-checked");
+                    } else {
+                        $(this).addClass("layui-form-checked");
+                    }
+                });
+                // form.render('checkbox'); // 渲染以显示变化
+            });
+            $("#batchDelete").on("click", function () {
+                var selectedIds = [];
+
+                $("input[name='checkbox']:checked").each(function () {
+                    var checkbox = $(this);
+                    // selectedIds.push(this.value); // 'this.value'直接获取当前选中复选框的值
+                    var row = checkbox.closest('tr');
+
+                    var seventhColumnValue = row.find('td:eq(6)').text();
+                    console.log(seventhColumnValue);
+                    // 现在您可以根据需要使用 seventhColumnValue,例如将其与ID一起存储
+
+                    selectedIds.push({
+                        id: this.value,
+                        ut: seventhColumnValue.trim() // 去除前后空白
+                    });
+                });
 
-    </body>
-    <script>
+                if (selectedIds.length === 0) {
+                    layer.msg('请至少选择一项进行删除!', {icon: 5, time: 2000});
+                    return;
+                }
+                console.log(selectedIds);
+                layer.confirm('您确定要删除选定的 ' + selectedIds.length + ' 条数据吗?', {
+                    icon: 3,
+                    title: '确认删除',
+                    btn: ['确定', '取消']
+                }, function (index) {
+                    layer.close(index);
+
+                    $.ajax({
+                        type: "POST",
+                        url: "/Device/DeviceWarning_dels",
+                        data: JSON.stringify({selectedIds}),
+                        contentType: "application/json;charset=utf-8",
+                        dataType: "json",
+                        success: function (response) {
+                            if (response.Code === 200) {
+                                layer.msg('删除成功! 已删除 ' + selectedIds.length + ' 条数据', {icon: 1, time: 2000});
+                                // location.reload();
+                            } else {
+                                layer.msg('删除失败,请重试!', {icon: 5, time: 2000});
+                            }
+                        },
+                        error: function (xhr, status, error) {
+                            console.error("Error occurred: " + error);
+                            layer.msg('请求错误,请检查网络连接!', {icon: 5, time: 2000});
+                        }
+                    });
+                }, function () {
+                    layer.msg('已取消删除操作', {icon: 1, time: 1000});
+                });
+            });
+            // 绑定复制添加按钮的点击事件
+            $('body').on('click', '.copy-add-btn', function(){
+                var btn = $(this);
+                var row = btn.parents('tr'); // 获取当前按钮所在行
+                var checkbox = row.find('input[type="checkbox"]'); // 找到本行的复选框
+                var rowId = checkbox.val(); // 获取当前行的ID(即复选框的value)
+                var sn = row.find('td[sn]');
+                var attr = sn.attr('sn');
+                var t_id = row.find('td[t_id]');
+                var t_idV = t_id.attr('t_id');
+                console.log(attr);
+                // 复制当前行并在其下方插入
+                var newRow = row.clone(true);
+                newRow.insertAfter(row);
+
+                // 改变复制行的背景色
+                newRow.css("background-color", "#07c5ea"); // 示例颜色,您可以自定义
+
+                // 提取数据并准备发送到后端的逻辑,排除第一列(ID列)和最后一列的按钮
+                var rowData = {
+                    rowId: rowId,
+                    sn: attr,
+                    t_id: t_idV
+                };
+                newRow.find("td:not(:first):not(:last)").each(function(index, cell){
+                    // 假设除了第一列和最后一列外,其他列的数据都需要提交
+                    rowData[`column${index + 1}`] = $(cell).text().trim(); // 动态生成键名以避免覆盖
+                });
 
+                // 发送POST请求到后端
+                $.ajax({
+                    type: "POST",
+                    url: "/Device/DeviceWarningAdd", // 替换为您的后端接口地址
+                    data: JSON.stringify(rowData),
+                    contentType: "application/json;charset=utf-8",
+                    dataType: "json",
+                    success: function(response){
+                        if(response.Code === 200){
+                            layer.msg('复制并添加成功!', {icon: 1, time: 2000});
+                        } else {
+                            layer.msg('添加失败,请重试!', {icon: 5, time: 2000});
+                            newRow.remove(); // 如果后端返回失败,移除新行
+                        }
+                    },
+                    error: function(xhr, status, error){
+                        layer.msg('请求错误,请检查网络连接!', {icon: 5, time: 2000});
+                        newRow.remove(); // 发生错误时移除新行
+                    }
+                });
+            });
+            // 绑定所有可编辑列的双击事件
+            $('tbody').on('dblclick', 'td:not(:last-child)', function(e){ // 排除最后一列的按钮
+                var cell = $(this);
+                var row = cell.closest('tr'); // 获取当前行
+                var checkbox = row.find('input[type="checkbox"]'); // 找到本行的复选框
+                var rowId = checkbox.val(); // 获取当前行的ID(即复选框的value)
+                var columnName = cell.attr('name'); // 获取当前列的名称
+                var originalText = cell.text().trim(); // 保存原始文本内容
+                var T_Ut_cell = row.find('td[name="t__ut"]');
+                var T_Ut_value = T_Ut_cell.text().trim();
+
+                // 检查是否是第一列或第五列
+                if (columnName === 'T_tp_name' || columnName === 't__state') {
+                    cell.html('<select style="display:block;"></select>');
+                    var selectBox = cell.find('select');
+                    console.log(selectBox);
+                    // 调用方法动态填充下拉选项
+                    populateSelectOptions(selectBox, columnName);
+
+                    selectBox.val(originalText);
+                    selectBox.focus();
+
+                    selectBox.change(function() {
+                        var newValue = $(this).val();
+                        if (newValue !== '') {
+                            cell.html(newValue);
+                            submitUpdate(rowId, columnName, newValue,T_Ut_value);
+                            selectBox.off('change'); // 清理事件监听
+                        } else {
+                            cell.text(originalText);
+                        }
+                    });
+                }else{
+                    // 将当前单元格内容替换为<input>元素
+                    cell.html('<input type="text" class="layui-input inline-edit-input" value="' + originalText + '">');
+                    // 自动聚焦到新创建的输入框
+                    cell.find('.inline-edit-input').focus();
+                    // 监听输入框的失焦事件,以便在用户完成编辑后保存更改
+                    cell.find('.inline-edit-input').blur(function(){
+                        var newValue = $(this).val().trim();
+                        if(newValue !== ''){ // 确保输入不为空
+                            cell.html(newValue); // 用新值替换输入框
+
+                            // 提交更改到后端,包含列名
+                            submitUpdate(rowId, columnName, newValue,T_Ut_value);
+
+                        } else {
+                            // 如果用户清空了输入框,则恢复原始内容
+                            cell.text(originalText);
+                        }
+                    });
+                }
 
+            });
 
-        layui.use(['layer','laydate', 'form'],
-            function() {
-                var laydate = layui.laydate;
-                var $ = layui.jquery,
-                layer = layui.layer; //独立版的layer无需执行这一句
+            // 定义提交更新到后端的函数
+            function submitUpdate(rowId, columnName, newValue,T_Ut_value) {
+                var dataToSubmit = {
+                    rowId: rowId,
+                    columnName: columnName,
+                    newValue: newValue,
+                    T_Ut: T_Ut_value
+                };
 
-                //执行一个laydate实例
+                // 发起POST请求到后端
+                $.ajax({
+                    type: "POST",
+                    url: "/Device/DeviceWarningUpdate", // 替换为您的后端更新接口地址
+                    data: JSON.stringify(dataToSubmit),
+                    contentType: "application/json;charset=utf-8",
+                    dataType: "json",
+                    success: function(response){
+                        console.log(response);
+                        if(response.Code === 200){
+                            layer.msg('更新成功!', {icon: 1, time: 2000});
+                            location.reload()
+                        } else {
+                            layer.msg('更新失败,请重试!', {icon: 5, time: 2000});
+                        }
+                    },
+                    error: function(xhr, status, error){
+                        layer.msg('请求错误,请检查网络连接!', {icon: 5, time: 2000});
+                    }
+                });
+            }
+            function populateSelectOptions(selectBox, columnName) {
+                // 这里只是一个示例逻辑,根据实际情况动态生成或从服务端获取选项
+                switch(columnName) {
+                    case 'T_tp_name':
+                        fetch("/Device/DeviceWarning_waraning")
+                            .then(response => {
+                                if (!response.ok) {
+                                    throw new Error('Network response was not ok');
+                                }
+                                return response.json(); // 假设后端返回的是JSON格式的数据
+                            })
+                            .then(data => {
+                                // const selectBox = document.getElementById('selectBox');
+                                console.log(data.Data);
+                                // 假设data是一个对象数组,每个对象有Key和Value属性
+                                data.Data.forEach(item => {
+                                    console.log(item.Key);
+                                    selectBox.append(`<option value='${item.Key}'>${item.Value}</option>`);                                });
+                            })
+                            .catch(error => {
+                                console.error('There has been a problem with your fetch operation:', error);
+                            });
+                        break;
+                    case 't__state':
+                        selectBox.append('<option value=0>删除</option>');
+                        selectBox.append('<option value=1>不处理</option>');
+                        selectBox.append('<option value=2>已处理</option>');
+                        selectBox.append('<option value=3>未处理</option>');
+                        break;
+                    default:
+                        // 万一其他列也需要处理,可以在这里扩展
+                        break;
+                }
+            }
+            //执行一个laydate实例
                 laydate.render({
                     elem: '#Time_start', //指定元素
                     value:{{.Time_start}}
@@ -155,29 +473,27 @@
                     value:{{.Time_end}}
                 ,type: 'datetime'
             });
-
-
         });
-        /*用户-删除*/
-        function member_del(obj, id) {
-            layer.confirm('确认要删除吗?',
-            function(index) {
+    /*用户-删除*/
+    function member_del(obj, id, t_ut) {
+        layer.confirm('确认要删除吗?',
+            function (index) {
                 //发异步删除数据
                 $(obj).parents("tr").remove();
 
                 $.ajax({
                     type: 'POST',
                     url: 'DeviceWarning_Del',//发送请求
-                    data: {Id:id},
-                    success: function(result) {
+                    data: {Id: id, Ut: t_ut},
+                    success: function (result) {
                         console.log(result)
-                        if (result.Code == 200 ){
+                        if (result.Code == 200) {
                             layer.msg('已删除!', {
                                 icon: 1,
                                 time: 2000
                             });
                             window.location.reload();
-                        }else {
+                        } else {
                             layer.msg('删除失败!', {
                                 time: 2000
                             });
@@ -187,12 +503,10 @@
                 });
 
 
-
             });
-        }
-
+    }
 
 
-    </script>
+</script>
 
 </html>

+ 1 - 1
views/index.html

@@ -175,7 +175,7 @@
     });
 
 
-    console.log(aa)
+    // console.log(aa)
 
     function r_nows(id) {
         $.ajax({