Browse Source

add:信息采集,信息采集模板、标签、数据

zoie 2 months ago
parent
commit
44123c0a0b

+ 61 - 4
Nats/Nats.go

@@ -24,7 +24,7 @@ func init() {
 	// 连接Nats服务器
 	lib.Nats, err = nats.Connect("nats://" + conf.NatsServer_Url)
 	if err != nil {
-		fmt.Println("nats 连接失败!")
+		logs.Error("nats 连接失败!")
 		panic(err)
 	}
 	logs.Println("nats OK!")
@@ -132,13 +132,16 @@ func NatsInit() {
 			_ = lib.Nats.Publish(m.Reply, b)
 			return
 		}
-		fmt.Printf("ColdVerify_Server_Update_Task message: %+v\n", t_Req)
+		logs.Debug(fmt.Sprintf("ColdVerify_Server_Update_Task message: %+v\n", t_Req))
 
 		col := []string{}
 		if t_Req.T_delivery_state > 0 {
 			col = append(col, "T_delivery_state")
 		}
 
+		if t_Req.T_collection_state > 0 {
+			col = append(col, "T_collection_state")
+		}
 		if !Task.Update_Task(t_Req, col...) {
 			logs.Error("Mats", lib.FuncName(), err)
 			t_R.Code = 202
@@ -248,7 +251,7 @@ func NatsInit() {
 			_ = lib.Nats.Publish(m.Reply, b)
 			return
 		}
-		fmt.Printf("ColdVerify_Server_Add_DeviceClassList message: %+v\n", t_Req)
+		logs.Debug(fmt.Sprintf("ColdVerify_Server_Add_DeviceClassList message: %+v\n", t_Req))
 
 		Task_r, is := Task.Read_Task(t_Req.T_task_id)
 		if !is {
@@ -362,7 +365,7 @@ func NatsInit() {
 			_ = lib.Nats.Publish(m.Reply, b)
 			return
 		}
-		fmt.Printf("ColdVerify_Server_Edit_DeviceClassList message: %+v\n", t_Req)
+		logs.Debug(fmt.Sprintf("ColdVerify_Server_Edit_DeviceClassList message: %+v\n", t_Req))
 
 		Task_r, is := Task.Read_Task(t_Req.T_task_id)
 		if !is {
@@ -449,4 +452,58 @@ func NatsInit() {
 
 	})
 
+	_, _ = lib.Nats.QueueSubscribe("ColdVerify_Server_Update_Task_BySN", "Update_Task_BySN", func(m *nats.Msg) {
+		type T_Req struct {
+			T_sn              string `xml:"T_sn"`
+			T_CalibrationTime string `xml:"T_CalibrationTime"`
+		}
+		var t_Req T_Req
+		var t_R lib.JSONS
+		err := msgpack.Unmarshal(m.Data, &t_Req)
+		if err != nil {
+			logs.Error("Mats", lib.FuncName(), err)
+			t_R.Code = 202
+			t_R.Msg = err.Error()
+			b, _ := msgpack.Marshal(&t_R)
+			_ = lib.Nats.Publish(m.Reply, b)
+			return
+		}
+		logs.Debug(fmt.Sprintf("ColdVerify_Server_Update_Task_BySN message: %+v\n", t_Req))
+
+		task, err := Task.Read_Task_BySN(t_Req.T_sn)
+		if err != nil && err.Error() != "record not found" {
+			logs.Error("Mats", lib.FuncName())
+			t_R.Code = 202
+			t_R.Msg = "查询失败"
+			b, _ := msgpack.Marshal(&t_R)
+			_ = lib.Nats.Publish(m.Reply, b)
+			return
+		}
+
+		col := []string{}
+		if len(t_Req.T_CalibrationTime) > 0 {
+			task.T_CalibrationExpirationTime = t_Req.T_CalibrationTime[0:10]
+			col = append(col, "T_CalibrationExpirationTime")
+		}
+
+		if !Task.Update_Task(task, col...) {
+			logs.Error("Mats", lib.FuncName(), err)
+			t_R.Code = 202
+			t_R.Msg = err.Error()
+			b, _ := msgpack.Marshal(&t_R)
+			_ = lib.Nats.Publish(m.Reply, b)
+			return
+		}
+
+		t_R.Code = 200
+		t_R.Msg = "ok"
+
+		b, _ := msgpack.Marshal(&t_R)
+		_ = lib.Nats.Publish(m.Reply, b)
+
+		Task.Add_TaskLogs_T("nats", task.T_task_id, "任务管理", "修改校准时间", t_Req)
+		System.Add_UserLogs_T("nats", "任务管理", "修改", t_Req)
+
+	})
+
 }

+ 49 - 0
Nats/NatsServer/NatsColdApi.go

@@ -0,0 +1,49 @@
+package NatsServer
+
+import (
+	"ColdVerify_server/lib"
+	"ColdVerify_server/logs"
+	"errors"
+	"github.com/vmihailenco/msgpack/v5"
+	"time"
+)
+
+func Cold_UpdateDevice_CalibrationTime(T_sn, T_CalibrationExpirationTime string) error {
+	logs.Println("Nats =>", lib.FuncName(), T_sn, T_CalibrationExpirationTime)
+
+	type T_Req struct {
+		T_sn              string
+		T_CalibrationTime string
+	}
+	t_r := T_Req{
+		T_sn:              T_sn,
+		T_CalibrationTime: T_CalibrationExpirationTime,
+	}
+
+	b, err := msgpack.Marshal(&t_r)
+	if err != nil {
+		logs.Error("Nats =>", "msgpack Marshal err", err)
+		return err
+	}
+
+	msg, err := lib.Nats.Request("Cold_UpdateDevice_CalibrationTime", b, 3*time.Second)
+	if err != nil {
+		return err
+	}
+
+	type T_R struct {
+		Code int16       `xml:"Code"`
+		Msg  string      `xml:"Msg"`
+		Data interface{} `xml:"Data"`
+	}
+	var t_R T_R
+
+	err = msgpack.Unmarshal(msg.Data, &t_R)
+	if err != nil {
+		return err
+	}
+	if t_R.Code != 200 {
+		return errors.New(t_R.Msg)
+	}
+	return nil
+}

+ 5 - 5
Nats/NatsServer/NatsQiniu.go

@@ -29,9 +29,9 @@ func Qiniu_UploadToken(T_suffix string, T_MimeLimit string) (string, bool) {
 	// 请求-响应, 向 test3 发布一个 `help me` 请求数据,设置超时间3秒,如果有多个响应,只接收第一个收到的消息
 	msg, err := lib.Nats.Request("Qiniu_UploadToken", b, 3*time.Second)
 	if err != nil {
-		fmt.Println(err)
+		logs.Error(err)
 	} else {
-		fmt.Printf("Qiniu_UploadToken : %s\n", string(msg.Data))
+		logs.Debug(fmt.Sprintf("Qiniu_UploadToken : %s\n", string(msg.Data)))
 		return string(msg.Data), true
 	}
 
@@ -54,9 +54,9 @@ func Qiniu_UploadToken(T_suffix string, T_MimeLimit string) (string, bool) {
 //	// 请求-响应, 向 test3 发布一个 `help me` 请求数据,设置超时间3秒,如果有多个响应,只接收第一个收到的消息
 //	msg, err := lib.Nats.Request("Qiniu_UploadFile", b, 3*time.Second)
 //	if err != nil {
-//		fmt.Println(err)
+//		logs.Error(err)
 //	} else {
-//		fmt.Printf("Qiniu_UploadFile : %s\n", string(msg.Data))
+//		logs.Debug(fmt.Sprintf("Qiniu_UploadFile : %s\n", string(msg.Data)))
 //		return string(msg.Data), true
 //	}
 //
@@ -71,7 +71,7 @@ func Qiniu_UploadFile(localFile string, name string) (string, bool) {
 	if err != nil {
 		return string(msg.Data), false
 	}
-	fmt.Printf("Qiniu_Token : %s\n", string(msg.Data))
+	logs.Debug(fmt.Sprintf("Qiniu_Token : %s\n", string(msg.Data)))
 	Qiniu_cs := strings.Split(string(msg.Data), "|")
 	Qiniu_AccessKey := Qiniu_cs[0]
 	Qiniu_SecretKey := Qiniu_cs[1]

+ 10 - 1
README.md

@@ -2,4 +2,13 @@
 
 冷链验证报告系统
 
-GOOS=linux GOARCH=amd64 go build ColdVerify_server.go
+## 项目部署
+
+### 1、修改配置文件
+conf/app.conf
+
+### 2、打包linux二进制包
+GOOS=linux GOARCH=amd64 go build ColdVerify_server.go
+
+### 3、启动服务
+./ColdVerify_server

+ 4 - 4
controllers/Account.go

@@ -316,16 +316,16 @@ func (c *AccountController) UpPassword() {
 	T_oldpass := c.GetString("T_oldpass")
 	T_pass := c.GetString("T_pass")
 
-	if len(T_pass) > 0 {
-		user_r.T_pass = T_pass
-	}
-
 	if T_oldpass != user_r.T_pass {
 		c.Data["json"] = lib.JSONS{Code: 202, Msg: "旧密码错误!"}
 		c.ServeJSON()
 		return
 	}
 
+	if len(T_pass) > 0 {
+		user_r.T_pass = T_pass
+	}
+
 	if !Account.Update_Admin(user_r, "T_pass") {
 		c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改失败!"}
 		c.ServeJSON()

+ 45 - 0
controllers/Certificate.go

@@ -5,7 +5,9 @@ import (
 	"ColdVerify_server/lib"
 	"ColdVerify_server/models/Account"
 	"ColdVerify_server/models/Certificate"
+	"ColdVerify_server/models/Device"
 	"ColdVerify_server/models/System"
+	"ColdVerify_server/models/Task"
 	beego "github.com/beego/beego/v2/server/web"
 	"math"
 )
@@ -68,6 +70,49 @@ func (c *CertificateController) List() {
 	c.ServeJSON()
 	return
 }
+func (c *CertificateController) ListWithoutDeviceList() {
+	// 验证登录 User_is, User_r
+	_, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_task_id := c.GetString("T_task_id")
+	task, is := Task.Read_Task(T_task_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "任务id错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	var r_jsons lib.R_JSONS
+	var list []Certificate.Certificate_
+	var cnt int
+	certificateList, _ := Certificate.Read_Certificate_List("", "", "", "", 0, 0, 0, 0, 9999)
+	DeviceList, _ := Device.Read_DeviceClassList_OrderList(task.T_class, "", "", "", 0, 9999)
+	var deviceMap = make(map[string]struct{})
+	for _, v := range DeviceList {
+		deviceMap[v.T_id] = struct{}{}
+	}
+
+	for _, certificate := range certificateList {
+		if _, ok := deviceMap[certificate.T_layout_no]; ok {
+			continue
+		}
+		list = append(list, certificate)
+		cnt += 1
+
+	}
+
+	r_jsons.List = list
+	r_jsons.Num = cnt
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
 
 // 删除-
 func (c *CertificateController) Get() {

+ 25 - 0
controllers/DeviceClass.go

@@ -709,3 +709,28 @@ func (c *DeviceClassController) List_Template_Download() {
 	// 返回生成的 Excel 文件
 	c.Ctx.Output.Download("ofile/添加设备列表模板.xlsx")
 }
+
+func (c *DeviceClassController) List_Del_Duplication() {
+	// 验证登录 User_is, User_r
+	_, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_task_id := c.GetString("T_task_id")
+	r, is := Task.Read_Task(T_task_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "任务id 错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	Device.Del_DeviceClassList_Duplication(r.T_class)
+
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}

+ 678 - 0
controllers/InfoTemplate.go

@@ -0,0 +1,678 @@
+package controllers
+
+import (
+	"ColdVerify_server/conf"
+	"ColdVerify_server/lib"
+	"ColdVerify_server/models/Account"
+	"ColdVerify_server/models/InfoCollection"
+	"ColdVerify_server/models/System"
+	"encoding/json"
+	beego "github.com/beego/beego/v2/server/web"
+	"math"
+	"strconv"
+)
+
+type InfoTemplateController struct {
+	beego.Controller
+}
+
+// 列表 -
+func (c *InfoTemplateController) List() {
+	// 验证登录 User_is, User_r
+	_, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	var r_jsons lib.R_JSONS
+	page, _ := c.GetInt("page")
+	if page < 1 {
+		page = 1
+	}
+	page_z, _ := c.GetInt("page_z")
+	if page_z < 1 {
+		page_z = conf.Page_size
+	}
+
+	T_class, _ := c.GetInt("T_class")
+	if T_class <= 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_class Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_name := c.GetString("T_name")
+
+	var cnt int64
+	List, cnt := InfoCollection.Read_InfoTemplate_List(T_class, T_name, page, page_z)
+	page_size := math.Ceil(float64(cnt) / float64(page_z))
+	r_jsons.List = List
+	r_jsons.Page = page
+	r_jsons.Page_size = int(page_size)
+	r_jsons.Pages = lib.Func_page(int64(page), int64(page_size))
+	r_jsons.Num = int(cnt)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+
+// 添加-
+func (c *InfoTemplateController) Add() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_name := c.GetString("T_name")
+	T_sort, _ := c.GetInt("T_sort")
+	T_class, _ := c.GetInt("T_class")
+
+	var_ := InfoCollection.InfoTemplate{
+		T_class: T_class,
+		T_name:  T_name,
+		T_sort:  T_sort,
+	}
+
+	Id, is := InfoCollection.Add_InfoTemplate(var_)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加失败!"}
+		c.ServeJSON()
+		return
+	}
+	System.Add_UserLogs_T(User_r.T_uuid, "信息采集模板", "添加", var_)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Id}
+	c.ServeJSON()
+	return
+}
+
+// 修改-
+func (c *InfoTemplateController) Up() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_name := c.GetString("T_name")
+	T_sort, T_sort_err := c.GetInt("T_sort")
+
+	T_InfoTemplate_id := c.GetString("T_InfoTemplate_id")
+
+	r, is := InfoCollection.Read_InfoTemplate(T_InfoTemplate_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	// .......
+	if len(T_name) > 0 {
+		r.T_name = T_name
+	}
+
+	if T_sort_err == nil {
+		r.T_sort = T_sort
+	}
+
+	// .......
+	if !InfoCollection.Update_InfoTemplate(r, "T_name", "T_sort") {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改失败!"}
+		c.ServeJSON()
+		return
+	}
+	System.Add_UserLogs_T(User_r.T_uuid, "信息采集模板", "修改", r)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}
+
+// 删除-
+func (c *InfoTemplateController) Del() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_InfoTemplate_id := c.GetString("T_InfoTemplate_id")
+
+	r, is := InfoCollection.Read_InfoTemplate(T_InfoTemplate_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
+		c.ServeJSON()
+		return
+	}
+	if !InfoCollection.Delete_InfoTemplate(r) {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"}
+		c.ServeJSON()
+		return
+	}
+
+	mapList, _ := InfoCollection.Read_InfoTemplateMap_List(T_InfoTemplate_id, 0, 0)
+	for _, v := range mapList {
+		if vtm, is := InfoCollection.Read_InfoTemplateMap(v.T_id); is {
+			InfoCollection.Delete_InfoTemplateMap(vtm)
+		}
+	}
+
+	System.Add_UserLogs_T(User_r.T_uuid, "信息采集模板", "删除", r)
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+
+}
+
+// 复制-
+func (c *InfoTemplateController) Copy() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_InfoTemplate_id := c.GetString("T_InfoTemplate_id")
+	T_name := c.GetString("T_name")
+	r, is := InfoCollection.Read_InfoTemplate(T_InfoTemplate_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	var_ := InfoCollection.InfoTemplate{
+		T_class: r.T_class,
+		T_name:  T_name,
+		T_sort:  r.T_sort,
+	}
+
+	new_id, is := InfoCollection.Add_InfoTemplate(var_)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "复制失败!"}
+		c.ServeJSON()
+		return
+	}
+
+	mapList, _ := InfoCollection.Read_InfoTemplateMap_List(T_InfoTemplate_id, 0, 0)
+	tempMap := make(map[string]struct{})
+	idList := make([]string, len(mapList))
+	// 生成mapList长度的T_id
+	for i := 0; i < len(mapList); i++ {
+		// 生成编号
+		rand_x := 0
+		T_id := ""
+		for true {
+			T_id = lib.GetRandstring(4, "", int64(rand_x))
+			_, is = InfoCollection.Read_InfoTemplateMap(T_id)
+			if !is {
+				if _, ok := tempMap[T_id]; !ok {
+					break
+				}
+			}
+			rand_x += 1
+		}
+		tempMap[T_id] = struct{}{}
+		idList[i] = T_id
+	}
+	mapInsertList := make([]InfoCollection.InfoTemplateMap, 0)
+	for i, v := range mapList {
+		vtm := InfoCollection.InfoTemplateMap{
+			T_id:              idList[i],
+			T_InfoTemplate_id: new_id,
+			T_name:            v.T_name,
+			T_text:            v.T_text,
+			T_label:           v.T_label,
+			T_sort:            v.T_sort,
+		}
+
+		mapInsertList = append(mapInsertList, vtm)
+	}
+
+	_, is = InfoCollection.Add_InfoTemplateMapMulti(mapInsertList)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "复制失败!"}
+		c.ServeJSON()
+		return
+	}
+
+	System.Add_UserLogs_T(User_r.T_uuid, "信息采集模板", "复制", var_)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: new_id}
+	c.ServeJSON()
+	return
+}
+
+/// -----------------------------------------------------------------------------
+
+// 标签列表 -
+func (c *InfoTemplateController) Map_List() {
+	// 验证登录 User_is, User_r
+	_, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	var r_jsons lib.R_JSONS
+
+	T_sort, _ := c.GetInt("T_sort")           // 排序
+	T_flow_sort, _ := c.GetInt("T_flow_sort") // 验证流程排序
+
+	T_InfoTemplate_id := c.GetString("T_InfoTemplate_id")
+
+	var cnt int64
+	List, cnt := InfoCollection.Read_InfoTemplateMap_List(T_InfoTemplate_id, T_sort, T_flow_sort)
+	r_jsons.List = List
+	r_jsons.Num = int(cnt)
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+
+// 标签添加-
+func (c *InfoTemplateController) Map_Add() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_InfoTemplate_id := c.GetString("T_InfoTemplate_id")
+	T_name := c.GetString("T_name")
+	T_text := c.GetString("T_text")
+	T_label, _ := c.GetInt("T_label")
+	T_sort, _ := c.GetInt("T_sort")
+
+	var_ := InfoCollection.InfoTemplateMap{
+		T_InfoTemplate_id: T_InfoTemplate_id,
+		T_name:            T_name,
+		T_text:            T_text,
+		T_label:           T_label,
+		T_sort:            T_sort,
+	}
+
+	Id, is := InfoCollection.Add_InfoTemplateMap(var_)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加失败!"}
+		c.ServeJSON()
+		return
+	}
+
+	System.Add_UserLogs_T(User_r.T_uuid, "信息采集模板标签", "添加", var_)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Id}
+	c.ServeJSON()
+	return
+}
+
+// 标签修改-
+func (c *InfoTemplateController) Map_Up() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_name := c.GetString("T_name")
+	T_text := c.GetString("T_text")
+	T_label, T_label_err := c.GetInt("T_label")
+	T_sort, T_sort_err := c.GetInt("T_sort")
+
+	T_id := c.GetString("T_id")
+
+	r, is := InfoCollection.Read_InfoTemplateMap(T_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	// .......
+	if len(T_name) > 0 {
+		r.T_name = T_name
+	}
+	if len(T_text) > 0 {
+		r.T_text = T_text
+	}
+	if T_label_err == nil {
+		r.T_label = T_label
+	}
+	if T_sort_err == nil {
+		r.T_sort = T_sort
+	}
+
+	if !InfoCollection.Update_InfoTemplateMap(r, "T_name", "T_label", "T_text", "T_sort") {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改失败!"}
+		c.ServeJSON()
+		return
+	}
+
+	System.Add_UserLogs_T(User_r.T_uuid, "信息采集模板标签", "修改", r)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}
+
+// 标签删除-
+func (c *InfoTemplateController) Map_Del() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_id := c.GetString("T_id")
+
+	if r, is := InfoCollection.Read_InfoTemplateMap(T_id); is {
+		if !InfoCollection.Delete_InfoTemplateMap(r) {
+			c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"}
+			c.ServeJSON()
+			return
+		}
+		System.Add_UserLogs_T(User_r.T_uuid, "信息采集模板标签", "删除", r)
+		c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+		c.ServeJSON()
+		return
+	}
+
+	c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
+	c.ServeJSON()
+	return
+}
+
+/// -----------------------------------------------------------------------------
+
+// 标签数据列表 -
+func (c *InfoTemplateController) Map_Data_List() {
+	// 验证登录 User_is, User_r
+	_, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_InfoTemplate_id := c.GetString("T_InfoTemplate_id")
+
+	T_InfoCollection_id := c.GetString("T_InfoCollection_id")
+	_, is := InfoCollection.Read_InfoCollection(T_InfoTemplate_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_InfoCollection_id 错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	Map_List := InfoCollection.Read_InfoTemplateMap_List_For_Data(T_InfoTemplate_id)
+	Data := InfoCollection.Read_InfoTemplateMapData_List(T_InfoCollection_id, T_InfoTemplate_id, Map_List)
+
+	type JSONS struct {
+		//必须的大写开头
+		Code int16
+		Msg  string
+		Data interface{} // 泛型
+	}
+
+	c.Data["json"] = JSONS{Code: 200, Msg: "ok!", Data: Data}
+	c.ServeJSON()
+	return
+}
+
+// 添加标签数据
+func (c *InfoTemplateController) Map_Data_Pu() {
+	//验证登录 User_is, User_r
+
+	//token := c.Ctx.Request.Header.Get("user_tokey")
+	//User_r, User_is := Account.Verification_Admin(token, "")
+	//if !User_is {
+	//	c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+	//	c.ServeJSON()
+	//	return
+	//}
+
+	type RequestBody struct {
+		User_tokey          string
+		T_InfoCollection_id string
+		T_InfoTemplate_id   string
+		InfoTemplateMapData []InfoCollection.InfoTemplateMapData_R
+	}
+
+	var body RequestBody
+	data := c.Ctx.Input.RequestBody
+	err := json.Unmarshal(data, &body)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "json返序列化失败:" + err.Error()}
+		c.ServeJSON()
+	}
+
+	User_r, User_is := Account.Verification_Admin(body.User_tokey, "")
+	if !User_is {
+		System.Add_UserLogs_T(User_r.T_uuid, "验证模版标签数据", "未登录-保存", body)
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+	_, is := InfoCollection.Read_InfoCollection(body.T_InfoCollection_id)
+
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_InfoCollection_id 错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	MapDataList := make([]InfoCollection.InfoTemplateMapData, 0)
+	for _, v := range body.InfoTemplateMapData {
+		val := InfoCollection.InfoTemplateMapData{
+			T_InfoCollection_id:  body.T_InfoCollection_id,
+			T_InfoTemplate_id:    body.T_InfoTemplate_id,
+			T_InfoTemplateMap_id: v.T_InfoTemplateMap_id,
+			T_value:              v.T_value,
+		}
+		MapDataList = append(MapDataList, val)
+	}
+	ids, is := InfoCollection.AddOrUpdate_InfoTemplateMapData(MapDataList)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "保存失败"}
+		c.ServeJSON()
+		return
+	}
+	System.Add_UserLogs_T(User_r.T_uuid, "验证模版标签数据", "保存", body)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: ids}
+	c.ServeJSON()
+	return
+}
+
+func (c *InfoTemplateController) Map_Data_Copy() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_source, _ := c.GetInt("T_source")
+
+	T_flow, _ := c.GetInt("T_flow")
+
+	if T_flow == 0 && T_source == 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_source Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_copy_InfoCollection_id := c.GetString("T_copy_InfoCollection_id")
+	copy_InfoCollection, is := InfoCollection.Read_InfoCollection(T_copy_InfoCollection_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_copy_InfoCollection_id 错误!"}
+		c.ServeJSON()
+		return
+	}
+	T_paste_InfoCollection_id := c.GetString("T_paste_InfoCollection_id")
+	paste_InfoCollection, is := InfoCollection.Read_InfoCollection(T_paste_InfoCollection_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_paste_InfoCollection_id 错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	if copy_InfoCollection.T_InfoTemplate_id != paste_InfoCollection.T_InfoTemplate_id {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "仅支持相同模板间复制!"}
+		c.ServeJSON()
+		return
+	}
+
+	list := InfoCollection.Read_MapData_List(T_source, T_copy_InfoCollection_id, copy_InfoCollection.T_InfoTemplate_id)
+
+	MapDataList := make([]InfoCollection.InfoTemplateMapData, 0)
+	for _, v := range list {
+		val := InfoCollection.InfoTemplateMapData{
+			T_InfoCollection_id:  paste_InfoCollection.T_InfoCollection_id,
+			T_InfoTemplate_id:    paste_InfoCollection.T_InfoTemplate_id,
+			T_InfoTemplateMap_id: v.T_InfoTemplateMap_id,
+			T_value:              v.T_value,
+		}
+		MapDataList = append(MapDataList, val)
+	}
+	var ids []int64
+	ids, is = InfoCollection.AddOrUpdate_InfoTemplateMapData(MapDataList)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "保存失败"}
+		c.ServeJSON()
+		return
+	}
+	System.Add_UserLogs_T(User_r.T_uuid, "验证模版标签数据", "复制", MapDataList)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: ids}
+	c.ServeJSON()
+	return
+}
+
+func (c *InfoTemplateController) Class_List() {
+	// 验证登录 User_is, User_r
+	_, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: InfoCollection.Read_InfoTemplateClass_List()}
+	c.ServeJSON()
+	return
+}
+func (c *InfoTemplateController) Class_Add() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_name := c.GetString("T_name")
+	T_fid, _ := c.GetInt("T_fid")
+
+	var_ := InfoCollection.InfoTemplateClass{
+		T_name:  T_name,
+		T_fid:   T_fid,
+		T_State: 1,
+	}
+
+	Id, err := InfoCollection.Add_InfoTemplateClass(var_)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "添加失败"}
+		c.ServeJSON()
+		return
+	}
+
+	System.Add_UserLogs_T(User_r.T_uuid, "模板分类", "添加", var_)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Id}
+	c.ServeJSON()
+	return
+}
+func (c *InfoTemplateController) Class_Up() {
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_id, _ := c.GetInt("T_id")
+	T_name := c.GetString("T_name")
+
+	R_InfoTemplateToolClass, err := InfoCollection.Read_InfoTemplateClass_ById(T_id)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "T_id Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	if len(T_name) > 0 {
+		R_InfoTemplateToolClass.T_name = T_name
+	}
+
+	if is := InfoCollection.Update_InfoTemplateClass(R_InfoTemplateToolClass, "T_name"); !is {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "修改失败"}
+		c.ServeJSON()
+		return
+	}
+
+	System.Add_UserLogs_T(User_r.T_uuid, "模板分类", "修改", R_InfoTemplateToolClass)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}
+func (c *InfoTemplateController) Class_Del() {
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_id, _ := c.GetInt("T_id")
+	R_InfoTemplateToolClass, err := InfoCollection.Read_InfoTemplateClass_ById(T_id)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "T_id Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	ids := InfoCollection.ReadInfoTemplateClassIds_T_path(R_InfoTemplateToolClass.T_path)
+
+	if is := InfoCollection.Delete_InfoTemplateClass_ByIds(ids); !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"}
+		c.ServeJSON()
+		return
+	}
+
+	System.Add_UserLogs(User_r.T_uuid, "模板分类", "删除", strconv.Itoa(T_id))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}

+ 19 - 0
controllers/Task.go

@@ -360,6 +360,8 @@ func (c *TaskController) Up() {
 	T_VerifyDeviceDataEndTime := c.GetString("T_VerifyDeviceDataEndTime")     // 验证设备数据开始时间
 	T_BindDeviceDataStartTime := c.GetString("T_BindDeviceDataStartTime")     // 绑定设备数据开始时间
 	T_BindDeviceDataEndTime := c.GetString("T_BindDeviceDataEndTime")         // 绑定设备数据结束时间
+	T_sn := c.GetString("T_sn")                                               // T_sn
+	T_CalibrationExpirationTime := c.GetString("T_CalibrationExpirationTime") // 校准到期时间
 
 	T_task_id := c.GetString("T_task_id")
 	r, is := Task.Read_Task(T_task_id)
@@ -460,6 +462,23 @@ func (c *TaskController) Up() {
 		r.T_BindDeviceDataEndTime = T_BindDeviceDataEndTime
 		clos = append(clos, "T_BindDeviceDataEndTime")
 	}
+	if len(T_sn) > 0 {
+		r.T_sn = T_sn
+		clos = append(clos, "T_sn")
+	}
+	if len(T_CalibrationExpirationTime) > 0 {
+		r.T_CalibrationExpirationTime = T_CalibrationExpirationTime
+		clos = append(clos, "T_CalibrationExpirationTime")
+	}
+
+	if len(T_sn) > 0 && len(T_CalibrationExpirationTime) > 0 {
+		err := NatsServer.Cold_UpdateDevice_CalibrationTime(T_sn, T_CalibrationExpirationTime)
+		if err != nil {
+			c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+			c.ServeJSON()
+			return
+		}
+	}
 
 	// .......
 	// "T_name", "T_Show", "T_VerifyTemplate_id", "T_deadline",

+ 41 - 0
controllers/TaskData.go

@@ -1106,6 +1106,7 @@ func (c *TaskDataController) TaskData_Pdf(Time_start, Time_end, T_task_id, T_sn,
 		var textH float64 = 20 // if text height is 25px.
 		if y >= 790 {
 			addStampImage(pdf, 455, y-150)
+			// AddWatermark(Task_r, pdf)
 			pdf.AddPage()
 			y = 30
 		} else {
@@ -1138,6 +1139,7 @@ func (c *TaskDataController) TaskData_Pdf(Time_start, Time_end, T_task_id, T_sn,
 			y += 20
 		} else {
 			addStampImage(pdf, 455, y-150)
+			// AddWatermark(Task_r, pdf)
 			pdf.AddPage()
 			y = 20
 			x = 10
@@ -1155,6 +1157,7 @@ func (c *TaskDataController) TaskData_Pdf(Time_start, Time_end, T_task_id, T_sn,
 		for i := 0; i < len(dataList2); i++ {
 			if y > 790 {
 				addStampImage(pdf, 455, y-130)
+				// AddWatermark(Task_r, pdf)
 				pdf.AddPage()
 				y = pdf.GetY()
 				x = 10
@@ -1241,6 +1244,7 @@ func (c *TaskDataController) TaskData_Pdf(Time_start, Time_end, T_task_id, T_sn,
 			y += 20
 		} else {
 			addStampImage(pdf, 455, y-150)
+			// AddWatermark(Task_r, pdf)
 			pdf.AddPage()
 			y = 20
 		}
@@ -1253,6 +1257,7 @@ func (c *TaskDataController) TaskData_Pdf(Time_start, Time_end, T_task_id, T_sn,
 
 			if y >= 790 {
 				addStampImage(pdf, StampImageX-130, y-130)
+				// AddWatermark(Task_r, pdf)
 				pdf.AddPage()
 				y = pdf.GetY()
 				x = 10
@@ -1307,6 +1312,8 @@ func (c *TaskDataController) TaskData_Pdf(Time_start, Time_end, T_task_id, T_sn,
 			x = 455
 		}
 		addStampImage(pdf, x, y)
+		// AddWatermark(Task_r, pdf)
+
 	} else if y > 790 && len(dcList2) == 0 {
 		if y < 150 {
 			y = 20
@@ -1408,3 +1415,37 @@ func splitData(data []Device.DeviceClassList, threshold float64, idWidthMap map[
 
 	return result
 }
+
+func AddWatermark(task Task.Task, pdf *gopdf.GoPdf) {
+	// 设置透明度 (通过绘制透明背景实现)
+	// 使用浅色字体来模拟透明度
+	//originalX := pdf.GetX()
+	//originalY := pdf.GetY()
+	//grayColor := color.RGBA{R: 200, G: 200, B: 200, A: 255} // 浅灰色,接近透明效果
+	//pdf.SetTextColor(grayColor.R, grayColor.G, grayColor.B) // 设置字体颜色
+	//pdf.SetFontSize(50)
+	//
+	//// 设置水印的重复布局
+	//text := "水印"
+	//xOffset := 180.0 // X 坐标的偏移量
+	//yOffset := 180.0 // Y 坐标的偏移量
+	//angle := 45.0    // 旋转角度(度)
+	//
+	//// 循环绘制水印
+	//for y := 0.0; y < 780; y += yOffset { // 842 是 A4 页面高度的像素数 (72 DPI)
+	//	for x := -100.0; x < 595; x += xOffset { // 595 是 A4 页面宽度的像素数 (72 DPI)
+	//		// 保存当前的绘制状态
+	//		pdf.SetX(x)
+	//		pdf.SetY(y)
+	//		pdf.Rotate(angle, x+100, y+50) // 旋转水印
+	//		pdf.Cell(nil, text)
+	//		pdf.RotateReset() // 恢复旋转状态
+	//	}
+	//}
+	//
+	//grayColor2 := color.RGBA{R: 0, G: 0, B: 0, A: 0}           // 浅灰色,接近透明效果
+	//pdf.SetTextColor(grayColor2.R, grayColor2.G, grayColor2.B) // 设置字体颜色
+	//pdf.SetFontSize(10)
+	//pdf.SetX(originalX)
+	//pdf.SetY(originalY)
+}

+ 6 - 4
controllers/VerifyTemplate.go

@@ -529,7 +529,7 @@ func (c *VerifyTemplateController) Map_Data_Pu() {
 	data := c.Ctx.Input.RequestBody
 	err := json.Unmarshal(data, &body)
 	if err != nil {
-		c.Data["json"] = lib.JSONS{Code: 202, Msg: "json.Unmarshal is err:" + err.Error()}
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "json返序列化失败:" + err.Error()}
 		c.ServeJSON()
 	}
 
@@ -573,7 +573,7 @@ func (c *VerifyTemplateController) Map_Data_Pu() {
 		}
 		MapDataList = append(MapDataList, val)
 	}
-	ids, is := VerifyTemplate.AddOrUpdate_VerifyTemplateMapData_ADD_History(MapDataList, body.T_source)
+	ids, is := VerifyTemplate.AddOrUpdate_VerifyTemplateMapData_ADD_History(MapDataList, body.T_source, User_r.T_uuid)
 	if !is {
 		c.Data["json"] = lib.JSONS{Code: 202, Msg: "保存失败"}
 		c.ServeJSON()
@@ -645,7 +645,7 @@ func (c *VerifyTemplateController) Map_Data_Copy() {
 		MapDataList = append(MapDataList, val)
 	}
 	var ids []int64
-	ids, is = VerifyTemplate.AddOrUpdate_VerifyTemplateMapData_ADD_History(MapDataList, T_source)
+	ids, is = VerifyTemplate.AddOrUpdate_VerifyTemplateMapData_ADD_History(MapDataList, T_source, User_r.T_uuid)
 	if !is {
 		c.Data["json"] = lib.JSONS{Code: 202, Msg: "保存失败"}
 		c.ServeJSON()
@@ -676,7 +676,9 @@ func (c *VerifyTemplateController) Map_Data_History_List() {
 		return
 	}
 
-	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: VerifyTemplate.Read_VerifyTemplateMapDataHistory_History_List(T_task_id, T_source)}
+	AdminMap := Account.AdminListToMap(Account.Read_Admin_List_ALL_1())
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: VerifyTemplate.Read_VerifyTemplateMapDataHistory_History_List(T_task_id, T_source, AdminMap)}
 	c.ServeJSON()
 	return
 }

+ 234 - 0
controllers/infoCollection.go

@@ -0,0 +1,234 @@
+package controllers
+
+import (
+	"ColdVerify_server/Nats/NatsServer"
+	"ColdVerify_server/conf"
+	"ColdVerify_server/lib"
+	"ColdVerify_server/models/Account"
+	"ColdVerify_server/models/InfoCollection"
+	"ColdVerify_server/models/System"
+	beego "github.com/beego/beego/v2/server/web"
+	"math"
+)
+
+type InfoCollectionController struct {
+	beego.Controller
+}
+
+// 列表 -
+func (c *InfoCollectionController) List() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	var r_jsons lib.R_JSONS
+	page, _ := c.GetInt("page")
+	if page < 1 {
+		page = 1
+	}
+	page_z, _ := c.GetInt("page_z")
+	if page_z < 1 {
+		page_z = conf.Page_size
+	}
+
+	T_name := c.GetString("T_name")
+	T_uuid := c.GetString("T_uuid")
+
+	AdminMap := Account.AdminListToMap(Account.Read_Admin_List_ALL_1())
+
+	var T_admin string
+	if User_r.T_power > 2 {
+		T_admin = User_r.T_uuid
+	}
+
+	var cnt int
+	List, cnt := InfoCollection.Read_InfoCollection_List(T_uuid, T_admin, T_name, AdminMap, page, page_z)
+
+	page_size := math.Ceil(float64(cnt) / float64(page_z))
+	r_jsons.List = List
+	r_jsons.Page = page
+	r_jsons.Page_size = int(page_size)
+	r_jsons.Pages = lib.Func_page(int64(page), int64(page_size))
+	r_jsons.Num = cnt
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+
+// 列表 -
+func (c *InfoCollectionController) UserInfoCollectionList() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	var r_jsons lib.R_JSONS
+	page, _ := c.GetInt("page")
+	if page < 1 {
+		page = 1
+	}
+	page_z, _ := c.GetInt("page_z")
+	if page_z < 1 {
+		page_z = conf.Page_size
+	}
+
+	T_name := c.GetString("T_name")
+	AdminMap := Account.AdminListToMap(Account.Read_Admin_List_ALL_1())
+
+	var cnt int
+	List, cnt := InfoCollection.Read_UserInfoCollection_List(User_r.T_uuid, T_name, AdminMap, page, page_z)
+	page_size := math.Ceil(float64(cnt) / float64(page_z))
+	r_jsons.List = List
+	r_jsons.Page = page
+	r_jsons.Page_size = int(page_size)
+	r_jsons.Pages = lib.Func_page(int64(page), int64(page_size))
+	r_jsons.Num = cnt
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+
+// 获取-
+func (c *InfoCollectionController) Get() {
+	// 验证登录 User_is, User_r
+	_, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_InfoCollection_id := c.GetString("T_InfoCollection_id")
+	r, is := InfoCollection.Read_InfoCollection(T_InfoCollection_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: InfoCollection.InfoCollectionToInfoCollection_R(r, map[string]string{})}
+	c.ServeJSON()
+	return
+}
+
+// 添加-
+func (c *InfoCollectionController) Add() {
+
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_name := c.GetString("T_name")
+	T_uuid := c.GetString("T_uuid") // 用户uuid
+	T_InfoTemplate_class := c.GetString("T_InfoTemplate_class")
+	T_InfoTemplate_id := c.GetString("T_InfoTemplate_id")
+
+	var_ := InfoCollection.InfoCollection{
+		T_uuid:               T_uuid,
+		T_name:               T_name,
+		T_InfoTemplate_class: T_InfoTemplate_class,
+		T_InfoTemplate_id:    T_InfoTemplate_id,
+		T_status:             1,
+		T_State:              1,
+	}
+
+	T_InfoCollection_id, err := InfoCollection.Add_InfoCollection(var_)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加失败!"}
+		c.ServeJSON()
+		return
+	}
+	NatsServer.Create_Local_Table(T_InfoCollection_id)
+	System.Add_UserLogs_T(User_r.T_uuid, "信息采集管理", "添加", var_)
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_InfoCollection_id}
+	c.ServeJSON()
+	return
+}
+
+// 修改-
+func (c *InfoCollectionController) Up() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_name := c.GetString("T_name")
+	T_InfoTemplate_class := c.GetString("T_InfoTemplate_class")
+	T_InfoTemplate_id := c.GetString("T_InfoTemplate_id")
+	T_InfoCollection_id := c.GetString("T_InfoCollection_id")
+	r, is := InfoCollection.Read_InfoCollection(T_InfoCollection_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	// .......
+	clos := make([]string, 0)
+	if len(T_name) > 0 {
+		r.T_name = T_name
+		clos = append(clos, "T_name")
+	}
+	if len(T_InfoTemplate_class) > 0 {
+		r.T_InfoTemplate_class = T_InfoTemplate_class
+		clos = append(clos, "T_InfoTemplate_class")
+	}
+	if len(T_InfoTemplate_id) > 0 {
+		r.T_InfoTemplate_id = T_InfoTemplate_id
+		clos = append(clos, "T_InfoTemplate_id")
+	}
+
+	if !InfoCollection.Update_InfoCollection(r, clos...) {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改失败!"}
+		c.ServeJSON()
+		return
+	}
+	System.Add_UserLogs_T(User_r.T_uuid, "信息采集管理", "修改", r)
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}
+
+// 删除-
+func (c *InfoCollectionController) Del() {
+	// 验证登录 User_is, User_r
+	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_InfoCollection_id := c.GetString("T_InfoCollection_id")
+	if r, is := InfoCollection.Read_InfoCollection(T_InfoCollection_id); is {
+		if !InfoCollection.Delete_InfoCollection(r) {
+			c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"}
+			c.ServeJSON()
+			return
+		}
+		System.Add_UserLogs_T(User_r.T_uuid, "信息采集管理", "删除", r)
+		c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+		c.ServeJSON()
+		return
+	}
+
+	c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"}
+	c.ServeJSON()
+	return
+}

+ 8 - 3
go.mod

@@ -7,6 +7,7 @@ require (
 	github.com/beego/beego/v2 v2.0.7
 	github.com/go-sql-driver/mysql v1.7.0
 	github.com/nats-io/nats.go v1.27.0
+	github.com/pdfcpu/pdfcpu v0.8.1
 	github.com/qiniu/go-sdk/v7 v7.14.0
 	github.com/satori/go.uuid v1.2.0
 	github.com/signintech/gopdf v0.15.1
@@ -27,7 +28,10 @@ require (
 	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/gomodule/redigo v2.0.0+incompatible // indirect
 	github.com/hashicorp/golang-lru v0.5.4 // indirect
+	github.com/hhrutter/lzw v1.0.0 // indirect
+	github.com/hhrutter/tiff v1.0.1 // indirect
 	github.com/klauspost/compress v1.16.5 // indirect
+	github.com/mattn/go-runewidth v0.0.16 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
@@ -42,16 +46,17 @@ require (
 	github.com/prometheus/procfs v0.8.0 // indirect
 	github.com/richardlehane/mscfb v1.0.4 // indirect
 	github.com/richardlehane/msoleps v1.0.3 // indirect
+	github.com/rivo/uniseg v0.4.7 // indirect
 	github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
 	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
 	github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect
 	github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
 	golang.org/x/crypto v0.9.0 // indirect
-	golang.org/x/image v0.7.0 // indirect
+	golang.org/x/image v0.20.0 // indirect
 	golang.org/x/net v0.10.0 // indirect
-	golang.org/x/sync v0.1.0 // indirect
+	golang.org/x/sync v0.8.0 // indirect
 	golang.org/x/sys v0.8.0 // indirect
-	golang.org/x/text v0.9.0 // indirect
+	golang.org/x/text v0.18.0 // indirect
 	google.golang.org/protobuf v1.28.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect

+ 17 - 12
go.sum

@@ -182,6 +182,10 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
 github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/hhrutter/lzw v1.0.0 h1:laL89Llp86W3rRs83LvKbwYRx6INE8gDn0XNb1oXtm0=
+github.com/hhrutter/lzw v1.0.0/go.mod h1:2HC6DJSn/n6iAZfgM3Pg+cP1KxeWc3ezG8bBqW5+WEo=
+github.com/hhrutter/tiff v1.0.1 h1:MIus8caHU5U6823gx7C6jrfoEvfSTGtEFRiM8/LOzC0=
+github.com/hhrutter/tiff v1.0.1/go.mod h1:zU/dNgDm0cMIa8y8YwcYBeuEEveI4B0owqHyiPpJPHc=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
@@ -211,6 +215,8 @@ 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/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
+github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 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=
@@ -240,6 +246,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/pdfcpu/pdfcpu v0.8.1 h1:AiWUb8uXlrXqJ73OmiYXBjDF0Qxt4OuM281eAfkAOMA=
+github.com/pdfcpu/pdfcpu v0.8.1/go.mod h1:M5SFotxdaw0fedxthpjbA/PADytAo6wJnGH0SSBWJ7s=
 github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
@@ -289,6 +297,9 @@ github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7
 github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
 github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
 github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
 github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
@@ -367,8 +378,8 @@ golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea h1:vLCWI/yYrdEHyN2JzIzPO3aaQ
 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=
-golang.org/x/image v0.7.0 h1:gzS29xtG1J5ybQlv0PuyfE3nmc6R4qB73m6LUUmvFuw=
-golang.org/x/image v0.7.0/go.mod h1:nd/q4ef1AKKYl/4kft7g+6UyGbdiqWqTP1ZAbRoV7Rg=
+golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
+golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -388,7 +399,6 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -425,7 +435,6 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su
 golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
-golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -446,8 +455,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -495,13 +504,11 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -510,9 +517,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
+golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 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=
@@ -559,7 +565,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
 golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

+ 1 - 1
models/Account/Tokey.go

@@ -74,7 +74,7 @@ func Add_Tokey(User_uuid string) (Tokey string) {
 		if !is {
 			break
 		}
-		fmt.Print("申请 TOKEY 重复!重新生成。", Tokey)
+		logs.Info("申请 TOKEY 重复!重新生成。", Tokey)
 	}
 	Redis_Tokey_Set(Tokey, User_uuid)
 

+ 3 - 1
models/Certificate/Certificate.go

@@ -201,7 +201,9 @@ func Read_Certificate_List(T_Certificate_sn, T_layout_no, Time_start, Time_end s
 	if len(sqlOrder) > 0 {
 		sql += " ORDER BY " + strings.Join(sqlOrder, ", ")
 	}
-	sql += " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(page_z)
+	if page_z != 9999 {
+		sql += " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(page_z)
+	}
 
 	logs.Println(sql)
 	_, err = o.Raw(sql).QueryRows(&maps)

+ 24 - 0
models/Device/DeviceClassList.go

@@ -296,3 +296,27 @@ func Read_DeviceClassList_List_id(T_class_Id int) (r []DeviceClassList) {
 
 	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
+}

+ 1 - 1
models/Device/DeviceData.go

@@ -75,7 +75,7 @@ func RedisDeviceData_Set(key string, r DeviceData_New) (err error) {
 	//json序列化
 	str, err := json.Marshal(r)
 	if err != nil {
-		fmt.Print(err)
+		logs.Error(lib.FuncName(), err)
 		return
 	}
 

+ 274 - 0
models/InfoCollection/InfoCollection.go

@@ -0,0 +1,274 @@
+package InfoCollection
+
+import (
+	"ColdVerify_server/conf"
+	"ColdVerify_server/lib"
+	"ColdVerify_server/logs"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/astaxie/beego/cache"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"time"
+)
+
+// 模板
+type InfoCollection struct {
+	Id                   int    `orm:"column(ID);size(11);auto;pk"`
+	T_InfoCollection_id  string `orm:"size(256);null"`     // 信息采集ID
+	T_uuid               string `orm:"size(256);null"`     // 用户 UUID
+	T_name               string `orm:"size(256);null"`     // 标题
+	T_InfoTemplate_class string `orm:"size(256);null"`     // 模板id
+	T_InfoTemplate_id    string `orm:"size(256);null"`     // 模板id
+	T_status             int    `orm:"size(2);default(0)"` // 状态 1 待提交
+	T_State              int    `orm:"size(2);default(1)"` // 0 删除   1 正常
+
+	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 InfoCollection_R struct {
+	Id                   int
+	T_InfoCollection_id  string // 信息采集ID
+	T_uuid               string // 用户 UUID
+	T_uuid_name          string // 用户姓名
+	T_name               string // 标题
+	T_InfoTemplate_class string // 模板id
+	T_InfoTemplate_id    string // 模板id
+	T_status             int    // 状态
+	T_State              int    // 0 删除   1 正常
+	CreateTime           string
+	UpdateTime           string
+}
+
+func (t *InfoCollection) TableName() string {
+	return "info_collection" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+var redisCache_InfoCollection cache.Cache
+
+func init() {
+
+	//注册模型
+	orm.RegisterModel(new(InfoCollection))
+
+	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
+		"redis_"+"InfoCollection", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
+	logs.Println(config)
+	var err error
+	redisCache_InfoCollection, err = cache.NewCache("redis", config)
+	if err != nil || redisCache_InfoCollection == nil {
+		errMsg := "failed to init redis"
+		logs.Println(errMsg, err)
+	}
+}
+
+// -------------------------------------------------------------
+func InfoCollectionToInfoCollection_R(T InfoCollection, adminMap map[string]string) (T_r InfoCollection_R) {
+
+	T_r.T_InfoCollection_id = T.T_InfoCollection_id
+	T_r.T_uuid = T.T_uuid
+	T_r.T_name = T.T_name
+	T_r.T_InfoTemplate_class = T.T_InfoTemplate_class
+	T_r.T_InfoTemplate_id = T.T_InfoTemplate_id
+	T_r.T_status = T.T_status
+	T_r.T_State = T.T_State
+	T_r.T_uuid_name = adminMap[T.T_uuid]
+
+	T_r.UpdateTime = T.UpdateTime.Format("2006-01-02 15:04:05")
+	T_r.CreateTime = T.CreateTime.Format("2006-01-02 15:04:05")
+
+	//......
+	return T_r
+}
+
+// ---------------- Redis -------------------
+// Redis_Set(m.T_sn,m) // Redis 更新缓存
+func Redis_InfoCollection_Set(key string, r InfoCollection) (err error) {
+	//json序列化
+	str, err := json.Marshal(r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	err = redisCache_InfoCollection.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_InfoCollection_Get(key string) (r InfoCollection, is bool) {
+	if redisCache_InfoCollection.IsExist(key) {
+		logs.Println("找到key:", key)
+		v := redisCache_InfoCollection.Get(key)
+		json.Unmarshal(v.([]byte), &r)
+		return r, true
+	}
+	logs.Println("没有 找到key:", key)
+	return InfoCollection{}, false
+}
+func Redis_InfoCollection_DelK(key string) (err error) {
+	err = redisCache_InfoCollection.Delete(key)
+	return
+}
+
+// ---------------- 特殊方法 -------------------
+
+// 获取 ById
+func Read_InfoCollection_ById(id int) (r InfoCollection, is bool) {
+	o := orm.NewOrm()
+	r = InfoCollection{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_InfoCollection(T_InfoCollection_id string) (r InfoCollection, is bool) {
+	if r, is = Redis_InfoCollection_Get(T_InfoCollection_id); is == true {
+		return r, true
+	}
+
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(InfoCollection))
+	//err := qs.Filter("T_InfoCollection_id", T_InfoCollection_id).Filter("T_State", 1).One(&r)
+	err := qs.Filter("T_InfoCollection_id", T_InfoCollection_id).Filter("T_State", 1).One(&r)
+	if err != nil {
+		return r, false
+	}
+
+	Redis_InfoCollection_Set(T_InfoCollection_id, r)
+	return r, true
+}
+
+// 添加
+func Add_InfoCollection(r InfoCollection) (string, error) {
+	o := orm.NewOrm()
+	// 查询标题是否重复
+	err := o.Read(&r, "T_name")
+	if err == nil {
+		return "", errors.New("信息采集标题重复")
+	}
+
+	// 生成编号
+	rand_x := 0
+	for true {
+		r.T_InfoCollection_id = lib.GetRandstring(12, "abcdefghijklmnopqrstuvwxyz0123456789", int64(rand_x)) // 1,336,336
+		err = o.Read(&r, "T_InfoCollection_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 "", errors.New("添加失败")
+	}
+	Redis_InfoCollection_Set(r.T_InfoCollection_id, r)
+	return r.T_InfoCollection_id, nil
+}
+
+// 删除
+func Delete_InfoCollection(v InfoCollection) 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.Error(lib.FuncName(), err)
+		return false
+	}
+
+	Redis_InfoCollection_DelK(v.T_InfoCollection_id)
+	return true
+}
+
+// 修改
+func Update_InfoCollection(m InfoCollection, 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_InfoCollection_Set(m.T_InfoCollection_id, m)
+		return true
+	} else {
+		logs.Error(lib.FuncName(), err)
+	}
+	return false
+}
+
+// 获取用户信息采集列表
+func Read_UserInfoCollection_List(T_uuid string, T_name string, adminMap map[string]string, page int, page_z int) ([]InfoCollection_R, int) {
+
+	o := orm.NewOrm()
+
+	qs := o.QueryTable(new(InfoCollection))
+	var r []InfoCollection
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_name__icontains", T_name).And("T_State", 1)
+	if len(T_uuid) > 0 {
+		cond1 = cond1.And("T_uuid", T_uuid)
+	}
+
+	qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&r)
+	cnt, _ := qs.SetCond((*orm2.Condition)(cond1)).Count()
+
+	// 转换
+	var InfoCollectionList []InfoCollection_R
+	for _, v := range r {
+		InfoCollectionList = append(InfoCollectionList, InfoCollectionToInfoCollection_R(v, adminMap))
+	}
+
+	return InfoCollectionList, int(cnt)
+}
+
+// 获取信息采集列表
+func Read_InfoCollection_List(T_uuid, T_admin string, T_name string, adminMap map[string]string, page int, page_z int) ([]InfoCollection_R, int) {
+
+	o := orm.NewOrm()
+
+	qs := o.QueryTable(new(InfoCollection))
+	var r []InfoCollection
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+	cond := orm.NewCondition()
+	cond1 := cond.AndCond(cond.Or("T_name__icontains", T_name).Or("T_InfoCollection_id", T_name)).And("T_State", 1)
+	if len(T_uuid) > 0 {
+		cond1 = cond1.And("T_uuid", T_uuid)
+
+	}
+	if len(T_admin) > 0 {
+		cond1 = cond1.AndCond(cond.Or("T_scheme", T_admin).Or("T_collection", T_admin).
+			Or("T_reporting", T_admin).Or("T_delivery", T_admin))
+	}
+
+	qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&r)
+	cnt, _ := qs.SetCond((*orm2.Condition)(cond1)).Count()
+
+	// 转换
+	var InfoCollectionList []InfoCollection_R
+	for _, v := range r {
+		InfoCollectionList = append(InfoCollectionList, InfoCollectionToInfoCollection_R(v, adminMap))
+	}
+
+	return InfoCollectionList, int(cnt)
+}

+ 166 - 0
models/InfoCollection/InfoTemplate.go

@@ -0,0 +1,166 @@
+package InfoCollection
+
+import (
+	"ColdVerify_server/lib"
+	"ColdVerify_server/logs"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"time"
+)
+
+// 模板
+type InfoTemplate struct {
+	Id      int `orm:"column(ID);size(11);auto;pk"`
+	T_class int `orm:"size(8);default(0)"` // 分类
+
+	T_InfoTemplate_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_inspect   string `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 InfoTemplate_R struct {
+	T_InfoTemplate_id string `orm:"size(256);null"` // id
+	T_name            string `orm:"size(256);null"` // 标题
+	T_sort            int    `orm:"size(200);null"` // 分类
+}
+
+func (t *InfoTemplate) TableName() string {
+	return "info_template" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+
+	//注册模型
+	orm.RegisterModel(new(InfoTemplate))
+
+}
+
+// -------------------------------------------------------------
+func InfoTemplateToInfoTemplate_R(T InfoTemplate) (T_r InfoTemplate_R) {
+	T_r.T_InfoTemplate_id = T.T_InfoTemplate_id
+	T_r.T_name = T.T_name
+	T_r.T_sort = T.T_sort
+
+	return T_r
+}
+
+// ---------------- 特殊方法 -------------------
+
+// 获取 ById
+func Read_InfoTemplate_ById(id int) (r InfoTemplate, is bool) {
+	o := orm.NewOrm()
+	r = InfoTemplate{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_InfoTemplate(T_InfoTemplate_id string) (r InfoTemplate, is bool) {
+
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(InfoTemplate))
+	err := qs.Filter("T_InfoTemplate_id", T_InfoTemplate_id).One(&r)
+	if err != nil {
+		return r, false
+	}
+
+	return r, true
+}
+
+func Read_InfoTemplate_T_name(T_name string) (r InfoTemplate, is bool) {
+
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(InfoTemplate))
+	err := qs.Filter("T_name", T_name).One(&r)
+	if err != nil {
+		return r, false
+	}
+
+	return r, true
+}
+
+// 添加
+func Add_InfoTemplate(r InfoTemplate) (T_InfoTemplate_id string, is bool) {
+	o := orm.NewOrm()
+
+	// 生成编号
+	rand_x := 0
+	for true {
+		r.T_InfoTemplate_id = lib.GetRandstring(4, "", int64(rand_x)) // 1,336,336
+		err := o.Read(&r, "T_InfoTemplate_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_InfoTemplate_id, true
+}
+
+// 删除
+func Delete_InfoTemplate(v InfoTemplate) 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_InfoTemplate(m InfoTemplate, 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_InfoTemplate_List(T_class int, T_name string, page int, page_z int) ([]InfoTemplate_R, int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []InfoTemplate
+	qs := o.QueryTable(new(InfoTemplate))
+	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 InfoTemplate_r []InfoTemplate_R
+	for _, v := range r {
+		InfoTemplate_r = append(InfoTemplate_r, InfoTemplateToInfoTemplate_R(v))
+	}
+
+	return InfoTemplate_r, cnt
+}

+ 153 - 0
models/InfoCollection/InfoTemplateClass.go

@@ -0,0 +1,153 @@
+package InfoCollection
+
+import (
+	"ColdVerify_server/lib"
+	"ColdVerify_server/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 InfoTemplateClass 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 []InfoTemplateClass `orm:"-"`
+}
+
+func (t *InfoTemplateClass) TableName() string {
+	return "info_template_class" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(InfoTemplateClass))
+}
+
+type InfoTemplateClass_R struct {
+	Id       int
+	T_fid    int                 // 项目 id, InfoTemplateClass.ID
+	T_name   string              // 名称
+	T_State  int                 // 0 删除(伪删除)   1 正常(已交付)     2 开发中
+	Children []InfoTemplateClass `orm:"-"`
+}
+
+// 获取 ById
+func Read_InfoTemplateClass_ById(id int) (r InfoTemplateClass, err error) {
+	o := orm.NewOrm()
+	r = InfoTemplateClass{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_InfoTemplateClass(var_ InfoTemplateClass) (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_InfoTemplateClass_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_InfoTemplateClass(r InfoTemplateClass, 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_InfoTemplateClass_ByIds(ids []int) bool {
+	o := orm.NewOrm()
+	o.Begin()
+	for _, id := range ids {
+		v := InfoTemplateClass{Id: id, T_State: 0}
+		if _, err := o.Update(&v, "T_State"); err != nil {
+			o.Rollback()
+			return false
+		}
+	}
+
+	o.Commit()
+	return true
+}
+
+// 获取列表
+func Read_InfoTemplateClass_List() (r []InfoTemplateClass) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var map_r []InfoTemplateClass
+	qs := o.QueryTable(new(InfoTemplateClass))
+
+	cond := orm.NewCondition()
+
+	cond1 := cond.And("T_State", 1)
+
+	qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&map_r)
+
+	r = InfoTemplateClass_Call(map_r, 0)
+
+	return r
+
+}
+
+func InfoTemplateClass_Call(list []InfoTemplateClass, parentId int) []InfoTemplateClass {
+	res := make([]InfoTemplateClass, 0)
+	for _, v := range list {
+		if v.T_fid == parentId {
+			v.Children = InfoTemplateClass_Call(list, v.Id)
+			res = append(res, v)
+		}
+	}
+	return res
+}
+
+// 通过T_pid查询所有子id
+func ReadInfoTemplateClassIds_T_path(T_path string) (InfoTemplateClassIds []int) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(InfoTemplateClass))
+	var InfoTemplateClassList []InfoTemplateClass
+	qs.Filter("T_path__startswith", T_path).Filter("T_State", 1).All(&InfoTemplateClassList)
+	for _, v := range InfoTemplateClassList {
+		InfoTemplateClassIds = append(InfoTemplateClassIds, v.Id)
+	}
+	return InfoTemplateClassIds
+}

+ 202 - 0
models/InfoCollection/VerifyTemplateMap.go

@@ -0,0 +1,202 @@
+package InfoCollection
+
+import (
+	"ColdVerify_server/lib"
+	"ColdVerify_server/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 InfoTemplateMap struct {
+	Id int `orm:"column(ID);size(11);auto;pk"`
+
+	T_id              string `orm:"size(256);null"`     // 标题
+	T_InfoTemplate_id string `orm:"size(256);null"`     // 标题
+	T_label           int    `orm:"size(2);default(1)"` // 数据类型
+
+	//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)"` // 排序
+
+	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 InfoTemplateMap_R struct {
+	T_id    string
+	T_label int    // 来源
+	T_name  string // 标签名称
+	T_text  string // 描述
+	T_sort  int    // 排序
+}
+
+func (t *InfoTemplateMap) TableName() string {
+	return "info_template_map" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+
+	//注册模型
+	orm.RegisterModel(new(InfoTemplateMap))
+
+}
+
+// -------------------------------------------------------------
+func InfoTemplateMapToInfoTemplateMap_R(T InfoTemplateMap) (T_r InfoTemplateMap_R) {
+	T_r.T_id = T.T_id
+	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
+	return T_r
+}
+
+// ---------------- 特殊方法 -------------------
+
+// 获取 ById
+func Read_InfoTemplateMap_ById(id int) (r InfoTemplateMap, is bool) {
+	o := orm.NewOrm()
+	r = InfoTemplateMap{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_InfoTemplateMap(T_id string) (r InfoTemplateMap, is bool) {
+
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(InfoTemplateMap))
+	err := qs.Filter("T_id", T_id).One(&r)
+	if err != nil {
+		return r, false
+	}
+
+	return r, true
+}
+
+// 添加
+func Add_InfoTemplateMap(r InfoTemplateMap) (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_InfoTemplateMapMulti(r []InfoTemplateMap) (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_InfoTemplateMap(v InfoTemplateMap) 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_InfoTemplateMap(m InfoTemplateMap, 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_InfoTemplateMap_List(T_InfoTemplate_id string, T_sort, T_flow_sort int) ([]InfoTemplateMap_R, int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []InfoTemplateMap
+	qs := o.QueryTable(new(InfoTemplateMap))
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_InfoTemplate_id", T_InfoTemplate_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 InfoTemplateMap_r []InfoTemplateMap_R
+	for _, v := range r {
+		InfoTemplateMap_r = append(InfoTemplateMap_r, InfoTemplateMapToInfoTemplateMap_R(v))
+	}
+
+	return InfoTemplateMap_r, cnt
+}
+
+func Read_InfoTemplateMap_List_For_Data(T_InfoTemplate_id string) []InfoTemplateMap {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []InfoTemplateMap
+	qs := o.QueryTable(new(InfoTemplateMap))
+
+	cond := orm.NewCondition()
+	cond = cond.And("T_InfoTemplate_id", T_InfoTemplate_id)
+	qs.SetCond((*orm2.Condition)(cond)).OrderBy("T_sort").All(&r)
+
+	return r
+}
+
+func InfoTemplateMap_RToMap(T []InfoTemplateMap_R) map[string]string {
+	maps := make(map[string]string, len(T))
+	for _, v := range T {
+		maps[v.T_id] = v.T_name
+	}
+	return maps
+}

+ 205 - 0
models/InfoCollection/VerifyTemplateMapData.go

@@ -0,0 +1,205 @@
+package InfoCollection
+
+import (
+	"ColdVerify_server/lib"
+	"ColdVerify_server/logs"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"time"
+)
+
+// 模板
+type InfoTemplateMapData struct {
+	Id int `orm:"column(ID);size(11);auto;pk"`
+	//T_source             int    `orm:"size(2);"`             // 来源 0-所有 1-方案 2-报告 3-表单
+	T_InfoCollection_id  string `orm:"index,size(256);null"` // 信息采集id
+	T_InfoTemplate_id    string `orm:"index,size(256);null"` // 模板id
+	T_InfoTemplateMap_id string `orm:"index,size(256);null"` // 标签id
+	T_value              string `orm:"size(1024);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 InfoTemplateMapData_R struct {
+	T_id                 int
+	T_InfoTemplateMap_id string // 标签id
+	T_label              int    //
+	T_name               string // 标题
+	T_text               string // 标题
+	T_value              string //
+}
+
+func (t *InfoTemplateMapData) TableName() string {
+	return "info_template_map_data" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(InfoTemplateMapData))
+
+}
+
+// -------------------------------------------------------------
+func InfoTemplateMapToInfoTemplateMapData_R(T InfoTemplateMap) (T_r InfoTemplateMapData_R) {
+	T_r.T_InfoTemplateMap_id = T.T_id
+	T_r.T_label = T.T_label
+	T_r.T_name = T.T_name
+	T_r.T_text = T.T_text
+
+	T_r.T_value = ""
+	return T_r
+}
+
+func InfoTemplateMapDataToInfoTemplateMapData_R(T InfoTemplateMap, InfoTemplateMapData map[string]InfoTemplateMapData) (T_r InfoTemplateMapData_R) {
+	T_r.T_InfoTemplateMap_id = T.T_id
+	T_r.T_label = T.T_label
+	T_r.T_name = T.T_name
+	T_r.T_text = T.T_text
+
+	T_r.T_value = ""
+	if v, ok := InfoTemplateMapData[T.T_id]; ok {
+		T_r.T_value = v.T_value
+	}
+	return T_r
+}
+
+// ---------------- 特殊方法 -------------------
+// 添加
+func AddOrUpdate_InfoTemplateMapData(List []InfoTemplateMapData) (ids []int64, is bool) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(InfoTemplateMapData))
+	o.Begin()
+	for _, v := range List {
+		var r InfoTemplateMapData
+		// 创建验证模版数据,有则更新,没有则创建
+		err := qs.Filter("T_InfoCollection_id", v.T_InfoCollection_id).Filter("T_InfoTemplate_id", v.T_InfoTemplate_id).Filter("T_InfoTemplateMap_id", v.T_InfoTemplateMap_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.Id = r.Id
+			//_, err = o.Update(&v, "T_flow_sort", "T_max_time", "T_min_time", "T_value")
+			_, err = o.QueryTable(new(InfoTemplateMapData)).Filter("T_InfoCollection_id", v.T_InfoCollection_id).Filter("T_InfoTemplate_id", v.T_InfoTemplate_id).
+				Filter("T_InfoTemplateMap_id", v.T_InfoTemplateMap_id).Update(orm2.Params{"T_value": v.T_value})
+			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_InfoTemplateMapData_List(T_InfoCollection_id, T_InfoTemplate_id string, Map_List []InfoTemplateMap) []InfoTemplateMapData_R {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []InfoTemplateMapData
+	qs := o.QueryTable(new(InfoTemplateMapData))
+	cond := orm.NewCondition()
+
+	cond1 := cond.And("T_InfoCollection_id", T_InfoCollection_id).And("T_InfoTemplate_id", T_InfoTemplate_id)
+
+	qs.SetCond((*orm2.Condition)(cond1)).All(&r)
+
+	if len(r) == 0 {
+		// 转换
+		var InfoTemplateMapData_r []InfoTemplateMapData_R
+		for k, v := range Map_List {
+			Data_r := InfoTemplateMapToInfoTemplateMapData_R(v)
+			Data_r.T_id = k
+			InfoTemplateMapData_r = append(InfoTemplateMapData_r, Data_r)
+		}
+
+		return InfoTemplateMapData_r
+	}
+
+	// 转换
+	var InfoTemplateMapData_r []InfoTemplateMapData_R
+	for k, v := range Map_List {
+		Data_r := InfoTemplateMapDataToInfoTemplateMapData_R(v, InfoTemplateMapDataToMap(r))
+		Data_r.T_id = k
+		InfoTemplateMapData_r = append(InfoTemplateMapData_r, Data_r)
+	}
+	return InfoTemplateMapData_r
+}
+
+// 获取列表
+func Read_MapData_List(T_source int, T_InfoCollection_id, T_InfoTemplate_id string) []InfoTemplateMapData {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var r []InfoTemplateMapData
+	qs := o.QueryTable(new(InfoTemplateMapData))
+	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_InfoCollection_id", T_InfoCollection_id).And("T_InfoTemplate_id", T_InfoTemplate_id)
+
+	qs.SetCond((*orm2.Condition)(cond1)).All(&r)
+
+	return r
+}
+
+func InfoTemplateMapDataToMap(T []InfoTemplateMapData) map[string]InfoTemplateMapData {
+	maps := make(map[string]InfoTemplateMapData, len(T))
+	for _, v := range T {
+		if _, ok := maps[v.T_InfoTemplateMap_id]; ok {
+			continue
+		}
+		maps[v.T_InfoTemplateMap_id] = v
+	}
+	return maps
+}
+
+// 清除T_value数据
+func Clear_InfoTemplateMapData_T_value(T_InfoCollection_id, T_InfoTemplate_id, T_InfoTemplateMap_id string) (err error) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(InfoTemplateMapData))
+
+	var r InfoTemplateMapData
+	// 创建验证模版数据,有则更新,没有则创建
+	err = qs.Filter("T_InfoCollection_id", T_InfoCollection_id).Filter("T_InfoTemplate_id", T_InfoTemplate_id).Filter("T_InfoTemplateMap_id", T_InfoTemplateMap_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
+}

+ 81 - 53
models/Task/Task.go

@@ -50,65 +50,72 @@ type Task struct {
 
 	T_step int `orm:"size(2);default(-1)"` // 验证步骤
 
+	T_sn                        string `orm:"size(256);null"` // sn
+	T_CalibrationExpirationTime string `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 Task_R struct {
-	T_task_id              string    // id
-	T_name                 string    // 标题
-	T_doc1                 string    // 封面
-	T_pdf1                 string    // 封面
-	T_doc2                 string    // 报告
-	T_pdf2                 string    // 报告
-	T_doc3                 string    // 证书
-	T_pdf3                 string    // 证书
-	T_Show                 int       // 公开/隐藏
-	T_Visit                int       // 浏览量
-	T_State                int       // 0    1
-	T_scheme_state         int       // 实施方案 状态 0 未完成 1 已完成
-	T_collection_state     int       // 数据采集 状态 0 未完成 1 已完成
-	T_reporting_state      int       // 报告编写 状态 0 未完成 1 已完成
-	T_delivery_state       int       // 交付审核 状态 0 未完成 1 已完成
-	T_VerifyDeviceDataTime [2]string // 验证设备数据开始-结束时间
-	T_BindDeviceDataTime   [2]string // 绑定设备数据开始-结束时间
-	CreateTime             string
-	UpdateTime             string
+	T_task_id                   string    // id
+	T_name                      string    // 标题
+	T_doc1                      string    // 封面
+	T_pdf1                      string    // 封面
+	T_doc2                      string    // 报告
+	T_pdf2                      string    // 报告
+	T_doc3                      string    // 证书
+	T_pdf3                      string    // 证书
+	T_Show                      int       // 公开/隐藏
+	T_Visit                     int       // 浏览量
+	T_State                     int       // 0    1
+	T_scheme_state              int       // 实施方案 状态 0 未完成 1 已完成
+	T_collection_state          int       // 数据采集 状态 0 未完成 1 已完成
+	T_reporting_state           int       // 报告编写 状态 0 未完成 1 已完成
+	T_delivery_state            int       // 交付审核 状态 0 未完成 1 已完成
+	T_VerifyDeviceDataTime      [2]string // 验证设备数据开始-结束时间
+	T_BindDeviceDataTime        [2]string // 绑定设备数据开始-结束时间
+	T_sn                        string    // sn
+	T_CalibrationExpirationTime string    // 校准到期时间
+	CreateTime                  string
+	UpdateTime                  string
 }
 
 type Task_ struct {
-	Id                     int
-	T_class                int       // 分类ID
-	T_task_id              string    // 任务ID
-	T_uuid                 string    // 用户 UUID
-	T_user_name            string    // 用户 UUID
-	T_name                 string    // 标题
-	T_VerifyTemplate_class string    // 任务模板id
-	T_VerifyTemplate_id    string    // 任务模板id
-	T_deadline             string    // 截止时间
-	T_scheme               string    // 实施方案 负责人UUID
-	T_collection           string    // 数据采集 负责人UUID
-	T_reporting            string    // 报告编写 负责人UUID
-	T_delivery             string    // 交付审核 负责人UUID
-	T_scheme_state         int       // 实施方案 状态 0 未完成 1 已完成
-	T_collection_state     int       // 数据采集 状态 0 未完成 1 已完成
-	T_reporting_state      int       // 报告编写 状态 0 未完成 1 已完成
-	T_delivery_state       int       // 交付审核 状态 0 未完成 1 已完成
-	T_scheme_name          string    // 实施方案 负责人姓名
-	T_collection_name      string    // 数据采集 负责人姓名
-	T_reporting_name       string    // 报告编写 负责人姓名
-	T_delivery_name        string    // 交付审核 负责人姓名
-	T_VerifyDeviceDataTime [2]string // 验证设备数据开始-结束时间
-	T_BindDeviceDataTime   [2]string // 绑定设备数据开始-结束时间
-	T_doc1                 string    // 封面
-	T_pdf1                 string    // 封面
-	T_doc2                 string    // 报告
-	T_pdf2                 string    // 报告
-	T_doc3                 string    // 证书
-	T_pdf3                 string    // 证书
-	T_Show                 int       // 0 公开 1 隐藏
-	T_Visit                int       // 浏览量
-	T_State                int       // 0 删除 1 正常
+	Id                          int
+	T_class                     int       // 分类ID
+	T_task_id                   string    // 任务ID
+	T_uuid                      string    // 用户 UUID
+	T_user_name                 string    // 用户 UUID
+	T_name                      string    // 标题
+	T_VerifyTemplate_class      string    // 任务模板id
+	T_VerifyTemplate_id         string    // 任务模板id
+	T_deadline                  string    // 截止时间
+	T_scheme                    string    // 实施方案 负责人UUID
+	T_collection                string    // 数据采集 负责人UUID
+	T_reporting                 string    // 报告编写 负责人UUID
+	T_delivery                  string    // 交付审核 负责人UUID
+	T_scheme_state              int       // 实施方案 状态 0 未完成 1 已完成
+	T_collection_state          int       // 数据采集 状态 0 未完成 1 已完成
+	T_reporting_state           int       // 报告编写 状态 0 未完成 1 已完成
+	T_delivery_state            int       // 交付审核 状态 0 未完成 1 已完成
+	T_scheme_name               string    // 实施方案 负责人姓名
+	T_collection_name           string    // 数据采集 负责人姓名
+	T_reporting_name            string    // 报告编写 负责人姓名
+	T_delivery_name             string    // 交付审核 负责人姓名
+	T_VerifyDeviceDataTime      [2]string // 验证设备数据开始-结束时间
+	T_BindDeviceDataTime        [2]string // 绑定设备数据开始-结束时间
+	T_doc1                      string    // 封面
+	T_pdf1                      string    // 封面
+	T_doc2                      string    // 报告
+	T_pdf2                      string    // 报告
+	T_doc3                      string    // 证书
+	T_pdf3                      string    // 证书
+	T_Show                      int       // 0 公开 1 隐藏
+	T_Visit                     int       // 浏览量
+	T_State                     int       // 0 删除 1 正常
+	T_sn                        string    // sn
+	T_CalibrationExpirationTime string    // 校准到期时间
 }
 
 func (t *Task) TableName() string {
@@ -155,6 +162,9 @@ func TaskToTask_R(T Task) (T_r Task_R) {
 	T_r.UpdateTime = T.UpdateTime.Format("2006-01-02 15:04:05")
 	T_r.CreateTime = T.CreateTime.Format("2006-01-02 15:04:05")
 
+	T_r.T_sn = T.T_sn
+	T_r.T_CalibrationExpirationTime = T.T_CalibrationExpirationTime
+
 	//......
 	return T_r
 }
@@ -193,6 +203,9 @@ func TaskToTask_(T Task, userMap, adminMap map[string]string) (T_ Task_) {
 	T_.T_Visit = T.T_Visit
 	T_.T_State = T.T_State
 
+	T_.T_sn = T.T_sn
+	T_.T_CalibrationExpirationTime = T.T_CalibrationExpirationTime
+
 	//......
 	return T_
 }
@@ -430,8 +443,7 @@ func Read_Task_List(T_uuid, T_admin string, T_name string, T_company_list []stri
 		offset = int64((page - 1) * page_z)
 	}
 	cond := orm.NewCondition()
-	//cond1 := cond.And("T_name__icontains", T_name).And("T_State", 1)
-	cond1 := cond.AndCond(cond.Or("T_name__icontains", T_name).Or("T_task_id", T_name)).And("T_State", 1)
+	cond1 := cond.AndCond(cond.Or("T_name__icontains", T_name).Or("T_task_id__icontains", T_name)).And("T_State", 1)
 	if len(T_uuid) > 0 {
 		cond1 = cond1.And("T_uuid", T_uuid)
 
@@ -498,3 +510,19 @@ func Read_Task_List_Time(page int, T_sn string, T_Title string, Time_start_ stri
 
 	return Task_r, cnt
 }
+
+func Read_Task_BySN(sn string) (r Task, err error) {
+	if task, is := Redis_Task_Get(sn); is == true {
+		return task, nil
+	}
+
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(Task))
+	err = qs.Filter("T_sn", sn).Filter("T_State", 1).One(&r)
+	if err != nil {
+		return r, err
+	}
+
+	Redis_Task_Set(sn, r)
+	return r, nil
+}

+ 2 - 2
models/Task/TaskLogs.go

@@ -1,8 +1,8 @@
 package Task
 
 import (
+	"ColdVerify_server/logs"
 	"encoding/json"
-	"fmt"
 	_ "github.com/astaxie/beego/cache/redis"
 	"github.com/beego/beego/v2/adapter/orm"
 	orm2 "github.com/beego/beego/v2/client/orm"
@@ -57,7 +57,7 @@ func Add_TaskLogs_T(T_uuid string, T_task_id string, Logs_class string, Logs_Tit
 	o := orm.NewOrm()
 	jsonStu, err := json.Marshal(Logs_Txt_T)
 	if err != nil {
-		fmt.Println("Add_TaskLogs_T JSON ,err=", err)
+		logs.Error("Add_TaskLogs_T JSON ,err=", err)
 	}
 	m := TaskLogs{T_uuid: T_uuid, T_task_id: T_task_id, Logs_class: Logs_class, Logs_Title: Logs_Title, Logs_Txt: string(jsonStu)}
 	o.Insert(&m)

+ 2 - 2
models/VerifyTemplate/VerifyTemplateClass.go

@@ -63,12 +63,12 @@ func Add_VerifyTemplateClass(var_ VerifyTemplateClass) (id int64, err error) {
 
 	T_Path := "/0/" + strconv.Itoa(int(id)) + "/"
 	if var_.T_fid != 0 {
-		Company_r, err := Read_VerifyTemplateClass_ById(var_.T_fid)
+		class_r, err := Read_VerifyTemplateClass_ById(var_.T_fid)
 		if err != nil {
 			o.Rollback()
 			return id, err
 		}
-		T_Path = Company_r.T_path + strconv.Itoa(int(id)) + "/"
+		T_Path = class_r.T_path + strconv.Itoa(int(id)) + "/"
 	}
 
 	var_.Id = int(id)

+ 10 - 3
models/VerifyTemplate/VerifyTemplateMapData.go

@@ -23,7 +23,7 @@ type VerifyTemplateMapData struct {
 	T_max_time  int `orm:"size(256);null"`     // 验证流程最大时间
 	T_min_time  int `orm:"size(256);null"`     // 验证流程最小时间
 
-	T_start_time int `orm:"size(256);null"` // 开始时间 app
+	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 保存时都会对时间自动更新
@@ -42,7 +42,7 @@ type VerifyTemplateMapData_R struct {
 	T_max_time  int // 验证流程最大时间
 	T_min_time  int // 验证流程最小时间
 
-	T_start_time int // 开始时间 app
+	T_start_time int64 // 开始时间 app
 }
 
 func (t *VerifyTemplateMapData) TableName() string {
@@ -91,7 +91,7 @@ func VerifyTemplateMapDataToVerifyTemplateMapData_R(T VerifyTemplateMap, VerifyT
 }
 
 // 添加或更新模板数据 并添加历史数据
-func AddOrUpdate_VerifyTemplateMapData_ADD_History(List []VerifyTemplateMapData, T_source int) (ids []int64, is bool) {
+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()
@@ -118,6 +118,9 @@ func AddOrUpdate_VerifyTemplateMapData_ADD_History(List []VerifyTemplateMapData,
 
 		// 更新验证模版数据
 		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).
@@ -137,6 +140,7 @@ func AddOrUpdate_VerifyTemplateMapData_ADD_History(List []VerifyTemplateMapData,
 			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,
@@ -185,6 +189,9 @@ func AddOrUpdate_VerifyTemplateMapData(List []VerifyTemplateMapData) (ids []int6
 
 		// 更新验证模版数据
 		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).

+ 19 - 5
models/VerifyTemplate/VerifyTemplateMapDataHistory.go

@@ -14,10 +14,11 @@ 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:"index,size(256);null"` // 模板id
-	T_VerifyTemplateMap_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:"size(1024);null"`      // 内容
 
+	T_uuid          string `orm:"index,size(256);null"` // 提交人
 	T_time          string `orm:"index,size(256);null"` // 提交时间
 	T_submit_source int    `orm:"size(4);"`             // 提交来源
 	// 验证流程
@@ -158,13 +159,26 @@ func VerifyTemplateMapDataHistoryToMap(T []VerifyTemplateMapDataHistory) map[str
 	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) (lists orm2.ParamsList) {
+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 orm2.ParamsList
-	_, err := o.Raw("SELECT DISTINCT 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).ValuesFlat(&pl_lists)
+
+	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

+ 6 - 5
routers/Certificate.go

@@ -7,11 +7,12 @@ import (
 
 func init() {
 	// - 校准证书
-	beego.Router("/Certificate/List", &controllers.CertificateController{}, "*:List") // 校准证书列表
-	beego.Router("/Certificate/Get", &controllers.CertificateController{}, "*:Get")   // 获取最新校准证书
-	beego.Router("/Certificate/Add", &controllers.CertificateController{}, "*:Add")   // 添加校准证书
-	beego.Router("/Certificate/Edit", &controllers.CertificateController{}, "*:Edit") // 编辑校准证书
-	beego.Router("/Certificate/Del", &controllers.CertificateController{}, "*:Del")   // 删除校准证书
+	beego.Router("/Certificate/List", &controllers.CertificateController{}, "*:List")                                   // 校准证书列表
+	beego.Router("/Certificate/Get", &controllers.CertificateController{}, "*:Get")                                     // 获取最新校准证书
+	beego.Router("/Certificate/Add", &controllers.CertificateController{}, "*:Add")                                     // 添加校准证书
+	beego.Router("/Certificate/Edit", &controllers.CertificateController{}, "*:Edit")                                   // 编辑校准证书
+	beego.Router("/Certificate/Del", &controllers.CertificateController{}, "*:Del")                                     // 删除校准证书
+	beego.Router("/Certificate/ListWithoutDeviceList", &controllers.CertificateController{}, "*:ListWithoutDeviceList") // 校准证书除开设备列表
 	// - 校准证书pdf
 	beego.Router("/Certificate/Pdf_List", &controllers.CertificateController{}, "*:Pdf_List") // 校准证书pdf列表
 	beego.Router("/Certificate/Pdf_Add", &controllers.CertificateController{}, "*:Pdf_Add")   // 添加校准证书pdf

+ 1 - 0
routers/Device.go

@@ -21,6 +21,7 @@ func init() {
 	beego.Router("/DeviceClassList/Del", &controllers.DeviceClassController{}, "*:List_Del")                             // 删除设备分类列表
 	beego.Router("/DeviceClassList/Copy", &controllers.DeviceClassController{}, "*:List_Copy")                           // 复制
 	beego.Router("/DeviceClassList/Template_Download", &controllers.DeviceClassController{}, "*:List_Template_Download") // 添加设备列表模板
+	beego.Router("/DeviceClassList/Del_Duplication", &controllers.DeviceClassController{}, "*:List_Del_Duplication")     // 删除重复设备列表
 
 	// - 设备管理
 	beego.Router("/Device/List", &controllers.DeviceController{}, "*:List") // 设别列表

+ 33 - 0
routers/InfoCollection.go

@@ -0,0 +1,33 @@
+package routers
+
+import (
+	"ColdVerify_server/controllers"
+	beego "github.com/beego/beego/v2/server/web"
+)
+
+func init() {
+	beego.Router("/InfoCollection/List", &controllers.InfoCollectionController{}, "*:List") // 信息采集列表
+	beego.Router("/InfoCollection/Get", &controllers.InfoCollectionController{}, "*:Get")   // 获取信息采集
+	beego.Router("/InfoCollection/Add", &controllers.InfoCollectionController{}, "*:Add")   // 添加信息采集
+	beego.Router("/InfoCollection/Up", &controllers.InfoCollectionController{}, "*:Up")     // 编辑信息采集
+	beego.Router("/InfoCollection/Del", &controllers.InfoCollectionController{}, "*:Del")   // 删除信息采集
+
+	beego.Router("/InfoTemplate/Class_List", &controllers.InfoTemplateController{}, "*:Class_List") // 分类列表
+	beego.Router("/InfoTemplate/Class_Add", &controllers.InfoTemplateController{}, "*:Class_Add")   // 分类添加
+	beego.Router("/InfoTemplate/Class_Up", &controllers.InfoTemplateController{}, "*:Class_Up")     // 分类修改
+	beego.Router("/InfoTemplate/Class_Del", &controllers.InfoTemplateController{}, "*:Class_Del")   // 分类删除
+
+	beego.Router("/InfoTemplate/List", &controllers.InfoTemplateController{}, "*:List") // 模板列表
+	beego.Router("/InfoTemplate/Add", &controllers.InfoTemplateController{}, "*:Add")   // 模板添加
+	beego.Router("/InfoTemplate/Up", &controllers.InfoTemplateController{}, "*:Up")     // 模板编辑
+	beego.Router("/InfoTemplate/Del", &controllers.InfoTemplateController{}, "*:Del")   // 模板修改
+	beego.Router("/InfoTemplate/Copy", &controllers.InfoTemplateController{}, "*:Copy") // 模板复制
+
+	beego.Router("/InfoTemplate/Map_List", &controllers.InfoTemplateController{}, "*:Map_List") // 标签列表
+	beego.Router("/InfoTemplate/Map_Add", &controllers.InfoTemplateController{}, "*:Map_Add")   // 标签添加
+	beego.Router("/InfoTemplate/Map_Up", &controllers.InfoTemplateController{}, "*:Map_Up")     // 标签修改
+	beego.Router("/InfoTemplate/Map_Del", &controllers.InfoTemplateController{}, "*:Map_Del")   // 标签删除
+
+	beego.Router("/InfoTemplateMapData/List", &controllers.InfoTemplateController{}, "*:Map_Data_List") // 标签数据列表
+	beego.Router("/InfoTemplateMapData/Pu", &controllers.InfoTemplateController{}, "*:Map_Data_Pu")     // 添加标签数据
+}