Browse Source

first commit

siked 9 months ago
commit
9e51860cd3
100 changed files with 12680 additions and 0 deletions
  1. 8 0
      .idea/.gitignore
  2. 9 0
      .idea/ColdP_server.iml
  3. 21 0
      .idea/deployment.xml
  4. 8 0
      .idea/modules.xml
  5. 6 0
      .idea/vcs.xml
  6. BIN
      ColdP_server
  7. 46 0
      Cold_server.go
  8. 8 0
      Z_Build.bat
  9. 28 0
      conf/app.conf
  10. 25 0
      conf/config.go
  11. 108 0
      controllers/CommonsController.go
  12. 247 0
      controllers/DataController.go
  13. 448 0
      controllers/DataGeneratorController.go
  14. 416 0
      controllers/DeviceController.go
  15. 182 0
      controllers/Handle/DeviceParameter.go
  16. 1 0
      controllers/Handle/WarningHandle.go
  17. 119 0
      controllers/MqttServer/MqttHandle.go
  18. 152 0
      controllers/MqttServer/MqttServerStruct.go
  19. 145 0
      controllers/MqttServer/MqttServer_old.txt
  20. 179 0
      controllers/MqttServer/MqttServer_oldf2.txt
  21. 90 0
      controllers/MqttServer/MqttServev2.go
  22. 62 0
      controllers/MqttServer/MqttServevStructv2.go
  23. 183 0
      controllers/WebSocket/WebSocket.go
  24. 61 0
      controllers/lib/Aes.go
  25. 44 0
      controllers/lib/Message.go
  26. 63 0
      controllers/lib/Qiniu.go
  27. 51 0
      controllers/lib/Voice.go
  28. 554 0
      controllers/lib/lib.go
  29. BIN
      debug.exe
  30. BIN
      dev.exe
  31. 70 0
      go.mod
  32. 436 0
      go.sum
  33. 1 0
      lastupdate.tmp
  34. 65 0
      logs/LogPrintln.go
  35. 0 0
      logs/access.log
  36. 155 0
      logs/logx/logx.2023-09-19.001.log
  37. 138 0
      logs/logx/logx.2023-09-20.001.log
  38. 6 0
      logs/logx/logx.log
  39. 315 0
      models/Account/Admin.go
  40. 63 0
      models/Account/Tokey.go
  41. 208 0
      models/Company/CompanyClass.go
  42. 294 0
      models/Company/CompanyNotice.go
  43. 335 0
      models/Device/Device.go
  44. 535 0
      models/Device/DeviceData.go
  45. 226 0
      models/Device/DeviceParameter.go
  46. 1016 0
      models/Device/DeviceSensor.go
  47. 249 0
      models/Device/DeviceSensorParameter.go
  48. 33 0
      models/GTime.go
  49. 82 0
      models/Product/ProductType.go
  50. 30 0
      models/Product/ProductUpgrade.go
  51. 896 0
      models/Warning/Warning.go
  52. 33 0
      models/Warning/WarningHandle.go
  53. 131 0
      models/Warning/WarningRate.go
  54. 244 0
      models/Warning/WarningSand.go
  55. 218 0
      models/Warning/WarningType.go
  56. 11 0
      monitor.sh
  57. 56 0
      nats/Nats.go
  58. 406 0
      nohup.out
  59. BIN
      ofile/20220118154606.xlsx
  60. 19 0
      routers/Admin.go
  61. 45 0
      routers/DataRouter.go
  62. 35 0
      routers/DeviceRouter.go
  63. 2 0
      run.sh
  64. BIN
      static/20240523140020.xlsx
  65. 16 0
      static/css/font.css
  66. 35 0
      static/css/jeDate-test.css
  67. 100 0
      static/css/jedate.css
  68. 0 0
      static/css/layui.css
  69. 105 0
      static/css/login.css
  70. 21 0
      static/css/theme1.css
  71. 21 0
      static/css/theme2.css
  72. 22 0
      static/css/theme3.css
  73. 21 0
      static/css/theme4.css
  74. 27 0
      static/css/theme5.css
  75. 533 0
      static/css/xadmin.css
  76. 18 0
      static/css/xcConfirm.css
  77. 596 0
      static/essjksh/css/index.css
  78. 438 0
      static/essjksh/data.html
  79. 62 0
      static/essjksh/fonts/icomoon.css
  80. BIN
      static/essjksh/fonts/icomoon.eot
  81. 22 0
      static/essjksh/fonts/icomoon.svg
  82. BIN
      static/essjksh/fonts/icomoon.ttf
  83. BIN
      static/essjksh/fonts/icomoon.woff
  84. BIN
      static/essjksh/images/border.png
  85. BIN
      static/essjksh/images/line.png
  86. BIN
      static/essjksh/images/logo.png
  87. BIN
      static/essjksh/images/rect.png
  88. BIN
      static/essjksh/images/智慧大屏.rar
  89. 44 0
      static/essjksh/js/china.js
  90. 445 0
      static/essjksh/js/index.js
  91. 1 0
      static/essjksh/js/jquery.min.js
  92. 492 0
      static/essjksh/js/mymap.js
  93. BIN
      static/favicon.ico
  94. BIN
      static/fonts/iconfont.eot
  95. 44 0
      static/fonts/iconfont.svg
  96. BIN
      static/fonts/iconfont.ttf
  97. BIN
      static/fonts/iconfont.woff
  98. BIN
      static/images/aiwrap.png
  99. BIN
      static/images/bg.png
  100. BIN
      static/images/bg1.png

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/

+ 9 - 0
.idea/ColdP_server.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 21 - 0
.idea/deployment.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="PublishConfigData" remoteFilesAllowedToDisappearOnAutoupload="false">
+    <serverData>
+      <paths name="Alot">
+        <serverdata>
+          <mappings>
+            <mapping local="$PROJECT_DIR$" web="/" />
+          </mappings>
+        </serverdata>
+      </paths>
+      <paths name="huitong">
+        <serverdata>
+          <mappings>
+            <mapping local="$PROJECT_DIR$" web="/" />
+          </mappings>
+        </serverdata>
+      </paths>
+    </serverData>
+  </component>
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/ColdP_server.iml" filepath="$PROJECT_DIR$/.idea/ColdP_server.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

BIN
ColdP_server


+ 46 - 0
Cold_server.go

@@ -0,0 +1,46 @@
+package main
+
+import (
+	"ColdP_server/conf"
+	_ "ColdP_server/routers"
+	"fmt"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	beego "github.com/beego/beego/v2/server/web"
+	"github.com/beego/beego/v2/server/web/filter/cors"
+	_ "github.com/go-sql-driver/mysql"
+	"runtime"
+	"strconv"
+)
+
+func init() {
+	fmt.Println(runtime.GOOS)
+	orm.RegisterDriver("mysql", orm.DRMySQL)
+	//orm.RegisterDataBase("default", "mysql", "zdxq:7e5853d9178edfcc@tcp(47.108.133.234:3306)/zdxq?charset=utf8",100,200)
+	orm.RegisterDataBase("default", "mysql",
+		conf.MysqlServer_Username+":"+conf.MysqlServer_Password+"@tcp("+conf.MysqlServer_UrlPort+")/"+conf.MysqlServer_Database+"?charset=utf8mb4&loc=Local&parseTime=True",
+		conf.MysqlServer_MaxIdleConnections, conf.MysqlServer_MaxOpenConnections)
+	orm.RunSyncdb("default", false, false) // 创建数据库
+	orm.Debug = true
+	orm2.Debug = true
+}
+func main() {
+	HTTPPort, _ := beego.AppConfig.String("HTTPPort")
+	HTTPPort_int, _ := strconv.Atoi(HTTPPort)
+
+	beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
+		AllowAllOrigins:  true,
+		AllowMethods:     []string{"*"},
+		AllowHeaders:     []string{"Origin", "Authorization", "Access-Control-Allow-Origin"},
+		ExposeHeaders:    []string{"Content-Length", "Access-Control-Allow-Origin"},
+		AllowCredentials: true,
+	}))
+	beego.BConfig.AppName = "main_cold"          // 项目名
+	beego.BConfig.ServerName = "main_cold"       //server  名称
+	beego.BConfig.RunMode = "dev"                //  应用的运行模式
+	beego.BConfig.Listen.HTTPPort = HTTPPort_int //监听端口  本地:8518  线上:8528
+	/*	beego.AddFuncMap("convertm", convertM)
+	 */
+	//go MqttServer.Run_MqttServer()
+	beego.Run()
+}

+ 8 - 0
Z_Build.bat

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

+ 28 - 0
conf/app.conf

@@ -0,0 +1,28 @@
+appname = ColdP_server
+HTTPPort = 6200
+runmode = dev
+EnableDocs = true
+copyrequestbody = true
+
+# Nats
+NatsServer_Url = "127.0.0.1:43422"
+
+# Mysql
+MysqlServer_UrlPort = "127.0.0.1:40306"
+MysqlServer_Database = "cold"
+MysqlServer_Username = "cold"
+MysqlServer_Password = "yjwyEckZS7rE5H!"
+MysqlServer_MaxIdleConnections = 100
+MysqlServer_MaxOpenConnections = 200
+
+# Redis
+# Redis
+Redis_address = "127.0.0.1:43379"
+Redis_password = ""
+Redis_dbNum = "1"
+
+#MQTT
+Mqtt_suffix = ".coldbaozhida.com"
+Mqtt_port = 1883
+Mqtt_username = test
+Mqtt_password = EHM5PpXDD579gmp

+ 25 - 0
conf/config.go

@@ -0,0 +1,25 @@
+package conf
+
+import (
+	beego "github.com/beego/beego/v2/server/web"
+)
+
+// Nats
+var NatsServer_Url, _ = beego.AppConfig.String("NatsServer_Url")
+
+var RunMode, _ = beego.AppConfig.String("RunMode")
+
+var Page_size = 10
+
+// Mysql
+var MysqlServer_UrlPort, _ = beego.AppConfig.String("MysqlServer_UrlPort")
+var MysqlServer_Database, _ = beego.AppConfig.String("MysqlServer_Database")
+var MysqlServer_Username, _ = beego.AppConfig.String("MysqlServer_Username")
+var MysqlServer_Password, _ = beego.AppConfig.String("MysqlServer_Password")
+var MysqlServer_MaxIdleConnections, _ = beego.AppConfig.Int("MysqlServer_MaxIdleConnections")
+var MysqlServer_MaxOpenConnections, _ = beego.AppConfig.Int("MysqlServer_MaxOpenConnections")
+
+// Redis
+var Redis_address, _ = beego.AppConfig.String("Redis_address")
+var Redis_password, _ = beego.AppConfig.String("Redis_password")
+var Redis_dbNum, _ = beego.AppConfig.String("Redis_dbNum")

+ 108 - 0
controllers/CommonsController.go

@@ -0,0 +1,108 @@
+package controllers
+
+import (
+	"ColdP_server/controllers/lib"
+	"ColdP_server/models/Account"
+	"fmt"
+	beego "github.com/beego/beego/v2/server/web"
+	"net/http"
+	"strings"
+	"time"
+)
+
+type AdminController struct {
+	beego.Controller
+}
+
+func (c *AdminController) Login() {
+	c.TplName = "login.html"
+}
+
+func (c *AdminController) Login_verification() {
+	Admin_user := c.GetString("bzd_username")
+	Admin_pass := c.GetString("bzd_password")
+	companyId := c.GetString("company_id")
+
+	println("Login_verification", Admin_user, Admin_pass)
+	err, admin_r := Account.Read_AdminLogin_verification(Admin_user, Admin_pass)
+
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "账号密码错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	if admin_r.T_pids == "*" {
+		User_tokey := Account.Add_Tokey_Set(admin_r.T_uuid, companyId)
+		c.Ctx.SetCookie("User_tokey", User_tokey, time.Second*60*60)
+		c.Data["json"] = lib.JSONS{Code: 200, Msg: "OK!", Data: User_tokey}
+		c.ServeJSON()
+		return
+	}
+	//如果自定义了公司ID,则标识是管理员,判断是否pids是否存在要操作的pid,并且要求登录用户的PID一定为0
+	if companyId != "" && admin_r.T_pid == 0 {
+		pids := strings.Split(admin_r.T_pids, "|")
+		for _, v := range pids {
+			newV := strings.Replace(v, "P", "", -1)
+			if newV == companyId {
+				User_tokey := Account.Add_Tokey_Set(admin_r.T_uuid, companyId)
+				c.Ctx.SetCookie("User_tokey", User_tokey, time.Second*60*60)
+				c.Data["json"] = lib.JSONS{Code: 200, Msg: "OK!", Data: User_tokey}
+				c.ServeJSON()
+				return
+			}
+		}
+		//不存在该公司的Pid
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "没有操作该公司的权限!"}
+		c.ServeJSON()
+		return
+	} else {
+		User_tokey := Account.Add_Tokey_Set(admin_r.T_uuid, fmt.Sprintf("%d", admin_r.T_pid))
+		c.Ctx.SetCookie("User_tokey", User_tokey, time.Second*60*60)
+		c.Data["json"] = lib.JSONS{Code: 200, Msg: "OK!", Data: User_tokey}
+		c.ServeJSON()
+		return
+	}
+
+}
+
+func (c *AdminController) Info() {
+
+	// 验证登录
+	b_, user_r := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "no"}
+		c.ServeJSON()
+		return
+	}
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok", Data: Account.AdminToAdmin_R(user_r)}
+	c.ServeJSON()
+	return
+}
+
+func (c *AdminController) Index() {
+	// 验证登录
+
+	b_, admin_r := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Ctx.Redirect(302, "Login")
+		return
+	}
+
+	// 基本信息
+	c.Data["Admin_name"] = admin_r.T_name
+	c.Data["Admin_root"] = admin_r.Id
+	c.TplName = "index.html"
+
+}
+
+func (c *AdminController) Home() {
+	b_, admin_r := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		fmt.Println("当前未登录,请先登录!")
+		c.Ctx.Redirect(http.StatusFound, "Login")
+	}
+	c.Data["T_name"] = admin_r.T_name
+	c.TplName = "home.html"
+}

+ 247 - 0
controllers/DataController.go

@@ -0,0 +1,247 @@
+package controllers
+
+import (
+	"ColdP_server/conf"
+	"ColdP_server/controllers/lib"
+	"ColdP_server/models/Company"
+	"ColdP_server/models/Device"
+	"encoding/json"
+	"fmt"
+	beego "github.com/beego/beego/v2/server/web"
+	"github.com/xuri/excelize/v2"
+	"io/ioutil"
+	"math"
+	"strconv"
+	"strings"
+)
+
+type DataController struct {
+	beego.Controller
+}
+
+func (c *DataController) DataList_html() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	// 验证登录
+	b_, R_u := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	Name := c.GetString("Name")
+
+	c.Data["Class_List"] = Company.Read_CompanyClass_All(R_u.T_pid, "")
+	c.Data["Name"] = Name
+	c.TplName = "Data/DataList.html"
+}
+
+// Device_Sensor_List 传感器列表
+func (c *DataController) Device_Sensor_List() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	// 验证登录
+	b_, admin_r := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	type R_JSONS struct {
+		//必须的大写开头
+		DeviceSensor_lite []Device.DeviceSensor_
+		Num               int
+		Page              int
+		Page_size         int
+		Pages             []lib.Page_T
+	}
+	var r_jsons R_JSONS
+	page, _ := c.GetInt("page")
+	println(page)
+	if page < 1 {
+		page = 1
+	}
+	page_z, _ := c.GetInt("page_z")
+	println(page_z)
+	if page_z == 0 {
+		page_z = conf.Page_size
+	}
+
+	T_sn := c.GetString("T_sn")
+	T_Calss_id, _ := c.GetInt("T_class_id")
+	T_name := c.GetString("T_name")
+	SN_type := c.GetString("SN_type")
+
+	//c.Data["Class_List"] = Device.Read_Class_All_1()
+
+	var cnt int64
+	fmt.Printf("当前登录用户的PID是:%d\n", admin_r.T_pid)
+	num, _ := strconv.ParseInt(SN_type, 10, 64)
+	r_jsons.DeviceSensor_lite, cnt = Device.Read_DeviceSensor_List_T_Class(admin_r.T_pid, T_Calss_id, T_sn, T_name, int(num), page, page_z)
+	page_size := math.Ceil(float64(cnt) / float64(page_z))
+	r_jsons.Page = int(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
+}
+
+// Device_Sensor_Data_More 列表 - 接口
+func (c *DataController) Device_Sensor_Data_More() {
+
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	page, _ := c.GetInt("page")
+	page_z, _ := c.GetInt("page_z")
+	println(page)
+	if page < 1 {
+		page = 1
+	}
+	if page_z < 1 {
+		page_z = conf.Page_size
+	}
+
+	T_snid := c.GetString("T_snid")
+	Time_start := c.GetString("Time_start")
+	Time_end := c.GetString("Time_end")
+
+	if len(T_snid) < 10 {
+		c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+		c.ServeJSON()
+		return
+	}
+
+	var cnt int64
+	var pageHelper = lib.PageHelper{}
+	pageHelper.List, cnt = Device.Read_DeviceData_By_T_snid_List(T_snid, Time_start, Time_end, page, page_z)
+	page_size := math.Ceil(float64(cnt) / float64(page_z))
+	pageHelper.CurrentPage = page
+	pageHelper.TotalPage = int(page_size)
+	pageHelper.TotalCount = int(cnt)
+	pageHelper.NextPage = page < int(page_size)
+	pageHelper.PreviousPage = page > 1
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: pageHelper}
+	c.ServeJSON()
+	return
+}
+
+// Device_Sensor_List_Delete 删除设备数据
+func (c *DataController) Device_Sensor_List_Delete() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	var datas = make([]Device.DeviceData_R, 0)
+	bytes, _ := ioutil.ReadAll(c.Ctx.Request.Body)
+	fmt.Println("body获取得到数据:", string(bytes))
+	json.Unmarshal(bytes, &datas)
+	fmt.Println("jsonUnmarshal获取得到数据:", datas)
+	Device.DeleteDeviceDataByDeviceDataRList(datas)
+	c.Data["json"] = lib.JSONS{200, "删除成功!", nil}
+	c.ServeJSON()
+	return
+}
+
+// Device_Sensor_Update /Data/Device_Sensor_List_Update 更新设备数据
+func (c *DataController) Device_Sensor_Update() {
+
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_sn := c.GetString("t_sn")
+	T_id, _ := c.GetInt("t_id")
+	T_t, _ := c.GetFloat("t_t")
+	T_rh, _ := c.GetFloat("t_rh")
+	T_site := c.GetString("t_site")
+	fieldName := c.GetString("type")
+	val := c.GetString("value")
+
+	data := Device.DeviceData_R{
+		T_sn:   T_sn,
+		T_id:   T_id,
+		T_t:    float32(T_t),
+		T_rh:   float32(T_rh),
+		T_site: T_site,
+	}
+
+	Device.Update_DeviceSensorData(data, fieldName, val)
+
+	c.Data["json"] = lib.JSONS{
+		200, "更新成功", nil,
+	}
+	c.ServeJSON()
+	return
+}
+
+// Device_Sensor_Record 数据记录
+func (c *DataController) Device_Sensor_Record() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	sn := c.GetString("sn")
+	tId := c.GetString("tId")
+	createTime := c.GetString("createTime")
+	fmt.Println("时间:", createTime)
+	list := Device.ReadDeviceOldBySnTid(sn, tId)
+	c.Data["json"] = lib.JSONS{200, "操作成功", list}
+	c.ServeJSON()
+	return
+}
+
+// ImportData 数据导入 excel
+func (c *DataController) ImportData() {
+
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	file, header, err := c.GetFile("file")
+	defer file.Close()
+
+	if err != nil {
+		panic(any(fmt.Sprintf("%s 获取上传文件错误", err.Error())))
+	}
+	fmt.Println("文件名称:", header.Filename)
+	sn := strings.Split(header.Filename, ".")[0]
+	fmt.Printf("sn:%s\n", sn)
+	reader, err := excelize.OpenReader(file)
+	if err != nil {
+		panic(any(fmt.Sprintf("%s 打开上传文件excel错误", err.Error())))
+	}
+	Device.ImportDeviceData(reader, sn)
+
+	c.Data["json"] = lib.JSONS{200, "操作成功", nil}
+	c.ServeJSON()
+	return
+}

+ 448 - 0
controllers/DataGeneratorController.go

@@ -0,0 +1,448 @@
+package controllers
+
+import (
+	"ColdP_server/controllers/lib"
+	"ColdP_server/logs"
+	"ColdP_server/models/Company"
+	"ColdP_server/models/Device"
+	"encoding/json"
+	"fmt"
+	beego "github.com/beego/beego/v2/server/web"
+	"github.com/xuri/excelize/v2"
+	"io"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type DataGeneratorController struct {
+	beego.Controller
+}
+
+// GeneratorHtml 获取页面
+func (c *DataGeneratorController) GeneratorHtml() {
+	b_, admin := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	classList := Company.Read_CompanyClass_All(admin.T_pid, "")
+	c.Data["Class_List"] = classList
+	//确认状态为登录状态后
+	c.TplName = "Data/GeneratorData2.html"
+}
+
+// DeviceSensorData 获取对应设备探头数据
+func (c *DataGeneratorController) DeviceSensorData() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	startTime := c.GetString("startTime")
+	endTime := c.GetString("endTime")
+	sns := make([][]string, 0)
+	json.Unmarshal([]byte(c.GetString("sns")), &sns)
+	type Temp struct {
+		Sn   []string                  `json:"sn"`
+		Data []Device.DeviceSensorData `json:"data"`
+	}
+	datas := make([]Temp, 0)
+	for _, sn := range sns {
+		//sn = [sn,探头id]
+		id, _ := strconv.ParseInt(sn[1], 10, 63)
+		v, err := Device.ReadDeviceSensorByTsnTidTimeRange(sn[0], int(id), startTime, endTime)
+		if err != nil {
+			c.Data["json"] = lib.JSONS{Code: 500, Msg: "读取设备探头错误!"}
+			c.ServeJSON()
+			return
+		}
+		datas = append(datas, Temp{sn, v})
+	}
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "获取数据成功", Data: datas}
+	c.ServeJSON()
+}
+
+// UpdateFix 更新固定值
+func (c *DataGeneratorController) UpdateFix() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	//1.解析数据
+	var body = c.Ctx.Request.Body
+	defer body.Close()
+	type T struct {
+		FixTemperature string      `json:"fixTemperature"`
+		FixHumidity    string      `json:"fixHumidity"`
+		Sns            [][2]string `json:"sns"`
+		Data           []int64     `json:"data"`
+	}
+	var temp = T{}
+	bytes, _ := io.ReadAll(body)
+	json.Unmarshal(bytes, &temp)
+	fmt.Println("解析后:", temp.Data[0])
+
+	//2.得到数据进行统一设置访问修改
+	humidity, _ := strconv.ParseFloat(temp.FixHumidity, 64)
+	temperature, _ := strconv.ParseFloat(temp.FixTemperature, 64)
+	//开始时间到结束时间
+	startTime := time.UnixMilli(temp.Data[0]).Format("2006-01-02 15:04:05")
+	endTime := time.UnixMilli(temp.Data[1]).Format("2006-01-02 15:04:05")
+
+	//3.循环更新数据
+	for _, v := range temp.Sns {
+		sn := v[0]
+		tId := v[1]
+		Device.UpdateDeviceSensorDataTemperatureAndHumidity(sn, tId, startTime, endTime, temperature, humidity)
+	}
+	//4.反馈成功
+	c.Data["json"] = lib.JSONS{200, "调整固定偏移值成功!", nil}
+	c.ServeJSON()
+}
+
+// Delete 删除
+func (c *DataGeneratorController) Delete() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	//1.解析数据
+	var body = c.Ctx.Request.Body
+	defer body.Close()
+	type T struct {
+		Sns  [][2]string `json:"sns"`
+		Data []int64     `json:"data"`
+	}
+	var temp = T{}
+	bytes, _ := io.ReadAll(body)
+	json.Unmarshal(bytes, &temp)
+	fmt.Println("解析后:", temp.Data[0])
+
+	//开始时间到结束时间
+	startTime := time.UnixMilli(temp.Data[0]).Format("2006-01-02 15:04:05")
+	endTime := time.UnixMilli(temp.Data[1]).Format("2006-01-02 15:04:05")
+
+	//3.循环更新数据
+	for _, v := range temp.Sns {
+		sn := v[0]
+		tId := v[1]
+		Device.DeleteDeviceSensorDataByTimeRange(sn, tId, startTime, endTime)
+	}
+	//4.反馈成功
+	c.Data["json"] = lib.JSONS{200, "调整固定偏移值成功!", nil}
+	c.ServeJSON()
+}
+
+// UpdateRand 更新随机值
+func (c *DataGeneratorController) UpdateRand() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	//解析请求参数
+	body := c.Ctx.Request.Body
+	defer body.Close()
+	bytes, _ := io.ReadAll(body)
+	type T struct {
+		TemperatureMin int         `json:"temperatureMin"`
+		TemperatureMax int         `json:"temperatureMax"`
+		HumidityMax    int         `json:"humidityMax"`
+		HumidityMin    int         `json:"humidityMin"`
+		Sns            [][2]string `json:"sns"`
+		Data           []int64     `json:"data"`
+	}
+	var t = T{}
+	json.Unmarshal(bytes, &t)
+	fmt.Println("requestJSON: ", t, "原始json:", string(bytes))
+	//开始时间到结束时间
+	startTime := time.UnixMilli(t.Data[0]).Format("2006-01-02 15:04:05")
+	endTime := time.UnixMilli(t.Data[1]).Format("2006-01-02 15:04:05")
+
+	for _, v := range t.Sns {
+		sn := v[0]
+		tId := v[1]
+		Device.UpdateDeviceSensorDataTemperatureAndHumidityRandom(sn, tId, startTime, endTime, t.TemperatureMax, t.TemperatureMin, t.HumidityMax, t.HumidityMin)
+	}
+
+	//反馈成功
+	c.Data["json"] = lib.JSONS{200, "调整随机偏移值成功!", nil}
+	c.ServeJSON()
+	return
+}
+
+// CopyFromPosition 数据拷贝
+func (c *DataGeneratorController) CopyFromPosition() {
+	b_, admin := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	var body = c.Ctx.Request.Body
+	defer body.Close()
+	bytes, _ := io.ReadAll(body)
+	type T struct {
+		CopyPosition string      `json:"copyPosition"`
+		Sns          [][2]string `json:"sns"`
+		Data         []int64     `json:"data"`
+	}
+	t := T{}
+	json.Unmarshal(bytes, &t)
+	//开始时间 和结束时间,插入的时间范围
+	fmt.Println(t)
+	copyTime, _ := time.Parse("2006-01-02 15:04:05", t.CopyPosition)
+
+	startTime := time.UnixMilli(t.Data[0]).Format("2006-01-02 15:04:05")
+	endTime := time.UnixMilli(t.Data[1]).Format("2006-01-02 15:04:05")
+	for _, v := range t.Sns {
+		sn := v[0]
+		tId := v[1]
+		list := Device.SelectDeviceSensorDataListByTimeRange(sn, tId, startTime, endTime)
+		saveTime := Device.ReadDeviceParameterByTsn(sn).T_saveT
+		ct := copyTime
+		go func(list []Device.DeviceSensorData, sn string, saveTime int) {
+			for _, d := range list {
+				d.T_time = ct.Format("2006-01-02 15:04:05")
+				d.CreateTime = ct.Format("2006-01-02 15:04:05")
+				Device.InsertDeviceSensorData(sn, d, admin)
+				ct = ct.Add(time.Second * time.Duration(saveTime))
+			}
+		}(list, sn, saveTime)
+	}
+
+	c.Data["json"] = lib.JSONS{200, "数据复制已提交后台处理!", nil}
+	c.ServeJSON()
+	return
+}
+
+// RepairSensorData 数据补漏
+func (c *DataGeneratorController) RepairSensorData() {
+	b_, admin := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	sns := make([][2]string, 0)
+	timeRange := make([]int64, 0)
+	json.Unmarshal([]byte(c.GetString("sns")), &sns)
+	json.Unmarshal([]byte(c.GetString("data")), &timeRange)
+
+	start := time.UnixMilli(timeRange[0]).Format("2006-01-02 15:04:05")
+	end := time.UnixMilli(timeRange[1]).Format("2006-01-02 15:04:05")
+	num := 0
+	for _, v := range sns {
+		sn := v[0]
+		tId := v[1]
+		saveTime := Device.ReadDeviceParameterByTsn(sn).T_saveT
+		list := Device.SelectDeviceSensorDataListByTimeRange(sn, tId, start, end)
+
+		for i := 0; i < len(list)-1; i++ {
+			current := list[i].T_time
+			next := list[i+1].T_time
+			c, _ := time.Parse("2006-01-02 15:04:05", current)
+			n, _ := time.Parse("2006-01-02 15:04:05", next)
+			interval := n.Unix() - c.Unix()
+			logs.Debug("时间间隔:", interval)
+			fmt.Println("当前:", current, "下一个:", next)
+			if int(interval) > saveTime {
+				ttInterval := list[i+1].T_t - list[i].T_t
+				ttt := list[i].T_t // 温度临时变量
+				trhInterval := list[i+1].T_rh - list[i].T_rh
+				trht := list[i].T_rh //湿度临时变量
+				count := int(interval) / saveTime
+				num += count
+				for k := 0; k < count; k++ {
+					t := c.Format("2006-01-02 15:04:05") //时间临时变量
+					ttt += ttInterval / float64(count)
+					trht += trhInterval / float64(count)
+					Device.InsertDeviceSensorData(sn, Device.DeviceSensorData{
+						list[i].T_id,
+						list[i].T_sp,
+						t,
+						lib.Decimal(ttt),
+						lib.Decimal(trht),
+						list[i].T_site,
+						list[i].CreateTime,
+					}, admin)
+					c = c.Add(time.Second * time.Duration(saveTime))
+				}
+			}
+		}
+
+	}
+
+	c.Data["json"] = lib.JSONS{200, fmt.Sprintf("补漏完成!共补漏%d条数据", num), nil}
+	c.ServeJSON()
+	return
+}
+
+// DataSensorDataSmooth 数据平滑
+func (c *DataGeneratorController) DataSensorDataSmooth() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	var (
+		sns       [][2]string
+		timeRange []int64
+		tRange    float64
+		hRange    float64
+	)
+	json.Unmarshal([]byte(c.GetString("sns")), &sns)
+	json.Unmarshal([]byte(c.GetString("data")), &timeRange)
+	tRange, _ = c.GetFloat("tRange")
+	hRange, _ = c.GetFloat("hRange")
+
+	start := time.UnixMilli(timeRange[0]).Format("2006-01-02 15:04:05")
+	end := time.UnixMilli(timeRange[1]).Format("2006-01-02 15:04:05")
+	fmt.Println(tRange, hRange)
+
+	var count int
+	for _, v := range sns {
+		sn := v[0]
+		id := v[1]
+		list := Device.SelectDeviceSensorDataListByTimeRange(sn, id, start, end)
+		for i := 1; i < len(list); i++ {
+			n := list[i-1]
+			old := list[i]
+			newO := list[i]
+			//变化差
+			var tInterval = old.T_t - n.T_t
+			var hInterval = old.T_rh - n.T_rh
+			fmt.Println("温度:", n.T_t, "温度next:", old.T_t, "差值:", n.T_t-old.T_t)
+			if tRange != 0 {
+				if tInterval > tRange {
+					newO.T_t = n.T_t + tRange
+				} else if tInterval < -tRange {
+					newO.T_t = n.T_t - tRange
+				}
+			}
+			if hRange != 0 {
+				if hInterval > hRange {
+					newO.T_rh = n.T_rh + hRange
+				} else if hInterval < -hRange {
+					newO.T_rh = n.T_rh - hRange
+				}
+			}
+			if old != newO {
+				fmt.Println("原始数据:", old, "新数据:", newO)
+				list[i] = newO
+				newO.T_t = lib.Decimal(newO.T_t)
+				newO.T_rh = lib.Decimal(newO.T_rh)
+				Device.UpdateDeviceSensorData(sn, id, old, newO)
+				count++
+			}
+		}
+	}
+	c.Data["json"] = lib.JSONS{200, "操作成功处理" + fmt.Sprint(count) + "条数据", nil}
+	c.ServeJSON()
+}
+
+// DataSensorDataTrend 数据趋势
+func (c *DataGeneratorController) DataSensorDataTrend() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	//获取数据
+	timeRange := make([]int64, 0)
+	sns := make([][2]string, 0)
+	json.Unmarshal([]byte(c.GetString("data")), &timeRange)
+	json.Unmarshal([]byte(c.GetString("sns")), &sns)
+
+	start := time.UnixMilli(timeRange[0]).Format("2006-01-02 15:04:05")
+	end := time.UnixMilli(timeRange[1]).Format("2006-01-02 15:04:05")
+
+	for _, v := range sns {
+		sn := v[0]
+		tId := v[1]
+		list := Device.SelectDeviceSensorDataListByTimeRange(sn, tId, start, end)
+		first := list[0]
+		last := list[len(list)-1]
+
+		ttInterval := (last.T_t - first.T_t) / float64(len(list)-2)
+		trhInterval := (last.T_rh - first.T_rh) / float64(len(list)-2)
+		if len(list) < 3 {
+			continue
+		}
+
+		for i, d := range list[1 : len(list)-1] {
+			old := list[i]
+			if ttInterval != 0 {
+				d.T_t = list[0].T_t + float64(i+1)*ttInterval
+			}
+			if trhInterval != 0 {
+				d.T_rh = list[0].T_rh + float64(i+1)*trhInterval
+			}
+			if d != old {
+				d.T_t = lib.Decimal(d.T_t)
+				d.T_rh = lib.Decimal(d.T_rh)
+				Device.UpdateDeviceSensorData(sn, tId, old, d)
+			}
+		}
+	}
+
+	c.Data["json"] = lib.JSONS{200, "设置平滑操作成功", nil}
+	c.ServeJSON()
+	return
+}
+
+// ImportSensorData 导入数据
+func (c *DataGeneratorController) ImportSensorData() {
+	b_, admin := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	//读取文件
+	file, _, err := c.GetFile("file")
+	if err != nil {
+		fmt.Println("读取form文件失败", err.Error())
+	}
+
+	//解析文件
+	read, err := excelize.OpenReader(file)
+	if err != nil {
+		fmt.Println("解析错误:", err.Error())
+	}
+	rows, err := read.GetRows("data")
+	if err != nil {
+		fmt.Println("解析excel错误", err.Error())
+	}
+	values := make([][]string, 0)
+	for _, row := range rows[1:] {
+		//t_id	t_sp	t_time	t_t	t_rh	t_site	create_time
+		values = append(values, row)
+	}
+
+	//添加操作
+	sns := strings.Split(c.GetString("sn"), "|")
+	for _, v := range sns {
+		for _, ev := range values {
+			temperature, _ := strconv.ParseFloat(ev[4], 64)
+			humidty, _ := strconv.ParseFloat(ev[5], 64)
+			temperature = lib.Decimal(temperature)
+			humidty = lib.Decimal(humidty)
+			data := Device.ToSensorData(strings.Split(v, ",")[1], ev[1], ev[2], ev[3], temperature, humidty, ev[6])
+			Device.InsertDeviceSensorData(strings.Split(v, ",")[0], data, admin)
+		}
+	}
+	c.Data["json"] = lib.JSONS{200, "导入数据成功!", nil}
+	c.ServeJSON()
+	return
+}

+ 416 - 0
controllers/DeviceController.go

@@ -0,0 +1,416 @@
+package controllers
+
+import (
+	conf "ColdP_server/conf"
+	"ColdP_server/controllers/MqttServer"
+	"ColdP_server/controllers/lib"
+	"ColdP_server/models/Company"
+	"ColdP_server/models/Device"
+	"ColdP_server/models/Warning"
+	"encoding/json"
+	"fmt"
+	beego "github.com/beego/beego/v2/server/web"
+	"io"
+	"io/ioutil"
+	"math"
+	"strings"
+	"time"
+)
+
+// DeviceController  设备管理页面
+type DeviceController struct {
+	beego.Controller
+}
+
+// DeviceManagerHtml 返回页面
+func (c *DeviceController) DeviceManagerHtml() {
+	//验证是否登录
+	is, admin := lib.VerificationController(&c.Controller)
+	if !is {
+		return
+	}
+
+	//类名列表
+	classList := Company.Read_CompanyClass_All(admin.T_pid, "")
+	c.Data["Class_List"] = classList
+	c.TplName = "Device/Device.html"
+}
+
+// DeviceList 获取设备列表
+func (c *DeviceController) DeviceList() {
+	tName := c.GetString("deviceName")      //设备名称
+	page, _ := c.GetInt64("currentPage")    //当前页码
+	tClassify, _ := c.GetInt("deviceClass") //设备分类
+
+	is, admin := lib.VerificationController(&c.Controller)
+	fmt.Println("当前用户的PID为:", admin.T_pid)
+	if !is {
+		//用户未登录
+		c.Data["json"] = lib.JSONS{202, "身份认证失效", nil}
+		c.ServeJSON()
+		return
+	}
+	device_list, count := Device.Read_DeviceSensor_List_T_ClassOr(admin.T_pid, tClassify, tName, tName, -1, int(page), conf.Page_size)
+	var pageCount int
+	if (int(count) % conf.Page_size) != 0 {
+		pageCount = int(count) / conf.Page_size
+		pageCount++
+	}
+	c.Data["json"] = lib.PageHelper{int(count), pageCount, int(page), int(page) >= pageCount, page <= 1, device_list}
+	c.ServeJSON()
+	return
+}
+
+// CompanyClass 获取公司设备类目
+func (c *DeviceController) CompanyClass() {
+	is, admin := lib.VerificationController(&c.Controller)
+	if !is {
+		c.Data["json"] = lib.JSONS{202, "用户未登录", nil}
+		c.ServeJSON()
+		return
+	}
+
+	//类名列表
+	classList := Company.Read_CompanyClass_All(admin.T_pid, "")
+	c.Data["json"] = classList
+	c.ServeJSON()
+}
+
+// DataRepeat 数据重传
+func (c *DeviceController) DataRepeat() {
+
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	t := MqttServer.DataRepeat_C{}
+	bytes, _ := ioutil.ReadAll(c.Ctx.Request.Body)
+	json.Unmarshal(bytes, &t)
+	fmt.Println("浏览器接收数据:", t)
+	s, _ := time.Parse("2006-01-02 15:04:05", t.StartTime)
+	e, _ := time.Parse("2006-01-02 15:04:05", t.EndTime)
+
+	//发送MQTT
+	for k, v := range t.Sns {
+		topic := fmt.Sprintf("/pub/%s", k)
+		repeatPub := MqttServer.DataRepeat_Pub{Sn: k, Type: 9, Mid: time.Now().Unix(), Data: MqttServer.DataRepeat_Pub_Data{Start: s.Unix(), End: e.Unix(), Id: v}}
+		msg, _ := json.Marshal(repeatPub)
+		mqttId := strings.Split(Device.ReadDeviceMqttId(k), "\"")[0]
+		client := MqttServer.GetMqttClient(mqttId)
+		for i := 0; i < 3; i++ {
+			time.Sleep(time.Second * time.Duration(i+1))
+			MqttServer.PubMqttMessage(client, topic, msg)
+		}
+		client.Disconnect()
+		client.Terminate()
+	}
+	c.Data["json"] = lib.JSONS{200, "数据重传成功", nil}
+	c.ServeJSON()
+	return
+}
+
+// ReadDeviation 读取偏差值
+func (c *DeviceController) ReadDeviation() {
+
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	t := make(map[string][]int)
+	bytes, _ := ioutil.ReadAll(c.Ctx.Request.Body)
+	json.Unmarshal(bytes, &t)
+	fmt.Println("浏览器接收数据:", t)
+
+	//MQTT发送
+	fmt.Println("发送MQTT t:", t)
+	deviation := make(chan string, 10)
+	var count = 0
+	for k, v := range t {
+		topicSub := fmt.Sprintf("/sub/%s", k)
+		fmt.Println(v)
+		topicPub := fmt.Sprintf("/pub/%s", k)
+		mqttId := Device.ReadDeviceMqttId(k)
+		client := MqttServer.GetMqttClient(mqttId)
+		MqttServer.Subscript(client, topicSub, deviation, "\"type\":7,")
+		pubData, _ := json.Marshal(MqttServer.Deviation_Pub{
+			Sn:   k,
+			Type: 7,
+			Mid:  time.Now().Unix(),
+			Data: v,
+		})
+		MqttServer.PubMqttMessage(client, topicPub, pubData)
+		count++
+	}
+	deviceRepeatData := make([]string, 0)
+	select {
+	case v := <-deviation:
+		fmt.Println("channel收到数据:", v)
+		fmt.Println("count:", count)
+		deviceRepeatData = append(deviceRepeatData, v)
+		count--
+		if count <= 0 {
+			close(deviation)
+			break
+		}
+	}
+	fmt.Println("响应数据:", deviceRepeatData)
+	c.Data["json"] = lib.JSONS{200, "偏差值上传成功", deviceRepeatData}
+	c.ServeJSON()
+	return
+}
+
+// WriteDeviation 设置偏差值
+func (c *DeviceController) WriteDeviation() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	bytes, _ := io.ReadAll(c.Ctx.Request.Body)
+	data := make([]MqttServer.Deviation_Sub, 0)
+	fmt.Println("请求json:", string(bytes))
+	json.Unmarshal(bytes, &data)
+	for _, v := range data {
+		go func(v MqttServer.Deviation_Sub) {
+			v.Type = 8
+			v.Mid = int(time.Now().Unix())
+			mqttid := Device.ReadDeviceMqttId(v.Sn)
+			cli := MqttServer.GetMqttClient(mqttid)
+			bytes, _ := json.Marshal(v)
+			for i := 0; i < 3; i++ {
+				time.Sleep(time.Second * time.Duration(i+1))
+				MqttServer.PubMqttMessage(cli, fmt.Sprintf("/pub/%s", v.Sn), bytes)
+			}
+			cli.Disconnect()
+			cli.Terminate()
+		}(v)
+	}
+	c.Data["json"] = lib.JSONS{200, "设置偏差值成功!", nil}
+	c.ServeJSON()
+	return
+}
+
+// ReadSensor 读取偏差值
+func (c *DeviceController) ReadSensor() {
+
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	t := make(map[string][]int)
+	bytes, _ := ioutil.ReadAll(c.Ctx.Request.Body)
+	json.Unmarshal(bytes, &t)
+	fmt.Println("浏览器接收数据:", t)
+
+	//MQTT发送
+	fmt.Println("发送MQTT t:", t)
+	deviation := make(chan string, 10)
+	var count = 0
+	for k, v := range t {
+		topicSub := fmt.Sprintf("/sub/%s", k)
+		fmt.Println(v)
+		topicPub := fmt.Sprintf("/pub/%s", k)
+		mqttId := Device.ReadDeviceMqttId(k)
+		client := MqttServer.GetMqttClient(mqttId)
+		MqttServer.Subscript(client, topicSub, deviation, "\"type\":5,")
+		pubData, _ := json.Marshal(MqttServer.Deviation_Pub{
+			Sn:   k,
+			Type: 5,
+			Mid:  time.Now().Unix(),
+			Data: v,
+		})
+		MqttServer.PubMqttMessage(client, topicPub, pubData)
+		count++
+	}
+	deviceRepeatData := make([]string, 0)
+	select {
+	case v := <-deviation:
+		fmt.Println("channel收到数据:", v)
+		fmt.Println("count:", count)
+
+		deviceRepeatData = append(deviceRepeatData, v)
+		count--
+		if count <= 0 {
+			close(deviation)
+			break
+		}
+
+	}
+	fmt.Println("响应数据:", deviceRepeatData)
+	c.Data["json"] = lib.JSONS{200, "偏差值上传成功", deviceRepeatData}
+	c.ServeJSON()
+	return
+}
+
+// WriteDeviation 设置偏差值
+func (c *DeviceController) WriteSensor() {
+	b_, _ := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	bytes, _ := io.ReadAll(c.Ctx.Request.Body)
+	data := make([]MqttServer.Sensor_Sub, 0)
+	fmt.Println("请求json:", string(bytes))
+	json.Unmarshal(bytes, &data)
+	for _, v := range data {
+		go func(v MqttServer.Sensor_Sub) {
+			v.Type = 6
+			v.Mid = int(time.Now().Unix())
+			mqttid := Device.ReadDeviceMqttId(v.Sn)
+			cli := MqttServer.GetMqttClient(mqttid)
+			bytes, _ := json.Marshal(v)
+			for i := 0; i < 3; i++ {
+				time.Sleep(time.Second * time.Duration(i+1))
+				MqttServer.PubMqttMessage(cli, fmt.Sprintf("/pub/%s", v.Sn), bytes)
+			}
+			cli.Disconnect()
+			cli.Terminate()
+		}(v)
+	}
+	c.Data["json"] = lib.JSONS{200, "设置偏差值成功!", nil}
+	c.ServeJSON()
+	return
+}
+
+// 列表 -
+func (c *DeviceController) DeviceWarning_List_html() {
+	// 验证登录
+	b_, admin_r := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return
+	}
+	c.Data["Admin_r"] = admin_r
+	page, _ := c.GetInt("page")
+	println(page)
+	if page < 1 {
+		page = 1
+	}
+	c.Data["Admin_r"] = admin_r
+
+	bindSN := c.GetStrings("bindSN")
+	tpList := c.GetStrings("tpList")
+
+	T_sn := c.GetString("T_sn")
+	if len(T_sn) != 0 {
+		bindSN = append(bindSN, T_sn)
+		c.Data["T_sn"] = T_sn
+	}
+	Time_start := c.GetString("Time_start")
+	Time_end := c.GetString("Time_end")
+
+	if len(Time_start) == 0 && len(Time_end) == 0 {
+		Time_start = time.Now().Format("2006-01-02") + " 00:00:00"
+		Time_end = time.Now().Format("2006-01-02") + " 23:59:59"
+	}
+	c.Data["Time_start"] = Time_start
+	c.Data["Time_end"] = Time_end
+
+	//c.Data["Class_List"] = Device.Read_DeviceWarningList_All_1()
+	//T_Title := ""
+	//if Class_1 > 0 {
+	//	T_Title = Device.Read_DeviceWarningList_ById(Class_1).T_name
+	//}
+
+	var cnt int64
+	DeviceWarning_List, cnt := Warning.Read_Warning_List(admin_r.T_pid, bindSN, tpList, Time_start, Time_end, page, 10)
+
+	c.Data["List"] = DeviceWarning_List
+	page_size := math.Ceil(float64(cnt) / float64(conf.Page_size))
+	c.Data["Page"] = page
+	c.Data["Page_size"] = page_size
+	c.Data["Pages"] = lib.Func_page(int64(page), int64(page_size))
+	c.Data["cnt"] = cnt
+
+	c.TplName = "Device/DeviceWarning.html"
+}
+
+func (c *DeviceController) DeviceWarning_() {
+	// 验证登录
+	//b_, admin_r := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	//if !b_ {
+	//	c.Data["json"] = lib.JSONS{Code: 201, Msg: "User_tokey Err!"}
+	//	c.ServeJSON()
+	//	return
+	//}
+
+	c.Data["WarningType"] = Warning.Read_WarningType_All()
+	c.TplName = "Device/DeviceWarning-.html"
+}
+
+func (c *DeviceController) DeviceWarning_Post() {
+	// 验证登录
+	b_, admin_r := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Ctx.Redirect(302, "Login")
+		return
+	}
+
+	T_tp, _ := c.GetInt("T_tp")
+	T_sn := c.GetString("T_sn")
+	T_id, _ := c.GetInt("T_id")
+	T_Ut := c.GetString("T_Ut")
+	T_Remark := c.GetString("T_Remark")
+	r_Device, err := Device.Read_Device_ByT_sn(T_sn)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "E!", Data: "SN 错误!!!"}
+		c.ServeJSON()
+		return
+	}
+	// 获取 传感器 参数
+	DeviceSensor_r, is := Device.Read_DeviceSensor_ByT_sn(r_Device.T_sn, T_id)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "E!", Data: "编号 错误!!!"}
+		c.ServeJSON()
+		return
+	}
+
+	t1, _ := time.ParseInLocation("2006-01-02 15:04:05", T_Ut, time.Local) // +8  时差
+	t_c := Warning.Warning{
+		T_pid:     admin_r.T_pid,
+		T_tp:      T_tp,
+		T_sn:      T_sn,
+		T_D_name:  r_Device.T_devName,
+		T_id:      T_id,
+		T_DS_name: DeviceSensor_r.T_name,
+		T_Ut:      t1,
+		T_State:   1,
+		T_Remark:  T_Remark,
+	}
+	Warning.Add_Warning(t_c)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}
+func (c *DeviceController) DeviceWarning_Del() {
+	// 验证登录
+	b_, admin_r := lib.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !b_ {
+		c.Ctx.Redirect(302, "Login")
+		return
+	}
+
+	Id, _ := c.GetInt("Id")
+
+	if Id > 1000 {
+		Warning.Delete_Warning(admin_r.T_pid, Id)
+	}
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}

+ 182 - 0
controllers/Handle/DeviceParameter.go

@@ -0,0 +1,182 @@
+package Handle
+
+import (
+	"ColdP_server/controllers/MqttServer"
+	"ColdP_server/controllers/lib"
+	"ColdP_server/models/Device"
+	"ColdP_server/models/System"
+	"encoding/json"
+	"fmt"
+	"time"
+)
+
+func Go_Read_DeviceParameter() {
+	for true {
+		for k, _ := range lib.CountryRead_DeviceParameterSnMap {
+
+			fmt.Println("CountryRead_DeviceParameterSnMap => KEY", k)
+			Read_DeviceParameter(k)
+			delete(lib.CountryRead_DeviceParameterSnMap, k)
+		}
+
+		time.Sleep(1)
+	}
+}
+
+func init() {
+	//go Go_Read_DeviceParameter()
+}
+
+func Read_DeviceParameter(T_sn string) {
+	//  base  读取基本参数
+	Msid := lib.Random(1, 9999)
+	Rt_parameter := MqttServer.Rt_Parameter{
+		Sn:    T_sn,
+		Type:  3,
+		Param: "base",
+		Msid:  (Msid * 10) + 1,
+	}
+
+	//  offset     温湿度补偿
+	Msid = lib.Random(1, 9999)
+	Rt_parameter.Param = "offset"
+	Rt_parameter.Msid = (Msid * 10) + 3
+	// 回复
+	jsonStu, err := json.Marshal(Rt_parameter)
+	if err != nil {
+		System.Add_Logs("MqttServer", "参数请求 [Rt_Parameter]", "offset")
+		fmt.Println("回复失败 [Rt_Parameter],err=", err)
+	}
+	fmt.Println(string(jsonStu))
+	MqttServer.Mqtt_publish(T_sn, string(jsonStu))
+	//lib.CountryMsidMap[(Msid*10)+3] = T_uuid   // Mqtt 消息透传
+
+	return
+
+}
+
+func Pu_DeviceParameter(T_uuid string, T_sn string, Rt_parameter_base_ MqttServer.Rt_Parameter_Base_) {
+	//  base  读取基本参数
+	Msid := lib.Random(1, 9999)
+	Rt_parameter := MqttServer.Rt_Parameter_Base{
+		Sn:   T_sn,
+		Type: 4,
+		Msid: (Msid * 10) + 1,
+		Base: Rt_parameter_base_,
+	}
+	// 回复
+	jsonStu, err := json.Marshal(Rt_parameter)
+	if err != nil {
+		System.Add_Logs("设备配置", "MQTT回复失败 [Pu_DeviceParameter]", string(jsonStu))
+		fmt.Println("设备配置 MQTT回复失败 [Pu_DeviceParameter],err=", err)
+		return
+	}
+	fmt.Println(string(jsonStu))
+	MqttServer.Mqtt_publish(T_sn, string(jsonStu))
+	//lib.CountryMsidMap[(Msid*10)+1] = T_uuid   // Mqtt 消息透传
+
+	Deviceparameter := Device.DeviceParameter{
+		T_sn:           T_sn,
+		T_devName:      Rt_parameter_base_.T_devName,
+		T_uploadTime:   Rt_parameter_base_.T_uploadTime,
+		T_saveTime:     Rt_parameter_base_.T_saveTime,
+		T_overrunSave:  Rt_parameter_base_.T_overrunSave,
+		T_overrunAlarm: Rt_parameter_base_.T_overrunAlarm,
+		T_outageAlarm:  Rt_parameter_base_.T_outageAlarm,
+		T_lostAlarm:    Rt_parameter_base_.T_lostAlarm,
+		T_warningTime:  Rt_parameter_base_.T_warningTime,
+		T_warningDelay: Rt_parameter_base_.T_warningDelay,
+		T_batteryLimit: Rt_parameter_base_.T_batteryLimit,
+		T_tempPre:      Rt_parameter_base_.T_tempPre,
+		T_humPre:       Rt_parameter_base_.T_humPre,
+		T_enwarning:    Rt_parameter_base_.T_enwarning,
+		T_uuid:         T_uuid,
+		T_Msid:         (Msid * 10) + 1,
+		T_SendState:    0,
+		T_State:        2,
+	}
+
+	if !Device.Add_DeviceParameter(Deviceparameter) {
+		System.Add_Logs("设备配置", "插入失败 [Pu_DeviceParameter]", string(jsonStu))
+		fmt.Println("设备配置 [Pu_DeviceParameter],err=", err)
+	}
+
+	return
+
+}
+
+func Pu_DeviceParameter_Sensor(T_uuid string, T_sn string, Rt_parameter_sensor_ []MqttServer.Rt_Parameter_Sensor_) {
+	//  base  读取基本参数
+	Msid := lib.Random(1, 9999)
+	Rt_parameter := MqttServer.Rt_Parameter_Sensor{
+		Sn:     T_sn,
+		Type:   4,
+		Msid:   (Msid * 10) + 2,
+		Sensor: Rt_parameter_sensor_,
+	}
+	// 回复
+	jsonStu, err := json.Marshal(Rt_parameter)
+	if err != nil {
+		System.Add_Logs("设备配置", "MQTT回复失败 [Pu_DeviceParameter_Sensor]", string(jsonStu))
+		fmt.Println("设备配置 MQTT回复失败 [Pu_DeviceParameter_Sensor],err=", err)
+	}
+	fmt.Println(string(jsonStu))
+	MqttServer.Mqtt_publish(T_sn, string(jsonStu))
+	//lib.CountryMsidMap[(Msid*10)+2] = T_uuid   // Mqtt 消息透传
+
+	//
+
+	///
+	for _, v := range Rt_parameter_sensor_ {
+		// 记录传感器
+		Devicesensorparameter := Device.DeviceSensorParameter{
+			T_sn:      T_sn,
+			T_id:      v.T_id,
+			T_name:    v.T_name,
+			T_Tlower:  v.T_Tlower,
+			T_Tupper:  v.T_Tupper,
+			T_RHlower: v.T_RHlower,
+			T_RHupper: v.T_RHupper,
+			T_en:      v.T_en,
+			T_free:    v.T_free,
+
+			T_uuid:      T_uuid,
+			T_Msid:      (Msid * 10) + 2,
+			T_SendState: 0,
+			T_State:     2,
+		}
+		if !Device.Add_DeviceSensorParameter(Devicesensorparameter) {
+			System.Add_Logs("设备配置", "插入失败 [Pu_DeviceParameter_Sensor]", string(jsonStu))
+			fmt.Println("设备配置 [Pu_DeviceParameter_Sensor],err=", err)
+		}
+	}
+
+	return
+
+}
+
+func Pu_DeviceParameter_Compensate(T_uuid string, T_sn string, Rt_parameter_compensate_ []MqttServer.Rt_Parameter_Compensate_) {
+	//  base  读取基本参数
+	Msid := lib.Random(1, 9999)
+	Rt_parameter_offset := MqttServer.Rt_Parameter_Offset{
+		Sn:     T_sn,
+		Type:   4,
+		Msid:   (Msid * 10) + 3,
+		Offset: Rt_parameter_compensate_,
+	}
+	// 回复
+	jsonStu, err := json.Marshal(Rt_parameter_offset)
+	if err != nil {
+		System.Add_Logs("MqttServer", "参数请求 [Pu_DeviceParameter_Compensate]", "Offset")
+		fmt.Println("回复失败 [Pu_DeviceParameter_Compensate],err=", err)
+	}
+	fmt.Println(string(jsonStu))
+
+	MqttServer.Mqtt_publish(T_sn, string(jsonStu))
+	// lib.CountryMsidMap[(Msid*10)+3] = T_uuid   // Mqtt 消息透传
+
+	///
+
+	return
+
+}

+ 1 - 0
controllers/Handle/WarningHandle.go

@@ -0,0 +1 @@
+package Handle

+ 119 - 0
controllers/MqttServer/MqttHandle.go

@@ -0,0 +1,119 @@
+package MqttServer
+
+import (
+	"ColdP_server/controllers/WebSocket"
+	"ColdP_server/controllers/lib"
+	"ColdP_server/models/Device"
+	"encoding/json"
+	"fmt"
+	"strings"
+	"time"
+)
+
+func AsyncFunc(r_Device Device.Device, Ms_project Ms_Project, msg []byte) {
+	//t1 := time.Now()
+	//
+	//SN := lib.To_string(Ms_project.Sn)
+	//Type := lib.To_int(Ms_project.Type)
+	//Msid := lib.To_int(Ms_project.Msid)
+	//
+
+	switch lib.To_int(Ms_project.Type) {
+
+	case 3: // 3:设备参数
+		var Ms_parameter Ms_Parameter
+
+		err := json.Unmarshal(msg, &Ms_parameter)
+		if err != nil {
+			fmt.Println("JSON反序列化失败[Ms_Parameter],err=", err)
+			return
+		}
+
+		// 反馈透传
+		jsonStu_map, err := json.Marshal(Ms_parameter)
+		if err != nil {
+			fmt.Println("反馈透传 [Ms_project_0],err=", err)
+			return
+		}
+		_, ok := lib.CountrySnMap[Ms_project.Sn] /*如果确定是真实的,则存在,否则不存在 */
+		if ok {
+			for _, v := range lib.CountrySnMap[Ms_project.Sn].Uuid_list {
+				fmt.Println("转发数据! SN:", Ms_project.Sn, "  Uuid:", v)
+				jsonStu_map_ := strings.Replace(string(jsonStu_map), "\"{", "{", -1)
+				//jsonStu_map_ =strings.Replace(jsonStu_map_, "}\"", "}", -1)
+				//jsonStu_map_ =strings.Replace(jsonStu_map_, "\\\"", "\"", -1)
+				println(jsonStu_map_)
+				WebSocket.Send_WebSocket(v, jsonStu_map_)
+			}
+		}
+		break
+
+	case 4: // 消息反馈
+
+		var Ms_parameter_r Ms_Parameter_r
+
+		err := json.Unmarshal(msg, &Ms_parameter_r)
+		if err != nil {
+			fmt.Println("JSON反序列化失败[Ms_Parameter_r],err=", err)
+			return
+		}
+
+		// 反馈透传
+		jsonStu_map, err := json.Marshal(Ms_parameter_r)
+		if err != nil {
+			fmt.Println("反馈透传 [Ms_project_0],err=", err)
+			return
+		}
+		_, ok := lib.CountrySnMap[Ms_project.Sn] /*如果确定是真实的,则存在,否则不存在 */
+		if ok {
+			for _, v := range lib.CountrySnMap[Ms_project.Sn].Uuid_list {
+				fmt.Println("转发数据! SN:", Ms_project.Sn, "  Uuid:", v)
+				jsonStu_map_ := strings.Replace(string(jsonStu_map), "\"{", "{", -1)
+				jsonStu_map_ = strings.Replace(jsonStu_map_, "}\"", "}", -1)
+				jsonStu_map_ = strings.Replace(jsonStu_map_, "\\\"", "\"", -1)
+				WebSocket.Send_WebSocket(v, jsonStu_map_)
+			}
+		}
+		break
+	}
+
+	//t2 := time.Now()
+	//fmt.Println("线程-》  MQTT RunTime:",t2.Sub(t1))
+
+}
+
+// 循环刷新
+func Realtime() {
+	//fmt.Println("=====================Realtime GO===============")
+	time.Sleep(time.Second * 10)
+	for true {
+		//fmt.Println("=====================Realtime GO===============")
+		//fmt.Println("CountrySnMap_z:", len(lib.CountrySnMap))
+		for k, _ := range lib.CountrySnMap {
+			//fmt.Println("CountrySnMap:",k)
+			Get_Device_Realtime(k)
+			time.Sleep(time.Millisecond * 100)
+		}
+		time.Sleep(time.Second * 10)
+	}
+}
+
+func Get_Device_Realtime(T_sn string) {
+	//  base  读取基本参数
+	Msid := lib.Random(1, 9999)
+	Rt_realtime := Rt_Realtime{
+		Sn:   T_sn,
+		Type: 0,
+		Msid: Msid,
+	}
+	// 回复
+	jsonStu, err := json.Marshal(Rt_realtime)
+	if err != nil {
+		fmt.Println("回复失败 [Pu_DeviceParameter_Compensate],err=", err)
+	}
+	fmt.Println(string(jsonStu))
+	//Mqtt_publish(T_sn, string(jsonStu))
+
+	return
+
+}

+ 152 - 0
controllers/MqttServer/MqttServerStruct.go

@@ -0,0 +1,152 @@
+package MqttServer
+
+// /  -   接收 实体
+type Ms_Project struct {
+	Sn   string `json:"sn"`
+	Type int    `json:"type"`
+	Msid int    `json:"msid"`
+}
+
+type Ms_Project_0 struct {
+	Sn      interface{}              `json:"sn"`
+	Type    interface{}              `json:"type"`
+	Msid    interface{}              `json:"msid"`
+	Site    string                   `json:"site"`
+	Dattery interface{}              `json:"battery"`
+	Sensor  []map[string]interface{} `json:"sensor"`
+}
+
+type Ms_Project_1 struct {
+	Sn      string                   `json:"sn"`
+	Type    int                      `json:"type"`
+	Msid    int                      `json:"msid"`
+	Site    string                   `json:"site"`
+	Dattery int                      `json:"battery"`
+	Sensor  []map[string]interface{} `json:"sensor"`
+}
+
+type Ms_Project_2 struct {
+	Sn     string  `json:"sn"`
+	Type   int     `json:"type"`
+	Msid   int     `json:"msid"`
+	Id     int     `json:"id"`
+	Name   string  `json:"name"`   //温度探头1
+	T      float32 `json:"T"`      //  26.1
+	RH     float32 `json:"RH"`     // 94
+	Title  string  `json:"title"`  // 温度超上限报警
+	Addr   string  `json:"addr"`   // 车载环境监测仪
+	Remark string  `json:"remark"` //备注
+	UT     int     `json:"UT"`     // 1640310466
+
+}
+
+type Ms_Project_6 struct {
+	Sn   string      `json:"sn"`
+	Type interface{} `json:"type"`
+	Msid interface{} `json:"msid"`
+	Task string      `json:"task"` //start:开始监测任务,stop:结束监测任务,print:中途打印任务
+	UT   int         `json:"UT"`   // 1640310466
+
+}
+type Ms_Parameter struct {
+	Sn     string                   `json:"sn"`
+	Type   int                      `json:"type"`
+	Msid   int                      `json:"msid"`
+	Base   map[string]interface{}   `json:"base"`   // 1 设备 数据
+	Sensor []map[string]interface{} `json:"sensor"` // 2 传感器 数据
+	Offset []map[string]interface{} `json:"offset"` // 3 温湿度补偿 数据
+}
+type Ms_Parameter_r struct {
+	Sn   interface{} `json:"sn"`
+	Type interface{} `json:"type"`
+	Msid interface{} `json:"msid"`
+	Set  int         `json:"set"` // 3 温湿度补偿 数据    //1设置成功,0设置失败
+}
+
+// /  -   发送 实体
+type Rt_Project_Data_Sensor struct {
+	Id     int `json:"id"`
+	Status int `json:"status"`
+}
+type Rt_Project_Data struct {
+	Sn     string                   `json:"sn"`
+	Type   int                      `json:"type"`
+	Msid   int                      `json:"msid"`
+	Sensor []Rt_Project_Data_Sensor `json:"sensor"`
+}
+type Rt_Project_2_Data struct {
+	Sn     string `json:"sn"`
+	Type   int    `json:"type"`
+	Msid   int    `json:"msid"`
+	Status int    `json:"status"`
+}
+
+type Rt_Parameter struct {
+	Sn    string `json:"sn"`
+	Type  int    `json:"type"`  //3代表读取设备参数
+	Msid  int    `json:"msid"`  //消息识别ID,随机生成,回复时ID不变
+	Param string `json:"param"` //读取基本参数
+	//Refresh string    `json:"refresh"`  //查询基本参数编号,每次参数改变都会有新的编号,若不带此参数,则返回所有参数
+}
+
+type Rt_Parameter_Base_ struct {
+	T_devName    string `json:"devName"`
+	T_uploadTime int    `json:"uploadTime"`
+	//T_scanTime     int     `json:"scanTime"`
+	T_saveTime     int     `json:"saveTime"`
+	T_overrunSave  int     `json:"overrunSave"`
+	T_overrunAlarm int     `json:"overrunAlarm"`
+	T_outageAlarm  int     `json:"outageAlarm"`
+	T_lostAlarm    int     `json:"lostAlarm"`
+	T_warningDelay int     `json:"warningDelay"`
+	T_warningTime  int     `json:"warningTime"`
+	T_batteryLimit int     `json:"batteryLimit"`
+	T_tempPre      float32 `json:"tempPre"`
+	T_humPre       float32 `json:"humPre"`
+	T_enwarning    int     `json:"enwarning"`
+}
+
+type Rt_Parameter_Base struct {
+	Sn   string             `json:"sn"`
+	Type int                `json:"type"` //  4代表参数设置
+	Msid int                `json:"msid"` //消息识别ID,随机生成,回复时ID不变
+	Base Rt_Parameter_Base_ `json:"base"` //查询基本参数编号,每次参数改变都会有新的编号,若不带此参数,则返回所有参数
+}
+
+type Rt_Parameter_Sensor_ struct {
+	T_id      int     `json:"id"`
+	T_name    string  `json:"name"`
+	T_Tlower  float32 `json:"Tlower"`
+	T_Tupper  float32 `json:"Tupper"`
+	T_RHlower float32 `json:"RHlower"`
+	T_RHupper float32 `json:"RHupper"`
+	T_en      int     `json:"en"`
+	T_free    int     `json:"free"`
+}
+
+type Rt_Parameter_Sensor struct {
+	Sn     string                 `json:"sn"`
+	Type   int                    `json:"type"`   //  4代表参数设置
+	Msid   int                    `json:"msid"`   //消息识别ID,随机生成,回复时ID不变
+	Sensor []Rt_Parameter_Sensor_ `json:"sensor"` //查询基本参数编号,每次参数改变都会有新的编号,若不带此参数,则返回所有参数
+}
+
+type Rt_Parameter_Compensate_ struct {
+	T_id int `json:"id"`
+
+	T_T  float32 `json:"T"`
+	T_RH float32 `json:"RH"`
+}
+
+type Rt_Parameter_Offset struct {
+	Sn     string                     `json:"sn"`
+	Type   int                        `json:"type"`   //  4代表参数设置
+	Msid   int                        `json:"msid"`   //消息识别ID,随机生成,回复时ID不变
+	Offset []Rt_Parameter_Compensate_ `json:"offset"` //查询基本参数编号,每次参数改变都会有新的编号,若不带此参数,则返回所有参数
+}
+
+type Rt_Realtime struct {
+	Sn   string `json:"sn"`
+	Type int    `json:"type"` //  0代表获取一次实时数据
+	Msid int    `json:"msid"` //消息识别ID,随机生成,回复时ID不变
+}

+ 145 - 0
controllers/MqttServer/MqttServer_old.txt

@@ -0,0 +1,145 @@
+//+build ignore
+
+package MqttServer
+
+import (
+	"ColdP_server/conf"
+	"ColdP_server/models/Device"
+	"ColdP_server/models/System"
+	"encoding/json"
+	"fmt"
+	"github.com/beego/beego/v2/core/logs"
+	mqtt "github.com/eclipse/paho.mqtt.golang"
+	"runtime"
+)
+
+var logx * logs.BeeLogger
+var client mqtt.Client
+var (
+	DeviceSn map[string]Device.Device /*创建集合 */
+	test = true
+)
+func init() {
+
+	logx = logs.NewLogger()
+	logx.SetLogger(logs.AdapterFile, `{"filename":"logs/Mqtt/Mqtt.log"}`)
+	//logs.Async(1e3)
+
+
+	cpuNum := runtime.NumCPU() //获得当前设备的cpu核心数
+	fmt.Println("cpu核心数:", cpuNum)
+	runtime.GOMAXPROCS(cpuNum) //设置需要用到的cpu数量
+
+	DeviceSn = make(map[string]Device.Device)
+	if runtime.GOOS == "windows" {
+		test = true
+	} else {
+		test = false
+	}
+	//test = false   // 强行启动 插入
+}
+
+var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
+	// 本地测试
+	if(test) {
+		fmt.Println("============= Mqtt JSON =============")
+		fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
+		return
+	}
+
+
+	logx.Info(string(msg.Payload()) )
+
+	var Ms_project Ms_Project
+	err := json.Unmarshal(msg.Payload(), &Ms_project)
+	if err != nil {
+		System.Add_Logs("MqttServer","JSON反序列化失败[Ms_Project]",string(msg.Payload()))
+		fmt.Println("JSON反序列化失败[Ms_Project],err=",err)
+		return
+	}
+	SN := Ms_project.Sn
+	//Type := lib.To_int(Ms_project.Type)
+	//Msid := lib.To_int(Ms_project.Msid)
+	//
+	//fmt.Println("SN:", SN)
+	//fmt.Println("Type:", Type)
+	//fmt.Println("Msid:", Msid)
+	// 过滤
+	if(len(SN) < 8){
+		return
+	}
+	_, ok := DeviceSn[SN] /*如果确定是真实的,则存在,否则不存在 */
+	if !ok {
+		r_Device,err := Device.Read_Device_ByT_sn(SN)
+		if err != nil {
+			Device.Add_DeviceSnOld(SN)
+			fmt.Println("没有该设备:",SN)
+			return
+		}
+		DeviceSn[SN] = r_Device
+
+	}
+
+	// 并发
+	//go AsyncFunc(Ms_project,msg.Payload())
+	AsyncFunc(Ms_project,msg.Payload())
+
+
+}
+
+var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) {
+	fmt.Println("Connected")
+}
+
+var connectLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) {
+	fmt.Printf("Connect lost: %v", err)
+}
+
+
+
+
+func Mqtt_publish(topic string,text string) {
+
+	token := client.Publish(topic, 0, false, text)
+	token.Wait()
+
+}
+
+func Mqtt_sub() {
+	topic := conf.MqttServer_Sub
+	token := client.Subscribe(topic, 1, nil)
+	token.Wait()
+	fmt.Printf("Subscribed to topic: %s", topic)
+}
+
+
+func  Run_MqttServer()  {
+
+	fmt.Printf("Run_MqttServer")
+	opts := mqtt.NewClientOptions()
+
+	MqttServer_Url := conf.MqttServer_Url
+	if runtime.GOOS == "windows" {
+		MqttServer_Url = "mqtt1.baozhida.cn"
+		opts.SetClientID("go_mqtt_client_test")
+	} else {
+		opts.SetClientID("go_mqtt_client")
+	}
+	opts.AddBroker(fmt.Sprintf("tcp://%s:%d",MqttServer_Url , conf.MqttServer_Port))
+
+	opts.SetUsername(conf.MqttServer_Username)
+	opts.SetPassword(conf.MqttServer_Password)
+	opts.SetDefaultPublishHandler(messagePubHandler)
+	opts.OnConnect = connectHandler
+	opts.OnConnectionLost = connectLostHandler
+	client = mqtt.NewClient(opts)
+	if token := client.Connect(); token.Wait() && token.Error() != nil {
+		panic(token.Error())
+	}
+
+	Mqtt_sub()
+	//publish(client)
+	//
+	//client.Disconnect(250)
+}
+

+ 179 - 0
controllers/MqttServer/MqttServer_oldf2.txt

@@ -0,0 +1,179 @@
+package MqttServer
+
+import (
+	"ColdP_server/models/Device"
+	"encoding/json"
+	"fmt"
+	beego "github.com/beego/beego/v2/server/web"
+	"github.com/yosssi/gmq/mqtt"
+	"github.com/yosssi/gmq/mqtt/client"
+	"runtime"
+)
+
+var (
+	cli      *client.Client
+	DeviceSn map[string]Device.Device /*创建集合 */
+	test     = true
+)
+
+func init() {
+
+	if runtime.GOOS == "windows" {
+		test = true
+	} else {
+		test = false
+	}
+	//test = false   // 强行启动 插入
+
+	go Realtime() // 循环刷新
+
+	//logs.Async(1e3)
+
+	//
+	//cpuNum := runtime.NumCPU() //获得当前设备的cpu核心数
+	//fmt.Println("cpu核心数:", cpuNum)
+	//runtime.GOMAXPROCS(cpuNum) //设置需要用到的cpu数量
+	//
+
+}
+
+func Run_MqttServer() {
+
+	fmt.Println("============Run_MqttServer=============")
+
+	// Create an MQTT Client.
+	cli = client.New(&client.Options{
+		// Define the processing of the error handler.
+		ErrorHandler: func(err error) {
+			fmt.Println(err)
+		},
+	})
+
+	// Terminate the Client.
+	defer cli.Terminate()
+
+	c := client.ConnectOptions{
+		Network:  "tcp",
+		Address:  "192.168.0.7:1883",
+		UserName: []byte("coldchain"),
+		Password: []byte("coldchainBZD"),
+	}
+	HTTPPort, _ := beego.AppConfig.String("HTTPPort")
+	var sub_str = ""
+	c.Address = "mqtt1.baozhida.cn:1883"
+	c.ClientID = []byte("go_mqtt_P_client" + HTTPPort)
+	sub_str = "temp_humidity_sub"
+
+	//sub_str = "temp_humidity_sub"
+
+	fmt.Println("Address:", c.Address)
+	fmt.Println("ClientID:", string(c.ClientID))
+	fmt.Println("sub_str:", sub_str)
+
+	// Connect to the MQTT Server.
+	err := cli.Connect(&c)
+	if err != nil {
+		println(err)
+	}
+
+	// Subscribe to topics.
+	err = cli.Subscribe(&client.SubscribeOptions{
+		SubReqs: []*client.SubReq{
+			&client.SubReq{
+				TopicFilter: []byte(sub_str),
+				QoS:         mqtt.QoS0,
+				// Define the processing of the message handler.
+				Handler: func(topicName, message []byte) {
+					//fmt.Println(string(topicName), string(message))
+					//messagePubHandler(string(topicName), message)
+				},
+			},
+			&client.SubReq{
+				TopicFilter: []byte("temp_humidity_sub_host"),
+				QoS:         mqtt.QoS0,
+				// Define the processing of the message handler.
+				Handler: func(topicName, message []byte) {
+					//fmt.Println(string(topicName), string(message))
+					//messagePubHandler(string(topicName), message)
+				},
+			},
+			//&client.SubReq{
+			//	TopicFilter: []byte("bar/#"),
+			//	QoS:         mqtt.QoS1,
+			//	Handler: func(topicName, message []byte) {
+			//		fmt.Println(string(topicName), string(message))
+			//	},
+			//},
+		},
+	})
+	if err != nil {
+
+	}
+
+}
+
+// 发送数据
+func Mqtt_publish(topic string, text string) {
+	fmt.Println(topic, "->", text)
+	// Publish a message.
+	err := cli.Publish(&client.PublishOptions{
+		QoS:       mqtt.QoS0,
+		TopicName: []byte(topic),
+		Message:   []byte(text),
+	})
+	if err != nil {
+
+	}
+
+}
+
+// 接收數據
+func Mqtt_Subscribe(topic string, callBack func([]byte, []byte)) {
+	fmt.Println(topic, "<-")
+	cli.Subscribe(&client.SubscribeOptions{
+		SubReqs: []*client.SubReq{
+			&client.SubReq{
+				TopicFilter: []byte(topic),
+				QoS:         mqtt.QoS0,
+				Handler:     callBack,
+			},
+		},
+	})
+}
+
+func messagePubHandler(topicName string, message []byte) {
+
+	//// 本地测试
+	//if test {
+	//	fmt.Println("============= Mqtt JSON =============")
+	//	fmt.Printf("topic: %s -> %s \n", topicName, string(message))
+	//}
+
+	var Ms_project Ms_Project
+	err := json.Unmarshal(message, &Ms_project)
+	if err != nil {
+		fmt.Println("JSON反序列化失败[Ms_Project],err=", err)
+		return
+	}
+	SN := Ms_project.Sn
+	//Type := lib.To_int(Ms_project.Type)
+	//Msid := lib.To_int(Ms_project.Msid)
+	//
+	//fmt.Println("SN:", SN)
+	//fmt.Println("Type:", Type)
+	//fmt.Println("Msid:", Msid)
+	// 过滤
+	if len(SN) < 8 {
+		return
+	}
+	r_Device, err := Device.Read_Device_ByT_sn(SN)
+	if err != nil {
+		//Device.Add_DeviceSnOld(SN)
+		//fmt.Println("没有该设备:", SN)
+		return
+	}
+
+	// 并发
+	//go AsyncFunc(Ms_project,message)
+	AsyncFunc(r_Device, Ms_project, message)
+}

+ 90 - 0
controllers/MqttServer/MqttServev2.go

@@ -0,0 +1,90 @@
+package MqttServer
+
+import (
+	"fmt"
+	beego "github.com/beego/beego/v2/server/web"
+	"github.com/yosssi/gmq/mqtt"
+	"github.com/yosssi/gmq/mqtt/client"
+	"log"
+	"math/rand"
+	"strings"
+	"time"
+)
+
+var (
+	mqtt_suffix,
+	mqtt_port,
+	mqtt_username,
+	mqtt_password string
+	err error
+)
+
+func init() {
+	mqtt_suffix, err = beego.AppConfig.String("Mqtt_suffix")
+	mqtt_port, err = beego.AppConfig.String("Mqtt_port")
+	mqtt_username, err = beego.AppConfig.String("Mqtt_username")
+	mqtt_password, err = beego.AppConfig.String("Mqtt_password")
+}
+
+// GetConnectionOptions 获取链接参数
+
+func GetMqttClient(mqttAddrPrefix string) *client.Client {
+	r := rand.New(rand.NewSource(time.Now().Unix()))
+	options := client.ConnectOptions{
+		Network:  "tcp",
+		Address:  fmt.Sprintf("%s.coldbaozhida.com:1883", mqttAddrPrefix),
+		UserName: []byte(mqtt_username),
+		Password: []byte(mqtt_password),
+		ClientID: []byte(fmt.Sprintf("ColdP_server_%d", r.Intn(9))),
+	}
+	cli := client.New(&client.Options{ErrorHandler: func(e error) {
+		fmt.Println("PubMqtt Error 发布信息错误:", e.Error())
+	}})
+	err = cli.Connect(&options)
+	if err != nil {
+		fmt.Println("MQTT 连接失败", err.Error())
+	}
+	return cli
+}
+
+// PubMqttMessage 发送信息
+func PubMqttMessage(cli *client.Client, topic string, msg []byte) {
+	fmt.Printf("发布主题:%s -> 发布内容:%s\n", topic, string(msg))
+	time.Sleep(time.Second)
+	err = cli.Publish(&client.PublishOptions{
+		QoS:       mqtt.QoS0,
+		TopicName: []byte(topic),
+		Message:   msg,
+	})
+	if err != nil {
+		log.Panicln("Mqtt发布失败", err.Error())
+		return
+	}
+	fmt.Println("MQTT发送成功!")
+}
+
+// Subscript 订阅信息
+func Subscript(cli *client.Client, topic string, msg chan string, is_str string) {
+	fmt.Println("连接成功", time.Now().Format("2006-01-02 15:04:05"))
+	fmt.Printf("订阅主题:%s\n", topic)
+	cli.Subscribe(&client.SubscribeOptions{
+		SubReqs: []*client.SubReq{
+			&client.SubReq{
+				TopicFilter: []byte(topic),
+				QoS:         mqtt.QoS0,
+				Handler: func(topicName, message []byte) {
+					//如果管道已经关闭,表示已经超时
+					fmt.Println("MQTT接收到信息:", string(message))
+					if strings.Contains(strings.Replace(string(message), " ", "", -1), is_str) {
+						msg <- topic + "||" + string(message)
+						if _, ok := <-msg; !ok {
+							cli.Disconnect()
+							cli.Terminate()
+						}
+					}
+
+				},
+			},
+		},
+	})
+}

+ 62 - 0
controllers/MqttServer/MqttServevStructv2.go

@@ -0,0 +1,62 @@
+package MqttServer
+
+type DataRepeat_C struct {
+	Sns       map[string][]int `json:"sns"`
+	StartTime string           `json:"startTime"`
+	EndTime   string           `json:"endTime"`
+}
+
+// DataRepeat_Pub 數據重傳 服務器下發
+type DataRepeat_Pub struct {
+	Sn   string              `json:"sn"`
+	Type int                 `json:"type"`
+	Mid  int64               `json:"mid"`
+	Data DataRepeat_Pub_Data `json:"data"`
+}
+
+type DataRepeat_Pub_Data struct {
+	Id    []int `json:"id"`
+	Start int64 `json:"start"`
+	End   int64 `json:"end"`
+}
+
+// DataRepeat_Pub 數據重傳 服務器收到
+type DataRepeat_Sub struct {
+	Type   int   `json:"type"`
+	Min    int64 `json:"min"`
+	Status int   `json:"status"`
+}
+
+// Deviation_Pub 读取温度补偿 服务器下发
+type Deviation_Pub struct {
+	Type int    `json:"type"`
+	Sn   string `json:"sn"`
+	Mid  int64  `json:"mid"`
+	Data []int  `json:"data"`
+}
+
+type Deviation_Sub struct {
+	Type int                  `json:"type"`
+	Sn   string               `json:"sn"`
+	Mid  int                  `json:"mid"`
+	Data []Deviation_Sub_Data `json:"data"`
+}
+
+type Deviation_Sub_Data struct {
+	Id int     `json:"id"`
+	T  float64 `json:"t"`
+	H  float64 `json:"h"`
+}
+
+type Sensor_Sub struct {
+	Type int               `json:"type"`
+	Sn   string            `json:"sn"`
+	Mid  int               `json:"mid"`
+	Data []Sensor_Sub_Data `json:"data"`
+}
+
+type Sensor_Sub_Data struct {
+	Id    int     `json:"id"`
+	Speed float64 `json:"speed"`
+	Sense float64 `json:"sense"`
+}

+ 183 - 0
controllers/WebSocket/WebSocket.go

@@ -0,0 +1,183 @@
+package WebSocket
+
+import (
+	"ColdP_server/controllers/lib"
+	"container/list"
+	"encoding/json"
+	"fmt"
+	beego "github.com/beego/beego/v2/server/web"
+	"github.com/gorilla/websocket"
+	"net/http"
+	"sync"
+	"time"
+)
+
+// WebSocketController handles WebSocket requests.
+type WebSocketController struct {
+	beego.Controller
+}
+
+// 网关 -》服务端    json 通用模板
+type Event_w struct {
+	Type      int // JOIN, LEAVE, MESSAGE
+	Timestamp int // Unix timestamp (secs)
+	Content   interface{}
+}
+type Ms_Project struct {
+	Cmd string `json:"Cmd"`
+	Sn  string `json:"Sn"`
+}
+
+// Event archives.
+var archive = list.New()
+
+type WsConn struct {
+	Conn *websocket.Conn
+	Mux  sync.RWMutex
+}
+
+var (
+	countryCapitalMap map[string]WsConn /*创建集合 */
+)
+
+func Join_wc(user string, ws *websocket.Conn) bool {
+	// 有先加入 给全部人发消息
+	_, ok := countryCapitalMap[user] /*如果确定是真实的,则存在,否则不存在 */
+	if ok {
+		fmt.Println(user + " 重复")
+		countryCapitalMap[user] = WsConn{Conn: ws}
+		return true
+	} else {
+		fmt.Println(user + " 注册成功")
+		countryCapitalMap[user] = WsConn{Conn: ws}
+		return false
+	}
+}
+
+func Leave(user string) {
+	fmt.Println("注销:" + user)
+
+	for k, _ := range lib.CountrySnMap {
+
+		_, ok := lib.CountrySnMap[k].Uuid_list[user]
+		if ok {
+			fmt.Println("清楚成功 用户! KEY:", k, "  Uuid:", lib.CountrySnMap[k].Uuid_list[user])
+			delete(lib.CountrySnMap[k].Uuid_list, user)
+
+			if len(lib.CountrySnMap[k].Uuid_list) == 0 {
+				fmt.Println("清楚成功 SN! KEY:", k)
+				delete(lib.CountrySnMap, k)
+			}
+		}
+	}
+	delete(countryCapitalMap, user)
+
+}
+
+// This function handles all incoming chan messages.
+func chatroom() {
+	countryCapitalMap = make(map[string]WsConn)
+}
+
+func init() {
+	go chatroom()
+
+}
+
+// 连接 注册   Join method handles WebSocket requests for WebSocketController.
+func (this *WebSocketController) Join() {
+
+	// 验证登录
+	b_, admin_r := lib.Verification(this.Ctx.GetCookie("User_tokey"), this.GetString("User_tokey"))
+	if !b_ {
+		this.Redirect("/", 302)
+		return
+	}
+
+	// Upgrade from http request to WebSocket.
+	ws, err := websocket.Upgrade(this.Ctx.ResponseWriter, this.Ctx.Request, nil, 1024, 1024)
+	if _, ok := err.(websocket.HandshakeError); ok {
+		http.Error(this.Ctx.ResponseWriter, "Not a websocket handshake", 400)
+		return
+	} else if err != nil {
+		fmt.Println("无法设置WebSocket连接:", err)
+		return
+	}
+
+	// Join chat room.
+	is := Join_wc(admin_r.T_uuid, ws)
+
+	if !is {
+		defer Leave(admin_r.T_uuid) //  退后 会自动执行
+		time.Sleep(3 * time.Second)
+		for {
+			_, p, err := ws.ReadMessage()
+			if err != nil {
+				return
+			}
+			fmt.Println("============= WebSocket JSON =============")
+			fmt.Println(admin_r.T_uuid, "收到信息:", string(p))
+
+			var Ms_project Ms_Project
+			err = json.Unmarshal(p, &Ms_project)
+			if err != nil {
+				fmt.Println("JSON反序列化失败[Ms_Project],err=", err)
+				return
+			}
+
+			//fmt.Println("Cmd:", Ms_project.Cmd)
+			fmt.Println("Sn:", Ms_project.Sn)
+
+			//Parameter.Read_DeviceParameter(admin_r.T_uuid,Ms_project.Sn)
+
+			_, ok := lib.CountrySnMap[Ms_project.Sn] /*如果确定是真实的,则存在,否则不存在 */
+			if ok {
+
+			} else {
+				fmt.Println("CountrySnMap 没有,新建", Ms_project.Sn)
+				lib.CountrySnMap[Ms_project.Sn] = lib.Cl_{
+					Uuid_list: make(map[string]string),
+				}
+			}
+
+			// 是否 有相同 用户
+			_, ok = lib.CountrySnMap[Ms_project.Sn].Uuid_list[admin_r.T_uuid]
+			if ok {
+				fmt.Println("用户重复 ", admin_r.T_uuid)
+				data, _ := json.Marshal(lib.JSONS{Code: 201, Msg: "用户重复!", Data: admin_r.T_uuid})
+				Send_WebSocket(admin_r.T_uuid, string(data))
+
+			} else {
+				fmt.Println("用户新建 ", admin_r.T_uuid)
+				lib.CountrySnMap[Ms_project.Sn].Uuid_list[admin_r.T_uuid] = admin_r.T_uuid
+
+				data, _ := json.Marshal(lib.JSONS{Code: 200, Msg: "ok!", Data: admin_r.T_uuid})
+				Send_WebSocket(admin_r.T_uuid, string(data))
+
+				//lib.CountryRead_DeviceParameterSnMap[Ms_project.Sn] = ""
+			}
+
+		}
+	} else {
+		this.Redirect("/", 302)
+		return
+
+	}
+
+}
+
+/// -------------    ---------------------------------------------
+
+func Send_WebSocket(T_uuid string, T_json string) {
+
+	ws, ok := countryCapitalMap[T_uuid] /*如果确定是真实的,则存在,否则不存在 */
+	if ok && ws.Conn != nil {
+		ws.Mux.Lock()
+		if ws.Conn.WriteMessage(websocket.TextMessage, []byte(T_json)) != nil {
+			println("ok!")
+		}
+		ws.Mux.Unlock()
+
+	}
+
+}

+ 61 - 0
controllers/lib/Aes.go

@@ -0,0 +1,61 @@
+package lib
+
+import (
+	"bytes"
+	"crypto/aes"
+	"crypto/cipher"
+	"encoding/base64"
+)
+
+func AesEncryptCBC(orig string, key string) string {
+	// 转成字节数组
+	origData := []byte(orig)
+	k := []byte(key)
+	// 分组秘钥
+	// NewCipher该函数限制了输入k的长度必须为16, 24或者32
+	block, _ := aes.NewCipher(k)
+	// 获取秘钥块的长度
+	blockSize := block.BlockSize()
+	// 补全码
+	origData = PKCS7Padding(origData, blockSize)
+	// 加密模式
+	blockMode := cipher.NewCBCEncrypter(block, k[:blockSize])
+	// 创建数组
+	cryted := make([]byte, len(origData))
+	// 加密
+	blockMode.CryptBlocks(cryted, origData)
+	return base64.StdEncoding.EncodeToString(cryted)
+}
+func AesDecryptCBC(cryted string, key string) string {
+	// 转成字节数组
+	crytedByte, _ := base64.StdEncoding.DecodeString(cryted)
+	k := []byte(key)
+	// 分组秘钥
+	block, _ := aes.NewCipher(k)
+	// 获取秘钥块的长度
+	blockSize := block.BlockSize()
+	// 加密模式
+	blockMode := cipher.NewCBCDecrypter(block, k[:blockSize])
+	// 创建数组
+	orig := make([]byte, len(crytedByte))
+	// 解密
+	blockMode.CryptBlocks(orig, crytedByte)
+	// 去补全码
+	orig = PKCS7UnPadding(orig)
+	return string(orig)
+}
+
+// 补码
+// AES加密数据块分组长度必须为128bit(byte[16]),密钥长度可以是128bit(byte[16])、192bit(byte[24])、256bit(byte[32])中的任意一个。
+func PKCS7Padding(ciphertext []byte, blocksize int) []byte {
+	padding := blocksize - len(ciphertext)%blocksize
+	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+	return append(ciphertext, padtext...)
+}
+
+// 去码
+func PKCS7UnPadding(origData []byte) []byte {
+	length := len(origData)
+	unpadding := int(origData[length-1])
+	return origData[:(length - unpadding)]
+}

+ 44 - 0
controllers/lib/Message.go

@@ -0,0 +1,44 @@
+package lib
+
+import (
+	"fmt"
+	openapi "github.com/alibabacloud-go/darabonba-openapi/client"
+	dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v2/client"
+	"github.com/alibabacloud-go/tea/tea"
+)
+
+func message_CreateClient(accessKeyId *string, accessKeySecret *string) (_result *dysmsapi20170525.Client, _err error) {
+	config := &openapi.Config{
+		// 您的AccessKey ID
+		AccessKeyId: accessKeyId,
+		// 您的AccessKey Secret
+		AccessKeySecret: accessKeySecret,
+	}
+	// 访问的域名
+	config.Endpoint = tea.String("dysmsapi.aliyuncs.com")
+	_result = &dysmsapi20170525.Client{}
+	_result, _err = dysmsapi20170525.NewClient(config)
+	return _result, _err
+}
+func Message_Sand(PhoneNumbers string, TemplateCode string, TemplateParam string) {
+	client, _err := message_CreateClient(tea.String("LTAI5tBmBMw5s1nFvZsKXSPi"), tea.String("6L386APuJyCS8wyS726spfiwmKSksi"))
+	if _err != nil {
+		//Config.AddSysMessage(PhoneNumbers, TemplateCode, TemplateParam, "CreateClient  _err")
+		return
+	}
+
+	sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
+		PhoneNumbers:  tea.String(PhoneNumbers),
+		SignName:      tea.String("宝智达网络科技"),
+		TemplateCode:  tea.String(TemplateCode),
+		TemplateParam: tea.String(TemplateParam),
+	}
+	// 复制代码运行请自行打印 API 的返回值
+	_result, _err := client.SendSms(sendSmsRequest)
+
+	str := fmt.Sprintf("%s", _result.Body)
+	println(str)
+
+}
+
+// 	println(lib.Message_Sand("18777951277","SMS_215350603","{\"code\":\"1111\"}"))

+ 63 - 0
controllers/lib/Qiniu.go

@@ -0,0 +1,63 @@
+package lib
+
+// 存储相关功能的引入包只有这两个,后面不再赘述
+
+// 存储相关功能的引入包只有这两个,后面不再赘述
+import (
+	"context"
+	"fmt"
+	"github.com/qiniu/go-sdk/v7/auth/qbox"
+	"github.com/qiniu/go-sdk/v7/storage"
+)
+
+var mac *qbox.Mac
+
+var (
+	//BUCKET是你在存储空间的名称
+	accessKey = "-8ezB_d-8-eUFTMvhOGbGzgeQRPeKQnaQ3DBcUxo"
+	secretKey = "KFhkYxTAJ2ZPN3ZS3euTsfWk8-C92rKgkhAMkDRN"
+	BUCKET    = "bzdcoldoss"
+)
+
+// if !lib.Pload_qiniu("ofile/"+timeStr+".xlsx","ofile/"+timeStr+".xlsx"){
+// c.Data["json"] = lib.JSONS{Code: 203, Msg: "oss!"}
+// c.ServeJSON()
+// return
+// }
+func Pload_qiniu(localFile string, name string) bool {
+	//localFile := "C:\\Users\\Administrator\\Downloads\\kodo-browser-Windows-x64-v1.0.15.zip"
+	//key := "kodo-browser-Windows-x64-v1.0.15.zip"
+	// 自定义返回值结构体
+	type MyPutRet struct {
+		Key    string
+		Hash   string
+		Fsize  int
+		Bucket string
+		Name   string
+	}
+
+	bucket := BUCKET
+	//key := "your file save key"
+	// 使用 returnBody 自定义回复格式
+	putPolicy := storage.PutPolicy{
+		Scope:      bucket,
+		ReturnBody: `{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}`,
+	}
+	mac := qbox.NewMac(accessKey, secretKey)
+	upToken := putPolicy.UploadToken(mac)
+	cfg := storage.Config{}
+	formUploader := storage.NewFormUploader(&cfg)
+	ret := MyPutRet{}
+	putExtra := storage.PutExtra{
+		Params: map[string]string{
+			"x:name": "github logo",
+		},
+	}
+	err := formUploader.PutFile(context.Background(), &ret, upToken, name, localFile, &putExtra)
+	if err != nil {
+		fmt.Println(err)
+		return false
+	}
+	fmt.Println(ret.Bucket, ret.Key, ret.Fsize, ret.Hash, ret.Name)
+	return true
+}

+ 51 - 0
controllers/lib/Voice.go

@@ -0,0 +1,51 @@
+package lib
+
+import (
+	openapi "github.com/alibabacloud-go/darabonba-openapi/client"
+	dyvmsapi20170525 "github.com/alibabacloud-go/dyvmsapi-20170525/v2/client"
+	"github.com/alibabacloud-go/tea/tea"
+)
+
+/**
+ * 使用AK&SK初始化账号Client
+ * @param accessKeyId
+ * @param accessKeySecret
+ * @return Client
+ * @throws Exception
+ */
+func CreateClient(accessKeyId *string, accessKeySecret *string) (_result *dyvmsapi20170525.Client, _err error) {
+	config := &openapi.Config{
+		// 您的AccessKey ID
+		AccessKeyId: accessKeyId,
+		// 您的AccessKey Secret
+		AccessKeySecret: accessKeySecret,
+	}
+
+	// 访问的域名
+	config.Endpoint = tea.String("dyvmsapi.aliyuncs.com")
+	_result = &dyvmsapi20170525.Client{}
+	_result, _err = dyvmsapi20170525.NewClient(config)
+	return _result, _err
+}
+
+func M_main(args []*string) (_err error) {
+
+	accessKeyId := ""
+	accessKeySecret := ""
+	client, _err := CreateClient(&accessKeyId, &accessKeySecret)
+	if _err != nil {
+		return _err
+	}
+
+	addRtcAccountRequest := &dyvmsapi20170525.AddRtcAccountRequest{
+		ResourceOwnerAccount: tea.String("test"),
+		ResourceOwnerId:      tea.Int64(1),
+		DeviceId:             tea.String("test"),
+	}
+	// 复制代码运行请自行打印 API 的返回值
+	_, _err = client.AddRtcAccount(addRtcAccountRequest)
+	if _err != nil {
+		return _err
+	}
+	return _err
+}

+ 554 - 0
controllers/lib/lib.go

@@ -0,0 +1,554 @@
+package lib
+
+import (
+	"ColdP_server/models/Account"
+	"encoding/json"
+	"fmt"
+	beego "github.com/beego/beego/v2/server/web"
+	"github.com/nats-io/nats.go"
+	"log"
+	"math"
+	"math/rand"
+	"os"
+	"path/filepath"
+	"runtime"
+
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+)
+
+var Run_My_Server = false // 运行当期服务
+
+type Cl_ struct {
+	Uuid_list map[string]string // 泛型
+}
+
+var CountrySnMap map[string]Cl_    /*创建集合 */
+var DeviceRealSnMap map[string]int /*创建集合 */
+var Nats *nats.Conn
+
+func init() {
+	CountrySnMap = make(map[string]Cl_)
+	DeviceRealSnMap = make(map[string]int)
+
+}
+
+// PageHelper 分页结构体
+type PageHelper struct {
+	//TotalCount 总记录数
+	TotalCount int `json:"totalCount"`
+	//TotalPage 总页数
+	TotalPage int `json:"totalPage"`
+	//CurrentPage 当前页
+	CurrentPage int `json:"currentPage"`
+	//NextPage 是否存在下一页
+	NextPage bool `json:"nextPage"`
+	//PreviousPage 是否存在上一页
+	PreviousPage bool `json:"previousPage"`
+	//List 数据
+	List interface{} `json:"list"`
+}
+
+type JSONS struct {
+	//必须的大写开头
+	Code int16
+	Msg  string
+	Data interface{} // 泛型
+}
+type R_JSONS_List struct {
+	//必须的大写开头
+	Data      []interface{}
+	Num       int64
+	Page      int
+	Page_size int
+}
+type R_JSONS struct {
+	//必须的大写开头
+	Data      interface{}
+	Num       int64
+	Page      int
+	Page_size int
+}
+
+type R1_JSONS struct {
+	//必须的大写开头
+	List      interface{}
+	Num       int
+	Page      int
+	Page_size int
+	Pages     []Page_T
+}
+
+// 登录验证
+func Verification(GetCookie string, GetString string) (bool, Account.Admin) {
+	Run_My_Server = true // 运行当期服务
+	// 自适应 参数
+	User_tokey := GetCookie
+	if len(User_tokey) == 0 {
+		User_tokey = GetString
+	}
+	if len(User_tokey) == 0 {
+		return false, Account.Admin{}
+	}
+	tokey, is := Account.Redis_Tokey_Get(User_tokey)
+	if !is {
+		return false, Account.Admin{}
+	}
+	admin_r, err := Account.Read_Admin_ByUuid(tokey)
+	if err != nil {
+		return false, Account.Admin{}
+	}
+	log.Println("登录 Admin_name 为:", admin_r.T_name)
+	return true, admin_r
+}
+
+// VerificationController 登录验证 需要控制器对象
+func VerificationController(c *beego.Controller) (bool, Account.Admin) {
+	Run_My_Server = true // 运行当期服务
+	GetString := c.GetString("User_tokey")
+	GetCookie := c.Ctx.GetCookie("User_tokey")
+	// 自适应 参数
+	User_tokey := GetCookie
+	if len(User_tokey) == 0 {
+		User_tokey = GetString
+	}
+	if len(User_tokey) == 0 {
+		c.Data["json"] = JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return false, Account.Admin{}
+	}
+	tokey, is := Account.Redis_Tokey_Get(User_tokey)
+	if !is {
+		c.Data["json"] = JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return false, Account.Admin{}
+	}
+	admin_r, err := Account.Read_Admin_ByUuid(tokey)
+	if err != nil {
+		c.Data["json"] = JSONS{Code: 201, Msg: "User_tokey Err!"}
+		c.ServeJSON()
+		return false, Account.Admin{}
+	}
+	log.Println("登录 Admin_name 为:", admin_r.T_name)
+	return true, admin_r
+}
+
+// 登录验证
+func Verification_Tokey(GetCookie string, GetString string) bool {
+	Run_My_Server = true // 运行当期服务
+	// 自适应 参数
+	User_tokey := GetCookie
+	if len(User_tokey) == 0 {
+		User_tokey = GetString
+	}
+	if len(User_tokey) == 0 {
+		return false
+	}
+	_, is := Account.Redis_Tokey_Get(User_tokey)
+	if !is {
+		return false
+	}
+
+	return is
+}
+
+// func_page 分页   [{3 1} {4 2} {4 3} {4 4} {4 5} {4 6} {4 7} {4 8} {4 9} {5 2}]-
+type Page_T struct {
+	A int
+	V int64
+}
+
+func Func_page(Page int64, Page_size int64) (page_t_list []Page_T) {
+	if Page > 1 {
+		page_t_list = append(page_t_list, Page_T{A: 1, V: Page - 1})
+	}
+	i := int64(0)
+	for aa := int64(1); aa < 5; aa++ {
+		if Page-aa <= 0 {
+			break
+		}
+		page_t_list = append(page_t_list, Page_T{A: 2, V: Page - aa})
+		i++
+	}
+	page_t_list = append(page_t_list, Page_T{A: 3, V: Page})
+
+	for aa := int64(1); aa < 10-i; aa++ {
+		if Page_size < Page+aa {
+			break
+		}
+		page_t_list = append(page_t_list, Page_T{A: 4, V: Page + aa})
+	}
+	sort.Slice(page_t_list, func(i, j int) bool {
+		if page_t_list[i].V < page_t_list[j].V {
+			return true
+		}
+		return false
+	})
+	sort.Slice(page_t_list, func(i, j int) bool {
+		if page_t_list[i].A < page_t_list[j].A {
+			return true
+		}
+		return false
+
+	})
+	if Page < Page_size {
+		page_t_list = append(page_t_list, Page_T{A: 5, V: Page + 1})
+	}
+
+	return page_t_list
+}
+
+func Strval(value interface{}) string {
+	var key string
+	if value == nil {
+		return key
+	}
+
+	switch value.(type) {
+	case float64:
+		ft := value.(float64)
+		key = strconv.FormatFloat(ft, 'f', -1, 64)
+	case float32:
+		ft := value.(float32)
+		key = strconv.FormatFloat(float64(ft), 'f', -1, 64)
+	case int:
+		it := value.(int)
+		key = strconv.Itoa(it)
+	case uint:
+		it := value.(uint)
+		key = strconv.Itoa(int(it))
+	case int8:
+		it := value.(int8)
+		key = strconv.Itoa(int(it))
+	case uint8:
+		it := value.(uint8)
+		key = strconv.Itoa(int(it))
+	case int16:
+		it := value.(int16)
+		key = strconv.Itoa(int(it))
+	case uint16:
+		it := value.(uint16)
+		key = strconv.Itoa(int(it))
+	case int32:
+		it := value.(int32)
+		key = strconv.Itoa(int(it))
+	case uint32:
+		it := value.(uint32)
+		key = strconv.Itoa(int(it))
+	case int64:
+		it := value.(int64)
+		key = strconv.FormatInt(it, 10)
+	case uint64:
+		it := value.(uint64)
+		key = strconv.FormatUint(it, 10)
+	case string:
+		key = value.(string)
+	case []byte:
+		key = string(value.([]byte))
+	default:
+		newValue, _ := json.Marshal(value)
+		key = string(newValue)
+	}
+
+	return key
+}
+
+func To_int(value interface{}) int {
+	var key int
+	if value == nil {
+		return key
+	}
+	switch value.(type) {
+	case float64:
+		key = int(value.(float64))
+	case float32:
+		key = int(value.(float32))
+	case int:
+		key = int(value.(int))
+	case uint:
+		key = int(value.(uint))
+	case int8:
+		key = int(value.(int8))
+	case uint8:
+		key = int(value.(uint8))
+	case int16:
+		key = int(value.(int16))
+	case uint16:
+		key = int(value.(uint16))
+	case int32:
+		key = int(value.(int32))
+	case uint32:
+		key = int(value.(uint32))
+	case int64:
+		key = int(value.(int64))
+	case uint64:
+		key = int(value.(uint64))
+	case string:
+		key, _ = strconv.Atoi(value.(string))
+	case []byte:
+		key, _ = strconv.Atoi(string(value.([]byte)))
+	default:
+		newValue, _ := json.Marshal(value)
+		key, _ = strconv.Atoi(string(newValue))
+	}
+	return key
+}
+
+func To_float32(value interface{}) float32 {
+	var key float32
+	if value == nil {
+		return key
+	}
+
+	switch value.(type) {
+	case float64:
+		key = float32(value.(float64))
+	case float32:
+		key = float32(value.(float32))
+	case int:
+		key = float32(value.(int))
+	case uint:
+		key = float32(value.(uint))
+	case int8:
+		key = float32(value.(int8))
+	case uint8:
+		key = float32(value.(uint8))
+	case int16:
+		key = float32(value.(int16))
+	case uint16:
+		key = float32(value.(uint16))
+	case int32:
+		key = float32(value.(int32))
+	case uint32:
+		key = float32(value.(uint32))
+	case int64:
+		key = float32(value.(int64))
+	case uint64:
+		key = float32(value.(uint64))
+	case string:
+		key_float64, _ := strconv.ParseFloat(value.(string), 32/64)
+		key = float32(key_float64)
+	case []byte:
+		key_float64, _ := strconv.ParseFloat(string(value.([]byte)), 32/64)
+		key = float32(key_float64)
+	default:
+		newValue, _ := json.Marshal(value)
+		key_float64, _ := strconv.ParseFloat(string(newValue), 32/64)
+		key = float32(key_float64)
+	}
+
+	key_float64, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", key), 32/64)
+	key = float32(key_float64)
+
+	return key
+}
+
+func To_string(value interface{}) string {
+	var key string
+	if value == nil {
+		return key
+	}
+
+	switch value.(type) {
+	case float64:
+		ft := value.(float64)
+		key = strconv.FormatFloat(ft, 'f', -1, 64)
+	case float32:
+		ft := value.(float32)
+		key = strconv.FormatFloat(float64(ft), 'f', -1, 64)
+	case int:
+		it := value.(int)
+		key = strconv.Itoa(it)
+	case uint:
+		it := value.(uint)
+		key = strconv.Itoa(int(it))
+	case int8:
+		it := value.(int8)
+		key = strconv.Itoa(int(it))
+	case uint8:
+		it := value.(uint8)
+		key = strconv.Itoa(int(it))
+	case int16:
+		it := value.(int16)
+		key = strconv.Itoa(int(it))
+	case uint16:
+		it := value.(uint16)
+		key = strconv.Itoa(int(it))
+	case int32:
+		it := value.(int32)
+		key = strconv.Itoa(int(it))
+	case uint32:
+		it := value.(uint32)
+		key = strconv.Itoa(int(it))
+	case int64:
+		it := value.(int64)
+		key = strconv.FormatInt(it, 10)
+	case uint64:
+		it := value.(uint64)
+		key = strconv.FormatUint(it, 10)
+	case string:
+		key = value.(string)
+	case []byte:
+		key = string(value.([]byte))
+	default:
+		newValue, _ := json.Marshal(value)
+		key = string(newValue)
+	}
+	return key
+}
+
+func Random(min, max int) int {
+	rand.Seed(time.Now().Unix()) //Seed生成的随机数
+	return rand.Intn(max-min) + min
+}
+
+// 取文本(字符串)中间
+func GetBetweenStr(str, start, end string) string {
+	n := strings.Index(str, start)
+	if n == -1 {
+		n = 0
+	} else {
+		n = n + len(start) // 增加了else,不加的会把start带上
+	}
+	str = string([]byte(str)[n:])
+	m := strings.Index(str, end)
+	if m == -1 {
+		m = len(str)
+	}
+	str = string([]byte(str)[:m])
+	return str
+}
+
+// getYearMonthToDay 查询指定年份指定月份有多少天
+// @params year int 指定年份
+// @params month int 指定月份
+func GetYearMonthToDay(year int, month int) int {
+	// 有31天的月份
+	day31 := map[int]bool{
+		1:  true,
+		3:  true,
+		5:  true,
+		7:  true,
+		8:  true,
+		10: true,
+		12: true,
+	}
+	if day31[month] == true {
+		return 31
+	}
+	// 有30天的月份
+	day30 := map[int]bool{
+		4:  true,
+		6:  true,
+		9:  true,
+		11: true,
+	}
+	if day30[month] == true {
+		return 30
+	}
+	// 计算是平年还是闰年
+	if (year%4 == 0 && year%100 != 0) || year%400 == 0 {
+		// 得出2月的天数
+		return 29
+	}
+	// 得出2月的天数
+	return 28
+}
+
+func Decimal(value float64) float64 {
+	value, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", value), 64)
+	return value
+}
+
+func Strconv_Atoi(string string) int {
+	int, _ := strconv.Atoi(string)
+	return int
+}
+
+// golang获取程序运行路径
+func GetCurrentDirectory() string {
+	dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
+
+	return strings.Replace(dir, "\\", "/", -1)
+}
+
+// 获取正在运行的函数名
+func FuncName() string {
+	pc := make([]uintptr, 1)
+	runtime.Callers(2, pc)
+	f := runtime.FuncForPC(pc[0])
+	return f.Name()
+}
+
+func SplitStringIds(str string, prefix string) (r []string) {
+	Ids_str := strings.TrimRight(str, "|")
+	Ids := strings.Split(Ids_str, "|")
+	for _, v := range Ids {
+		r = append(r, strings.TrimLeft(v, prefix))
+	}
+	return r
+}
+
+// 过滤sql特殊字符
+func ReplaceSQL(name string) string {
+	name = strings.Replace(name, ";", "", -1)
+	name = strings.Replace(name, ",", "", -1)
+	name = strings.Replace(name, "?", "", -1)
+	name = strings.Replace(name, "<", "", -1)
+	name = strings.Replace(name, ">", "", -1)
+	name = strings.Replace(name, "(", "", -1)
+	name = strings.Replace(name, ")", "", -1)
+	name = strings.Replace(name, "@", "", -1)
+	name = strings.Replace(name, "=", "", -1)
+	name = strings.Replace(name, "+", "", -1)
+	name = strings.Replace(name, "*", "", -1)
+	name = strings.Replace(name, "&", "", -1)
+	name = strings.Replace(name, "#", "", -1)
+	name = strings.Replace(name, "%", "", -1)
+	name = strings.Replace(name, "$", "", -1)
+
+	return name
+}
+
+func StringListToDotStr(str []string) (r string) {
+	//for _, v := range str {
+	//	r += v + ","
+	//}
+	//r = strings.TrimRight(r, ",")
+
+	return strings.Join(str, ",")
+}
+
+func IntListToDotStr(list []int) (r string) {
+	for _, v := range list {
+		r += fmt.Sprintf("%d,", v)
+	}
+	r = strings.TrimRight(r, ",")
+	return r
+}
+func SplitStringToDotStr(str string, prefix string) (r string) {
+	Ids_str := strings.TrimRight(str, "|")
+	Ids := strings.Split(Ids_str, "|")
+	for _, v := range Ids {
+		r += strings.TrimLeft(v, prefix) + ","
+	}
+	r = strings.TrimRight(r, ",")
+	return r
+}
+
+// ["a","b","c"] ==> "'a','b','c'"
+func StringListToQuotesDotStr(str []string) (r string) {
+	for _, v := range str {
+		r += fmt.Sprintf("'%s',", v)
+	}
+	r = strings.TrimRight(r, ",")
+	return r
+}
+
+// 四舍五入保留小数点后几位
+func RoundToDecimal(num float64, decimalPlaces int) float64 {
+	shift := math.Pow(10, float64(decimalPlaces))
+	return math.Round(num*shift) / shift
+}

BIN
debug.exe


BIN
dev.exe


+ 70 - 0
go.mod

@@ -0,0 +1,70 @@
+module ColdP_server
+
+go 1.19
+
+require (
+	github.com/alibabacloud-go/darabonba-openapi v0.1.14
+	github.com/alibabacloud-go/dysmsapi-20170525/v2 v2.0.8
+	github.com/alibabacloud-go/dyvmsapi-20170525/v2 v2.1.1
+	github.com/alibabacloud-go/tea v1.1.17
+	github.com/beego/beego/v2 v2.0.1
+	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/cespare/xxhash/v2 v2.1.1 // indirect
+	github.com/go-sql-driver/mysql v1.6.0
+	github.com/golang/protobuf v1.4.2 // indirect
+	github.com/gorilla/websocket v1.4.2
+	github.com/hashicorp/golang-lru v0.5.4 // indirect
+	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
+	github.com/mitchellh/mapstructure v1.3.3 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	github.com/prometheus/client_golang v1.7.0 // indirect
+	github.com/prometheus/client_model v0.2.0 // indirect
+	github.com/prometheus/common v0.10.0 // indirect
+	github.com/satori/go.uuid v1.2.0
+	github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
+	github.com/xuri/excelize/v2 v2.7.0
+	golang.org/x/crypto v0.11.0 // indirect
+	golang.org/x/mod v0.8.0 // indirect
+	golang.org/x/net v0.10.0 // indirect
+	golang.org/x/sys v0.10.0 // indirect
+	golang.org/x/text v0.11.0 // indirect
+	golang.org/x/tools v0.6.0 // indirect
+	google.golang.org/protobuf v1.23.0 // indirect
+	gopkg.in/yaml.v2 v2.2.8 // indirect
+)
+
+require (
+	github.com/astaxie/beego v1.12.3
+	github.com/nats-io/nats.go v1.28.0
+	github.com/qiniu/go-sdk/v7 v7.11.1
+	github.com/vmihailenco/msgpack/v5 v5.3.5
+	github.com/yosssi/gmq v0.0.1
+)
+
+require (
+	github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.2 // indirect
+	github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect
+	github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
+	github.com/alibabacloud-go/openapi-util v0.0.10 // indirect
+	github.com/alibabacloud-go/tea-utils v1.4.3 // indirect
+	github.com/aliyun/credentials-go v1.1.2 // indirect
+	github.com/gomodule/redigo v2.0.0+incompatible // indirect
+	github.com/json-iterator/go v1.1.10 // indirect
+	github.com/klauspost/compress v1.16.7 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.1 // indirect
+	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
+	github.com/nats-io/nats-server/v2 v2.9.21 // indirect
+	github.com/nats-io/nkeys v0.4.4 // indirect
+	github.com/nats-io/nuid v1.0.1 // indirect
+	github.com/prometheus/procfs v0.1.3 // indirect
+	github.com/richardlehane/mscfb v1.0.4 // indirect
+	github.com/richardlehane/msoleps v1.0.3 // indirect
+	github.com/tjfoc/gmsm v1.3.2 // 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/sync v0.1.0 // indirect
+	gopkg.in/ini.v1 v1.56.0 // indirect
+
+)

+ 436 - 0
go.sum

@@ -0,0 +1,436 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.2 h1:/c6fLTlYKFd44Bx36A/cNuKekFzMqEPRc0QCLOC2Nok=
+github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.2/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
+github.com/alibabacloud-go/darabonba-openapi v0.1.11/go.mod h1:MPJMxv7HYrFm5m9uOZWkDYsAWyZztEgnBRfk9Fg0eIU=
+github.com/alibabacloud-go/darabonba-openapi v0.1.14 h1:3bQEoqeO0ZvSor1n5uqkb4TiFNAd8XMFYeGFll75L/c=
+github.com/alibabacloud-go/darabonba-openapi v0.1.14/go.mod h1:w4CosR7O/kapCtEEMBm3JsQqWBU/CnZ2o0pHorsTWDI=
+github.com/alibabacloud-go/darabonba-string v1.0.0/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA=
+github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 h1:NqugFkGxx1TXSh/pBcU00Y6bljgDPaFdh5MUSeJ7e50=
+github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY=
+github.com/alibabacloud-go/dysmsapi-20170525/v2 v2.0.8 h1:KXMiCg99Jx7B6V+DlRFbWwL9UCGippE5z1wGzhyimiA=
+github.com/alibabacloud-go/dysmsapi-20170525/v2 v2.0.8/go.mod h1:8aL6tSyQIWJygF7W/Vqxdf/QDbN2S+u57k36bEA8hD8=
+github.com/alibabacloud-go/dyvmsapi-20170525/v2 v2.1.1 h1:H/7br9z1bxF93mKo8YSbg4+KYWhPp/ht2BNgWA7zfBo=
+github.com/alibabacloud-go/dyvmsapi-20170525/v2 v2.1.1/go.mod h1:P+OKazJXlBImmn2gF0QF2qeb88rUqhfYF9NYG6FUQXw=
+github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q=
+github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
+github.com/alibabacloud-go/openapi-util v0.0.9/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
+github.com/alibabacloud-go/openapi-util v0.0.10 h1:wzTQc6ZSHhCI1FybUITHE26451zLgQAmYdTaMOUmoqE=
+github.com/alibabacloud-go/openapi-util v0.0.10/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
+github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg=
+github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
+github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
+github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
+github.com/alibabacloud-go/tea v1.1.15/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
+github.com/alibabacloud-go/tea v1.1.17 h1:05R5DnaJXe9sCNIe8KUgWHC/z6w/VZIwczgUwzRnul8=
+github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
+github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
+github.com/alibabacloud-go/tea-utils v1.3.9/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
+github.com/alibabacloud-go/tea-utils v1.4.3 h1:8SzwmmRrOnQ09Hf5a9GyfJc0d7Sjv6fmsZoF4UDbFjo=
+github.com/alibabacloud-go/tea-utils v1.4.3/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw=
+github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
+github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
+github.com/aliyun/credentials-go v1.1.2 h1:qU1vwGIBb3UJ8BwunHDRFtAhS6jnQLnde/yk0+Ih2GY=
+github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
+github.com/astaxie/beego v1.12.3 h1:SAQkdD2ePye+v8Gn1r4X6IKZM1wd28EyUOVQ3PDSOOQ=
+github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA=
+github.com/beego/beego/v2 v2.0.1 h1:07a7Z0Ok5vbqyqh+q53sDPl9LdhKh0ZDy3gbyGrhFnE=
+github.com/beego/beego/v2 v2.0.1/go.mod h1:8zyHi1FnWO1mZLwTn62aKRIZF/aIKvkCBB2JYs+eqQI=
+github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
+github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
+github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
+github.com/coreos/etcd v3.3.25+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U=
+github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
+github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
+github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
+github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
+github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
+github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
+github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0=
+github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
+github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
+github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
+github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
+github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
+github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
+github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
+github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/nats-io/jwt/v2 v2.4.1 h1:Y35W1dgbbz2SQUYDPCaclXcuqleVmpbRa7646Jf2EX4=
+github.com/nats-io/nats-server/v2 v2.9.21 h1:2TBTh0UDE74eNXQmV4HofsmRSCiVN0TH2Wgrp6BD6fk=
+github.com/nats-io/nats-server/v2 v2.9.21/go.mod h1:ozqMZc2vTHcNcblOiXMWIXkf8+0lDGAi5wQcG+O1mHU=
+github.com/nats-io/nats.go v1.28.0 h1:Th4G6zdsz2d0OqXdfzKLClo6bOfoI/b1kInhRtFIy5c=
+github.com/nats-io/nats.go v1.28.0/go.mod h1:XpbWUlOElGwTYbMR7imivs7jJj9GtK7ypv321Wp6pjc=
+github.com/nats-io/nkeys v0.4.4 h1:xvBJ8d69TznjcQl9t6//Q5xXuVhyYiSos6RPtvQNTwA=
+github.com/nats-io/nkeys v0.4.4/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64=
+github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
+github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
+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/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
+github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
+github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.7.0 h1:wCi7urQOGBsYcQROHqpUUX4ct84xp40t9R9JX0FuA/U=
+github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
+github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
+github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
+github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk=
+github.com/qiniu/go-sdk/v7 v7.11.1 h1:/LZ9rvFS4p6SnszhGv11FNB1+n4OZvBCwFg7opH5Ovs=
+github.com/qiniu/go-sdk/v7 v7.11.1/go.mod h1:btsaOc8CA3hdVloULfFdDgDc+g4f3TDZEFsDY0BLE+w=
+github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
+github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
+github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
+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/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=
+github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
+github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
+github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 h1:DAYUYH5869yV94zvCES9F51oYtN5oGlwjxJJz7ZCnik=
+github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
+github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
+github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=
+github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v1.1.0 h1:MkTeG1DMwsrdH7QtLXy5W+fUxWq+vmb6cLmyJ7aRtF0=
+github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
+github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
+github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
+github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM=
+github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
+github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
+github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
+github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
+github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
+github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
+github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
+github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c=
+github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
+github.com/xuri/excelize/v2 v2.7.0 h1:Hri/czwyRCW6f6zrCDWXcXKshlq4xAZNpNOpdfnFhEw=
+github.com/xuri/excelize/v2 v2.7.0/go.mod h1:ebKlRoS+rGyLMyUx3ErBECXs/HNYqyj+PbkkKRK5vSI=
+github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M=
+github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
+github.com/yosssi/gmq v0.0.1 h1:GhlDVaAQoi3Mvjul/qJXXGfL4JBeE0GQwbWp3eIsja8=
+github.com/yosssi/gmq v0.0.1/go.mod h1:mReykazh0U1JabvuWh1PEbzzJftqOQWsjr0Lwg5jL1Y=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
+go.etcd.io/etcd v3.3.25+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
+golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
+golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 h1:Lj6HJGCSn5AjxRAH2+r35Mir4icalbqku+CLUtjnvXY=
+golang.org/x/image v0.0.0-20220902085622-e7cb96979f69/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
+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-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+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 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+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=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+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.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=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+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/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=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+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.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
+golang.org/x/sys v0.10.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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+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.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
+golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+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=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/ini.v1 v1.56.0 h1:DPMeDvGTM54DXbPkVIZsp19fp/I2K7zwA/itHYHKo8Y=
+gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=

+ 1 - 0
lastupdate.tmp

@@ -0,0 +1 @@
+{"C:\\BZD\\Cold\\ColdP_server\\controllers":1716529645711645400}

+ 65 - 0
logs/LogPrintln.go

@@ -0,0 +1,65 @@
+package logs
+
+import (
+	"ColdP_server/conf"
+	"github.com/astaxie/beego/logs"
+	"runtime"
+)
+
+var logx *logs.BeeLogger
+var Test = true
+
+func init() {
+	logx = logs.NewLogger()
+	logx.SetLogger(logs.AdapterFile, `{"filename":"logs/logx/logx.log"}`)
+	logx.EnableFuncCallDepth(true)
+	logx.SetLogFuncCallDepth(3)
+	if conf.RunMode == "dev" {
+		logx.SetLogger("console")
+	}
+	if runtime.GOOS == "windows" {
+		Test = true
+	} else {
+		Test = false
+	}
+}
+
+func Println(format string, v ...interface{}) {
+	for _, _ = range v {
+		format += " %v"
+	}
+	logx.Info(format, v...)
+}
+
+// Debug Log DEBUG level message.
+func Debug(format string, v ...interface{}) {
+	for _, _ = range v {
+		format += " %v"
+	}
+	logx.Debug(format, v...)
+}
+
+// Info Log ERROR level message.
+func Info(format string, v ...interface{}) {
+	for _, _ = range v {
+		format += " %v"
+	}
+	logx.Info(format, v...)
+}
+
+// Error Log ERROR level message.
+func Error(format string, v ...interface{}) {
+	for _, _ = range v {
+		format += " %v"
+	}
+
+	logx.Error(format, v...)
+}
+
+// Warning Log WARNING level message.
+func Warning(format string, v ...interface{}) {
+	for _, _ = range v {
+		format += " %v"
+	}
+	logx.Warning(format, v...)
+}

+ 0 - 0
logs/access.log


+ 155 - 0
logs/logx/logx.2023-09-19.001.log

@@ -0,0 +1,155 @@
+2023/03/17 01:30:34.956 [D] [DataGeneratorController.go:187]  时间间隔: 60
+2023/03/17 01:30:34.956 [D] [DataGeneratorController.go:187]  时间间隔: 720
+2023/03/17 01:30:35.112 [D] [DataGeneratorController.go:187]  时间间隔: 60
+2023/03/17 01:30:35.112 [D] [DataGeneratorController.go:187]  时间间隔: 60
+2023/03/17 01:30:35.112 [D] [DataGeneratorController.go:187]  时间间隔: 60
+2023/03/17 14:42:03.981 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:42:03.981 [D] [DataGeneratorController.go:188]  时间间隔: 2760
+2023/03/17 14:42:04.953 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:24.629 [D] [DataGeneratorController.go:188]  时间间隔: 4680
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: -5640
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:53:26.446 [D] [DataGeneratorController.go:188]  时间间隔: 60
+2023/03/17 14:57:10.637 [D] [DataGeneratorController.go:190]  时间间隔: 60
+2023/03/17 14:57:10.638 [D] [DataGeneratorController.go:190]  时间间隔: 60
+2023/03/17 14:57:10.638 [D] [DataGeneratorController.go:190]  时间间隔: 60
+2023/03/17 14:57:10.638 [D] [DataGeneratorController.go:190]  时间间隔: 60
+2023/03/17 14:57:10.638 [D] [DataGeneratorController.go:190]  时间间隔: 1140
+2023/03/17 14:57:11.105 [D] [DataGeneratorController.go:190]  时间间隔: 60
+2023/03/17 14:57:11.105 [D] [DataGeneratorController.go:190]  时间间隔: 60
+2023/03/17 14:57:11.105 [D] [DataGeneratorController.go:190]  时间间隔: 60
+2023/03/17 14:57:11.105 [D] [DataGeneratorController.go:190]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:26:37.172 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:27:53.630 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:27:53.630 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:27:53.630 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:27:53.630 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:27:53.630 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:27:53.630 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:27:53.630 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:27:53.630 [D] [DataGeneratorController.go:220]  时间间隔: 2460
+2023/03/17 15:35:23.004 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.004 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.004 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.004 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.004 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.004 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.004 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.005 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.005 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.005 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.005 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.005 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.005 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:35:23.005 [D] [DataGeneratorController.go:220]  时间间隔: 2400
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:36:38.421 [D] [DataGeneratorController.go:220]  时间间隔: 2340
+2023/03/17 15:37:52.138 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:37:52.138 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:37:52.138 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:37:52.138 [D] [DataGeneratorController.go:220]  时间间隔: 2280
+2023/03/17 15:39:23.876 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:39:23.877 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:39:23.877 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:39:23.877 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:39:23.877 [D] [DataGeneratorController.go:220]  时间间隔: 2220
+2023/03/17 15:40:01.104 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:01.104 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:01.104 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:01.104 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:01.104 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:01.104 [D] [DataGeneratorController.go:220]  时间间隔: 2160
+2023/03/17 15:40:04.418 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.418 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.418 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.418 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.418 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.418 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.418 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.418 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.418 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.418 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.418 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.419 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.419 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.419 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.419 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.419 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.419 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.419 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.419 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.419 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.419 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.419 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.420 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.420 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.420 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.420 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.420 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.420 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.420 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.420 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.420 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:04.420 [D] [DataGeneratorController.go:220]  时间间隔: 660
+2023/03/17 15:40:05.442 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:05.442 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:05.443 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/03/17 15:40:05.443 [D] [DataGeneratorController.go:220]  时间间隔: 60
+2023/09/18 15:33:32.627 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/18 15:50:29.473 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/18 15:51:26.987 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/18 15:58:45.047 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/18 17:28:34.985 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/18 17:29:58.329 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/18 17:29:59.566 [E] [Device.go:203]  ColdP_server/models/Device.Read_Device_ByT_sn <QuerySeter> no row found
+2023/09/18 17:30:54.590 [E] [Device.go:203]  ColdP_server/models/Device.Read_Device_ByT_sn <QuerySeter> no row found
+2023/09/18 17:44:39.305 [E] [Device.go:203]  ColdP_server/models/Device.Read_Device_ByT_sn <QuerySeter> no row found
+2023/09/18 17:45:00.522 [E] [Device.go:203]  ColdP_server/models/Device.Read_Device_ByT_sn <QuerySeter> no row found
+2023/09/18 17:45:15.050 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/18 17:47:35.778 [E] [Device.go:203]  ColdP_server/models/Device.Read_Device_ByT_sn <QuerySeter> no row found
+2023/09/18 17:51:54.955 [E] [Device.go:203]  ColdP_server/models/Device.Read_Device_ByT_sn <QuerySeter> no row found
+2023/09/18 17:52:33.875 [E] [Device.go:203]  ColdP_server/models/Device.Read_Device_ByT_sn <QuerySeter> no row found
+2023/09/18 17:54:08.110 [E] [Device.go:203]  ColdP_server/models/Device.Read_Device_ByT_sn <QuerySeter> no row found
+2023/09/18 19:03:01.226 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/18 19:06:27.536 [I] [WarningType.go:192]  =========== 初始化报警类型 =========

+ 138 - 0
logs/logx/logx.2023-09-20.001.log

@@ -0,0 +1,138 @@
+2023/09/19 09:26:51.031 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/19 09:28:48.682 [E] [Device.go:203]  ColdP_server/models/Device.Read_Device_ByT_sn <QuerySeter> no row found
+2023/09/19 09:29:56.464 [E] [DeviceSensor.go:324]  ColdP_server/models/Device.Read_DeviceSensor_ByT_sn <QuerySeter> no row found
+2023/09/19 09:34:44.338 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/19 09:35:42.495 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/19 09:41:31.111 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.111 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.111 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.111 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.111 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.111 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.111 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.111 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.111 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.111 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.111 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.112 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 120
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 180
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 300
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 300
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 300
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 300
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 300
+2023/09/19 09:41:31.113 [D] [DataGeneratorController.go:220]  时间间隔: 300
+2023/09/19 09:58:00.702 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/19 09:58:56.161 [D] [DataGeneratorController.go:254]  时间间隔: 17700
+2023/09/19 10:03:27.881 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:03:27.881 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:03:27.881 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:03:27.881 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:03:27.881 [D] [DataGeneratorController.go:254]  时间间隔: 19200
+2023/09/19 10:03:30.807 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:03:30.807 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:06:49.008 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:06:49.008 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:06:49.008 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:06:49.008 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:06:49.008 [D] [DataGeneratorController.go:254]  时间间隔: 29100
+2023/09/19 10:06:55.760 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:06:55.760 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:06:55.760 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:54.567 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:54.567 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:54.567 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:54.567 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:54.567 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:54.567 [D] [DataGeneratorController.go:254]  时间间隔: 600
+2023/09/19 10:09:54.653 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:54.653 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:54.653 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:54.653 [D] [DataGeneratorController.go:254]  时间间隔: 600
+2023/09/19 10:09:54.747 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:54.747 [D] [DataGeneratorController.go:254]  时间间隔: 3300
+2023/09/19 10:09:55.241 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:55.241 [D] [DataGeneratorController.go:254]  时间间隔: 600
+2023/09/19 10:09:55.321 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:55.321 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 10:09:55.321 [D] [DataGeneratorController.go:254]  时间间隔: 300
+2023/09/19 11:30:57.860 [I] [WarningType.go:192]  =========== 初始化报警类型 =========

+ 6 - 0
logs/logx/logx.log

@@ -0,0 +1,6 @@
+2023/09/26 13:53:02.487 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2023/09/26 14:02:08.650 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/05/24 13:48:36.259 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/05/24 14:19:32.469 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/05/24 14:31:08.432 [I] [WarningType.go:192]  =========== 初始化报警类型 =========
+2024/05/24 14:33:19.628 [I] [WarningType.go:192]  =========== 初始化报警类型 =========

+ 315 - 0
models/Account/Admin.go

@@ -0,0 +1,315 @@
+package Account
+
+import (
+	"ColdP_server/conf"
+	"encoding/json"
+	"fmt"
+	"github.com/astaxie/beego/cache"
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type Admin struct {
+	Id      int    `orm:"column(ID);size(11);auto;pk"`
+	T_uuid  string `orm:"size(256);null"`     //  用户编号
+	T_pid   int    `orm:"size(200);null"`     //  绑定公司 ( 只有创建公司用户时添加,内部人员 为0)
+	T_pids  string `orm:"size(200);null"`     //  绑定公司管理 Pid| 如 P1|P2
+	T_power int    `orm:"size(2);default(0)"` // 权限 (关联权限表)
+	T_user  string `orm:"size(256);null"`     // 用户名 (唯一)
+	T_pass  string `orm:"size(256);null"`     // MD5
+
+	T_name  string `orm:"size(256);null"` // 姓名
+	T_phone string `orm:"size(256);null"` // 电话
+	T_mail  string `orm:"size(200);null"` // 邮箱
+	T_wx    string `orm:"size(256);null"` // 微信
+
+	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 每次 model 保存时都会对时间自动更新
+	UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now_add 第一次保存时才设置时间
+}
+
+type Admin_R struct {
+	T_uuid  string // 用户编号
+	T_pid   int    // 绑定公司 ( 只有创建公司用户时添加,内部人员 为0)
+	T_pids  string //  绑定公司管理 Pid| 如 P1|P2
+	T_power int    // 权限 (关联权限表)
+	T_user  string // 用户名 (唯一)
+	T_name  string // 姓名
+	T_phone string // 电话
+	T_mail  string // 邮箱
+	T_wx    string // 微信
+}
+
+type Admin_ struct {
+	T_name  string // 姓名
+	T_phone string // 电话
+}
+
+func AdminToAdmin_R(r Admin) (v Admin_R) {
+	v.T_uuid = r.T_uuid
+	v.T_pid = r.T_pid
+	v.T_pids = r.T_pids
+	v.T_power = r.T_power
+	v.T_user = r.T_user
+	v.T_name = r.T_name
+	v.T_phone = r.T_phone
+	v.T_mail = r.T_mail
+	v.T_wx = r.T_wx
+
+	return v
+}
+
+func AdminToAdmin_(r Admin) (v Admin_) {
+	v.T_name = r.T_name
+	v.T_phone = r.T_phone
+	return v
+}
+
+func (t *Admin) TableName() string {
+	return "admin" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+var redisCache_Admin cache.Cache
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(Admin))
+
+	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
+		"redis_ColdP_User_Admin", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
+	fmt.Println(config)
+	var err error
+	redisCache_Admin, err = cache.NewCache("redis", config)
+	if err != nil || redisCache_Admin == nil {
+		errMsg := "failed to init redis"
+		fmt.Println(errMsg, err)
+	}
+
+}
+
+// ---------------- Redis -------------------
+// Redis_Set(m.T_sn,m) // Redis 更新缓存
+func Redis_Admin_Set(r Admin) (err error) {
+	//json序列化
+	str, err := json.Marshal(r)
+	if err != nil {
+		fmt.Print(err)
+		return
+	}
+
+	err = redisCache_Admin.Put(r.T_uuid, str, 24*time.Hour)
+	if err != nil {
+		fmt.Println("set key:", r.T_uuid, ",value:", str, err)
+	}
+	return
+}
+
+// if r,is :=Redis_Get(T_sn);is{
+// return r,nil
+// }
+func Redis_Admin_Get(key string) (r Admin, is bool) {
+	if redisCache_Admin.IsExist(key) {
+		//println("找到key:",key)
+		v := redisCache_Admin.Get(key)
+
+		json.Unmarshal(v.([]byte), &r)
+		return r, true
+	}
+	//println("没有 找到key:",key)
+	return Admin{}, false
+}
+
+func Redis_Admin_DelK(key string) (err error) {
+	err = redisCache_Admin.Delete(key)
+	return
+}
+
+// ---------------- 特殊方法 -------------------
+
+// 添加
+func Add_Admin(m Admin) (id int64, err error) {
+	o := orm.NewOrm()
+	id, err = o.Insert(&m)
+	if err != nil {
+		fmt.Println(err)
+	}
+	m.Id = int(id)
+	Redis_Admin_Set(m)
+	return id, err
+}
+
+//// 修改
+//func Update_Delete_Admin_ByT_uuid(T_uuid string) (err error) {
+//	o := orm.NewOrm()
+//	v := Admin{T_uuid: T_uuid}
+//	// ascertain id exists in the database
+//	if err = o.Read(&v, "T_uuid"); err == nil {
+//		var num int64
+//		v.T_State = 0
+//
+//		if num, err = o.Update(&v, "T_State"); err == nil {
+//			fmt.Println("Number of records updated in database:", num)
+//		}
+//
+//		Redis_Admin_Set(v)
+//	}
+//	return err
+//}
+
+func Read_Admin_T_user(T_user string) (Admin, error) {
+
+	o := orm.NewOrm()
+	r := Admin{T_user: T_user, T_State: 1}
+	err := o.Read(&r, "T_user", "T_State") // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		fmt.Println(err)
+	}
+	return r, err
+}
+
+func Read_AdminLogin_verification(T_user string, T_pass string) (error, Admin) {
+
+	o := orm.NewOrm()
+	r := Admin{T_user: T_user, T_pass: T_pass, T_State: 1}
+	err := o.Read(&r, "T_user", "T_pass", "T_State") // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		fmt.Println(err)
+	}
+	Redis_Admin_Set(r) // Redis 更新缓存
+	return err, r
+}
+
+// 修改
+func Update_Admin(m Admin, cols ...string) bool {
+	o := orm.NewOrm()
+	if num, err := o.Update(&m, cols...); err == nil {
+		fmt.Println("Number of records updated in database:", num)
+		Redis_Admin_Set(m) // Redis 更新缓存
+		return true
+	}
+	return false
+}
+
+// 删除
+func Delete_Admin(v Admin) bool {
+	o := orm.NewOrm()
+	v.T_State = 0
+	if num, err := o.Update(&v, "T_State"); err == nil {
+		fmt.Println("Number of records updated in database:", num)
+	} else {
+		return false
+	}
+	Redis_Admin_DelK(v.T_uuid) // Redis 更新缓存
+	return true
+}
+
+// 获取 ById
+func Read_Admin_ById(Id int) (r Admin, err error) {
+	o := orm.NewOrm()
+	r = Admin{Id: Id, T_State: 1}
+	err = o.Read(&r, "Id", "T_State") // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		fmt.Println(err)
+	}
+	return r, err
+}
+
+// 获取 ByT_uuid
+func Read_Admin_ByUuid(T_uuid string) (r Admin, err error) {
+	if r, is := Redis_Admin_Get(T_uuid); is {
+		//println("Redis_Get  OK")
+		return r, nil
+	}
+	o := orm.NewOrm()
+	//redis 保存方式 uuid|公司pid
+	arr := strings.Split(T_uuid, "|")
+	r = Admin{T_uuid: arr[0], T_State: 1}
+	err = o.Read(&r, "T_uuid", "T_State") // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		fmt.Println(err)
+	}
+	//设置为redis中存储的pid
+	pid, _ := strconv.ParseInt(arr[1], 10, 64)
+	r.T_pid = int(pid)
+	return r, err
+}
+
+// 获取列表
+func Read_Admin_List(T_pid int, T_name string, page int, page_z int) (AdminList []Admin_R, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(Admin))
+	var maps []Admin
+
+	var offset int64
+	if page_z == 0 {
+		page_z = conf.Page_size
+	}
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_State", 1)
+
+	if T_pid > 0 {
+		cond1 = cond1.AndCond(cond.And("T_pid", T_pid))
+	}
+
+	if len(T_name) > 0 {
+		cond1 = cond1.AndCond(cond.Or("T_name__icontains", T_name).Or("T_user__icontains", T_name))
+	}
+
+	qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&maps)
+	cnt, _ = qs.SetCond((*orm2.Condition)(cond1)).Count()
+
+	for _, v := range maps {
+		AdminList = append(AdminList, AdminToAdmin_R(v))
+	}
+
+	return AdminList, cnt
+}
+
+func Read_Admin_List_T_pids(T_pid int) (AdminList []Admin_) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(Admin))
+	var maps []Admin
+	cond := orm.NewCondition()
+
+	cond1 := cond.And("T_State", 1).And("T_pid", 0).And("T_pids__icontains", "P"+strconv.Itoa(T_pid)+"|")
+
+	qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&maps)
+
+	for _, v := range maps {
+		AdminList = append(AdminList, AdminToAdmin_(v))
+	}
+
+	return AdminList
+}
+
+// 获取列表
+func Read_Admin_List_All() (AdminList []Admin_R) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(Admin))
+	var maps []Admin
+
+	qs.All(&maps)
+	for _, v := range maps {
+		AdminList = append(AdminList, AdminToAdmin_R(v))
+	}
+	return AdminList
+}

+ 63 - 0
models/Account/Tokey.go

@@ -0,0 +1,63 @@
+package Account
+
+import (
+	"ColdP_server/conf"
+	"fmt"
+	"github.com/astaxie/beego/cache"
+	_ "github.com/astaxie/beego/cache/redis"
+	uuid "github.com/satori/go.uuid"
+	"time"
+)
+
+var redisCache_Tokey cache.Cache
+
+func init() {
+	//注册模型
+	//orm.RegisterModel(new(Tokey))
+
+	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
+		"redis_Cold_User_Tokey", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
+	fmt.Println(config)
+	var err error
+	redisCache_Tokey, err = cache.NewCache("redis", config)
+	if err != nil || redisCache_Tokey == nil {
+		errMsg := "failed to init redis"
+		fmt.Println(errMsg, err)
+	}
+}
+
+// ---------------- Redis -------------------
+// Redis_Set(m.T_sn,m) // Redis 更新缓存
+func Add_Tokey_Set(Uuid, Pid string) string {
+	var Tokey string
+	for true {
+		Tokey = uuid.NewV4().String()
+		if !redisCache_Tokey.IsExist(Tokey) {
+			break
+		}
+		fmt.Print("申请 TOKEY 重复!重新生成。", Tokey)
+	}
+	userLoginInfo := fmt.Sprintf("%s|%s", Uuid, Pid)
+	redisCache_Tokey.Put(Tokey, userLoginInfo, 2*time.Hour)
+
+	return Tokey
+}
+
+// if r,is :=Redis_Get(T_sn);is{
+// return r,nil
+// }
+func Redis_Tokey_Get(Tokey string) (string, bool) {
+	if len(Tokey) < 10 {
+		return "", false
+	}
+	if redisCache_Tokey.IsExist(Tokey) {
+		//println("找到key:",key)
+		v := redisCache_Tokey.Get(Tokey)
+		value := string(v.([]byte)) //这里的转换很重要,Get返回的是interface
+
+		redisCache_Tokey.Put(Tokey, value, 2*time.Hour) //  重新计次
+		return value, true
+	}
+	//println("没有 找到key:",key)
+	return "", false
+}

+ 208 - 0
models/Company/CompanyClass.go

@@ -0,0 +1,208 @@
+package Company
+
+import (
+	"ColdP_server/conf"
+	"encoding/json"
+	"fmt"
+	"github.com/astaxie/beego/cache"
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"strconv"
+	"time"
+)
+
+type CompanyClass struct {
+	Id     int    `orm:"column(ID);size(11);auto;pk"`
+	T_pid  int    `orm:"index;size(256);null"` // Account.Company 绑定公司
+	T_name string `orm:"size(256);null"`       // 分类
+
+	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 CompanyClass_R struct {
+	Id     int
+	T_pid  int    // Account.Company 绑定公司
+	T_name string // 分类
+}
+
+func (t *CompanyClass) TableName() string {
+	return "company_class" // 数据库名称   // ************** 替换 DesignClass **************
+}
+
+var redisCache_CompanyClass cache.Cache
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(CompanyClass))
+}
+
+// Redis_Set(m.T_sn,m) // Redis 更新缓存
+func Redis_CompanyClass_Set(r CompanyClass) (err error) {
+	key := strconv.Itoa(r.Id)
+
+	//json序列化
+	str, err := json.Marshal(r)
+	if err != nil {
+		fmt.Print(err)
+		return
+	}
+
+	err = redisCache_CompanyClass.Put(key, str, 2*time.Hour)
+	if err != nil {
+		fmt.Println("set key:", key, ",value:", str, err)
+	}
+	return
+}
+
+// if r,is :=Redis_Get(T_sn);is{
+// return r,nil
+// }
+func Redis_CompanyClass_Get(key string) (CompanyClass, bool) {
+	println("找到key:", key)
+	if redisCache_CompanyClass.IsExist(key) {
+		//println("找到key:",key)
+		v := redisCache_CompanyClass.Get(key)
+		var r CompanyClass
+		json.Unmarshal(v.([]byte), &r)
+
+		return r, true
+	}
+
+	return CompanyClass{}, false
+}
+func Redis_CompanyClass_DelK(key string) (err error) {
+	err = redisCache_CompanyClass.Delete(key)
+	return
+}
+
+// ---------------- 特殊方法 -------------------
+func CompanyClassToCompanyClass_R(t CompanyClass) (r CompanyClass_R) {
+	r.Id = t.Id
+	r.T_pid = t.T_pid
+	r.T_name = t.T_name
+	return r
+}
+
+// 获取 ById
+func Read_CompanyClass_ById(id int) (r CompanyClass, err error) {
+	key := strconv.Itoa(id)
+	if r, is := Redis_CompanyClass_Get(key); is {
+		return r, nil
+	}
+	o := orm.NewOrm()
+	r = CompanyClass{Id: id, T_State: 1}
+	err = o.Read(&r, "Id", "T_pid", "T_State")
+	if err != nil {
+		fmt.Println(err)
+		return r, err
+	}
+	Redis_CompanyClass_Set(r)
+	return r, err
+}
+
+// 添加
+func Add_CompanyClass(m CompanyClass) (id int64, err error) {
+	o := orm.NewOrm()
+	id, err = o.Insert(&m)
+	if err != nil {
+		fmt.Println(err)
+	}
+	Redis_CompanyClass_Set(m)
+	return
+}
+
+// 修改
+func Update_CompanyClass(r CompanyClass, cols ...string) bool {
+	o := orm.NewOrm()
+	if num, err := o.Update(&r, cols...); err == nil {
+		fmt.Println("Number of records updated in database:", num)
+		Redis_CompanyClass_Set(r)
+		return true
+	}
+	return false
+}
+
+// 删除
+func Delete_CompanyClass_ById(id int) bool {
+	o := orm.NewOrm()
+	v := CompanyClass{Id: id}
+	// ascertain id exists in the database
+	if err := o.Read(&v); err == nil {
+		var num int64
+		v.T_State = 0
+		if num, err = o.Update(&v, "T_State"); err == nil {
+			fmt.Println("Number of records updated in database:", num)
+			key := strconv.Itoa(v.Id)
+			Redis_CompanyClass_DelK(key)
+			return true
+		}
+	}
+	return false
+}
+
+// 获取列表
+func Read_CompanyClass_List(T_pid int, T_name string, page int, page_z int) (r []CompanyClass_R, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var map_r []CompanyClass
+	qs := o.QueryTable(new(CompanyClass))
+	var offset int64
+	if page_z == 0 {
+		page_z = conf.Page_size
+	}
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	cond := orm.NewCondition()
+
+	cond1 := cond.And("T_State", 1)
+
+	if T_pid > 0 {
+		cond1 = cond1.And("T_pid", T_pid)
+	}
+	if len(T_name) > 0 {
+		cond1 = cond1.And("T_name", T_name)
+	}
+
+	qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&map_r)
+	cnt, _ = qs.SetCond((*orm2.Condition)(cond1)).Count()
+
+	for _, v := range map_r {
+		r = append(r, CompanyClassToCompanyClass_R(v))
+	}
+
+	return r, cnt
+
+}
+
+// 获取全部列表
+func Read_CompanyClass_All(T_pid int, T_name string) (r []CompanyClass_R) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var map_r []CompanyClass
+	qs := o.QueryTable(new(CompanyClass))
+
+	cond := orm.NewCondition()
+
+	cond1 := cond.And("T_State", 1).And("T_pid", T_pid)
+
+	if len(T_name) > 0 {
+		cond1 = cond1.And("T_name", T_name)
+	}
+
+	qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&map_r)
+
+	for _, v := range map_r {
+		r = append(r, CompanyClassToCompanyClass_R(v))
+	}
+	return r
+}

+ 294 - 0
models/Company/CompanyNotice.go

@@ -0,0 +1,294 @@
+package Company
+
+import (
+	"ColdP_server/conf"
+	"encoding/json"
+	"fmt"
+	"github.com/astaxie/beego/cache"
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type CompanyNotice struct {
+	Id     int    `orm:"column(ID);size(11);auto;pk"`
+	T_pid  int    `orm:"index;size(256);null"` // Account.Company 绑定公司
+	T_name string `orm:"size(256);null"`       // 分类
+
+	T_Notice_wx        string `orm:"type(text);null"` //w微信公众号  appid/名字|
+	T_Notice_wx2       string `orm:"type(text);null"` //w微信公众号  appid/名字|
+	T_Notice_phone     string `orm:"type(text);null"` //p手机  1111111|
+	T_Notice_message   string `orm:"type(text);null"` //m短信   1111111|
+	T_Notice_mailbox   string `orm:"type(text);null"` //e邮箱    1111111|
+	T_Notice_bind      string `orm:"type(text);null"` // 绑定T_sn,Tid|    862289056463538,1|8622546456433,1|
+	T_Notice_mechanism string `orm:"type(text);null"` // 报警机制
+	// W报警编号,处理,w启用,数量,上限,~|
+	// W15,0,0,0,0,0,0,0,0,0,0,0,0|
+
+	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 CompanyNotice_R struct {
+	T_name             string `orm:"size(256);null"`  // 分类
+	T_Notice_wx        string `orm:"type(text);null"` //w微信公众号  appid/名字|
+	T_Notice_wx2       string `orm:"type(text);null"` //w微信公众号  appid/名字|
+	T_Notice_phone     string `orm:"type(text);null"` //p手机  1111111|
+	T_Notice_message   string `orm:"type(text);null"` //m短信   1111111|
+	T_Notice_mailbox   string `orm:"type(text);null"` //e邮箱    1111111|
+	T_Notice_bind      string `orm:"type(text);null"` // 绑定T_sn,Tid|
+	T_Notice_mechanism string `orm:"type(text);null"` // 报警机制
+}
+
+func (t *CompanyNotice) TableName() string {
+	return "company_notice" // 数据库名称   // ************** 替换 DesignClass **************
+}
+
+var redisCache_CompanyNotice cache.Cache
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(CompanyNotice))
+
+	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
+		"redis_CompanyNotice", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
+	fmt.Println(config)
+	var err error
+	redisCache_CompanyNotice, err = cache.NewCache("redis", config)
+	if err != nil || redisCache_CompanyNotice == nil {
+		errMsg := "failed to init redis"
+		fmt.Println(errMsg, err)
+		panic(errMsg)
+	}
+
+}
+
+// Redis_Set(m.T_sn,m) // Redis 更新缓存
+func Redis_CompanyNotice_Set(r CompanyNotice) (err error) {
+	key := strconv.Itoa(r.Id)
+
+	//json序列化
+	str, err := json.Marshal(r)
+	if err != nil {
+		fmt.Print(err)
+		return
+	}
+
+	err = redisCache_CompanyNotice.Put(key, str, 2*time.Hour)
+	if err != nil {
+		fmt.Println("set key:", key, ",value:", str, err)
+	}
+	return
+}
+
+// if r,is :=Redis_Get(T_sn);is{
+// return r,nil
+// }
+func Redis_CompanyNotice_Get(key string) (CompanyNotice, bool) {
+	println("找到key:", key)
+	if redisCache_CompanyNotice.IsExist(key) {
+		//println("找到key:",key)
+		v := redisCache_CompanyNotice.Get(key)
+		var r CompanyNotice
+		json.Unmarshal(v.([]byte), &r)
+
+		return r, true
+	}
+
+	return CompanyNotice{}, false
+}
+func Redis_CompanyNotice_DelK(key string) (err error) {
+	err = redisCache_CompanyNotice.Delete(key)
+	return
+}
+
+// ---------------- 特殊方法 -------------------
+func CompanyNoticeToCompanyNotice_R(t CompanyNotice) (r CompanyNotice_R) {
+	r.T_name = t.T_name
+	r.T_Notice_wx = t.T_Notice_wx
+	r.T_Notice_wx2 = t.T_Notice_wx2
+	r.T_Notice_phone = t.T_Notice_phone
+	r.T_Notice_message = t.T_Notice_message
+	r.T_Notice_mailbox = t.T_Notice_mailbox
+	r.T_Notice_bind = t.T_Notice_bind
+	r.T_Notice_mechanism = t.T_Notice_mechanism
+	return r
+}
+
+// 获取 ById
+func Read_CompanyNotice_ById(id int) (r CompanyNotice, err error) {
+	key := strconv.Itoa(id)
+	if r, is := Redis_CompanyNotice_Get(key); is {
+		//println("Redis_Get  OK")
+		return r, nil
+	}
+
+	o := orm.NewOrm()
+	r = CompanyNotice{Id: id}
+	err = o.Read(&r) // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		fmt.Println(err)
+		return r, err
+	}
+
+	Redis_CompanyNotice_Set(r)
+	return r, err
+}
+
+// 添加
+func Add_CompanyNotice(m CompanyNotice) (id int64, err error) {
+	o := orm.NewOrm()
+	id, err = o.Insert(&m)
+	if err != nil {
+		fmt.Println(err)
+	}
+	Redis_CompanyNotice_Set(m)
+	return
+}
+
+// 删除
+func Delete_CompanyNotice_ById(id int) bool {
+	o := orm.NewOrm()
+	v := CompanyNotice{Id: id}
+	// ascertain id exists in the database
+	if err := o.Read(&v); err == nil {
+		var num int64
+		v.T_State = 0
+		if num, err = o.Update(&v, "T_State"); err == nil {
+			fmt.Println("Number of records updated in database:", num)
+			key := strconv.Itoa(v.Id)
+			Redis_CompanyNotice_DelK(key)
+			return true
+		}
+	}
+	return false
+}
+
+// 修改
+func Update_CompanyNotice(m CompanyNotice, cols ...string) bool {
+	o := orm.NewOrm()
+	if num, err := o.Update(&m, cols...); err == nil {
+		fmt.Println("Number of records updated in database:", num)
+		Redis_CompanyNotice_Set(m)
+		return true
+	}
+	return false
+}
+
+// 删除
+func Delete_CompanyNotice_ByT_pid_All(T_pid int) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(CompanyNotice))
+
+	var r []CompanyNotice
+	qs.Filter("T_pid", T_pid).Filter("T_State", 1).All(&r)
+	for _, v := range r {
+		v.T_State = 0
+		if _, err := o.Update(&v, "T_State"); err == nil {
+			Redis_CompanyNotice_DelK(strconv.Itoa(v.Id))
+		}
+	}
+
+}
+
+// 获取全部
+func Read_CompanyNotice_All_1() (r []CompanyNotice) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(CompanyNotice))
+	qs.Filter("T_State", 1).All(&r)
+	return r
+}
+
+// 获取列表
+func Read_CompanyNotice_List(T_pid int, T_name string, page int, page_z int) (r []CompanyNotice_R, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(CompanyNotice))
+	var maps []CompanyNotice
+	var offset int64
+	if page_z == 0 {
+		page_z = conf.Page_size
+	}
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	qs.Limit(conf.Page_size, offset).Filter("T_pid", T_pid).Filter("T_name__icontains", T_name).Filter("T_State", 1).OrderBy("-Id").All(&maps)
+	cnt, _ = qs.Filter("T_pid", T_pid).Filter("T_name__icontains", T_name).Filter("T_State", 1).Count()
+	for _, v := range maps {
+		r = append(r, CompanyNoticeToCompanyNotice_R(v))
+	}
+	return r, cnt
+}
+
+// 获取列表
+func Read_CompanyNotice_ALL_T_pid(T_pid int) (r []CompanyNotice) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(CompanyNotice))
+
+	qs.Filter("T_pid", T_pid).OrderBy("-Id").Filter("T_State", 1).All(&r)
+
+	return r
+}
+
+// 获取全部列表
+func Read_CompanyNotice_All(T_pid int, T_name string) (r []CompanyNotice_R) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var map_r []CompanyNotice
+	qs := o.QueryTable(new(CompanyNotice))
+
+	cond := orm.NewCondition()
+
+	cond1 := cond.And("T_State", 1).And("T_pid", T_pid)
+
+	if len(T_name) > 0 {
+		cond1 = cond1.And("T_name", T_name)
+	}
+
+	qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&map_r)
+
+	for _, v := range map_r {
+		r = append(r, CompanyNoticeToCompanyNotice_R(v))
+	}
+
+	return r
+
+}
+
+func Add_T_Notice_bind(T_sn string, T_id int, T_Notice_id int) (err error) {
+
+	o := orm.NewOrm()
+	v := CompanyNotice{Id: T_Notice_id}
+	T_Notice_bind := T_sn + strconv.Itoa(T_id) + "|"
+	if err = o.Read(&v, "Id"); err == nil {
+		v.T_Notice_bind = strings.Replace(v.T_Notice_bind, T_Notice_bind, "", -1)
+		v.T_Notice_bind = v.T_Notice_bind + T_Notice_bind
+		o.Update(&v, "T_Notice_bind")
+	}
+	return err
+}
+
+func Delete_T_Notice_bind(T_sn string, T_id int, T_Notice_id int) (err error) {
+	o := orm.NewOrm()
+	v := CompanyNotice{Id: T_Notice_id}
+	T_Notice_bind := T_sn + strconv.Itoa(T_id) + "|"
+	if err = o.Read(&v, "Id"); err == nil {
+		v.T_Notice_bind = strings.Replace(v.T_Notice_bind, T_Notice_bind, "", -1)
+		o.Update(&v, "T_Notice_bind")
+	}
+	return err
+
+}

+ 335 - 0
models/Device/Device.go

@@ -0,0 +1,335 @@
+package Device
+
+import (
+	"ColdP_server/conf"
+	"ColdP_server/controllers/lib"
+	"ColdP_server/logs"
+	"ColdP_server/models/Account"
+	"ColdP_server/models/Product"
+	"encoding/json"
+	"fmt"
+	"github.com/astaxie/beego/cache"
+	_ "github.com/astaxie/beego/cache/redis"
+	orm2 "github.com/beego/beego/v2/client/orm"
+
+	"github.com/beego/beego/v2/adapter/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"strconv"
+	"time"
+)
+
+// 设备
+type Device struct {
+	T_sn              string    `orm:"pk;size(256);null"`    // 设备序列号
+	T_pid             int       `orm:"index;size(256);null"` // Account.Company 绑定公司
+	T_devName         string    `orm:"size(256);null"`       // 设备名称  20字
+	T_protocol        int       `orm:"size(2);default(1)"`   // 冷链通讯协议 1 :1.0协议   2 :2.0协议    3 :3.0协议
+	T_mqttid          string    `orm:"size(256);null"`       // MQTT 服务ID
+	T_VerifyTime      time.Time `orm:"type(timestamp);null"` // 验证时间
+	T_CalibrationTime time.Time `orm:"type(timestamp);null"` // 校准时间
+	T_PatrolTime      time.Time `orm:"type(timestamp);null"` // 巡检时间
+	T_ist             int       `orm:"size(2);default(1)"`   // 温度   1开启   2关闭
+	T_ish             int       `orm:"size(2);default(1)"`   // 湿度   1开启   2关闭
+
+	// 设备同步参数
+	T_Dattery  int    `orm:"size(4);null"`             // 电量
+	T_Site     string `orm:"size(200);null"`           // GPS
+	T_monitor  int    `orm:"index;size(2);null"`       // 监控状态 0 未监控 1 监控  停止记录
+	T_online   int    `orm:"index;size(2);default(1)"` // 在线状态 0 未启用  1 在线  2 离线
+	T_online_s int    `orm:"index;size(2);default(0)"` // 在线状态-备用  0 未启用  1 在线  2 离线
+	T_State    int    `orm:"index;size(2);default(1)"` // 0 屏蔽   1 正常  (屏蔽后 只有内部管理员才能看到,用户 输入SN\名称 搜索时 也能看到)
+
+	// 硬件信息
+	T_model string `orm:"size(200);null"` // KF200BG  设备型号
+	T_sver  string `orm:"size(200);null"` // "1.0.0",//软件版本
+	T_hver  string `orm:"size(200);null"` // "1.0.0",//硬件版本
+	T_imei  string `orm:"size(200);null"` // "867387060327718",//模组imei
+	T_iccid string `orm:"size(200);null"` // "89860477102170049750",//sim卡号
+	T_rssi  string `orm:"size(200);null"` // "80",//信号强度
+
+	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 Device_R struct {
+	T_sn              string // 设备序列号 KF开头,环境监测主机。 YD开头,温途监测主机
+	T_devName         string // 设备名称
+	T_protocol        int    // 1 1.0协议  2 2.0协议
+	T_VerifyTime      string // 验证时间
+	T_CalibrationTime string // 校准时间
+	T_PatrolTime      string // 巡检时间
+	T_ist             int    // 温度   1开启   2关闭
+	T_ish             int    // 湿度   1开启   2关闭
+	T_Dattery         int    // 电量
+	T_Site            string // GPS
+	T_monitor         int    // 监控状态 0 未监控 1 监控 停止记录
+	T_online          int    // 在线状态 0 未启用  1 在线  2 离线
+	T_online_s        int    // 在线状态-备用  0 未启用  1 在线  2 离线
+	T_State           int    // 0 屏蔽   1 正常
+	// 硬件信息
+	T_model           string // KF200BG  产品型号
+	T_ProductTypeName string // 验证工具LoRa  产品统称 + 类型
+	T_sver            string // "1.0.0",//软件版本
+	T_hver            string // "1.0.0",//硬件版本
+	T_imei            string // "867387060327718",//模组imei
+	T_iccid           string // "89860477102170049750",//sim卡号
+	T_rssi            string // "80",//信号强度
+	CreateTime        string //auto_now_add 第一次保存时才设置时间
+	UpdateTime        string //auto_now 每次 model 保存时都会对时间自动更新
+
+	T_DeviceSensor_Num int // 传感器数量
+
+}
+
+type Device_task struct {
+	T_sn   string
+	T_task string
+}
+
+func (t *Device) TableName() string {
+	return "device" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+var redisCache_Device cache.Cache
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(Device))
+
+	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
+		"redis_Device", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
+	fmt.Println(config)
+	var err error
+	redisCache_Device, err = cache.NewCache("redis", config)
+	if err != nil || redisCache_Device == nil {
+		errMsg := "failed to init redis"
+		logs.Error(errMsg, err)
+		panic(any(errMsg))
+	}
+}
+
+func DeviceToDevice_R(r Device) (t Device_R) {
+	t.T_sn = r.T_sn
+	t.T_devName = r.T_devName
+	t.T_protocol = r.T_protocol
+	if !r.T_VerifyTime.IsZero() {
+		t.T_VerifyTime = r.T_VerifyTime.Format("2006-01-02 15:04:05")
+	}
+	if !r.T_CalibrationTime.IsZero() {
+		t.T_CalibrationTime = r.T_CalibrationTime.Format("2006-01-02 15:04:05")
+	}
+	if !r.T_PatrolTime.IsZero() {
+		t.T_PatrolTime = r.T_PatrolTime.Format("2006-01-02 15:04:05")
+	}
+
+	t.T_ist = r.T_ist
+	t.T_ish = r.T_ish
+	t.T_Dattery = r.T_Dattery
+	t.T_Site = r.T_Site
+	t.T_monitor = r.T_monitor
+	t.T_online = r.T_online
+	t.T_online_s = r.T_online_s
+	if r.T_online == 2 && (r.T_online_s == 0 || r.T_online_s == 2) && r.T_monitor == 1 {
+		t.T_monitor = 2
+	}
+	t.T_State = r.T_State
+
+	t.T_model = r.T_model
+	t.T_ProductTypeName = Product.Read_ProductType_Get(r.T_model)
+	t.T_sver = r.T_sver
+	t.T_hver = r.T_hver
+	t.T_imei = r.T_imei
+	t.T_iccid = r.T_iccid
+	t.T_rssi = r.T_rssi
+	t.CreateTime = r.CreateTime.Format("2006-01-02 15:04:05")
+	t.UpdateTime = r.UpdateTime.Format("2006-01-02 15:04:05")
+	t.T_DeviceSensor_Num = Read_DeviceSensor_Num_ByT_sn(r.T_sn)
+	return
+}
+
+// ---------------- Redis -------------------
+// Redis_Device_Set(m.T_sn,m) // Redis 更新缓存
+func Redis_Device_Set(r Device) (err error) {
+	//json序列化
+	str, err := json.Marshal(r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	err = redisCache_Device.Put(r.T_sn, str, 24*time.Hour)
+	if err != nil {
+		logs.Error("set key:", r.T_sn, ",value:", str, err)
+	}
+	return
+}
+
+// if r,is :=Redis_Device_Get(T_sn);is{
+// return r,nil
+// }
+func Redis_Device_Get(key string) (r Device, is bool) {
+	if redisCache_Device.IsExist(key) {
+		//println("找到key:",key)
+		v := redisCache_Device.Get(key)
+
+		err := json.Unmarshal(v.([]byte), &r)
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+			return Device{}, false
+		}
+		return r, true
+	}
+	return Device{}, false
+}
+
+func Redis_Device_DelK(key string) (err error) {
+	err = redisCache_Device.Delete(key)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	return
+}
+
+// ---------------- 特殊方法 -------------------
+
+// 获取 ById
+func Read_Device_ByT_sn(T_sn string) (r Device, err error) {
+
+	//println("没有 Redis_Device_Get SN")
+	o := orm.NewOrm()
+	r = Device{T_sn: T_sn}
+	err = o.Read(&r, "T_sn") // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, err
+	}
+
+	return r, nil
+}
+
+// 添加
+func Add_Device(m Device) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(&m)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	Redis_Device_Set(m) // Redis 更新缓存
+	return nil
+}
+
+// 删除
+func Delete_Device(m Device) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Delete(&m)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	Redis_Device_DelK(m.T_sn)
+	return
+}
+
+// 修改
+func Update_Device(r Device, cols ...string) bool {
+	o := orm.NewOrm()
+	num, err := o.Update(&r, cols...)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return false
+	}
+	fmt.Println("Number of records updated in database:", num)
+	Redis_Device_Set(r) // Redis 更新缓存
+	return true
+}
+
+// 获取列表
+func Read_Device_List(admin *Account.Admin, T_pid int, T_name string, T_monitor string, T_online string, page int, page_z int) (r []Device_R, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(Device))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_pid", T_pid)
+	// 非内部权限 - 不可查看屏蔽数据
+	if admin.T_pid > 0 {
+		cond1 = cond1.And("T_State", 1)
+	}
+
+	if len(T_name) > 0 {
+		cond1 = cond1.AndCond(cond.Or("T_sn__icontains", T_name).Or("T_devName__icontains", T_name))
+	}
+
+	if len(T_monitor) > 0 {
+		T_monitor_int, err := strconv.Atoi(T_monitor)
+		if err == nil {
+			cond1 = cond1.AndCond(cond.And("T_monitor", T_monitor_int))
+		}
+	}
+
+	//0 未启用  1 在线  2 离线
+	if T_online == "1" {
+		cond1 = cond1.AndCond(cond.And("T_online", 1))
+	} else if T_online == "2" {
+		cond1 = cond1.AndCond(cond.And("T_online", 2))
+	} else if T_online == "0" {
+		cond1 = cond1.AndCond(cond.And("T_online", 0).Or("T_online", 2))
+	}
+
+	var rx []Device
+
+	_, err := qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("CreateTime").All(&rx)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	cnt, err = qs.SetCond((*orm2.Condition)(cond1)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range rx {
+		r = append(r, DeviceToDevice_R(v))
+	}
+
+	return r, cnt
+}
+
+func Read_Device_ALL_T_Type_Count(T_pid int, T_type int) (cnt int64) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(Device))
+	cnt, _ = qs.Filter("T_pid", T_pid).Filter("T_type", T_type).Filter("T_State", 1).Count()
+	return cnt
+}
+
+func Read_Device_List_ByT_model(T_model string) (r []Device) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	qs := o.QueryTable(new(Device))
+	_, err := qs.Filter("T_model", T_model).All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	return r
+}
+
+// 获取设备sn的MqttId
+func ReadDeviceMqttId(sn string) (mqttId string) {
+	sql := orm.NewOrm()
+	sql.Raw("select t_mqttid from device where t_sn = ?", sn).QueryRow(&mqttId)
+	return
+}

+ 535 - 0
models/Device/DeviceData.go

@@ -0,0 +1,535 @@
+package Device
+
+import (
+	"ColdP_server/conf"
+	"ColdP_server/controllers/lib"
+	"encoding/json"
+	"fmt"
+	"github.com/astaxie/beego/cache"
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"github.com/xuri/excelize/v2"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// 建表
+// var CREATEsql = "CREATE TABLE IF NOT EXISTS `z_device_data_" + SN + " ( " +
+var CREATEsql = " ( " +
+	"`t_id` int(6) NOT NULL," +
+	"`t_sp` int(6) NOT NULL," +
+	"`t_time` datetime NOT NULL," +
+	"`t_t` double(6, 2) NULL DEFAULT NULL," +
+	"`t_rh` double(6, 2) NULL DEFAULT NULL," +
+	"`t_site` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL," +
+	"`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP," +
+	"PRIMARY KEY (`t_time`, `t_id`) USING BTREE" +
+	") ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;"
+
+type DeviceData_ struct {
+	T_id        int       // 传感器id
+	T_sp        int       // 传感器参数id
+	T_t         float32   // 温度
+	T_rh        float32   // 湿度
+	T_site      string    // GPS
+	T_time      time.Time // 采集时间
+	Create_time time.Time //创建时间
+}
+
+// 模板
+type DeviceData_R struct {
+	T_sn        string  `json:"t_sn"`   //设备
+	T_id        int     `json:"t_id"`   // 传感器id
+	T_name      string  `json:"t_name"` // 传感器名称
+	T_t         float32 `json:"t_t"`    // 温度
+	T_rh        float32 `json:"t_rh"`   // 湿度
+	T_site      string  `json:"t_site"` // GPS
+	T_tl        float32 `json:"t_tl"`   // 温度下限
+	T_tu        float32 `json:"t_tu"`   // 温度上限
+	T_rhl       float32 `json:"t_rhl"`  // 湿度下限
+	T_rhu       float32 `json:"t_rhu"`  // 湿度上限
+	T_time      string  `json:"t_time"` // 采集时间
+	Create_Time string  `json:"create_time"`
+}
+
+//func (t *DeviceData) TableName() string {
+//	return "DeviceData" // 数据库名称   // ************** 替换 FormulaList **************
+//}
+
+var redis_DeviceData cache.Cache
+
+func init() {
+
+	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
+		"redis_DeviceData", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
+	fmt.Println(config)
+	var err error
+	redis_DeviceData, err = cache.NewCache("redis", config)
+	if err != nil || redis_DeviceData == nil {
+		errMsg := "failed to init redis"
+		fmt.Println(errMsg, err)
+	}
+}
+
+func DeviceData_ToDeviceData_R(r DeviceData_, maps map[int]DeviceSensorParameter_M) (t DeviceData_R) {
+	t.T_id = r.T_id
+	t.T_t = r.T_t
+	t.T_rh = r.T_rh
+	t.T_site = r.T_site
+	t.T_time = r.T_time.Format("2006-01-02 15:04:05")
+	t.Create_Time = r.Create_time.Format("2006-01-02 15:04:05")
+	if sp, ok := maps[r.T_sp]; ok {
+		t.T_name = sp.T_name
+		t.T_tl = sp.T_Tlower
+		t.T_tu = sp.T_Tupper
+		t.T_rhl = sp.T_RHlower
+		t.T_rhu = sp.T_Tupper
+	}
+	return
+}
+
+// ---------------- Redis -------------------
+// Redis_Set(m.T_sn,m) // Redis 更新缓存
+func RedisDeviceData_Set(key string, r DeviceData_R) (err error) {
+	if redis_DeviceData.IsExist(key) {
+		var t DeviceData_R
+		v := redis_DeviceData.Get(key)
+		json.Unmarshal(v.([]byte), &t)
+		tTime, _ := time.Parse("2006-01-02 15:04:05", t.T_time)
+		rTime, _ := time.Parse("2006-01-02 15:04:05", r.T_time)
+		if tTime.Unix() > rTime.Unix() {
+			// 储存的 是最新数据
+			return
+		}
+	}
+
+	//json序列化
+	str, err := json.Marshal(r)
+	if err != nil {
+		fmt.Print(err)
+		return
+	}
+	err = redis_DeviceData.Put(key, str, 1*time.Hour)
+	if err != nil {
+		fmt.Println("set key:", key, ",value:", str, err)
+	}
+	return
+}
+
+func RedisDeviceData_Get(key string) (r DeviceData_R, is bool) {
+	if redis_DeviceData.IsExist(key) {
+		v := redis_DeviceData.Get(key)
+		json.Unmarshal(v.([]byte), &r)
+		return r, true
+	}
+	return DeviceData_R{}, false
+}
+
+// -------------------------------------------------------
+// 创建数据库  Device.CREATE_DeviceData("")
+func CREATE_DeviceData(SN string) bool {
+
+	sql := "CREATE TABLE IF NOT EXISTS `z_device_data_" + SN + "` " + CREATEsql
+	o := orm.NewOrm()
+	_, err := o.Raw(sql).Exec()
+	if err != nil {
+		return false
+	}
+	return true
+}
+
+func DELETE_DeviceDatar(SN string) bool {
+	timeStr := time.Now().Format("2006_01_02_15_04_05")
+	//sql := "DROP TABLE z_device_data_" + SN
+	sql := "ALTER TABLE z_device_data_" + SN + " RENAME TO " + "z_device_data_" + SN + "_dle_" + timeStr + ";"
+	o := orm.NewOrm()
+	_, err := o.Raw(sql).Exec()
+	if err != nil {
+		return false
+	}
+	return true
+}
+
+// ---------------- 特殊方法 ------------------
+type DeviceData_T struct {
+	T_id   int       // ID
+	T_t    float32   // 温度
+	T_rh   float32   // 湿度
+	T_Site string    // GPS
+	T_time time.Time // 采集时间
+}
+
+// 添加
+func Add_DeviceData(SN string, v DeviceData_T) bool {
+	//if(conf.Test_server){
+	//	fmt.Println("Add_DeviceData:",SN , t_name , t_id , t_t , t_rh , t_tl , t_tu , t_rhl , t_rhu , t_site , t_battery , t_time)
+	//	return true
+	//}
+
+	key_time := SN + "|" + strconv.Itoa(v.T_id) + "|" + v.T_time.Format("2006-01-02 15:04:05")
+	fmt.Println(key_time)
+	if redis_DeviceData.IsExist(key_time) {
+		//println("找到key:",key)
+		return true
+	}
+
+	o := orm.NewOrm()
+
+	// 检查 超过时间,查询 数据库
+	if time.Now().Unix()-v.T_time.Unix() >= 60*40 {
+		// 查看是否 有记录
+		var maps_z []orm2.ParamsList
+		sql_c := "SELECT COUNT(ID) FROM z_device_data_" + SN + " WHERE t_time = '" + v.T_time.Format("2006-01-02 15:04:05") + "' AND t_id = " + strconv.Itoa(v.T_id)
+		_, err := o.Raw(sql_c).ValuesList(&maps_z)
+		if err != nil {
+			return false
+		}
+		//fmt.Println("maps_z[0][0]:",maps_z[0][0])
+		if lib.To_int(maps_z[0][0]) > 0 {
+			return true
+		}
+	}
+
+	// 开始插入数据
+	sql := "INSERT INTO z_device_data_" + SN + " ( `t_id`, `t_t`, `t_rh`, `t_site`, `t_time`) " +
+		"VALUES (" + strconv.Itoa(v.T_id) + ", " + lib.To_string(v.T_t) + ", " + lib.To_string(v.T_rh) + ", '" + v.T_Site + "'," + v.T_time.Format("2006-01-02 15:04:05") + "')"
+	//  这里有时间优化  用于一次 prepare 多次 exec,以提高批量执行的速度
+	fmt.Println(sql)
+	res, err := o.Raw(sql).Exec()
+	if err != nil {
+		fmt.Println(err)
+		return false
+	}
+	res.RowsAffected()
+
+	return true
+}
+
+///---------------
+//type DeviceData_ struct {
+//	T_sn     string  `orm:"column(t_sn);size(256);null"`          // 标题
+//	T_id      int     `orm:"column(t_id);size(10);null"`           // ID
+//	T_t       float32 `orm:"column(t_t);size(10);null"`            // 温度
+//	T_rh      float32 `orm:"column(t_rh);size(10);null"`           // 湿度
+//	T_site    string  `orm:"column(t_site);type(timestamp);null;"` // GPS
+//	T_time    string  `orm:"column(t_time);type(timestamp);null;"` // 采集时间
+//}
+//type DeviceData_New struct {
+//	T_name    string    `orm:"column(t_name);size(256);null"`        // 标题
+//	T_id      int       `orm:"column(t_id);size(10);null"`           // ID
+//	T_t       float32   `orm:"column(t_t);size(10);null"`            // 温度
+//	T_rh      float32   `orm:"column(t_rh);size(10);null"`           // 湿度
+//	T_Tlower  float32   `orm:"column(t_tl);size(10);null"`           // 湿度
+//	T_Tupper  float32   `orm:"column(t_tu);size(10);null"`           // 湿度
+//	T_RHlower float32   `orm:"column(t_rhl);size(10);null"`          // 湿度
+//	T_RHupper float32   `orm:"column(t_rhu);size(10);null"`          // 湿度
+//	T_Site    string    `orm:"column(t_site);null;"`                 // GPS
+//	T_Dattery int       `orm:"column(t_dattery);size(10);null"`      // 电量
+//	T_time    time.Time `orm:"column(t_time);type(timestamp);null;"` // 采集时间
+//}
+
+func Read_DeviceData_ById_List(SN string, T_id int, Time_start_ string, Time_end_ string, page int, page_z int, SParamMap map[int]DeviceSensorParameter_M) ([]DeviceData_R, int) {
+	o := orm.NewOrm()
+	var maps []DeviceData_
+	var maps_z []orm2.ParamsList
+	var r []DeviceData_R
+	var offset int
+	if page_z == 0 {
+		page_z = conf.Page_size
+	}
+
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = (page - 1) * page_z
+	}
+	sql_time := ""
+
+	if len(Time_start_) > 1 {
+		sql_time += " t_time >= '" + Time_start_ + "' AND "
+	}
+
+	if len(Time_end_) > 1 {
+		sql_time += " t_time <= '" + Time_end_ + "' AND "
+	}
+
+	sql := "SELECT COUNT(t_id) FROM z_device_data_" + SN + " WHERE " + sql_time + " t_id = " + strconv.Itoa(T_id)
+	fmt.Println(sql)
+	_, err := o.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		return r, 0
+	}
+	if len(maps_z) == 0 {
+		return r, 0
+	}
+	//fmt.Println("maps_z;",maps_z[0][0])
+	//t_tl,t_tu,t_rhl,t_rhu,
+	sql = "SELECT t_id,t_sp,t_t,t_rh,t_site,DATE_FORMAT(t_time,'%Y-%m-%d %H:%i:%s') AS t_time,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%s') AS create_time  FROM z_device_data_" + SN + " WHERE " + sql_time + " t_id = " + strconv.Itoa(T_id) + " ORDER BY t_time DESC "
+	if page_z != 9999 {
+		sql = sql + " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(page_z)
+	}
+
+	fmt.Println(sql)
+	_, err = o.Raw(sql).QueryRows(&maps)
+
+	//value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", cnt), 64)
+	key, _ := strconv.Atoi(maps_z[0][0].(string))
+	fmt.Println("\n\n\n\n\n\n搜索结果:", maps)
+	for _, v := range maps {
+		r = append(r, DeviceData_ToDeviceData_R(v, SParamMap))
+	}
+	return r, key
+}
+
+func Read_SqlRaw(T_SQL string) []orm2.Params {
+	o := orm.NewOrm()
+	var lists []orm2.Params
+
+	fmt.Println(T_SQL)
+	o.Raw(T_SQL).Values(&lists)
+	fmt.Println(T_SQL+":", len(lists))
+	return lists
+}
+
+func Read_SqlRawL(T_SQL string, T_data []string) (string, []orm2.Params) {
+	o := orm.NewOrm()
+	var lists []orm2.Params
+	fmt.Println(T_SQL)
+	_, err := o.Raw(T_SQL, T_data).Values(&lists)
+	if err != nil {
+
+		return err.Error(), lists
+	}
+
+	return "", lists
+}
+
+func Read_DeviceData_By_T_snid_List(T_snid string, Time_start_ string, Time_end_ string, page int, page_z int) ([]DeviceData_R, int64) {
+	T_snid_list := strings.Split(T_snid, "|")
+	var maps []DeviceData_R
+	var maps_num int64
+	var offset, offset_z int
+
+	for _, v := range T_snid_list {
+		sn_id := strings.Split(v, ",")
+
+		if len(sn_id) == 2 {
+			SParamMap := Read_DeviceSensorParameter_Map_All(sn_id[0], lib.To_int(sn_id[1]))
+			r_maps, r_maps_num := Read_DeviceData_ById_List(sn_id[0], lib.To_int(sn_id[1]), Time_start_, Time_end_, 0, 9999, SParamMap)
+			//for i, _ := range r_maps {
+			//	r_maps[i].T_sn = sn_id[0]
+			//}
+			//添加一个sn设备标识
+			for i := range r_maps {
+				r_maps[i].T_sn = sn_id[0]
+			}
+			maps = append(maps, r_maps...)
+			maps_num = maps_num + int64(r_maps_num)
+
+			fmt.Println("加载数据:", sn_id[0], sn_id[1], r_maps_num)
+		}
+	}
+	if page <= 1 {
+		offset = 0
+	} else {
+		page -= 1
+		offset = page * page_z
+	}
+
+	offset_z = offset + page_z
+	if maps_num < int64(offset_z) {
+		offset_z = int(maps_num)
+	}
+
+	if page_z == 9999 {
+		fmt.Println("总数据:", maps_num, " 导出")
+		return maps, maps_num
+	}
+	fmt.Println("总数据:", maps_num, " 截取", offset, offset+page_z)
+	return maps[offset:offset_z], maps_num
+}
+
+// DeleteDeviceDataByDeviceDataRList 删除记录
+func DeleteDeviceDataByDeviceDataRList(datas []DeviceData_R) {
+	o := orm.NewOrm()
+	for _, v := range datas {
+		_, err := o.Raw(fmt.Sprintf("delete from z_device_data_%s where t_id = ? and t_t = ? and t_rh = ? and t_site = ? ", v.T_sn), v.T_id, v.T_t, v.T_rh, v.T_site).Exec()
+		if err != nil {
+			fmt.Println(err.Error())
+		}
+	}
+}
+
+// ImportDeviceData 批量导入
+func ImportDeviceData(reader *excelize.File, sn string) {
+	sheetName := reader.GetSheetName(0)
+	rows, err := reader.GetRows(sheetName)
+	if err != nil {
+		panic(any(err.Error()))
+	}
+	values := make([]string, len(rows)-1)
+	for i, row := range rows {
+		if i == 0 {
+			//跳过第一条头部描述
+			continue
+		}
+
+		t_sp := Read_device_sensor_parameter(sn, row[0])
+
+		// t_id,t_t,t_rh,t_time
+		//传感器	传感器参数ID	温度	湿度	GPS	采集时间	创建时间
+		values[i-1] = fmt.Sprintf("(%s,%s,%s,%s,'','%s')", row[0], t_sp, row[1], row[2], row[3])
+	}
+	sqlStatement := fmt.Sprintf("insert into z_device_data_%s(t_id,t_sp,t_t,t_rh,t_site,t_time) values %s", sn, strings.Join(values, ","))
+	fmt.Println("执行批量导入SQL:", sqlStatement)
+
+	//执行SQL
+	o := orm.NewOrm()
+	exec, err := o.Raw(sqlStatement).Exec()
+	if err != nil {
+		fmt.Println("执行失败")
+	} else {
+		rowsAffected, _ := exec.RowsAffected()
+		fmt.Println("插入", rowsAffected, "条数据")
+	}
+}
+
+// ExportDeviceData 导出 未完成
+/*func ExportDeviceData(sns []string, startTime, endTime string) *os.File {
+
+	f, err := os.Create(fmt.Sprintf("[%s]导出数据.zip", time.Now().Format("2006-01-02")))
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	z := zip.NewWriter(f)
+
+	o := orm.NewOrm()
+	sqlStatement := "select * from z_device_data_%s where create_time between %s and %s"
+	title := map[string]string{
+		"A1": "传感器",
+		"B1": "传感器参数ID",
+		"C1": "温度",
+		"D1": "湿度",
+		"E1": "GPS",
+		"F1": "采集时间",
+		"G1": "创建时间",
+	}
+	for _, sn := range sns {
+		datas := make([]DeviceData_, 0)
+		sqlNew := fmt.Sprintf(sqlStatement, sn, startTime, endTime)
+		o.Raw(sqlNew).QueryRows(&datas)
+
+		//创建压缩包中的excel
+		excelT, err := z.Create(fmt.Sprintf("%s.xlsx", sn))
+		if err != nil {
+			fmt.Println(err.Error())
+		}
+
+		//创建新的excel
+		excelNew := excelize.NewFile()
+		excelNew.NewSheet(sn)
+		//设置表头
+		for k, v := range title {
+			excelNew.SetCellStr(sn, k, v)
+		}
+		//设置内容
+		for i, v := range datas {
+
+		}
+	}
+	return f
+
+}
+*/
+// Update_DeviceSensorData 更新设备数据
+func Update_DeviceSensorData(v DeviceData_R, fieldName, val string) {
+	o := orm.NewOrm()
+	sqlStatemt := fmt.Sprintf("update z_device_data_%s set %s = ? where t_id = ? and t_t = ? and t_rh = ? and t_site = ? ", v.T_sn, fieldName)
+	_, err := o.Raw(sqlStatemt, val, v.T_id, v.T_t, v.T_rh, v.T_site).Exec()
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+}
+
+func Read_DeviceData_ById_Year_List(SN string) []orm2.ParamsList {
+	o := orm.NewOrm()
+
+	var maps_z []orm2.ParamsList
+
+	//sql = "SELECT t_name,t_t,t_rh,t_tl,t_tu,t_rhl,t_rhu,t_site,DATE_FORMAT(t_time,'%Y-%c-%d %H:%i:%s') AS t_time  FROM z_device_data_"+SN+" WHERE "+sql_time+" t_id = "+ strconv.Itoa(T_id) +" ORDER BY t_time DESC "
+	sql := "SELECT DATE_FORMAT(t_time,\"%m\") AS m ,DATE_FORMAT(t_time,\"%d\") AS d FROM z_device_data_" + SN + "  WHERE t_time > '" + strconv.Itoa(time.Now().Year()) + "-0-0 00:00:00' GROUP BY DATE_FORMAT(t_time,\"%m\");"
+	fmt.Println(sql)
+	num, err := o.Raw(sql).ValuesList(&maps_z)
+	if err == nil && num > 0 {
+		fmt.Println(maps_z[0][0]) // slene
+	}
+	//value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", cnt), 64)
+	//key,_ := strconv.Atoi(maps_z[0][0].(string))
+	return maps_z
+} //
+func Read_DeviceData_ById_Month_List(SN string) []orm2.ParamsList {
+	o := orm.NewOrm()
+
+	var maps_z []orm2.ParamsList
+	currentTime := time.Now() //获取当前时间,类型是Go的时间类型Time
+
+	time_x := currentTime.Format("2006-01") + "-00 00:00:00"
+
+	//sql = "SELECT t_name,t_t,t_rh,t_tl,t_tu,t_rhl,t_rhu,t_site,DATE_FORMAT(t_time,'%Y-%c-%d %H:%i:%s') AS t_time  FROM z_device_data_"+SN+" WHERE "+sql_time+" t_id = "+ strconv.Itoa(T_id) +" ORDER BY t_time DESC "
+	sql := "SELECT DATE_FORMAT(t_time,\"%d\") AS d FROM z_device_data_" + SN + "  WHERE t_time > '" + time_x + "' GROUP BY DATE_FORMAT(t_time,\"%d\");"
+	fmt.Println(sql)
+	o.Raw(sql).ValuesList(&maps_z)
+
+	//value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", cnt), 64)
+	//key,_ := strconv.Atoi(maps_z[0][0].(string))
+	return maps_z
+}
+func Read_device_sensor_parameter(SN, t_id string) string {
+	o := orm.NewOrm()
+	var maps_z []orm2.ParamsList
+
+	//sql = "SELECT t_name,t_t,t_rh,t_tl,t_tu,t_rhl,t_rhu,t_site,DATE_FORMAT(t_time,'%Y-%c-%d %H:%i:%s') AS t_time  FROM z_device_data_"+SN+" WHERE "+sql_time+" t_id = "+ strconv.Itoa(T_id) +" ORDER BY t_time DESC "
+	sql := "SELECT ID FROM device_sensor_parameter WHERE `t_sn` = '" + SN + "' AND `t_id` = '" + t_id + "' AND `t__state` = '1' ORDER BY `ID` DESC LIMIT 0,2;"
+	fmt.Println(sql)
+	o.Raw(sql).ValuesList(&maps_z)
+
+	//value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", cnt), 64)
+	//key,_ := strconv.Atoi(maps_z[0][0].(string))
+	return maps_z[0][0].(string)
+}
+func Read_DeviceData_ById_Day_List(SN string) []orm2.ParamsList {
+	o := orm.NewOrm()
+
+	var maps_z []orm2.ParamsList
+	currentTime := time.Now() //获取当前时间,类型是Go的时间类型Time
+
+	time_x := currentTime.Format("2006-01-02") + " 00:00:00"
+
+	//sql = "SELECT t_name,t_t,t_rh,t_tl,t_tu,t_rhl,t_rhu,t_site,DATE_FORMAT(t_time,'%Y-%c-%d %H:%i:%s') AS t_time  FROM z_device_data_"+SN+" WHERE "+sql_time+" t_id = "+ strconv.Itoa(T_id) +" ORDER BY t_time DESC "
+	sql := "SELECT DATE_FORMAT(t_time,\"%H\") AS m FROM z_device_data_" + SN + "  WHERE t_time > '" + time_x + "' GROUP BY DATE_FORMAT(t_time,\"%H\");"
+	fmt.Println(sql)
+	o.Raw(sql).ValuesList(&maps_z)
+
+	//value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", cnt), 64)
+	//key,_ := strconv.Atoi(maps_z[0][0].(string))
+	return maps_z
+}
+
+func Read_DeviceData_List_GROUP_BY_t_time(SN string, Time_start_ string, Time_end_ string) []orm2.ParamsList {
+	o := orm.NewOrm()
+
+	var maps_z []orm2.ParamsList
+
+	sql_time := ""
+	if len(Time_start_) > 1 {
+		sql_time += " t_time >= '" + Time_start_ + "' AND " + " t_time <= '" + Time_end_ + "' "
+	}
+
+	sql := "SELECT DATE_FORMAT(t_time,'%Y-%c-%d %H:%i:%s') AS t_time FROM z_device_data_" + SN + " WHERE " + sql_time + "   GROUP BY t_time  ORDER BY t_time DESC "
+	fmt.Println(sql)
+	o.Raw(sql).ValuesList(&maps_z)
+	return maps_z
+}

+ 226 - 0
models/Device/DeviceParameter.go

@@ -0,0 +1,226 @@
+package Device
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"time"
+)
+
+// 模板
+/*type DeviceParameter struct {
+	Id int `orm:"column(ID);size(11);auto;pk"`
+
+	T_sn           string `orm:"index;size(256);null"` //设备序列号 KF开头,环境监测主机。 YD开头,温途监测主机
+	T_devName      string `orm:"size(256);null"`       //设备名称
+	T_uploadTime   int    `orm:"size(200);null"`       //实时数据上传间隔
+	T_saveTime     int    `orm:"size(200);null"`       //数据保存间隔
+	T_overrunSave  int    `orm:"size(200);null"`       //数据超限保存间隔
+	T_overrunAlarm int    `orm:"size(200);null"`       //超限报警触发间隔
+	T_outageAlarm  int    `orm:"size(200);null"`       //断电报警触发间隔
+	T_lostAlarm    int    `orm:"size(200);null"`       //传感器掉线报警触发间隔
+	T_warningTime  int    `orm:"size(200);null"`       //超限预警触发间隔
+	T_warningDelay int    `orm:"size(200);null"`       //超限预警延时
+	T_batteryLimit int    `orm:"size(200);null"`       //电池电量下限
+	T_enwarning    int    `orm:"size(2);null"`         //是否启动超限预警
+	T_company      string `orm:"size(256);''"`         //公司名称
+	T_btname       string `orm:"size(256);''"`         //蓝牙打印机名称
+	T_btserverID   string `orm:"size(256);''"`         //打印机服务号
+	T_btchar       string `orm:"size(256);''"`         //蓝牙特征码
+	T_decTotal     string `orm:"size(256);''"`         ////配置管理主机总终端数量
+	T_chDecTotal   string `orm:"size(256);''"`         //[18,19,21,12,30,0,0,0,0,0]  //配置每个通道数量[第1通道,第2通道…第10通道]
+
+	T_uuid      string    `orm:"size(256);null"`                                        // 处理 人员
+	T_Msid      int       `orm:"size(50);0"`                                            // 消息识别ID
+	T_SendState int       `orm:"size(2);0"`                                             // 发送状态  0 待发送   1 发送成功  2 发送失败  3 丢弃
+	T_State     int       `orm:"size(2);default(1)"`                                    //  1 系统获取   2 用户提交
+	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 DeviceParameter struct {
+	Id int `orm:"column(ID);size(11);auto;pk"`
+
+	T_sn string `orm:"size(256);"` // 设备序列号 KF开头,环境监测主机。 YD开头,温途监测主机
+
+	T_name  string `orm:"size(256);"` //设备名称 (传 * 代表托管给平台处理) *
+	T_saveT int    `orm:"size(5);"`   //数据保存间隔 s(60~3600) 默认:60 *
+	T_overA int    `orm:"size(5);"`   //数据保存间隔 超限报警触发间隔 s(60~600) 默认:60  *
+	T_outA  int    `orm:"size(5);"`   //超限报警触发间隔 s(0,60~600)  为0时只触发一次 默认:60 *
+	T_lostA int    `orm:"size(5);"`   //传感器掉线报警触发间隔  s(0,60~600) 为0时只触发一次 默认:60  *
+	T_bat   int    `orm:"size(5);"`   // 电池电量下限   %(0~30) 默认:20 *
+	T_warn  int    `orm:"size(5);"`   // 超限预警触发间隔 s(0,60~600)为0时只触发一次 默认:60  *
+	T_warnD int    `orm:"size(5);"`   // 超限预警延时   s(0~600) 默认:0 *
+	//T_speed    int    `orm:"size(5);"`   // 传感器采样率   s(1~240) 默认:15 *
+	T_dormancy int    `orm:"size(5);"`   // 是否进入休眠  0:关闭 1:开启    默认:0
+	T_snum     int    `orm:"size(5);"`   // 【管理主机】 - 传感器数量  (范围0~255)
+	T_btname   string `orm:"size(256);"` //蓝牙打印机名称
+	T_btsid    int    `orm:"size(256);"` //打印机服务号
+	T_btchar   int    `orm:"size(256);"` //蓝牙特征码
+
+	T_uuid      string `orm:"size(256);"`          //处理 人员
+	T_Msid      int64  `orm:"size(50);default(0)"` // 消息识别ID
+	T_SendState int    `orm:"size(2);default(1)"`  // 发送状态  0 待发送   1 发送成功  2 发送失败  3 丢弃
+	T_State     int    `orm:"size(2);default(1)"`  //  1 系统获取   2 用户提交
+
+	CreateTime time.Time `orm:"column(create_time);type(timestamp);auto_now_add"` //auto_now_add 第一次保存时才设置时间
+	UpdateTime time.Time `orm:"column(update_time);type(timestamp);auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
+}
+
+func (t *DeviceParameter) TableName() string {
+	return "device_parameter" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(DeviceParameter))
+}
+
+// ---------------- 特殊方法 -------------------
+
+// 添加
+func Add_DeviceParameter(m DeviceParameter) (DeviceParameter, bool) {
+	o := orm.NewOrm()
+
+	id, err := o.Insert(&m)
+	if err != nil {
+		fmt.Println(err)
+		return m, false
+	}
+	m.Id = int(id)
+	return m, true
+}
+
+// 修改
+func Update_DeviceParameter(r DeviceParameter, cols ...string) bool {
+	o := orm.NewOrm()
+	if num, err := o.Update(&r, cols...); err == nil {
+		fmt.Println("Number of records updated in database:", num)
+		return true
+	}
+	return false
+}
+
+// 获取列表
+func Read_DeviceParameter_SN_Msid(T_sn string, T_Msid int) (r DeviceParameter, err error) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceParameter))
+
+	err = qs.Filter("T_sn", T_sn).Filter("T_Msid", T_Msid).One(&r)
+
+	return r, err
+}
+
+// 修改
+func Update_DeviceParameter_(m DeviceParameter) (err error) {
+	o := orm.NewOrm()
+	if num, err := o.Update(&m, "T_SendState"); err == nil {
+		fmt.Println("Number of records updated in database:", num)
+	}
+
+	return err
+}
+func DELETE_DeviceParameter(SN string) bool {
+
+	sql := "DELETE FROM `cold`.`device_parameter` WHERE `t_sn` = '" + SN + "' "
+	o := orm.NewOrm()
+	_, err := o.Raw(sql).Exec()
+	if err != nil {
+		return false
+	}
+	return true
+}
+
+// 获取列表
+func Read_DeviceParameter_SN(T_sn string) (r []DeviceParameter) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceParameter))
+	cond := orm.NewCondition()
+
+	cond1 := cond.And("T_sn", T_sn)
+
+	cond1 = cond.AndCond(cond1).AndCond(cond.And("T_State", 1).Or("T_SendState", 1))
+
+	qs.Limit(1, 0).SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&r)
+
+	return r
+}
+
+// 获取列表
+func Read_DeviceParameter_SN_T_State_1(T_sn string) (r []DeviceParameter) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceParameter))
+
+	qs.Limit(3, 0).Filter("T_sn", T_sn).Filter("T_State", 2).OrderBy("-Id").All(&r)
+
+	return r
+}
+
+// 获取列表
+func Read_DeviceParameter_SN_List(T_sn string) (r []DeviceParameter) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceParameter))
+
+	qs.Limit(10, 0).Filter("T_sn", T_sn).OrderBy("-Id").All(&r)
+
+	return r
+}
+
+// 获取列表
+func Read_DeviceParameter_SN_T_SendState_0(T_sn string) (r []DeviceParameter) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceParameter))
+
+	qs.Limit(1, 0).Filter("T_sn", T_sn).Filter("T_State", 2).Filter("T_SendState", 0).OrderBy("-Id").All(&r)
+
+	return r
+}
+
+// 获取最新数据
+func Read_DeviceParameter_SN_T_SendState_0_sql() (maps []orm2.ParamsList) {
+	o := orm.NewOrm()
+
+	sql := "SELECT DISTINCT t_sn FROM `cold`.`device_parameter` WHERE `t__send_state` = '0' AND `t__state` = '2'"
+
+	fmt.Println(sql)
+	o.Raw(sql).ValuesList(&maps)
+
+	return maps
+}
+
+// 获取最新数据
+func UPDATE_DeviceParameter_SN_T_SendState_2_sql(T_sn string) {
+	o := orm.NewOrm()
+
+	res, err := o.Raw("UPDATE DeviceParameter SET `t__send_state` = 3 WHERE `t_sn` LIKE '%" + T_sn + "%' AND `t__send_state` = '0' AND `t__state` = '2'").Exec()
+	if err == nil {
+		num, _ := res.RowsAffected()
+		fmt.Println("mysql row affected nums: ", num)
+	}
+
+}
+
+// ReadDeviceParameterByTsn 通过sn获取设备擦属
+func ReadDeviceParameterByTsn(tSn string) DeviceParameter {
+	o := orm.NewOrm()
+	query := o.QueryTable(new(DeviceParameter))
+	deviceParameter := DeviceParameter{}
+	query.Filter("t_sn", tSn).OrderBy("-update_time").One(&deviceParameter)
+	return deviceParameter
+}

+ 1016 - 0
models/Device/DeviceSensor.go

@@ -0,0 +1,1016 @@
+package Device
+
+import (
+	"ColdP_server/conf"
+	"ColdP_server/controllers/lib"
+	"ColdP_server/logs"
+	"ColdP_server/models/Account"
+	"encoding/json"
+	"fmt"
+	"github.com/astaxie/beego/cache"
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"log"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// 模板
+type DeviceSensor struct {
+	Id     int    `orm:"column(ID);size(11);auto;pk"`
+	T_sn   string `orm:"index;size(256);null"` // 设备序列号 KF开头,环境监测主机。 YD开头,温途监测主机
+	T_id   int    `orm:"index;size(11);null"`  // 传感器编号
+	T_name string `orm:"size(256);null"`       // 标题
+
+	T_pid      int    `orm:"index;size(256);null"`       // Account.Company 绑定公司
+	T_Class    string `orm:"size(256);null"`             // Device.DeviceClass.Id 设备分类  C1|C2|
+	T_Notice   string `orm:"size(256);null"`             // 通知绑定
+	T_datashow int    `orm:"index;size(2);default(1)"`   // 0 屏蔽数据展示  1 正常数据展示   (屏蔽后 数据展示无法看到,设备管理中 不受影响)
+	T_sort     int    `orm:"index;size(200);default(1)"` // 排序
+	T_3dview   string `orm:"size(256);null"`             // 3D 视图ID
+	T_type     int    `orm:"index;size(4);null"`         // Device.DeviceSensorType  1库房   2移动
+
+	// 设备同步参数
+	T_Dattery  int    `orm:"size(4);null"`             // 电量
+	T_Site     string `orm:"size(200);null"`           // GPS
+	T_monitor  int    `orm:"index;size(2);null"`       // 监控状态 0 未监控 1 监控
+	T_online   int    `orm:"index;size(2);default(1)"` // 在线状态 0 未启用  1 在线  2 离线
+	T_online_s int    `orm:"index;size(2);default(0)"` // 在线状态-备用  0 未启用  1 在线  2 离线
+	T_State    int    `orm:"index;size(2);default(1)"` // 0 屏蔽   1 正常  (屏蔽后 只有内部管理员才能看到,用户 输入SN\名称 搜索时 也能看到)
+
+	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 DeviceSensor_Del struct {
+	T_sn string
+	T_id int
+}
+
+func (t *DeviceSensor) TableName() string {
+	return "device_sensor" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+// 模板
+type DeviceSensor_R struct {
+	T_sn   string // 设备序列号 KF开头,环境监测主机。 YD开头,温途监测主机
+	T_id   int    // 传感器编号
+	T_name string // 标题
+
+	T_3dview   string // 3D 视图ID
+	T_sort     int    // 排序
+	T_Dattery  int    // 电量
+	T_Site     string // GPS
+	T_monitor  int    // 记录状态
+	T_online   int    // 在线状态 1 在线  0 离线
+	T_online_s int    // 在线状态-备用  0 未启用  1 在线  2 离线
+	T_datashow int    // 0 屏蔽数据展示  1 正常数据展示
+	T_type     int    // 1库房   2移动
+
+	T_DeviceSensorData      DeviceData_R            // 传感器最新数据
+	T_DeviceSensorParameter DeviceSensorParameter_R //  设备参数
+
+}
+
+// DeviceSensorData 处理数据生成专用
+type DeviceSensorData struct {
+	T_id       int     `json:"t_id"`
+	T_sp       string  `json:"t_sp"`
+	T_time     string  `json:"t_time"`
+	T_t        float64 `json:"t_t"`
+	T_rh       float64 `json:"t_rh"`
+	T_site     string  `json:"t_site"`
+	CreateTime string  `json:"create_time"`
+}
+
+// 传感器管理
+type DeviceSensor_P struct {
+	T_sn   string // 设备序列号 KF开头,环境监测主机。 YD开头,温途监测主机
+	T_id   int    // 传感器编号
+	T_name string // 标题
+
+	T_sort     int // 排序
+	T_datashow int // 0 屏蔽数据展示  1 正常数据展示
+	T_State    int // 0 屏蔽   1 正常
+
+	// DeviceSensorParameter
+	T_Tlower  *float32 //  温度下限
+	T_Tupper  *float32 //  温度上限
+	T_RHlower *float32 //  湿度下限
+	T_RHupper *float32 //  湿度上限
+
+	T_enprel *int     //  是否启用预警 1开启  0 关闭
+	T_tprel  *float32 //  温度预警下限
+	T_tpreu  *float32 //  温度预警上限
+	T_hprel  *float32 //  湿度预警下限
+	T_hpreu  *float32 //  温度预警上限
+
+	T_en   *int // en:是否启用传感器,
+	T_free *int // free:监测点是否为闲置状态(空库,只监测不报警)
+
+}
+
+type DeviceSensor_ struct {
+	T_sn   string // 设备序列号 KF开头,环境监测主机。 YD开头,温途监测主机
+	T_id   int    // 传感器编号
+	T_name string // 标题
+}
+
+type DataOld struct {
+	ID         int     `json:"ID"`
+	TSn        string  `json:"t_sn"`
+	TId        int     `json:"t_id"`
+	TTime      string  `json:"t_time"`
+	TT         float64 `json:"t_t"`
+	TRh        float64 `json:"t_rh"`
+	TSite      string  `json:"t__site"`
+	TOperation int     `json:"t_operation"`
+	TUuid      string  `json:"t_uuid"`
+	CreateTime string  `json:"create_time"`
+}
+
+var redisCache_DeviceSensor cache.Cache
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(DeviceSensor))
+
+	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
+		"redis_DeviceSensor", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
+	fmt.Println(config)
+	var err error
+	redisCache_DeviceSensor, err = cache.NewCache("redis", config)
+	if err != nil || redisCache_DeviceSensor == nil {
+		errMsg := "failed to init redis"
+		logs.Error(errMsg, err)
+		panic(any(errMsg))
+	}
+
+}
+
+// ---------------- Redis -------------------
+// Redis_Device_Set(m.T_sn,m) // Redis 更新缓存
+func Redis_DeviceSensor_Set(r DeviceSensor) (err error) {
+	key := r.T_sn + "|" + strconv.Itoa(r.T_id)
+
+	//json序列化
+	str, err := json.Marshal(r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	err = redisCache_DeviceSensor.Put(key, str, 24*time.Hour)
+	if err != nil {
+		logs.Error("set key:", key, ",value:", str, err)
+	}
+	return
+}
+func Redis_DeviceSensor_Get(key string) (r DeviceSensor, is bool) {
+	if redisCache_DeviceSensor.IsExist(key) {
+		//println("找到key:",key)
+		v := redisCache_DeviceSensor.Get(key)
+		err := json.Unmarshal(v.([]byte), &r)
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+			return DeviceSensor{}, false
+		}
+		return r, true
+	}
+	return DeviceSensor{}, false
+}
+func Redis_DeviceSensor_DelK(r DeviceSensor) (err error) {
+	key := r.T_sn + "|" + strconv.Itoa(r.T_id)
+	err = redisCache_DeviceSensor.Delete(key)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return
+}
+
+// ---------------- 特殊方法 -------------------
+/*
+func DeviceSensorToDeviceSensor_R(DeviceSensor_ DeviceSensor) (DeviceSensor_r DeviceSensor_R) {
+	lib.DeviceRealSnMap[DeviceSensor_.T_sn] = 3 // 连续请求 实时数据
+
+	DeviceSensor_r.T_sn = DeviceSensor_.T_sn
+	DeviceSensor_r.T_id = DeviceSensor_.T_id
+	DeviceSensor_r.T_name = DeviceSensor_.T_name
+	DeviceSensor_r.T_Site = DeviceSensor_.T_Site
+	DeviceSensor_r.T_Dattery = DeviceSensor_.T_Dattery
+	DeviceSensor_r.T_monitor = DeviceSensor_.T_monitor
+	DeviceSensor_r.T_3dview = DeviceSensor_.T_3dview
+	DeviceSensor_r.T_type = DeviceSensor_.T_type
+	DeviceSensor_r.T_sort = DeviceSensor_.T_sort
+
+	DeviceSensor_r.T_datashow = DeviceSensor_.T_datashow
+
+	DeviceSensor_r.T_Dattery = DeviceSensor_.T_Dattery
+	DeviceSensor_r.T_online = DeviceSensor_.T_online
+	DeviceSensor_r.T_online_s = DeviceSensor_.T_online_s
+	DeviceSensor_r.T_monitor = DeviceSensor_.T_monitor
+	if DeviceSensor_.T_online == 2 && (DeviceSensor_.T_online_s == 0 || DeviceSensor_.T_online_s == 2) && DeviceSensor_.T_monitor == 1 {
+		DeviceSensor_r.T_monitor = 2
+	}
+
+	// 最新系统参数
+	DeviceSensor_r.T_DeviceSensorParameter, _ = Read_DeviceSensorParameter(DeviceSensor_.T_sn, DeviceSensor_.T_id)
+
+	// 最新数据
+	//key_data := DeviceSensor_.T_sn + "|" + strconv.Itoa(DeviceSensor_.T_id)
+	//DeviceSensor_r.T_DeviceSensorData, _ = RedisDeviceData_Get(key_data)
+	DeviceData := Read_DeviceData(DeviceSensor_.T_sn, DeviceSensor_.T_id)
+	device, _ := Read_Device_ByT_sn(DeviceSensor_.T_sn)
+	DeviceSensor_r.T_DeviceSensorData = DeviceData_ToDeviceData_R(device, DeviceData)
+
+	return
+}
+*/
+func DeviceSensorToDeviceSensor_(r DeviceSensor) (t DeviceSensor_) {
+	t.T_sn = r.T_sn
+	t.T_id = r.T_id
+	t.T_name = r.T_name
+	return
+}
+
+// ---------------- 特殊方法 -------------------
+
+// 获取列表 - 总数
+func Read_DeviceSensor_Num_ByT_sn(T_sn string) int {
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	qs := o.QueryTable(new(DeviceSensor))
+	cnt, err := qs.Filter("T_sn", T_sn).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return 0
+	}
+	return int(cnt)
+}
+
+/*// 获取列表
+func Read_DeviceSensorList(admin_r *Account.Admin, T_pid int, T_sn string, T_name string, T_Class_id, T_datashow, T_type, T_State int, page int, page_z int) (DeviceSensor_r []DeviceSensor_R, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensor))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	var r []DeviceSensor
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_pid", T_pid)
+
+	if T_Class_id > 0 {
+		T_Class := "C" + strconv.Itoa(T_Class_id) + "|"
+		fmt.Println("T_Class:", T_Class)
+		cond1 = cond1.And("T_Class__icontains", T_Class)
+	}
+
+	if T_type > 0 {
+		cond1 = cond1.And("T_type", T_type)
+	}
+
+	if len(T_sn) > 0 {
+		cond1 = cond1.And("T_sn__icontains", T_sn)
+	}
+
+	if len(T_name) > 0 {
+		cond1 = cond1.AndCond(cond.Or("T_name__icontains", T_name).Or("T_sn__icontains", T_name))
+	}
+
+	// 不是内部权限(T_pid>0),T_State=1 0 屏蔽  1 正常
+	if admin_r.T_pid > 0 || T_State == 1 {
+		cond1 = cond1.And("T_State", 1)
+	}
+
+	if T_datashow == 1 { // 0 屏蔽数据展示  1 正常数据展示
+		cond1 = cond1.And("T_datashow", 1)
+	}
+
+	_, err := qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("T_sort", "T_id").All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	cnt, err = qs.SetCond((*orm2.Condition)(cond1)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range r {
+		DeviceSensor_r = append(DeviceSensor_r, DeviceSensorToDeviceSensor_R(v))
+	}
+	return DeviceSensor_r, cnt
+}
+*/
+// 获取
+func Read_DeviceSensor_ByT_sn(T_sn string, T_id int) (r DeviceSensor, is bool) {
+
+	o := orm.NewOrm()
+	r = DeviceSensor{T_sn: T_sn, T_id: T_id}
+	err := o.Read(&r, "T_sn", "T_id") // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, false
+	}
+
+	return r, true
+}
+
+// 删除
+func Delete_DeviceSensor_ById(T_sn string, T_id int) (err error) {
+	fmt.Println("Delete_DeviceSensor  : T_sn", T_sn, "T_id", T_id)
+	o := orm.NewOrm()
+	r := DeviceSensor{T_sn: T_sn, T_id: T_id}
+	err = o.Read(&r, "T_sn", "T_id") // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		fmt.Println("Delete_DeviceSensor_ById", err)
+		return err
+	}
+	_, err = o.Delete(&DeviceSensor{Id: r.Id})
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	Redis_DeviceSensor_DelK(r)
+	return
+}
+
+// 修改
+func Update_DeviceSensor(r DeviceSensor, cols ...string) bool {
+	o := orm.NewOrm()
+	num, err := o.Update(&r, cols...)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return false
+	}
+	fmt.Println("Number of records updated in database:", num)
+	Redis_DeviceSensor_Set(r)
+	return true
+
+}
+
+// 修改T_Class,替换为""
+func DeviceSensor_Bind_T_Class_Del(T_sn string, T_id int, T_Class_id int) (err error) {
+	o := orm.NewOrm()
+	v := DeviceSensor{T_sn: T_sn, T_id: T_id}
+	T_Class := "C" + strconv.Itoa(T_Class_id) + "|"
+	err = o.Read(&v, "T_sn", "T_id")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	v.T_Class = strings.Replace(v.T_Class, T_Class, "", -1)
+	_, err = o.Update(&v, "T_Class")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	Redis_DeviceSensor_Set(v)
+	return nil
+
+}
+
+// 修改T_Class,追加
+func DeviceSensor_Bind_T_Class_Add(T_sn string, T_id int, T_Class_id int) (err error) {
+	o := orm.NewOrm()
+	v := DeviceSensor{T_sn: T_sn, T_id: T_id}
+	T_Class := "C" + strconv.Itoa(T_Class_id) + "|"
+	err = o.Read(&v, "T_sn", "T_id")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	v.T_Class = strings.Replace(v.T_Class, T_Class, "", -1)
+	v.T_Class = v.T_Class + T_Class
+	_, err = o.Update(&v, "T_Class")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	Redis_DeviceSensor_Set(v)
+	return nil
+}
+
+// 获取 ById
+func Read_DeviceSensor_ByTsn_Tid(T_sn string, T_id int) (r DeviceSensor, err error) {
+
+	o := orm.NewOrm()
+	r = DeviceSensor{T_sn: T_sn, T_id: T_id}
+	err = o.Read(&r, "T_sn", "T_id") // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+
+	return r, err
+}
+
+// ReadDeviceSensorByTsnTidTimeRange 获取通过id和时间设备探头数据
+func ReadDeviceSensorByTsnTidTimeRange(T_sn string, T_id int, startTime, endTime string) (datas []DeviceSensorData, err error) {
+
+	o := orm.NewOrm()
+	sqlStatement := fmt.Sprintf("select t_id,t_sp,DATE_FORMAT(t_time,'%%Y-%%m-%%d %%H:%%i:%%s') as t_time,t_t,t_rh,DATE_FORMAT(create_time,'%%Y-%%m-%%d %%H:%%i:%%s') as create_time from z_device_data_%s where t_id = %d and t_time between '%s' and '%s'", T_sn, T_id, startTime, endTime)
+	_, err = o.Raw(sqlStatement).QueryRows(&datas)
+	return
+}
+
+// 获取列表
+func Read_DeviceSensor_ByTsn(T_sn string) ([]DeviceSensor, int) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensor))
+	var r []DeviceSensor
+	_, err := qs.Filter("T_sn", T_sn).OrderBy("T_id").All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, 0
+	}
+	cnt, err := qs.Filter("T_sn", T_sn).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, 0
+	}
+
+	return r, int(cnt)
+}
+
+// 获取列表
+func Read_DeviceSensor_List_T_ClassOr(T_pid int, T_Class_id int, T_sn string, T_name string, T_type int, page int, page_z int) (DeviceSensor_r []DeviceSensor_, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensor))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	T_Class := ""
+	if T_Class_id != 0 {
+		T_Class = "C" + strconv.Itoa(T_Class_id) + "|"
+	}
+
+	fmt.Println("T_Class:", T_Class)
+
+	var r []DeviceSensor
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_pid", T_pid).And("T_State", 1).And("T_Class__icontains", T_Class).And("T_sn__icontains", T_sn).Or("T_name__icontains", T_name).And("T_pid", T_pid).And("T_State", 1).And("T_Class__icontains", T_Class) // .AndNot("status__in", 1).Or("profile__age__gt", 2000)
+	if T_type > 0 {
+		cond1 = cond1.AndCond(cond.And("T_type", T_type))
+	}
+
+	fmt.Printf("分页数据:%d ,%d\n\n\n\n", offset, page_z)
+	_, err := qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("T_sort", "T_id").All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+
+		return
+	}
+	cnt, err = qs.SetCond((*orm2.Condition)(cond1)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range r {
+		DeviceSensor_r = append(DeviceSensor_r, DeviceSensorToDeviceSensor_(v))
+	}
+	return DeviceSensor_r, cnt
+}
+
+// 获取列表
+func Read_DeviceSensor_List_T_Class(T_pid int, T_Class_id int, T_sn string, T_name string, T_type int, page int, page_z int) (DeviceSensor_r []DeviceSensor_, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensor))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	T_Class := ""
+	if T_Class_id != 0 {
+		T_Class = "C" + strconv.Itoa(T_Class_id) + "|"
+	}
+
+	fmt.Println("T_Class:", T_Class)
+
+	var r []DeviceSensor
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_pid", T_pid).And("T_State", 1).And("T_Class__icontains", T_Class).And("T_sn__icontains", T_sn).And("T_name__icontains", T_name) // .AndNot("status__in", 1).Or("profile__age__gt", 2000)
+	if T_type > 0 {
+		cond1 = cond1.AndCond(cond.And("T_type", T_type))
+	}
+
+	fmt.Printf("分页数据:%d ,%d\n\n\n\n", offset, page_z)
+	_, err := qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("T_sort", "T_id").All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+
+		return
+	}
+	cnt, err = qs.SetCond((*orm2.Condition)(cond1)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range r {
+		DeviceSensor_r = append(DeviceSensor_r, DeviceSensorToDeviceSensor_(v))
+	}
+	return DeviceSensor_r, cnt
+}
+
+// 获取列表
+func Read_DeviceSensor_ALL_T_sn_T_id_T_Class(T_sn string, T_id int, T_Class_id int) (r []DeviceSensor) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensor))
+	T_Class := "C" + strconv.Itoa(T_Class_id) + "|"
+	_, err := qs.Filter("T_Class__icontains", T_Class).Filter("T_id", T_id).Filter("T_sn", T_sn).All(&r)
+
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	return r
+}
+
+// 获取列表
+func Read_DeviceSensor_ALL_List_T_sn(T_sn string) (r []DeviceSensor) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensor))
+
+	_, err := qs.Filter("T_sn", T_sn).All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	return r
+}
+
+// 获取列表
+func Read_DeviceSensor_ALL_Class_Id(T_Class_id int) (r []DeviceSensor) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensor))
+	T_Class := "C" + strconv.Itoa(T_Class_id) + "|"
+	_, err := qs.Filter("T_Class__icontains", T_Class).All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	return r
+}
+
+func DELETE_DeviceSensor(SN string) bool {
+
+	sql := "DELETE FROM `cold`.`device_sensor` WHERE `t_sn` = '" + SN + "' "
+	o := orm.NewOrm()
+	_, err := o.Raw(sql).Exec()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return false
+	}
+	return true
+}
+
+// 报警策略 -------------------
+
+// 通过T_sn T_id T_Notice_id 获取全部列表
+func Read_DeviceSensor_ALL_T_sn_T_id_T_Notice(T_sn string, T_id int, T_Notice_id int) (r []DeviceSensor) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensor))
+	T_Notice := "N" + strconv.Itoa(T_Notice_id) + "|"
+	_, err := qs.Filter("T_Notice__icontains", T_Notice).Filter("T_id", T_id).Filter("T_sn", T_sn).All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	return r
+}
+
+// 修改T_Notice,替换为""
+func DeviceSensor_Bind_T_Notice_Del(T_sn string, T_id int, T_Notice_id int) (err error) {
+	o := orm.NewOrm()
+	v := DeviceSensor{T_sn: T_sn, T_id: T_id}
+	T_Notice := "N" + strconv.Itoa(T_Notice_id) + "|"
+	err = o.Read(&v, "T_sn", "T_id")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	v.T_Notice = strings.Replace(v.T_Notice, T_Notice, "", -1)
+	_, err = o.Update(&v, "T_Notice")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	Redis_DeviceSensor_Set(v)
+	return nil
+
+}
+
+// 修改T_Notice,追加
+func DeviceSensor_Bind_T_Notice_Add(T_sn string, T_id int, T_Notice_id int) (err error) {
+	o := orm.NewOrm()
+	v := DeviceSensor{T_sn: T_sn, T_id: T_id}
+	T_Notice := "N" + strconv.Itoa(T_Notice_id) + "|"
+	err = o.Read(&v, "T_sn", "T_id")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	v.T_Notice = strings.Replace(v.T_Notice, T_Notice, "", -1)
+	v.T_Notice = v.T_Notice + T_Notice
+	_, err = o.Update(&v, "T_Notice")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	Redis_DeviceSensor_Set(v)
+	return nil
+}
+
+// 获取列表
+func Read_DeviceSensor_ALL_Notice_Id(T_Notice_id int) (r []DeviceSensor) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensor))
+	T_Notice := "N" + strconv.Itoa(T_Notice_id) + "|"
+	_, err := qs.Filter("T_Notice__icontains", T_Notice).All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	return r
+}
+
+// 获取列表
+func Read_DeviceSensor_List_T_Notice(T_pid int, T_Notice_id int, page int, page_z int, T_sn string, T_name string, T_type int) (DeviceSensor_r []DeviceSensor_, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensor))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	T_Notice := ""
+	if T_Notice_id != 0 {
+		T_Notice = "N" + strconv.Itoa(T_Notice_id) + "|"
+	}
+
+	fmt.Println("T_Notice:", T_Notice)
+
+	var r []DeviceSensor
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_pid", T_pid).And("T_State", 1).And("T_Notice__icontains", T_Notice).And("T_sn__icontains", T_sn).And("T_name__icontains", T_name) // .AndNot("status__in", 1).Or("profile__age__gt", 2000)
+	if T_type > 0 {
+		cond1 = cond1.AndCond(cond.And("T_type", T_type))
+	}
+
+	_, err := qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("T_sort", "T_id").All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	cnt, err = qs.SetCond((*orm2.Condition)(cond1)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range r {
+		DeviceSensor_r = append(DeviceSensor_r, DeviceSensorToDeviceSensor_(v))
+	}
+	return DeviceSensor_r, cnt
+}
+
+// 设备同步参数
+func Update_Device_To_DeviceSensor(r_Device Device) bool {
+	DeviceSensor_list, _ := Read_DeviceSensor_ByTsn(r_Device.T_sn)
+	for _, v := range DeviceSensor_list {
+
+		// 设备同步参数
+		v.T_Dattery = r_Device.T_Dattery   // 电量
+		v.T_Site = r_Device.T_Site         // GPS
+		v.T_monitor = r_Device.T_monitor   // 监控状态 0 未监控 1 监控
+		v.T_online = r_Device.T_online     // 在线状态 0 未启用  1 在线  2 离线
+		v.T_online_s = r_Device.T_online_s // 在线状态-备用  0 未启用  1 在线  2 离线
+		v.T_State = r_Device.T_State       // 0 屏蔽   1 正常  (屏蔽后 只有内部管理员才能看到,用户 输入SN\名称 搜索时 也能看到)
+
+		Update_DeviceSensor(v, "T_Dattery", "T_Site", "T_type", "T_State", "T_monitor", "T_online", "T_online_s")
+	}
+
+	return true
+}
+
+// 传感器管理列列表 -------------------
+func Read_DeviceSensorManageList(admin_r *Account.Admin, T_pid int, T_name string, T_calss_id, T_en, T_free, T_datashow, T_sort, page, page_z int) (DeviceSensor_p []DeviceSensor_P, cnt int64) {
+	o := orm.NewOrm()
+	var maps []DeviceSensor_P
+	var maps_z []orm2.ParamsList
+
+	var offset int
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = (page - 1) * page_z
+	}
+
+	sql_WHERE := "t_pid = " + strconv.Itoa(T_pid)
+
+	if admin_r.T_pid > 0 {
+		sql_WHERE += " AND t__state = 1"
+	}
+
+	if len(T_name) > 0 {
+		sql_WHERE += " AND (ds.t_sn like '%" + T_name + "%' OR t_name like '%" + T_name + "%')"
+	}
+	if T_calss_id > 0 {
+		T_calss := "C" + strconv.Itoa(T_calss_id) + "|"
+		sql_WHERE += " AND t__class like '%" + T_calss + "%'"
+	}
+
+	if T_en != -1 {
+		sql_WHERE += " AND t_en = " + strconv.Itoa(T_en)
+	}
+	if T_free != -1 {
+		sql_WHERE += " AND t_free = " + strconv.Itoa(T_free)
+	}
+	if T_datashow != -1 {
+		sql_WHERE += " AND t_datashow =" + strconv.Itoa(T_datashow)
+	}
+
+	sql_ORDER := " ORDER BY t_sort ASC"
+	if T_sort == 1 {
+		sql_ORDER = " ORDER BY t_sort DESC"
+	}
+
+	// -------------
+	sql := "SELECT COUNT(ds.ID) FROM " + "device_sensor ds " +
+		"LEFT JOIN ( SELECT t_sn AS tsn,t_id AS tid,t_en,t_free " +
+		"FROM device_sensor_parameter WHERE id IN (SELECT MAX(id) FROM device_sensor_parameter GROUP BY t_sn,t_id)) AS dsp " +
+		"ON ds.t_sn = dsp.tsn AND ds.t_id = dsp.tid" + " WHERE " + sql_WHERE
+	fmt.Println(sql)
+	_, err := o.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return DeviceSensor_p, 0
+	}
+	if len(maps_z) == 0 {
+		return DeviceSensor_p, 0
+	}
+	//fmt.Println("maps_z;",maps_z[0][0])
+	sql = "SELECT * FROM device_sensor ds " +
+		"LEFT JOIN ( SELECT t_sn AS tsn,t_id AS tid,t_en,t_free,t__tlower,t__tupper,t__r_hlower,t__r_hupper,t_enprel,t_tprel,t_tpreu,t_hprel,t_hpreu " +
+		"FROM device_sensor_parameter WHERE id IN (SELECT MAX(id) FROM device_sensor_parameter GROUP BY t_sn,t_id)) AS dsp " +
+		"ON ds.t_sn = dsp.tsn AND ds.t_id = dsp.tid " +
+		"WHERE " + sql_WHERE + sql_ORDER
+
+	if page_z != 9999 {
+		sql = sql + " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(page_z)
+	}
+
+	fmt.Println(sql)
+	_, err = o.Raw(sql).QueryRows(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	key, _ := strconv.ParseInt(maps_z[0][0].(string), 10, 64)
+
+	return maps, key
+}
+
+// 数据展示菜单下 传感器参数列表
+/*
+func Read_DeviceSensor_List_For_Data(T_pid int, T_name string, T_Class_id, T_type, T_RealTime int, page int, page_z int) (DeviceSensor_r []DeviceSensor_R, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensor))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	var r []DeviceSensor
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_pid", T_pid).And("T_State", 1)
+
+	if T_Class_id > 0 {
+		T_Class := "C" + strconv.Itoa(T_Class_id) + "|"
+		fmt.Println("T_Class:", T_Class)
+		cond1 = cond1.And("T_Class__icontains", T_Class)
+	}
+
+	if T_type > 0 {
+		cond1 = cond1.And("T_type", T_type)
+	}
+
+	if len(T_name) == 16 {
+		cond1 = cond1.And("T_sn", T_name)
+	} else {
+		cond1 = cond1.And("T_name__icontains", T_name).And("T_datashow", 1)
+	}
+
+	_, err := qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("T_sort", "T_id").All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	cnt, err = qs.SetCond((*orm2.Condition)(cond1)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	// 实时数据页面,温度或者湿度不在正常区间,排在最前面
+	if T_RealTime == 1 {
+		var DeviceSensor_unusual []DeviceSensor_R
+		for _, v := range r {
+			v_r := DeviceSensorToDeviceSensor_R(v)
+			data := v_r.T_DeviceSensorData
+			// 温度或者湿度不在正常区间,排在最前面
+			if data.T_t > data.T_tu || data.T_t < data.T_tl || data.T_rh > data.T_rhu || data.T_rh < data.T_rhl {
+				DeviceSensor_unusual = append(DeviceSensor_unusual, v_r)
+			} else {
+				DeviceSensor_r = append(DeviceSensor_r, v_r)
+			}
+		}
+		DeviceSensor_unusual = append(DeviceSensor_unusual, DeviceSensor_r...)
+		return DeviceSensor_unusual, cnt
+	}
+
+	for _, v := range r {
+		DeviceSensor_r = append(DeviceSensor_r, DeviceSensorToDeviceSensor_R(v))
+	}
+	return DeviceSensor_r, cnt
+}
+*/
+
+func ToSensorData(tid, tSp, tTime, tSite string, tt, trh float64, createTime string) DeviceSensorData {
+	num, _ := strconv.ParseInt(tid, 10, 64)
+	return DeviceSensorData{
+		int(num),
+		tSp,
+		tTime,
+		tt,
+		trh,
+		tSite,
+		createTime,
+	}
+}
+
+// UpdateDeviceSensorDataTemperatureAndHumidity 更新设备探头数据温湿度
+func UpdateDeviceSensorDataTemperatureAndHumidity(sn, id, startTime, endTime string, temperature, humidity float64) {
+	sqlStatement := fmt.Sprintf("update z_device_data_%s set t_t = t_t + %f , t_rh = t_rh + %f where t_id = '%s' and t_time BETWEEN '%s' and '%s'", sn, temperature, humidity, id, startTime, endTime)
+	o := orm.NewOrm()
+
+	exec, err := o.Raw(sqlStatement).Exec()
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	affected, err := exec.RowsAffected()
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	fmt.Printf("影响了%d行\n", affected)
+}
+
+// SelectDeviceSensorDataListByTimeRange 搜索设备列表通过时间
+func SelectDeviceSensorDataListByTimeRange(sn, tId, startTime, endTime string) (list []DeviceSensorData) {
+	sqlStatement := fmt.Sprintf("select t_id,t_sp,DATE_FORMAT(t_time,'%%Y-%%m-%%d %%k:%%i:%%s') as t_time,t_t,t_rh,t_site,DATE_FORMAT(create_time,'%%Y-%%m-%%d %%k:%%i:%%s') as create_time from z_device_data_%s where t_id = %s and t_time BETWEEN '%s' AND '%s' ORDER BY t_time ASC", sn, tId, startTime, endTime)
+	o := orm.NewOrm()
+	rows, err := o.Raw(sqlStatement).QueryRows(&list)
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	fmt.Println("影响行数:", rows)
+	return
+}
+
+// UpdateDeviceSensorDataTemperatureAndHumidityRandom 随机更新
+func UpdateDeviceSensorDataTemperatureAndHumidityRandom(sn, id, startTime, endTime string, ttMax, ttMin, trhMax, trhMin int) {
+
+	//sql语句
+	sqlStatement := fmt.Sprintf("update z_device_data_%s set t_t = t_t + Round(FLOOR(%d + RAND() * (%d - %d + 1)) /100.0,1), t_rh = t_rh + Round(FLOOR(%d + RAND() * (%d - %d + 1)) /100.0,1) where t_id =  '%s' AND t_time BETWEEN '%s' AND '%s'", sn, ttMin, ttMax, ttMin, trhMin, trhMax, trhMin, id, startTime, endTime)
+	o := orm.NewOrm()
+	exec, err := o.Raw(sqlStatement).Exec()
+	if err != nil {
+		fmt.Println("执行错误:", sqlStatement)
+	}
+	affected, _ := exec.RowsAffected()
+	fmt.Println("执行更新行数:", affected)
+}
+
+// UpdateDeviceSensorData 更新设备探头数据
+func UpdateDeviceSensorData(sn, tId string, old, newO DeviceSensorData) {
+	sqlStatement := fmt.Sprintf("update z_device_data_%s set t_t = %f , t_rh = %f where t_id = %s and t_t = %f and t_rh = %f and t_time= '%s'", sn, newO.T_t, newO.T_rh, tId, old.T_t, old.T_rh, old.T_time)
+	fmt.Println("执行SQL:", sqlStatement)
+	o := orm.NewOrm()
+	exec, err := o.Raw(sqlStatement).Exec()
+	if err != nil {
+		fmt.Println("执行错误:", sqlStatement, err.Error())
+	}
+	affected, _ := exec.RowsAffected()
+	fmt.Println("执行更新行数:", affected)
+}
+
+// DeleteDeviceSensorDataByTimeRange 删除时间范围内的数据
+func DeleteDeviceSensorDataByTimeRange(sn, id, start, end string) {
+	sqlStatement := fmt.Sprintf("delete from z_device_data_%s where create_time between '%s' and '%s' and t_id = %s", sn, start, end, id)
+	o := orm.NewOrm()
+	exec, err := o.Raw(sqlStatement).Exec()
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	affected, _ := exec.RowsAffected()
+	fmt.Printf("从%s~%s时间段删除了%d条数据", start, end, affected)
+}
+
+// InsertDeviceSensorData 添加设备数据
+func InsertDeviceSensorData(sn string, d DeviceSensorData, admin Account.Admin) {
+	sqlStatement := fmt.Sprintf("insert into z_device_data_%s(t_id,t_sp,t_time,t_t,t_rh,t_site,create_time) value(%d,'%s','%s',%f,%f,'%s','%s')", sn, d.T_id, d.T_sp, d.T_time, d.T_t, d.T_rh, d.T_site, d.CreateTime)
+	o := orm.NewOrm()
+	_, err := o.Raw(sqlStatement).Exec()
+	if err != nil {
+		fmt.Println(err.Error())
+		if strings.Contains(err.Error(), "Duplicate entry") {
+			//已经存在该条目,更新
+			sqlStatement = fmt.Sprintf("update z_device_data_%s set t_t = %f,t_rh = %f where t_time= '%s' and t_id = %d and t_sp = '%s'", sn, d.T_t, d.T_rh, d.T_time, d.T_id, d.T_sp)
+			exec, err := o.Raw(sqlStatement).Exec()
+			if err != nil {
+				fmt.Println("更新错误:", err.Error())
+			} else {
+				affected, _ := exec.RowsAffected()
+				fmt.Println("修改了", affected, "条")
+			}
+		}
+	} else {
+		//向DataOld插入数据
+		sqlStatement = fmt.Sprintf("insert into device_data_old(t_sn,t_id,t_time,t_t,t_rh,t__site,t_operation,t_uuid,create_time) value('%s',%d,'%s',%f,%f,'%s',%d,'%s','%s')", sn, d.T_id, d.T_time, d.T_t, d.T_rh, d.T_site, 2, admin.T_uuid, d.CreateTime)
+		_, err := o.Raw(sqlStatement).Exec()
+		if err != nil {
+			log.Panicln("插入失败:", err.Error())
+		} else {
+			fmt.Println("插入成功!")
+		}
+	}
+}
+
+// ReadDeviceOldBySnTid 读取设备探头记录数据
+func ReadDeviceOldBySnTid(sn, tId string) (list []DataOld) {
+	o := orm.NewOrm()
+	sqlStatement := fmt.Sprintf("SELECT d.*,a.t_name as t_uuid FROM device_data_old as d LEFT JOIN admin as a on a.t_uuid = d.t_uuid WHERE t_sn = '%s' AND t_id = '%s'", sn, tId)
+	o.Raw(sqlStatement).QueryRows(&list)
+	return list
+}

+ 249 - 0
models/Device/DeviceSensorParameter.go

@@ -0,0 +1,249 @@
+package Device
+
+import (
+	"ColdP_server/conf"
+	"ColdP_server/models"
+	"encoding/json"
+	"fmt"
+	"github.com/astaxie/beego/cache"
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"strconv"
+	"time"
+)
+
+// 模板
+type DeviceSensorParameter struct {
+	Id     int    `orm:"column(ID);size(11);auto;pk"`
+	T_sn   string `orm:"index;size(256);"` // 设备序列号 KF开头,环境监测主机。 YD开头,温途监测主机
+	T_id   int    `orm:"index;size(11);"`  // 传感器编号
+	T_name string `orm:"size(256);"`       //传感器名称
+
+	// 报警
+
+	T_Tlower  float32 `orm:"size(200);"` //  温度下限
+	T_Tupper  float32 `orm:"size(200);"` //  温度上限
+	T_RHlower float32 `orm:"size(200);"` //  湿度下限
+	T_RHupper float32 `orm:"size(200);"` //  湿度上限
+
+	// 预警
+	T_enprel int     `orm:"size(2);default(1)"` // 是否启用预警
+	T_tprel  float32 `orm:"size(200);"`         //  温度预警下限
+	T_tpreu  float32 `orm:"size(200);"`         //  温度预警上限
+	T_hprel  float32 `orm:"size(200);"`         //  湿度预警下限
+	T_hpreu  float32 `orm:"size(200);"`         //  温度预警上限
+	//
+	//T_speed int `orm:"size(5);"`           // 传感器采样率   s(1~240) 默认:15 *
+	//T_sense int `orm:"size(5);"`           // 传感器灵敏度   s(0~10) 默认:5
+	T_en   int `orm:"size(2);default(1)"` // en:是否启用传感器,   0 停用   1 启用
+	T_free int `orm:"size(2);default(1)"` //   是否为闲置状态    1:启用(正常 实时、记录, 不 报警、预警)
+	//0:关闭(正常 实时、记录、报警、预警)  默认:0
+
+	// 逻辑字段
+	T_uuid      string `orm:"size(256);"`          //处理 人员
+	T_Msid      int64  `orm:"size(50);default(0)"` // 消息识别ID
+	T_SendState int    `orm:"size(2);default(0)"`  // 发送状态  0 待发送   1 发送成功  2 失败  3 覆盖
+	T_State     int    `orm:"size(2);default(1)"`  //  1 系统获取   2 用户提交
+
+	CreateTime time.Time `orm:"column(create_time);type(timestamp);auto_now_add"` //auto_now_add 第一次保存时才设置时间
+	UpdateTime time.Time `orm:"column(update_time);type(timestamp);auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
+}
+
+type DeviceSensorParameter_R struct {
+
+	// 报警
+	T_Tlower  float32 //  温度下限
+	T_Tupper  float32 //  温度上限
+	T_RHlower float32 //  湿度下限
+	T_RHupper float32 //  湿度上限
+	// 预警
+	T_enprel int     // 是否启用预警
+	T_tprel  float32 //  温度预警下限
+	T_tpreu  float32 //  温度预警上限
+	T_hprel  float32 //  湿度预警下限
+	T_hpreu  float32 //  温度预警上限
+
+	T_en   int // en:是否启用传感器,
+	T_free int // free:监测点是否为闲置状态(空库,只监测不报警)
+
+	T_time models.JsonTime
+}
+
+type DeviceSensorParameter_M struct {
+	T_name string // 标题
+	// 报警
+	T_Tlower  float32 //  温度下限
+	T_Tupper  float32 //  温度上限
+	T_RHlower float32 //  湿度下限
+	T_RHupper float32 //  湿度上限
+}
+
+func DeviceSensorParameterTo_DeviceSensorParameter_R(r DeviceSensorParameter) (t DeviceSensorParameter_R) {
+	t.T_Tlower = r.T_Tlower
+	t.T_Tupper = r.T_Tupper
+	t.T_RHlower = r.T_RHlower
+	t.T_RHupper = r.T_RHupper
+	t.T_enprel = r.T_enprel
+	t.T_tprel = r.T_tprel
+	t.T_tpreu = r.T_tpreu
+	t.T_hprel = r.T_hprel
+	t.T_hpreu = r.T_hpreu
+	t.T_en = r.T_en
+	t.T_free = r.T_free
+	t.T_time.Time = r.CreateTime
+
+	return t
+}
+func (t *DeviceSensorParameter) TableName() string {
+	return "device_sensor_parameter" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+var redisCache_DeviceSensorParameter cache.Cache
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(DeviceSensorParameter))
+	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
+		"redis_DeviceSensorParameter", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
+	fmt.Println(config)
+	var err error
+	redisCache_DeviceSensorParameter, err = cache.NewCache("redis", config)
+	if err != nil || redisCache_DeviceSensorParameter == nil {
+		errMsg := "failed to init redis"
+		fmt.Println(errMsg, err)
+	}
+
+}
+
+// ---------------- Redis -------------------
+// Redis_Set(m.T_sn,m) // Redis 更新缓存
+func Redis_DeviceSensorParameter_Set(key string, r DeviceSensorParameter_R) (err error) {
+
+	//json序列化
+	str, err := json.Marshal(r)
+	if err != nil {
+		fmt.Print(err)
+		return
+	}
+
+	err = redisCache_DeviceSensorParameter.Put(key, str, 8*time.Hour)
+	if err != nil {
+		fmt.Println("set key:", key, ",value:", str, err)
+	}
+	return
+}
+
+// if r,is :=Redis_Get(T_sn);is{
+// return r,nil
+// }
+func Redis_DeviceSensorParameter_Get(key string) (r DeviceSensorParameter_R, is bool) {
+	if redisCache_DeviceSensorParameter.IsExist(key) {
+		//println("找到key:",key)
+		v := redisCache_DeviceSensorParameter.Get(key)
+		json.Unmarshal(v.([]byte), &r)
+		return r, true
+	}
+	//println("没有 找到key:",key)
+	return DeviceSensorParameter_R{}, false
+}
+
+// ---------------- 特殊方法 -------------------
+// 获取设备参数
+func Read_V2DeviceSensorParameter(T_sn string, T_id int) (t DeviceSensorParameter_R, bool bool) {
+	key := T_sn + "|" + strconv.Itoa(T_id)
+	if t, is := Redis_DeviceSensorParameter_Get(key); is {
+		return t, true
+	}
+
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(DeviceSensorParameter))
+	var r []DeviceSensorParameter
+	cond := orm.NewCondition()
+	cond = cond.And("T_sn", T_sn).And("T_id", T_id).AndCond(cond.And("T_State", 1).OrCond(cond.And("T_State", 2).And("T_SendState", 1)))
+
+	qs.Limit(1, 0).SetCond((*orm2.Condition)(cond)).OrderBy("-UpdateTime").All(&r)
+	// 判断是否有数据
+	if len(r) == 0 {
+		return t, false
+	}
+
+	return DeviceSensorParameterTo_DeviceSensorParameter_R(r[0]), true
+}
+
+// 获取列表  T_State  1 系统获取   2 用户提交
+func Read_V2DeviceSensorParameter_List(T_sn string, T_id int, T_State int, page_z int) (r []DeviceSensorParameter) {
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(DeviceSensorParameter))
+	cond := orm.NewCondition()
+
+	cond = cond.And("T_sn", T_sn)
+	cond = cond.And("T_id", T_id)
+	if T_State != 0 {
+		cond = cond.And("T_State", T_State)
+	}
+	qs.Limit(page_z, 0).SetCond((*orm2.Condition)(cond)).OrderBy("-Id").All(&r)
+
+	return r
+}
+
+// 添加
+func Add_DeviceSensorParameter(m DeviceSensorParameter) (int64, bool) {
+	o := orm.NewOrm()
+	id, err := o.Insert(&m)
+	if err != nil {
+		fmt.Println(err)
+		return 0, false
+	}
+	return id, true
+}
+
+// 修改
+func Update_DeviceSensorParameter(r DeviceSensorParameter, cols ...string) bool {
+	o := orm.NewOrm()
+	if num, err := o.Update(&r, cols...); err == nil {
+		fmt.Println("Number of records updated in database:", num)
+		return true
+	}
+	return false
+}
+
+func DELETE_DeviceSensorParameter(SN string) bool {
+
+	sql := "DELETE FROM `cold`.`device_sensor_parameter` WHERE `t_sn` = '" + SN + "' "
+	o := orm.NewOrm()
+	_, err := o.Raw(sql).Exec()
+	if err != nil {
+		return false
+	}
+	return true
+}
+
+// 获取列表  T_State  1 系统获取   2 用户提交
+func Read_DeviceSensorParameter_Map_All(T_sn string, T_id int) (maps map[int]DeviceSensorParameter_M) {
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var list []DeviceSensorParameter
+	qs := o.QueryTable(new(DeviceSensorParameter))
+	cond := orm.NewCondition()
+
+	cond = cond.And("T_sn", T_sn).And("T_id", T_id).AndCond(cond.And("T_State", 1).OrCond(cond.And("T_State", 2).And("T_SendState", 1)))
+
+	qs.SetCond((*orm2.Condition)(cond)).OrderBy("-Id").All(&list)
+
+	maps = make(map[int]DeviceSensorParameter_M)
+	for _, v := range list {
+		maps[v.Id] = DeviceSensorParameter_M{
+			T_name:    v.T_name,
+			T_Tlower:  v.T_Tlower,
+			T_Tupper:  v.T_Tupper,
+			T_RHlower: v.T_RHlower,
+			T_RHupper: v.T_RHupper,
+		}
+	}
+
+	return maps
+}

+ 33 - 0
models/GTime.go

@@ -0,0 +1,33 @@
+package models
+
+import (
+	"database/sql/driver"
+	"fmt"
+	"time"
+)
+
+type JsonTime struct {
+	time.Time
+}
+
+func (t JsonTime) MarshalJSON() ([]byte, error) {
+	str := fmt.Sprintf("\"%s\"", t.Format("2006-01-02 15:04:05"))
+	return []byte(str), nil
+}
+
+func (t JsonTime) Value() (driver.Value, error) {
+	var zeroTime time.Time
+	if t.Time.UnixNano() == zeroTime.UnixNano() {
+		return nil, nil
+	}
+	return t.Time, nil
+}
+
+func (t *JsonTime) Scan(v interface{}) error {
+	value, ok := v.(time.Time)
+	if ok {
+		*t = JsonTime{Time: value}
+		return nil
+	}
+	return fmt.Errorf("error %v", v)
+}

+ 82 - 0
models/Product/ProductType.go

@@ -0,0 +1,82 @@
+package Product
+
+import (
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"time"
+)
+
+// 产品类型
+type ProductType struct {
+	Id      int    `orm:"column(ID);size(11);auto;pk"`
+	T_name  string `orm:"size(256);null"` // 产品统称 + 类型
+	T_model string `orm:"size(256);null"` // 产品型号
+}
+
+// 产品统称	产品型号	类型
+// 验证工具	M1	LoRa
+// YZ100N	NB-Iot
+// YZ200G	4G-Cat.1
+// 库房采集器(高配版)	KF100N	RS485(NB-Iot)
+// 库房采集器(标准版)	KF100B	RS485
+// 库房采集器(黑白版)	KF200L	RS485
+// 冰箱采集器(数码管版)	BX200GSE	4G-Cat.1
+// 冰箱采集器(黑白版)	BX200GBL	4G-Cat.1
+// 保温箱采集器V1	BW100	4G-Cat.1
+// 运输采集器V1	YD100	4G-Cat.1/GPS
+// 保温箱采集器V2	BW200	4G-Cat.1
+// 运输采集器V2	YD200	4G-Cat.1/GPS
+// 新管理主机	MD100	TCP/4G/WiFi
+// 小管理主机	MD200G	4G-Cat.1/RS485
+
+var ProductType_list map[string]string // 泛型
+
+func (t *ProductType) TableName() string {
+	return "product_type" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+//var redisCache_WarningType cache.Cache
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(ProductType))
+
+	ProductType_list = make(map[string]string)
+
+	//go Read_WarningType_All()
+}
+
+// 获取全部
+func Read_ProductType_All() {
+	time.Sleep(time.Second)
+
+	o := orm.NewOrm()
+	//for true {
+	//	var r []ProductType
+	//	qs := o.QueryTable(new(ProductType))
+	//	qs.All(&r)
+	//
+	//	for _, v := range r {
+	//		ProductType_list[v.T_model] = v.T_name
+	//	}
+	//	time.Sleep(1 * time.Hour)
+	//}
+	var r []ProductType
+	qs := o.QueryTable(new(ProductType))
+	qs.All(&r)
+
+	for _, v := range r {
+		ProductType_list[v.T_model] = v.T_name
+	}
+
+}
+func Read_ProductType_Get(T_model string) string {
+	// 有先加入 给全部人发消息
+	v, ok := ProductType_list[T_model] /*如果确定是真实的,则存在,否则不存在 */
+	if ok {
+		return v
+	} else {
+		return "未知类型"
+	}
+}

+ 30 - 0
models/Product/ProductUpgrade.go

@@ -0,0 +1,30 @@
+package Product
+
+import (
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"time"
+)
+
+// 产品类型
+type ProductUpgrade struct {
+	Id         int    `orm:"column(ID);size(11);auto;pk"`
+	T_model    string `orm:"size(256);null"` // 产品型号
+	T_version  string `orm:"size(256);null"` // 版本
+	T_file     string `orm:"size(256);null"` // 文件
+	T_remarks  string `orm:"size(256);null"` // 备注
+	T_carryout int    `orm:"size(1);null"`   // 全量发布
+
+	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
+}
+
+func (t *ProductUpgrade) TableName() string {
+	return "product_upgrade" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(ProductUpgrade))
+
+}

+ 896 - 0
models/Warning/Warning.go

@@ -0,0 +1,896 @@
+package Warning
+
+import (
+	"ColdP_server/conf"
+	"ColdP_server/controllers/lib"
+	"ColdP_server/logs"
+	"fmt"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"strconv"
+	"strings"
+	"time"
+)
+
+var (
+	CompanyCallthepolice = "companyCallthepolice" // 公司管理-设备报警
+	Callthepolice        = "callthepolice"        // 公司管理-设备报警
+)
+
+// 模板
+type Warning struct {
+	Id        int64     `orm:"column(ID);size(11);auto;pk"`
+	T_pid     int       `orm:"size(256);null"`        // Account.Company 绑定公司
+	T_tp      int       `orm:"size(200);null"`        // 报警类型   ->WarningList
+	T_sn      string    `orm:"index;size(256);null"`  // 设备序列号
+	T_D_name  string    `orm:"size(256);null"`        // 设备名称
+	T_id      int       `orm:"size(200);null"`        // 传感器 ID
+	T_DS_name string    `orm:"size(256);null"`        // 传感器名称
+	T_Remark  string    `orm:"type(text);null"`       // 采集内容
+	T_Ut      time.Time `orm:"type(timestamp);null;"` // 采集时间
+	T_fUt     time.Time `orm:"type(timestamp);null;"` // 首次采集时间
+
+	T_Text string `orm:"type(text);null"` // 处理备注
+	T_Log  string `orm:"type(text);null"` // 通知日志
+	T_Msid int64  `orm:"size(256);null"`  // 消息ID
+
+	T_State    int       `orm:"size(2);default(2)"`                                    // 0 删除   1 不处理   2 已处理   3 未处理
+	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
+	UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
+}
+
+// 多字段索引
+func (u *Warning) TableIndex() [][]string {
+	return [][]string{
+		[]string{"T_pid", "T_tp", "T_State"},
+	}
+}
+
+/*
+分表机制
+|--------30天--------|
+|-----8月---||--------7月---------||--------6月---------||--------5月---------|
+
+每天备份 到对应 月份
+
+*/
+
+// 模板
+type Warning_R struct {
+	Id         int64
+	T_pid      int      // Account.Company 绑定公司
+	T_tp       int      // 报警类型   ->WarningList
+	T_tp_name  string   // 报警类型名称
+	T_sn       string   // 设备序列号
+	T_D_name   string   // 设备名称
+	T_id       int      // 传感器 ID
+	T_DS_name  string   // 传感器名称
+	T_Remark   string   // 采集内容
+	T_Ut       string   // 采集时间
+	T_fUt      string   // 首次采集时间
+	T_Text     string   // 处理备注
+	T_Log      []string // 处理日志
+	T_Msid     int64    // 消息ID
+	T_State    int      // 0 删除   1 未处理   2 已处理
+	T_history  int      // 0 40天 1 历史数据
+	CreateTime string   // 创建时间
+}
+type CompanyWarning_R struct {
+	Id    int64
+	T_pid int // Account.Company 绑定公司
+	//T_pid_name string   // Account.Company 公司名称
+	T_tp       int      // 报警类型   ->WarningList
+	T_tp_name  string   // 报警类型名称
+	T_sn       string   // 设备序列号
+	T_D_name   string   // 设备名称
+	T_id       int      // 传感器 ID
+	T_DS_name  string   // 传感器名称
+	T_Remark   string   // 采集内容
+	T_Ut       string   // 采集时间
+	T_fUt      string   // 首次采集时间
+	T_Text     string   // 处理备注
+	T_Log      []string // 处理日志
+	T_Msid     int64    // 消息ID
+	T_State    int      // 0 删除   1 未处理   2 已处理
+	T_history  int      // 0 40天 1 历史数据
+	CreateTime string   // 创建时间
+}
+type Warning_Applet struct {
+	Id    int64
+	T_pid int // Account.Company 绑定公司
+	//T_company_name string   // 公司名称
+	T_tp       int      // 报警类型   ->WarningList
+	T_tp_name  string   // 报警类型名称
+	T_sn       string   // 设备序列号
+	T_D_name   string   // 设备名称
+	T_id       int      // 传感器 ID
+	T_DS_name  string   // 传感器名称
+	T_Remark   string   // 采集内容
+	T_Ut       string   // 采集时间
+	T_fUt      string   // 首次采集时间
+	T_Text     string   // 处理备注
+	T_Log      []string // 处理日志
+	T_Msid     int64    // 消息ID
+	T_State    int      // 0 删除   1 未处理   2 已处理
+	CreateTime string   // 创建时间
+}
+
+func (t *Warning) TableName() string {
+	return "warning" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(Warning))
+}
+
+// ---------------- 特殊方法 -------------------
+// T_history 0 40天 1 历史数据
+func WarningToWarning_R(T_history int, t Warning) (r Warning_R) {
+	r.Id = t.Id
+	r.T_pid = t.T_pid
+	r.T_tp = t.T_tp
+	r.T_tp_name = Read_WarningType_Get(t.T_tp)
+	r.T_sn = t.T_sn
+	r.T_D_name = t.T_D_name
+	r.T_id = t.T_id
+	r.T_DS_name = t.T_DS_name
+	r.T_Remark = t.T_Remark
+	r.T_Ut = t.T_Ut.Format("2006-01-02 15:04:05")
+	if !t.T_fUt.IsZero() {
+		r.T_fUt = t.T_fUt.Format("2006-01-02 15:04:05")
+	}
+	r.T_Text = t.T_Text
+	if len(t.T_Log) > 0 {
+		r.T_Log = strings.Split(strings.TrimRight(t.T_Log, "\n"), "\n")
+	}
+
+	r.T_Msid = t.T_Msid
+	r.T_State = t.T_State
+	r.T_history = T_history
+	r.CreateTime = t.CreateTime.Format("2006-01-02 15:04:05")
+	return r
+}
+func WarningToCompanyWarning_R(T_history int, t Warning) (r CompanyWarning_R) {
+	r.Id = t.Id
+	r.T_pid = t.T_pid
+	r.T_tp = t.T_tp
+	r.T_tp_name = Read_WarningType_Get(t.T_tp)
+	r.T_sn = t.T_sn
+	r.T_D_name = t.T_D_name
+	r.T_id = t.T_id
+	r.T_DS_name = t.T_DS_name
+	r.T_Remark = t.T_Remark
+	r.T_Ut = t.T_Ut.Format("2006-01-02 15:04:05")
+	if !t.T_fUt.IsZero() {
+		r.T_fUt = t.T_fUt.Format("2006-01-02 15:04:05")
+	}
+	r.T_Text = t.T_Text
+	if len(t.T_Log) > 0 {
+		r.T_Log = strings.Split(strings.TrimRight(t.T_Log, "\n"), "\n")
+	}
+
+	r.T_Msid = t.T_Msid
+	r.T_State = t.T_State
+	r.T_history = T_history
+	r.CreateTime = t.CreateTime.Format("2006-01-02 15:04:05")
+	return r
+}
+
+func WarningToWarning_Applet(t Warning) (r Warning_Applet) {
+	r.Id = t.Id
+	r.T_pid = t.T_pid
+	//company, _ := Account.Read_Company_ById(t.T_pid)
+	//r.T_company_name = company.T_name
+	r.T_tp = t.T_tp
+	r.T_tp_name = Read_WarningType_Get(t.T_tp)
+	r.T_sn = t.T_sn
+	r.T_D_name = t.T_D_name
+	r.T_id = t.T_id
+	r.T_DS_name = t.T_DS_name
+	r.T_Remark = t.T_Remark
+	r.T_Ut = t.T_Ut.Format("2006-01-02 15:04:05")
+	if !t.T_fUt.IsZero() {
+		r.T_fUt = t.T_fUt.Format("2006-01-02 15:04:05")
+	}
+	r.T_Text = t.T_Text
+	if len(t.T_Log) > 0 {
+		r.T_Log = strings.Split(strings.TrimRight(t.T_Log, "\n"), "\n")
+	}
+
+	r.T_Msid = t.T_Msid
+	r.T_State = t.T_State
+	r.CreateTime = t.CreateTime.Format("2006-01-02 15:04:05")
+	return r
+}
+
+// 获取 ById
+func Read_Warning_ById(id int64) (r Warning) {
+	o := orm.NewOrm()
+	r = Warning{Id: id}
+	err := o.Read(&r) // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return r
+}
+
+// 获取 ById
+func Read_Warning_ById_Backups(id int, T_year string, T_month string) (r Warning, err error) {
+	o := orm.NewOrm()
+	var maps []Warning
+	// Warning_2022_07
+	Wtab := "warning_" + T_year + "_" + T_month
+
+	sql_WHERE := fmt.Sprintf(" t__state > 0 AND `ID`= %d", id)
+
+	sql := "SELECT ID,t_pid,t_tp,t_sn,t__d_name,t_id,t__d_s_name,t__remark,t__ut,t__text,t__log,t__msid,t__state,create_time,update_time " +
+		"FROM " + Wtab + " WHERE" + sql_WHERE
+
+	fmt.Println(sql)
+	num, err := o.Raw(sql).QueryRows(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	if num == 0 {
+		return r, orm.ErrNoRows
+	}
+
+	return maps[0], nil
+}
+
+// 添加
+func Add_Warning(m Warning) (id int64, err error) {
+	o := orm.NewOrm()
+
+	id, err = o.Insert(&m)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return id, err
+}
+
+// 修改
+func Update_Warning(r Warning, cols ...string) bool {
+	o := orm.NewOrm()
+	num, err := o.Update(&r, cols...)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return false
+	}
+	fmt.Println("Number of records updated in database:", num)
+	return true
+}
+
+// 删除
+func Delete_Warning(t_pid, Id int) (err error) {
+	fmt.Println("Delete_Warning  : Id", Id)
+
+	o := orm.NewOrm()
+
+	o.Raw("UPDATE warning SET t__state = 0 WHERE t_pid = ? AND ID = ?", t_pid, Id).Exec()
+
+	// 后 一个月
+	dd, _ := time.ParseDuration(fmt.Sprintf("-%dh", 24*30*1))
+	dd1 := time.Now().Add(dd)
+	println(int(dd1.Month()))
+	xx := fmt.Sprintf("%d_%02d", int(dd1.Year()), int(dd1.Month()))
+	o.Raw("UPDATE warning_"+xx+"  SET t__state = 0  WHERE t_pid = ? AND ID = ?", t_pid, Id).Exec()
+
+	return
+}
+
+// 修改
+func Update_Warning_Backups(r Warning, T_year string, T_month string) bool {
+	o := orm.NewOrm()
+	Wtab := "warning_" + T_year + "_" + T_month
+
+	num, err := o.Raw("UPDATE "+Wtab+" SET `t__text` = ?,`t__state` = ? WHERE `ID` = ?", r.T_Text, r.T_State, r.Id).Exec()
+
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return false
+	}
+	fmt.Println("Number of records updated in database:", num)
+
+	return true
+}
+
+// 获取列表
+func Read_Warning_List(T_pid int, bindSN, tpList []string, Time_start_ string, Time_end_ string, page int, page_z int) (r []Warning_R, cnt int64) {
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var map_r []Warning
+	qs := o.QueryTable(new(Warning))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+	cond1 := orm.NewCondition()
+
+	if len(bindSN) > 0 {
+		cond1 = cond1.And("T_sn__in", bindSN)
+	}
+
+	if T_pid > 0 {
+		cond1 = cond1.And("T_pid", T_pid)
+	}
+	if len(tpList) > 0 {
+		cond1 = cond1.And("T_tp__in", tpList)
+	}
+
+	if len(Time_start_) > 0 {
+		cond1 = cond1.And("T_Ut__gte", Time_start_)
+	}
+	if len(Time_end_) > 0 {
+		cond1 = cond1.And("T_Ut__lte", Time_end_)
+	}
+
+	var err error
+	if page_z == 9999 {
+		// 获取全部
+		_, err = qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-T_Ut").All(&map_r)
+	} else {
+		_, err = qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-T_Ut").All(&map_r)
+	}
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	cnt, err = qs.SetCond((*orm2.Condition)(cond1)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range map_r {
+		r = append(r, WarningToWarning_R(0, v))
+	}
+
+	return r, cnt
+
+}
+
+// 获取列表备份
+func Read_Warning_Backups(T_pid int, bindSN []string, T_year string, T_month string, tpList []string, T_name string, T_handle int, Time_start_ string, Time_end_ string, page int, page_z int) (r []Warning_R, cnt int64) {
+
+	o := orm.NewOrm()
+	var maps []Warning
+	var maps_z []orm2.ParamsList
+	// 也可以直接使用 Model 结构体作为表名
+	// Warning_2022_07
+	Wtab := "warning_" + T_year + "_" + T_month
+
+	var offset int
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = (page - 1) * page_z
+	}
+
+	sql_WHERE := ""
+
+	//cond := orm.NewCondition()
+	//
+	//cond1 := cond.And("T_State__gt", 0)
+	sql_WHERE += " t__state > 0"
+
+	if len(bindSN) > 0 {
+		sql_WHERE += fmt.Sprintf(" AND t_sn in (%s)", lib.StringListToQuotesDotStr(bindSN))
+	}
+
+	if T_pid > 0 {
+		sql_WHERE += " AND t_pid = " + strconv.Itoa(T_pid)
+	}
+
+	if len(tpList) > 0 {
+		tp := lib.StringListToDotStr(tpList)
+		sql_WHERE += fmt.Sprintf(" AND t_tp in (%s)", tp)
+
+	}
+	if len(T_name) > 0 {
+		sql_WHERE += " AND (t_sn like '%" + T_name + "%' OR t__d_name like '%" + T_name + "%' OR t_id like '%" + T_name + "%' OR t__d_s_name like '%" + T_name + "%')"
+	}
+
+	if len(Time_start_) > 0 {
+		//cond1 = cond1.And("T_Ut__gte", Time_start_)
+		Time_start_ = lib.ReplaceSQL(Time_start_)
+		sql_WHERE += fmt.Sprintf(" AND t__ut >= '%s'", Time_start_)
+	}
+	if len(Time_end_) > 0 {
+		//cond1 = cond1.And("T_Ut__lte", Time_end_)
+		Time_end_ = lib.ReplaceSQL(Time_end_)
+		sql_WHERE += fmt.Sprintf(" AND t__ut <= '%s'", Time_end_)
+	}
+	//不填或0:所有      1:已处理     2:未处理
+	if T_handle == 1 {
+		//cond1 = cond1.And("T_Text__isnull", true)
+		sql_WHERE += " AND t__state > 1"
+	}
+	if T_handle == 3 {
+		//cond1 = cond1.And("T_Text__isnull", false).And("T_State", 2)
+		sql_WHERE += " AND t__state = 3"
+	}
+
+	// -------------
+
+	sql := "SELECT COUNT(ID) FROM " + Wtab + " WHERE " + sql_WHERE
+	fmt.Println(sql)
+	_, err := o.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, 0
+	}
+	if len(maps_z) == 0 {
+		return r, 0
+	}
+	//fmt.Println("maps_z;",maps_z[0][0])
+	sql = "SELECT ID,t_pid,t_tp,t_sn,t__d_name,t_id,t__d_s_name,t__remark,t__ut,t__text,t__log,t__msid,t__state,create_time,update_time " +
+		"FROM " + Wtab + " WHERE" + sql_WHERE + " ORDER BY t__ut DESC"
+	if page_z != 9999 {
+		sql = sql + " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(page_z)
+	}
+
+	fmt.Println(sql)
+	_, err = o.Raw(sql).QueryRows(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	key, _ := strconv.ParseInt(maps_z[0][0].(string), 10, 64)
+
+	for _, v := range maps {
+		r = append(r, WarningToWarning_R(1, v))
+	}
+
+	return r, key
+
+}
+
+// 获取管理员列表备份
+func Read_Admin_Warning_Backups(T_pids string, T_year string, T_month string, T_tp []string, T_name string, T_handle int, Time_start_ string, Time_end_ string, page int, page_z int) (r []Warning_R, cnt int64) {
+
+	if len(T_pids) == 0 {
+		return r, cnt
+	}
+
+	o := orm.NewOrm()
+	var maps []Warning
+	var maps_z []orm2.ParamsList
+	// 也可以直接使用 Model 结构体作为表名
+	// Warning_2022_07
+	Wtab := "warning_" + T_year + "_" + T_month
+
+	var offset int
+	if page_z == 0 {
+		page_z = conf.Page_size
+	}
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = (page - 1) * page_z
+	}
+
+	sql_WHERE := ""
+
+	sql_WHERE += " t__state > 0"
+
+	if T_pids != "*" {
+		list := lib.SplitStringToDotStr(T_pids, "P")
+		sql_WHERE += fmt.Sprintf(" AND t_pid in (%s)", list)
+	}
+
+	if len(T_tp) > 0 {
+		tp := lib.StringListToDotStr(T_tp)
+		sql_WHERE += fmt.Sprintf(" AND t_tp in (%s)", tp)
+
+	}
+	if len(T_name) > 0 {
+		sql_WHERE += " AND (t_sn like '%" + T_name + "%' OR t__d_name like '%" + T_name + "%' OR t_id like '%" + T_name + "%' OR t__d_s_name like '%" + T_name + "%')"
+	}
+
+	if len(Time_start_) > 0 {
+		//cond1 = cond1.And("T_Ut__gte", Time_start_)
+		Time_start_ = lib.ReplaceSQL(Time_start_)
+		sql_WHERE += fmt.Sprintf(" AND t__ut >= '%s'", Time_start_)
+	}
+	if len(Time_end_) > 0 {
+		//cond1 = cond1.And("T_Ut__lte", Time_end_)
+		Time_end_ = lib.ReplaceSQL(Time_end_)
+		sql_WHERE += fmt.Sprintf(" AND t__ut <= '%s'", Time_end_)
+	}
+	//1:默认 2:全部记录 3 未处理
+	if T_handle == 1 {
+		//cond1 = cond1.And("T_Text__isnull", true)
+		sql_WHERE += " AND t__state > 1"
+	}
+	if T_handle == 3 {
+		//cond1 = cond1.And("T_Text__isnull", false).And("T_State", 2)
+		sql_WHERE += " AND t__state = 3"
+	}
+
+	// -------------
+
+	sql := "SELECT COUNT(ID) FROM " + Wtab + " WHERE" + sql_WHERE
+	fmt.Println(sql)
+	_, err := o.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, 0
+	}
+	if len(maps_z) == 0 {
+		return r, 0
+	}
+	//fmt.Println("maps_z;",maps_z[0][0])
+	sql = "SELECT ID,t_pid,t_tp,t_sn,t__d_name,t_id,t__d_s_name,t__remark,t__ut,t__text,t__log,t__msid,t__state,create_time,update_time " +
+		"FROM " + Wtab + " WHERE" + sql_WHERE + " ORDER BY t__ut DESC"
+	if page_z != 9999 {
+		sql = sql + " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(page_z)
+	}
+
+	fmt.Println(sql)
+	_, err = o.Raw(sql).QueryRows(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	key, _ := strconv.ParseInt(maps_z[0][0].(string), 10, 64)
+
+	for _, v := range maps {
+		r = append(r, WarningToWarning_R(1, v))
+	}
+
+	return r, key
+
+}
+
+func Read_Warning_ALL_T_State_Count(T_pid int, T_pids []int, T_handle int, bindSN []string, T_Warning string, Is_Today bool) (cnt int64) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(Warning))
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_State__gt", 0)
+	if T_pid > 0 {
+		cond1 = cond1.And("T_pid", T_pid)
+	}
+	if T_pid == 0 {
+		cond1 = cond1.And("T_pid__in", T_pids)
+	}
+
+	if len(bindSN) > 0 {
+		cond1 = cond1.And("T_sn__in", bindSN)
+	}
+
+	if Is_Today {
+		startTime := time.Now().Format("2006-01-02") + " 00:00:00"
+		endTime := time.Now().Format("2006-01-02") + " 23:59:59"
+		cond1 = cond1.And("T_Ut__gte", startTime).And("T_Ut__lte", endTime)
+	}
+
+	if len(T_Warning) > 0 && T_Warning != "*" {
+		list := lib.SplitStringIds(T_Warning, "W")
+		cond1 = cond1.And("T_tp__in", list)
+	}
+
+	// T_State 0 删除   1 不处理   2 已处理   3 未处理
+	// T_handle  1:默认 2:全部记录 3 未处理
+	if T_handle == 1 {
+		cond1 = cond1.And("T_State__gt", 1)
+	}
+	if T_handle == 3 {
+		cond1 = cond1.And("T_State", 3)
+	}
+	cnt, err := qs.SetCond((*orm2.Condition)(cond1)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+
+	return cnt
+}
+
+// 设备日志
+type DeviceLogs struct {
+	Id         int64
+	T_sn       string //
+	Logs_Txt   string // 详情
+	CreateTime string
+}
+
+func WarningToDeviceLogs(t Warning) (r DeviceLogs) {
+	r.Id = t.Id
+	r.T_sn = t.T_sn
+	r.Logs_Txt = t.T_Remark
+	r.CreateTime = t.CreateTime.Format("2006-01-02 15:04:05")
+	return r
+}
+
+// 获取列表
+func Read_DeviceLogs_List(T_sn string, page, page_z int) (r []DeviceLogs, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(Warning))
+	var maps []Warning
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	_, err := qs.Limit(page_z, offset).Filter("T_sn", T_sn).Filter("T_tp__in", DeviceLogType).OrderBy("-Id").All(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	cnt, err = qs.Filter("T_sn", T_sn).Filter("T_tp__in", DeviceLogType).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range maps {
+		r = append(r, WarningToDeviceLogs(v))
+	}
+
+	return r, cnt
+}
+
+// 通过传感器类型获取报警列表
+func Read_Warning_List_By_DS_T_type(T_pid int, bindSN []string, DS_T_type int, T_name string, page int, page_z int) (r []Warning_Applet, cnt int64) {
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var maps []Warning
+	var maps_z []orm2.ParamsList
+	var offset int
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = (page - 1) * page_z
+	}
+
+	// T_State 0 删除   1 不处理   2 已处理   3 未处理
+	sql_WHERE := " t__state > 1 AND t_pid = " + strconv.Itoa(T_pid)
+
+	if len(bindSN) > 0 {
+		sql_WHERE += fmt.Sprintf(" AND t_sn in (%s)", lib.StringListToQuotesDotStr(bindSN))
+	}
+
+	if DS_T_type > 0 {
+		sql_WHERE += " AND ds.t_type = " + strconv.Itoa(DS_T_type)
+	}
+
+	if len(T_name) > 0 {
+		sql_WHERE += " AND (t_sn like '%" + T_name + "%' OR t__d_name like '%" + T_name + "%' OR t_id like '%" + T_name + "%' OR t__d_s_name like '%" + T_name + "%')"
+	}
+
+	sql := "SELECT COUNT(w.ID) FROM warning w " +
+		"LEFT JOIN ( SELECT t_sn AS tsn,t_id AS tid,t_type FROM device_sensor) AS ds " +
+		"ON w.t_sn = ds.tsn AND w.t_id = ds.tid " +
+		"WHERE " + sql_WHERE
+	fmt.Println(sql)
+	_, err := o.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, 0
+	}
+	if len(maps_z) == 0 {
+		return r, 0
+	}
+
+	sql = "SELECT * FROM warning w " +
+		"LEFT JOIN ( SELECT t_sn AS tsn,t_id AS tid,t_type FROM device_sensor) AS ds " +
+		"ON w.t_sn = ds.tsn AND w.t_id = ds.tid " +
+		"WHERE " + sql_WHERE + " ORDER BY t__ut DESC"
+
+	if page_z != 9999 {
+		sql = sql + " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(page_z)
+	}
+
+	fmt.Println(sql)
+	_, err = o.Raw(sql).QueryRows(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range maps {
+		r = append(r, WarningToWarning_Applet(v))
+	}
+
+	cnt, _ = strconv.ParseInt(maps_z[0][0].(string), 10, 64)
+
+	return r, cnt
+
+}
+
+// 获取当天设备报警总数
+func Read_WarningCount_byDay(T_pids []int) (cnt int64) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(Warning))
+	cond := orm.NewCondition()
+	yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
+	cond = cond.And("T_State__gt", 0).And("T_pid__in", T_pids).And("T_tp__in", RateType).And("CreateTime__gte", yesterday+" 00:00:00").And("CreateTime__lte", yesterday+" 23:59:59")
+
+	cnt, err := qs.SetCond((*orm2.Condition)(cond)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+
+	return cnt
+
+}
+
+// 公司管理报警列表
+func Read_Company_Warning_List(T_pids []int, T_tp []string, T_name string, T_handle int, Time_start_ string, Time_end_ string, page int, page_z int) (r []CompanyWarning_R, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var map_r []Warning
+	qs := o.QueryTable(new(Warning))
+	var offset int64
+	if page_z == 0 {
+		page_z = conf.Page_size
+	}
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	cond := orm.NewCondition()
+	cond1 := orm.NewCondition()
+	cond1 = cond1.And("T_pid__in", T_pids)
+
+	if len(T_tp) > 0 {
+		cond1 = cond1.And("T_tp__in", T_tp)
+	}
+	if len(T_name) > 0 {
+		if len(T_name) == 16 {
+			cond1 = cond1.And("T_sn", T_name)
+		} else {
+			cond1 = cond1.AndCond(cond.Or("T_sn__icontains", T_name).
+				Or("T_D_name__icontains", T_name).
+				Or("T_id__icontains", T_name).
+				Or("T_DS_name__icontains", T_name))
+		}
+	}
+
+	if len(Time_start_) > 0 {
+		cond1 = cond1.And("T_Ut__gte", Time_start_)
+	}
+	if len(Time_end_) > 0 {
+		cond1 = cond1.And("T_Ut__lte", Time_end_)
+	}
+	//1:默认 2:全部记录 3 未处理
+	if T_handle == 1 {
+		cond1 = cond1.And("T_State__gt", 1)
+	}
+	if T_handle == 2 {
+		cond1 = cond1.And("T_State__gt", 0)
+	}
+	if T_handle == 3 {
+		cond1 = cond1.And("T_State", 3)
+	}
+
+	_, err := qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-T_Ut").All(&map_r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	cnt, err = qs.SetCond((*orm2.Condition)(cond1)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range map_r {
+		r = append(r, WarningToCompanyWarning_R(0, v))
+	}
+
+	return r, cnt
+
+}
+
+// 获取公司管理列表备份
+func Read_Company_Warning_Backups(T_pids []int, T_year string, T_month string, T_tp []string, T_name string, T_handle int, Time_start_ string, Time_end_ string, page int, page_z int) (r []CompanyWarning_R, cnt int64) {
+
+	if len(T_pids) == 0 {
+		return r, cnt
+	}
+
+	o := orm.NewOrm()
+	var maps []Warning
+	var maps_z []orm2.ParamsList
+	// 也可以直接使用 Model 结构体作为表名
+	// Warning_2022_07
+	Wtab := "warning_" + T_year + "_" + T_month
+
+	var offset int
+	if page_z == 0 {
+		page_z = conf.Page_size
+	}
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = (page - 1) * page_z
+	}
+
+	sql_WHERE := ""
+
+	sql_WHERE += " t__state > 0"
+
+	if len(T_pids) > 0 {
+		sql_WHERE += fmt.Sprintf(" AND t_pid in (%s)", lib.IntListToDotStr(T_pids))
+	}
+
+	if len(T_tp) > 0 {
+		tp := lib.StringListToDotStr(T_tp)
+		sql_WHERE += fmt.Sprintf(" AND t_tp in (%s)", tp)
+
+	}
+	if len(T_name) > 0 {
+		sql_WHERE += " AND (t_sn like '%" + T_name + "%' OR t__d_name like '%" + T_name + "%' OR t_id like '%" + T_name + "%' OR t__d_s_name like '%" + T_name + "%')"
+	}
+
+	if len(Time_start_) > 0 {
+		//cond1 = cond1.And("T_Ut__gte", Time_start_)
+		Time_start_ = lib.ReplaceSQL(Time_start_)
+		sql_WHERE += fmt.Sprintf(" AND t__ut >= '%s'", Time_start_)
+	}
+	if len(Time_end_) > 0 {
+		//cond1 = cond1.And("T_Ut__lte", Time_end_)
+		Time_end_ = lib.ReplaceSQL(Time_end_)
+		sql_WHERE += fmt.Sprintf(" AND t__ut <= '%s'", Time_end_)
+	}
+	//1:默认 2:全部记录 3 未处理
+	if T_handle == 1 {
+		//cond1 = cond1.And("T_Text__isnull", true)
+		sql_WHERE += " AND t__state > 1"
+	}
+	if T_handle == 3 {
+		//cond1 = cond1.And("T_Text__isnull", false).And("T_State", 2)
+		sql_WHERE += " AND t__state = 3"
+	}
+
+	// -------------
+
+	sql := "SELECT COUNT(ID) FROM " + Wtab + " WHERE" + sql_WHERE
+	fmt.Println(sql)
+	_, err := o.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, 0
+	}
+	if len(maps_z) == 0 {
+		return r, 0
+	}
+	//fmt.Println("maps_z;",maps_z[0][0])
+	sql = "SELECT ID,t_pid,t_tp,t_sn,t__d_name,t_id,t__d_s_name,t__remark,t__ut,t__text,t__log,t__msid,t__state,create_time,update_time " +
+		"FROM " + Wtab + " WHERE" + sql_WHERE + " ORDER BY t__ut DESC"
+	if page_z != 9999 {
+		sql = sql + " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(page_z)
+	}
+
+	fmt.Println(sql)
+	_, err = o.Raw(sql).QueryRows(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	key, _ := strconv.ParseInt(maps_z[0][0].(string), 10, 64)
+
+	for _, v := range maps {
+		r = append(r, WarningToCompanyWarning_R(1, v))
+	}
+
+	return r, key
+
+}

+ 33 - 0
models/Warning/WarningHandle.go

@@ -0,0 +1,33 @@
+package Warning
+
+import (
+	"ColdP_server/controllers/lib"
+	"ColdP_server/logs"
+	"github.com/beego/beego/v2/adapter/orm"
+)
+
+type WarningHandle struct {
+	Id     int    `orm:"column(ID);size(11);auto;pk"`
+	T_name string `orm:"size(256);null"` // 报警处理备注
+}
+
+func (t *WarningHandle) TableName() string {
+	return "warning_handle"
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(WarningHandle))
+}
+
+func Read_WarningHandle_List() (maps []WarningHandle) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(WarningHandle))
+
+	_, err := qs.OrderBy("Id").All(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+
+	return maps
+}

+ 131 - 0
models/Warning/WarningRate.go

@@ -0,0 +1,131 @@
+package Warning
+
+import (
+	"ColdP_server/controllers/lib"
+	"ColdP_server/logs"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+var (
+	WarningRateDay   = "Day"
+	WarningRateMonth = "Month"
+)
+
+// 报警率
+type WarningRate struct {
+	Id            int     `orm:"column(ID);size(11);auto;pk"`
+	T_uuid        string  `orm:"index;size(64);null"`    // 用户uuid
+	T_date        string  `orm:"size(64);null"`          // 记薪日期,2023-03-01
+	T_device_num  int64   `orm:"size(20);default(0)"`    // 探头数量
+	T_warning_num int64   `orm:"size(20);default(0)"`    // 报警数量
+	T_type        string  `orm:"size(20);default(0)"`    // 类型 Day-每日 Month-每月
+	T_rate        float32 `orm:"digits(12);decimals(2)"` // 报警率
+
+	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 WarningRate_R struct {
+	Id            int
+	T_uuid        string  // 用户uuid
+	T_date        string  // 记薪日期,2023-03-01
+	T_device_num  int64   // 探头数量
+	T_warning_num int64   // 报警数量
+	Value         float32 // 报警率
+}
+type WarningRate_User struct {
+	T_uuid string // 用户uuid
+	T_name string // 用户名
+}
+
+func WarningRateToWarningRate_R(t WarningRate) (r WarningRate_R) {
+	r.Id = t.Id
+	r.T_uuid = t.T_uuid
+	r.T_date = t.T_date
+	r.T_device_num = t.T_device_num
+	r.T_warning_num = t.T_warning_num
+	r.Value = t.T_rate
+	return r
+}
+
+func (t *WarningRate) TableName() string {
+	return "warning_rate"
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(WarningRate))
+}
+
+func Add_WarningRate(m WarningRate) (id int64, err error) {
+	o := orm.NewOrm()
+	id, err = o.Insert(&m)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return id, err
+}
+
+func Read_WarningRate_List(T_uuid, T_type string, startTime, endTime string) (r []map[string]interface{}) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(WarningRate))
+	cond := orm.NewCondition()
+	var maps []WarningRate
+
+	cond = cond.And("T_uuid", T_uuid).And("T_type", T_type)
+	if len(startTime) > 0 {
+		cond = cond.And("T_date__gte", startTime)
+	}
+	if len(endTime) > 0 {
+		cond = cond.And("T_date__lte", endTime)
+	}
+
+	_, err := qs.SetCond((*orm2.Condition)(cond)).OrderBy("T_date").All(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+
+	for _, v := range maps {
+		rate := map[string]interface{}{
+			"T_uuid":        v.T_uuid,
+			"T_date":        v.T_date,
+			"T_device_num":  v.T_device_num,
+			"T_warning_num": v.T_warning_num,
+			"value":         v.T_rate,
+		}
+		r = append(r, rate)
+	}
+
+	return r
+}
+
+// 获取每月平均值
+func Read_WarningRateAvg_Month(startTime, endTime string) (r []WarningRate_R) {
+	o := orm.NewOrm()
+
+	sql := "SELECT t_uuid, ROUND(avg(t_device_num)) as t_device_num ,ROUND(avg(t_warning_num)) as t_warning_num FROM warning_rate WHERE `t_type` = '" + WarningRateDay + "' AND T_date >= '" + startTime + "' AND T_date <= '" + endTime + "'" +
+		" GROUP BY t_uuid"
+
+	_, err := o.Raw(sql).QueryRows(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	return r
+}
+
+// 获取昨天的设备报警率
+func Read_WarningRate_Yesterday(T_uuid string) float32 {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(WarningRate))
+	var r WarningRate
+	T_date := time.Now().AddDate(0, -1, 0).Format("2006-01-02")
+	err := qs.Filter("T_uuid", T_uuid).Filter("T_date", T_date).Filter("T_type", WarningRateDay).One(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return r.T_rate
+}

+ 244 - 0
models/Warning/WarningSand.go

@@ -0,0 +1,244 @@
+package Warning
+
+import (
+	"ColdP_server/controllers/lib"
+	"ColdP_server/logs"
+	"ColdP_server/models/Account"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// 模板
+// 报警发送统计
+type WarningSand struct {
+	Id       int    `orm:"column(ID);size(11);auto;pk"`
+	T_pid    int    `orm:"index;size(100);null"` // Account.Company 绑定公司, -1:未知   0:管理员  >0 :绑定公司
+	T_Spid   int    `orm:"index;size(100);"`     // 触发公司 ID
+	T_tp     int    `orm:"index;size(20);null"`  // 报警类型   ->WarningList
+	T_Notice string `orm:"size(256);null"`       // 18888888888
+	T_type   int    `orm:"index;size(4);null"`   // 1 短信   2 电话
+	T_Remark string `orm:"size(256);null"`       // 备注
+
+	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
+}
+
+func (t *WarningSand) TableName() string {
+	return "warning_sand" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(WarningSand))
+}
+
+type WarningSand_R struct {
+	Id         int
+	T_pid      int // Account.Company 绑定公司, -1:未知   0:管理员  >0 :绑定公司
+	T_tp       int // 报警类型   ->WarningList
+	T_tp_name  string
+	T_Notice   string   // 18888888888
+	T_type     int      // 1 短信   2 电话
+	T_Remark   []string // 备注
+	CreateTime string   //auto_now_add 第一次保存时才设置时间
+}
+
+func WarningSandToWarningSand_R(t WarningSand) (r WarningSand_R) {
+	r.Id = t.Id
+	r.T_pid = t.T_pid
+	r.T_tp = t.T_tp
+	r.T_tp_name = Read_WarningType_Get(t.T_tp)
+	r.T_Notice = t.T_Notice
+	r.T_type = t.T_type
+	//r.T_Remark = t.T_Remark
+	if len(t.T_Remark) > 0 {
+		r.T_Remark = strings.Split(strings.TrimRight(t.T_Remark, "\n"), "\n")
+	}
+
+	r.CreateTime = t.CreateTime.Format("2006-01-02 15:04:05")
+	return r
+}
+
+// ---------------- 特殊方法 -------------------
+
+// 获取 ById
+func Read_WarningWx_ById(id int) (r WarningSand) {
+	o := orm.NewOrm()
+	r = WarningSand{Id: id}
+	err := o.Read(&r) // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	if err != nil {
+		fmt.Println(err)
+	}
+	return r
+}
+
+// 添加
+func Add_WarningHand(m WarningSand) {
+	warningWxList := Read_DeviceWarning(m)
+	if len(warningWxList) == 0 {
+		Add_WarningHand(m)
+	}
+}
+
+// 添加
+func Add_WarningSand(m WarningSand) (id int64, err error) {
+	o := orm.NewOrm()
+	id, err = o.Insert(&m)
+	//if err != nil {
+	//	fmt.Println(err)
+	//}
+	return id, err
+}
+
+// 获取列表
+func Read_DeviceWarning(Warning WarningSand) (r []WarningSand) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+
+	qs := o.QueryTable(new(WarningSand))
+	now := time.Now()
+	// N 个小时前
+	dd, _ := time.ParseDuration("-1m") //"s", "m", "h".
+	currentTime := now.Add(dd)
+
+	qs.Filter("T_pid", Warning.T_pid).Filter("T_tp", Warning.T_tp).Filter("T_Notice", Warning.T_Notice).Filter("T_type", Warning.T_type).Filter("CreateTime__gte", currentTime.Format("2006-01-02 15:04:05")).OrderBy("-Id").All(&r)
+	// 记录 ++
+	if len(r) > 0 {
+		ColAdd_DeviceWarningBy_ID(r[0].Id)
+	}
+	return r
+}
+
+// 获取时  累加 1
+func ColAdd_DeviceWarningBy_ID(id int) {
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	design := new(WarningSand)
+	qs := o.QueryTable(design)
+	// 获取时  累加 1
+	qs.Filter("Id", id).Update(orm2.Params{"T_Filter": orm2.ColValue(orm.ColAdd, 1)})
+	return
+}
+
+func Read_WarningSand_ALL_T_sn_TIME_Count(T_sn string) (cnt int) {
+	o := orm.NewOrm()
+	var maps_z []orm2.ParamsList
+
+	now := time.Now()
+	timeStr := now.Format("2006-01-02") + " 00:00:00"
+
+	sql := "SELECT COUNT(ID) FROM warning_sand WHERE t__title NOT LIKE '%恢复%' AND t__ut > '" + timeStr + "' AND t_sn LIKE '%" + T_sn + "%' "
+	fmt.Println(sql)
+	_, err := o.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		return 0
+	}
+	if len(maps_z) == 0 {
+		return 0
+	}
+
+	//value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", cnt), 64)
+	key, _ := strconv.Atoi(maps_z[0][0].(string))
+	return key
+}
+
+func Read_WarningSand_ALL_T_Bind_TIME_Count(user_ Account.Admin, T_sn string) (cnt int) {
+	o := orm.NewOrm()
+	var maps_z []orm2.ParamsList
+
+	now := time.Now()
+	timeStr := now.Format("2006-01-02") + " 00:00:00"
+
+	T_Bind := "U" + strconv.Itoa(user_.Id) + "|"
+
+	sql := "SELECT COUNT(ID) FROM warning_sand WHERE t__title NOT LIKE '%恢复%' AND t__ut > '" + timeStr + "' AND t__bind LIKE '%" + T_Bind + "%' AND t_sn  LIKE '%" + T_sn + "%'"
+	fmt.Println(sql)
+	_, err := o.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		return 0
+	}
+	if len(maps_z) == 0 {
+		return 0
+	}
+
+	//value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", cnt), 64)
+	key, _ := strconv.Atoi(maps_z[0][0].(string))
+	return key
+}
+
+// 获取 发送统计数量
+func Get_WarningSandNum(TABLE_name string, Pid, Ntype int, StartTine, EndTime string) int {
+	o := orm.NewOrm()
+	var maps []orm.Params
+	num, err := o.Raw("SELECT count(ID) AS count FROM " + TABLE_name + " WHERE `t_pid` = " + strconv.Itoa(Pid) + " AND `t__ntype` = " + strconv.Itoa(Ntype) + " AND `create_time` >= '" + StartTine + "' AND `create_time` <= '" + EndTime + "'").Values(&maps)
+	if err == nil && num > 0 {
+		intx, _ := strconv.Atoi(lib.To_string(maps[0]["count"]))
+		logs.Println("Get_WarningSandNum:", TABLE_name, Pid, Ntype, StartTine, EndTime, intx) // slene
+		return intx
+	}
+	logs.Error("执行错误!!!", "Get_WarningSandNum:", TABLE_name, Pid, Ntype, StartTine, EndTime, maps) // slene
+	return 0
+}
+
+// 获取本月通知数量
+func Get_WarningSandNum_CurrentMonth(T_pid, Ntype int) int {
+	o := orm.NewOrm()
+	var maps []orm.Params
+	tableName := fmt.Sprintf("warning_sand_%s", time.Now().Format("200601"))
+	_, err := o.Raw("SELECT count(ID) AS count FROM " + tableName + " WHERE `t_pid` = " + strconv.Itoa(T_pid) + " AND `t__ntype` = " + strconv.Itoa(Ntype)).Values(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return 0
+	}
+	intx, _ := strconv.Atoi(lib.To_string(maps[0]["count"]))
+	return intx
+}
+
+func Read_WarningSand_List(T_pid, Ntype int, page int, page_z int) (r []WarningSand_R, cnt int64) {
+	o := orm.NewOrm()
+
+	var offset int
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = (page - 1) * page_z
+	}
+	var maps []WarningSand
+	var maps_z []orm2.ParamsList
+
+	tableName := fmt.Sprintf("warning_sand_%s", time.Now().Format("200601"))
+
+	sql := "SELECT count(ID) FROM " + tableName + " WHERE `t_pid` = " + strconv.Itoa(T_pid) + " AND `t__ntype` = " + strconv.Itoa(Ntype)
+
+	_, err := o.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return r, 0
+	}
+	if len(maps_z) == 0 {
+		return r, 0
+	}
+	sql = "SELECT * FROM " + tableName + " WHERE `t_pid` = " + strconv.Itoa(T_pid) + " AND `t__ntype` = " + strconv.Itoa(Ntype)
+
+	if page_z != 9999 {
+		sql = sql + " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(page_z)
+	}
+	_, err = o.Raw(sql).QueryRows(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	key, _ := strconv.ParseInt(maps_z[0][0].(string), 10, 64)
+
+	for _, v := range maps {
+		r = append(r, WarningSandToWarningSand_R(v))
+	}
+
+	return r, key
+}

+ 218 - 0
models/Warning/WarningType.go

@@ -0,0 +1,218 @@
+package Warning
+
+import (
+	"ColdP_server/controllers/lib"
+	"ColdP_server/logs"
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+// 模板
+type WarningType struct {
+	Id       int    `orm:"column(ID);size(11);auto;pk"`
+	T_name   string `orm:"size(256);null"`            // 分类
+	T_Tips   string `orm:"type(text);size(256);null"` // 提示
+	T_Notice int    `orm:"size(2);default(0)"`        // 是否在报警策略通知机制处展示 0 不展示  1 展示
+}
+
+var DeviceLogType = [3]int{101, 102, 103}
+var RateType = [8]int{1, 2, 3, 4, 6, 7, 8, 9}
+
+//3
+//tp   报警类型
+// 1  温度超上限报警
+// 2  温度超下限报警
+// 3  温度超上限预警
+// 4  温度超下限预警
+// 5  温度恢复正常
+// 6  湿度超上限报警
+// 7  湿度超下限报警
+// 8  湿度超上限预警
+// 9  湿度超下限预警
+// 10 湿度恢复正常
+
+//12
+//tp   报警类型
+// 101 主机报警
+// 102 时间报警
+// 103 闪存报警
+// 104 SD卡报警
+// 105 网络报警
+// 106  普通日志
+// 107 升级固件报警
+// 108 系统故障报警
+// 109 市电断电报警
+// 110 市电已恢复
+// 111 电池电量低报警
+// 112 电池电量恢复
+// 113 传感器故障报警
+// 114 传感器恢复
+// 115 开始任务(移动端)
+// 116 中途打印任务(移动端)
+// 117 结束任务(移动端)
+
+// 预警系统
+// 1001 设备状态异常
+// 1002 传感器数据异常
+// 1011    报警策略异常
+
+func (t *WarningType) TableName() string {
+	return "warning_type" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+// var redisCache_WarningType cache.Cache
+var WarningType_list *sync.Map // 泛型
+func init() {
+	//注册模型
+	WarningType_list = new(sync.Map)
+	orm.RegisterModel(new(WarningType))
+	go Read_WarningType_All_Maps()
+
+}
+
+type WarningType_R struct {
+	Id      int
+	T_name  string // 分类
+	T_check bool   // 是否勾选
+}
+
+type WarningType_ struct {
+	Id     int
+	T_name string // 分类
+}
+
+func WarningTypeToWarningType_R(r WarningType, T_warning string) (v WarningType_R) {
+	v.Id = r.Id
+	v.T_name = r.T_name
+	if strings.Contains(T_warning, "W"+strconv.Itoa(v.Id)+"|") || T_warning == "*" {
+		v.T_check = true
+	}
+	return v
+}
+
+func WarningTypeToWarningType_(r WarningType) (v WarningType_) {
+	v.Id = r.Id
+	v.T_name = r.T_name
+	return v
+}
+
+// 获取全部
+func Read_WarningType_All_T_Notice_mechanism() string {
+	logs.Println("=========== 初始化报警规则 =========")
+	time.Sleep(3 * time.Second)
+	o := orm.NewOrm()
+	var r []WarningType
+	qs := o.QueryTable(new(WarningType))
+	_, err := qs.Filter("T_Notice", 1).All(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return ""
+	}
+	str := ""
+	for _, v := range r {
+		str += v.T_Tips
+	}
+
+	return str
+}
+
+// 获取全部
+func Read_WarningType_All() (r []WarningType_) {
+	o := orm.NewOrm()
+	var maps []WarningType
+	qs := o.QueryTable(new(WarningType))
+	_, err := qs.All(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range maps {
+		r = append(r, WarningTypeToWarningType_(v))
+	}
+	return r
+}
+
+// 报警列表 返回权限拥有的报警类型列表
+func Read_WarningType_Power_All(T_warning string) (r []WarningType_) {
+	if len(T_warning) == 0 {
+		return r
+	}
+
+	o := orm.NewOrm()
+	var maps []WarningType
+	qs := o.QueryTable(new(WarningType))
+	if T_warning == "*" {
+		_, err := qs.All(&maps)
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+			return
+		}
+	} else {
+		list := lib.SplitStringIds(T_warning, "W")
+		_, err := qs.Filter("Id__in", list).All(&maps)
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+			return
+		}
+	}
+
+	for _, v := range maps {
+		r = append(r, WarningTypeToWarningType_(v))
+	}
+	return r
+}
+
+// 权限修改 返回全部,已勾选的T_check=true
+func Read_WarningType_All_Power_T_Warning(T_warning string) (r []WarningType_R) {
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var maps []WarningType
+	qs := o.QueryTable(new(WarningType))
+	_, err := qs.OrderBy("Id").All(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	for _, v := range maps {
+		r = append(r, WarningTypeToWarningType_R(v, T_warning))
+	}
+	return r
+}
+
+// 获取全部
+func Read_WarningType_All_Maps() {
+	time.Sleep(2 * time.Second)
+
+	logs.Println("=========== 初始化报警类型 =========")
+
+	o := orm.NewOrm()
+
+	for true {
+		var r []WarningType
+		qs := o.QueryTable(new(WarningType))
+		_, err := qs.All(&r)
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+		}
+
+		for _, v := range r {
+			WarningType_list.Store(v.Id, v.T_name)
+		}
+		time.Sleep(1 * time.Hour)
+	}
+
+}
+func Read_WarningType_Get(id int) string {
+	v, ok := WarningType_list.Load(id) /*如果确定是真实的,则存在,否则不存在 */
+	if ok {
+		return v.(string)
+	} else {
+		return "未知类型"
+	}
+}

+ 11 - 0
monitor.sh

@@ -0,0 +1,11 @@
+#!/bin/bash
+while true ;do
+    num=`ps -ef|grep Cold_server|grep -v grep|wc -l`
+    if [ $num -lt 1 ];then
+        run.sh
+    fi
+    sleep 10
+done
+
+
+

+ 56 - 0
nats/Nats.go

@@ -0,0 +1,56 @@
+package Nats
+
+import (
+	"ColdP_server/conf"
+	"ColdP_server/controllers/lib"
+	"ColdP_server/models/Account"
+	"fmt"
+	"github.com/nats-io/nats.go"
+	"github.com/vmihailenco/msgpack/v5"
+	"time"
+)
+
+func Init() {
+	fmt.Println("============Nats init============")
+	var err error
+	// 连接Nats服务器
+	lib.Nats, err = nats.Connect("nats://" + conf.NatsServer_Url)
+	if err != nil {
+		fmt.Println("nats 连接失败!")
+		panic(err)
+	}
+	fmt.Println("nats OK!")
+
+}
+
+func Verification(GetCookie string, GetString string) (bool, Account.Admin) {
+
+	Admin_tokey := GetCookie
+	if len(Admin_tokey) == 0 {
+		Admin_tokey = GetString
+	}
+	if len(Admin_tokey) == 0 {
+		return false, Account.Admin{}
+	}
+	// 请求-响应, 向 verification 发布一个 `ToKey` 请求数据,设置超时间3秒,如果有多个响应,只接收第一个收到的消息
+	msg, err := lib.Nats.Request("Cold_Admin_verification", []byte(Admin_tokey), 3*time.Second)
+	if err != nil {
+		return false, Account.Admin{}
+	}
+	fmt.Printf("Cold_Admin_verification : %s\n", string(msg.Data))
+	type T_R struct {
+		Code int16         `xml:"Code"`
+		Msg  string        `xml:"Msg"`
+		Data Account.Admin `xml:"Data"` // 泛型
+	}
+
+	var t_R T_R
+
+	err = msgpack.Unmarshal(msg.Data, &t_R)
+	if err != nil || t_R.Code != 200 {
+		return false, Account.Admin{}
+	}
+
+	return true, t_R.Data
+
+}

File diff suppressed because it is too large
+ 406 - 0
nohup.out


BIN
ofile/20220118154606.xlsx


+ 19 - 0
routers/Admin.go

@@ -0,0 +1,19 @@
+package routers
+
+import (
+	"ColdP_server/controllers"
+	beego "github.com/beego/beego/v2/server/web"
+)
+
+func init() {
+	//登录页面
+	beego.Router("/", &controllers.AdminController{}, "*:Login")
+	beego.Router("/Login", &controllers.AdminController{}, "*:Login")
+	//登录验证
+	beego.Router("/Login_verification", &controllers.AdminController{}, "POST:Login_verification")
+
+	//登录后的页面
+	beego.Router("/Index", &controllers.AdminController{}, "*:Index")
+	//显示主页
+	beego.Router("/Home", &controllers.AdminController{}, "*:Home")
+}

+ 45 - 0
routers/DataRouter.go

@@ -0,0 +1,45 @@
+package routers
+
+import (
+	"ColdP_server/controllers"
+	beego "github.com/beego/beego/v2/server/web"
+)
+
+func init() {
+
+	//获取数据列表页面,对应数据展示按钮
+	beego.Router("/Data/DataList_html", &controllers.DataController{}, "*:DataList_html")
+	//获取传感器列表
+	beego.Router("/Data/Device_Sensor_List", &controllers.DataController{}, "POST:Device_Sensor_List")
+	//获取更多传感器数据
+	beego.Router("Data/Device_Sensor_Data_More", &controllers.DataController{}, "POST:Device_Sensor_Data_More")
+	//删除记录
+	beego.Router("/Data/Device_Sensor_List_Delete", &controllers.DataController{}, "POST:Device_Sensor_List_Delete")
+	//更新记录
+	beego.Router("/Data/Device_Sensor_Update", &controllers.DataController{}, "POST:Device_Sensor_Update")
+	//数据记录
+	beego.Router("/Data/Device_Sensor_Record", &controllers.DataController{}, "POST:Device_Sensor_Record")
+
+	//数据导入
+	beego.Router("/Data/importData", &controllers.DataController{}, "POST:ImportData")
+
+	//数据生成
+	beego.Router("/Data/DataGenerator_html", &controllers.DataGeneratorController{}, "*:GeneratorHtml")
+	//获取对应设备探头数据
+	beego.Router("/Data/DeviceSensorData", &controllers.DataGeneratorController{}, "POST:DeviceSensorData")
+	//固定值偏移
+	beego.Router("/Data/UpdateFix", &controllers.DataGeneratorController{}, "POST:UpdateFix")
+	// 删除数据
+	beego.Router("/Data/Delete", &controllers.DataGeneratorController{}, "POST:Delete")
+	//随机偏移值
+	beego.Router("/Data/UpdateRand", &controllers.DataGeneratorController{}, "POST:UpdateRand")
+	//复制数据到另一时间起点中
+	beego.Router("/Data/CopyFromPosition", &controllers.DataGeneratorController{}, "POST:CopyFromPosition")
+	//数据补漏
+	beego.Router("/Data/RepairSensorData", &controllers.DataGeneratorController{}, "POST:RepairSensorData")
+	//数据平滑
+	beego.Router("/Data/DataSensorDataSmooth", &controllers.DataGeneratorController{}, "POST:DataSensorDataSmooth")
+	beego.Router("/Data/DataSensorDataTrend", &controllers.DataGeneratorController{}, "POST:DataSensorDataTrend")
+	//数据导入
+	beego.Router("/Data/ImportSensorData", &controllers.DataGeneratorController{}, "POST:ImportSensorData")
+}

+ 35 - 0
routers/DeviceRouter.go

@@ -0,0 +1,35 @@
+package routers
+
+import (
+	"ColdP_server/controllers"
+	beego "github.com/beego/beego/v2/server/web"
+)
+
+func init() {
+	//设备管理
+	beego.Router("/Device/DeviceManager_html", &controllers.DeviceController{}, "*:DeviceManagerHtml")
+	//获取分类数据
+	beego.Router("/Device/CompanyClass", &controllers.DeviceController{}, "*:CompanyClass")
+	//设备列表
+	beego.Router("/Device/DeviceList", &controllers.DeviceController{}, "*:DeviceList")
+	//数据重传
+	beego.Router("/Device/DataRepeat", &controllers.DeviceController{}, "POST:DataRepeat")
+	//数据偏差值读取
+	beego.Router("/Device/ReadDeviation", &controllers.DeviceController{}, "POST:ReadDeviation")
+	//数据偏差值写入
+	beego.Router("/Device/WriteDeviation", &controllers.DeviceController{}, "POST:WriteDeviation")
+	//数据偏差值读取
+	beego.Router("/Device/ReadSensor", &controllers.DeviceController{}, "POST:ReadSensor")
+	//数据偏差值写入
+	beego.Router("/Device/WriteSensor", &controllers.DeviceController{}, "POST:WriteSensor")
+
+	beego.Router("/Device/DeviceWarning_List_html", &controllers.DeviceController{}, "*:DeviceWarning_List_html") // 获取未读消息
+	//beego.Router("/Device/DeviceWarning_List", &controllers.DeviceController{}, "*:DeviceWarning_List")                   // 获取未读消息
+	beego.Router("/Device/DeviceWarning_", &controllers.DeviceController{}, "*:DeviceWarning_") // 获取未读消息
+	//beego.Router("/Device/DeviceWarning_log", &controllers.DeviceController{}, "*:DeviceWarning_log")                     // 获取未读消息
+	//beego.Router("/Device/DeviceWarning_M", &controllers.DeviceController{}, "*:DeviceWarning_M")                         // 获取未读消息
+	beego.Router("/Device/DeviceWarning_Post", &controllers.DeviceController{}, "*:DeviceWarning_Post") // 获取未读消息
+	//beego.Router("/Device/DeviceWarning_Data_Excel", &controllers.DeviceController{}, "*:DeviceWarning_Data_Excel")       // 获取未读消息
+	beego.Router("/Device/DeviceWarning_Del", &controllers.DeviceController{}, "*:DeviceWarning_Del") // 获取未读消息
+	//beego.Router("/Device/DeviceWarningListT_Tips", &controllers.DeviceController{}, "*:DeviceWarningList_T_Tips")        // 获取未读消息
+}

+ 2 - 0
run.sh

@@ -0,0 +1,2 @@
+#无日志输出
+nohup ./Cold_server >/dev/null 2>&1 &

BIN
static/20240523140020.xlsx


+ 16 - 0
static/css/font.css

@@ -0,0 +1,16 @@
+@font-face {
+  font-family: 'iconfont';
+  src: url('../fonts/iconfont.eot');
+  src: url('../fonts/iconfont.eot?#iefix') format('embedded-opentype'),
+  url('../fonts/iconfont.woff') format('woff'),
+  url('../fonts/iconfont.ttf') format('truetype'),
+  url('../fonts/iconfont.svg#iconfont') format('svg');
+}
+.iconfont{
+  font-family:"iconfont" !important;
+  font-size:16px;font-style:normal;
+  -webkit-font-smoothing: antialiased;
+  -webkit-text-stroke-width: 0.2px;
+  -moz-osx-font-smoothing: grayscale;
+}
+

+ 35 - 0
static/css/jeDate-test.css

@@ -0,0 +1,35 @@
+html,body{min-height:100%;}
+html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}
+body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin: 0;padding: 0;border: 0;outline: 0;-webkit-tap-highlight-color:transparent;}
+article,aside,header,footer,nav,section,figure,figcaption,hgroup,progress,canvas{display:block}
+blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}
+body{font-size:14px;font-family:'PingFangSC-Light','PingFang SC','Segoe UI','Lucida Grande','NotoSansHans-Light','Microsoft YaHei', '\5FAE\8F6F\96C5\9ED1', STHeiti, 'WenQuanYi Micro Hei', SimSun, sans-serif;text-rendering:geometricPrecision;color:#333333;background:#FFFFFF;}
+
+a:active,a:hover{outline:0}
+img{display:inline-block;border:0}
+li{list-style:none}
+table{border-collapse:collapse;border-spacing:0}
+h1,h2,h3{font-size:14px;font-weight:400}
+h4,h5,h6{font-size:100%;font-weight:400}
+button,input,optgroup,option,select,textarea{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;outline:0;margin: 0px;padding: 0px;}
+pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}
+
+hr{height:1px;margin:10px 0;border:0;background-color:#e2e2e2;clear:both}
+a{color:#333;text-decoration:none}
+a:hover{color:#777}
+.gray{background-color: #f2f2f2;}
+
+.icons{background-image: url("jedate.png"); background-repeat:no-repeat; }
+.jequote{max-width: 1200px;margin-bottom: 10px;padding: 15px;line-height: 22px;border: 4px solid #00A080;border-radius: 4px;background-color: #f5f5f5;font-size: 15px;}
+.jebody{max-width: 1200px;margin: 40px auto 100px auto;position: relative;}
+.jewarp{width:100%;margin: 15px 0; }
+.jewarp h3{position: relative;left: 0;height: 40px;line-height:40px;padding-left:10px;white-space: nowrap;border-radius: 4px 4px 0 0;font-size: 16px;color:#00A080;text-align: left;border: 1px solid #ededed;border-bottom: none;}
+.jewarp .content{border: 1px solid #ededed;border-radius:0 0 4px 4px;padding: 25px 10px 10px 10px;overflow: hidden;}
+.jeitem{width:33.33%;margin:0 0px 15px 0;position: relative;float: left;}
+.jelabel{width: 120px;float: left;display: block;padding: 9px 10px;font-weight: 400;text-align: right; color:#555;}
+.jeinpbox{width: 230px;margin-right: 10px;float: left;vertical-align: middle;position: relative;}
+.jeinput{display: block;width: 100%;padding-left: 10px; height: 36px;line-height: 34px\9;border: 1px solid #e6e6e6;background-color: #fff;border-radius: 3px;background-color: #fcfcfc;}
+.jeindiv{display: block;width: 100%;padding-left: 10px; height: 36px;line-height: 36px;border-bottom: 1px solid #e6e6e6;background-color: #fff;background-color: #fcfcfc;}
+.jebtns{width: 35px;margin-left: 10px; height: 36px;line-height: 36px\9;border: 1px solid #e6e6e6;background-color: #fff;border-radius: 3px;background-position:right center;float: left;cursor: pointer;position: absolute;top:0;right:-12px;}
+.jefixeitem{width:25%;margin:0 0px 15px 0;position: relative;float: left; text-align: center;}
+

+ 100 - 0
static/css/jedate.css

@@ -0,0 +1,100 @@
+/**
+ @Name : jeDate V6.5.0 日期控件
+ @Author: chen guojun
+ @QQ群:516754269
+ @官网:http://www.jemui.com/ 或 https://github.com/singod/jeDate
+ */
+@font-face {font-family: "jedatefont";
+    src: url('jedatefont.eot?t=1510763148800'); /* IE9*/
+    src: url('jedatefont.eot?t=1510763148800#iefix') format('embedded-opentype'), /* IE6-IE8 */
+    url('jedatefont.woff?t=1510763148800') format('woff'),
+    url('jedatefont.ttf?t=1510763148800') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
+    url('jedatefont.svg?t=1510763148800#jedatefont') format('svg'); /* iOS 4.1- */
+}
+  
+.jedatefont {font-family:"jedatefont" !important;font-style:normal;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}
+.jedate{height:auto; font-family:'PingFangSC-Light','PingFang SC','Segoe UI','Lucida Grande','NotoSansHans-Light','Microsoft YaHei', '\5FAE\8F6F\96C5\9ED1', STHeiti, 'WenQuanYi Micro Hei', SimSun, sans-serif;font-size:12px; cursor:default;margin: 0;padding: 0;overflow: hidden;position: relative;border-radius:4px;display: inline-block;border: 1px solid #e2e2e2;box-shadow: 0 1px 6px rgba(0,0,0,.15);background-color:#fff;}
+.jedate *{margin: 0;padding: 0;list-style-type:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-style:normal;font-family:'PingFangSC-Light','PingFang SC','Segoe UI','Lucida Grande','NotoSansHans-Light','Microsoft YaHei', '\5FAE\8F6F\96C5\9ED1', STHeiti, 'WenQuanYi Micro Hei', SimSun, sans-serif;}
+
+.jedate table thead,.jedate table td{border: 1px #fff solid;}
+.jedate ul,.jedate ol,.jedate li,.jedate dl{list-style-type:none;font-style:normal;font-weight: 300;}
+
+.jedate .yearprev{left:0;font-size: 14px;}
+.jedate .monthprev{left:25px;font-size: 14px;}
+.jedate .yearnext{right:0;font-size: 14px;}
+.jedate .monthnext{right:25px;font-size: 14px;}
+.jedate .jedate-tips{position: absolute; top: 40%; left: 50%;z-index: 800; width: 200px; margin-left: -100px; line-height: 20px; padding: 15px; text-align: center; font-size: 12px; color: #ff0000;background-color: #FFFEF4;border: 1px rgb(247, 206, 57) solid;display: none;}
+.jedate .timecontent ul::-webkit-scrollbar,.jedate-menu::-webkit-scrollbar{height:6px;width:6px;margin-right:5px;background-color: #f5f5f5;transition:all 0.3s ease-in-out;border-radius:0px}
+.jedate .timecontent ul::-webkit-scrollbar-track,.jedate-menu::-webkit-scrollbar-track { -webkit-border-radius: 0px;border-radius: 0px;}
+.jedate .timecontent ul::-webkit-scrollbar-thumb,.jedate-menu::-webkit-scrollbar-thumb{-webkit-border-radius: 0px;border-radius: 0px;background: rgba(0,0,0,0.5); }
+.jedate .timecontent ul::-webkit-scrollbar-thumb:hover,.jedate-menu::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,0.6)}
+.jedate .timecontent ul::-webkit-scrollbar-thumb:active,.jedate-menu::-webkit-scrollbar-thumb:active{background:rgba(0,0,0,0.8)}
+.jedate .timecontent ul::-webkit-scrollbar-thumb:window-inactive,.jedate-menu::-webkit-scrollbar-thumb:window-inactive {background: rgba(0,0,0,0.4);}
+.jedate .jedate-hmsmask{width:100%;display: block;background-color: rgba(0,0,0,.7);background-color:#fff;position: absolute;top: 0;left:0;right:0;bottom: 36px;z-index: 100;}
+.jedatetipscon{color:#333; float:left; overflow:hidden;background-color: #FFFEF4; line-height:22px;padding:6px;border: 1px rgb(247, 206, 57) solid;font-style:normal;font-family: Arial, "\5b8b\4f53", 'sans-serif';font-size:12px;font-weight: 300;}
+.jedatetipscon p{padding: 0;margin: 0;font-size:12px;}
+.jedatetipscon p.red{color: #ff0000;}
+
+.jedate.leftmenu{padding-left: 90px;}
+.jedate .jedate-menu{width:90px;position: absolute;top: 0;left:0;bottom: 0;z-index: 10;background: #f2f2f2;border-right: 1px solid #efefef;border-radius: 4px 0 0 4px;overflow:auto;display: block;padding:4px 0;}
+.jedate .jedate-menu p{height: 30px;line-height: 30px;padding-left: 8px;overflow:hidden;font-size: 12px;cursor: pointer;}
+.jedate .jedate-menu p:hover{background-color: #00A680;color:#FFFFFF;}
+.jedate .jedate-wrap{min-width:230px;background: #fff;overflow: hidden;}
+.jedate .jedate-pane{width: 230px;float: left;overflow: hidden;}
+.jedate .jedate-header{width:100%;height:36px;line-height: 36px;float: left;background-color: #f2f2f2;text-align: center;font-size: 14px;padding: 0 50px;position: relative;}
+.jedate .jedate-header em{width:25px;height:36px;line-height: 36px;position:absolute;color: #666;top:0;background-repeat: no-repeat;background-position: center center;cursor: pointer;}
+.jedate .jedate-header .ymbtn{padding: 8px;border-radius: 4px;cursor:pointer;font-size: 14px;}
+/* .jedate .jedate-header em:hover,.jedate .jedate-header .ymbtn:hover{color: #00A680;} */
+.jedate .jedate-content{width:100%;height: 220px;float: left;padding: 5px;overflow: hidden;}
+.jedate .jedate-content.bordge{border-left: 1px #e9e9e9 solid;}
+.jedate .jedate-content .yeartable,.jedate .jedate-content .monthtable{width: 100%;border-collapse: collapse;border-spacing: 0;border: 1px solid #fff;}
+.jedate .jedate-content .yeartable td,.jedate .jedate-content .monthtable td{width:73px;height: 51px;line-height: 51px;text-align:center; position:relative; overflow:hidden;font-size: 14px;}
+.jedate .jedate-content .yeartable td span,.jedate .jedate-content .monthtable td span{padding: 8px 10px;border: 1px solid #fff;}
+.jedate .jedate-content .yeartable td.action span,.jedate .jedate-content .monthtable td.action span,
+.jedate .jedate-content .yeartable td.action span:hover,.jedate .jedate-content .monthtable td.action span:hover{background-color:#00A680;border:1px #00A680 solid;color:#fff;}
+.jedate .jedate-content .yeartable td span:hover,.jedate .jedate-content .monthtable td span:hover{background-color:#f2f2f2;border: 1px #f2f2f2 solid;}
+.jedate .jedate-content .yeartable td.disabled span,.jedate .jedate-content .monthtable td.disabled span,
+.jedate .jedate-content .yeartable td.disabled span:hover,.jedate .jedate-content .monthtable td.disabled span:hover{color:#bbb;background-color:#fff;border: 1px solid #fff;}
+.jedate .jedate-content .yeartable td.contain span,.jedate .jedate-content .monthtable td.contain span,
+.jedate .jedate-content .yeartable td.contain span:hover,.jedate .jedate-content .monthtable td.contain span:hover{background-color: #D0F0E3;border:1px #D0F0E3 solid;}
+
+.jedate.grid .daystable thead,.jedate.grid .daystable td{border: 1px #f2f2f2 solid;}
+.jedate .jedate-content .daystable{width: 100%;border-collapse: collapse;border-spacing: 0;border: 1px solid #fff;}
+.jedate .jedate-content .daystable thead{background-color:#fff;}
+.jedate .jedate-content .daystable th{width:31px;height:27px;  text-align:center; position:relative; overflow:hidden;font-size: 12px;font-weight: 400;}
+.jedate .jedate-content .daystable td{width:31px;height:30px;  text-align:center; position:relative; overflow:hidden;font-size: 14px;font-family: Arial, "\5b8b\4f53", 'sans-serif';}
+.jedate .jedate-content .daystable td .nolunar{line-height:29px;font-size: 14px;font-family: Arial, "\5b8b\4f53", 'sans-serif';}
+.jedate .jedate-content .daystable td .solar{height:14px;line-height:14px;font-size: 14px;padding-top: 2px;display: block;font-family: Arial, "\5b8b\4f53", 'sans-serif';}
+.jedate .jedate-content .daystable td .lunar{height:15px;line-height:15px;font-size: 12px;overflow:hidden;display: block;font-family: Arial, "\5b8b\4f53", 'sans-serif';color: #888;transform: scale(.95);}
+.jedate .jedate-content .daystable td.action,.jedate .jedate-content .daystable td.action:hover,
+.jedate .jedate-content .daystable td.action .lunar{background-color: #00A680;color:#fff;}
+.jedate .jedate-content .daystable td.other,.jedate .jedate-content .daystable td.other .nolunar,.jedate .jedate-content .daystable td.other .lunar{color:#00DDAA;}
+.jedate .jedate-content .daystable td.disabled,.jedate .jedate-content .daystable td.disabled .nolunar,.jedate .jedate-content .daystable td.disabled .lunar{ color:#bbb;}
+.jedate .jedate-content .daystable td.contain,.jedate .jedate-content .daystable td.contain:hover{background-color: #00DDAA;color:#fff;}
+.jedate .jedate-content .daystable td.disabled:hover{background-color:#fff;}
+.jedate .jedate-content .daystable td:hover{background-color:#f2f2f2;}
+.jedate .jedate-content .daystable td.red{ color:#ff0000;}
+.jedate .jedate-content .daystable td .marks{ width:5px; height:5px; background-color:#ff0000; -webkit-border-radius:50%;border-radius:50%; position:absolute; right:2px; top:4px;}
+.jedate .jedate-content .daystable td.action .marks{ width:5px; height:5px; background-color:#fff; -webkit-border-radius:50%;border-radius:50%; position:absolute; right:2px; top:4px;}
+
+.jedate .jedate-time{overflow: hidden;padding-bottom: 4px; background-color:#fff;position: absolute;top:0;right: 0;z-index: 150;}
+.jedate .jedate-time .timepane{width:230px;float:left;}
+.jedate .jedate-time .timeheader{width: 100%;float:left;height: 36px;line-height: 36px;background-color: #f2f2f2;text-align: center;font-size: 14px;position: relative;}
+.jedate .jedate-time .timecontent{width: 100%;float:left;}
+.jedate .jedate-time .hmstitle{width: 211px;margin: 0 auto;overflow: hidden;padding-top: 4px;text-align: center;}
+.jedate .jedate-time .hmstitle p{width: 33.33%;float:left;height: 30px;line-height: 30px;font-size: 13px;}
+.jedate .jedate-time .hmslist{width: 211px;margin: 0 auto 6px auto;border: 1px solid #ddd;border-right: none;overflow: hidden;}
+.jedate .jedate-time .hmslist .hmsauto{height: 100%;margin: 0;text-align: center;}
+.jedate .jedate-time .hmslist ul {width: 70px;height: 174px;float: left;border-right: 1px solid #ddd;overflow: hidden;}
+.jedate .jedate-time .hmslist .hmsauto:hover ul {overflow-y: auto}
+.jedate .jedate-time .hmslist ul li {width: 130%;padding-left:26px;text-align: left;height: 25px;line-height: 25px;font-size: 14px;font-family: Arial, "\5b8b\4f53", 'sans-serif';}
+.jedate .jedate-time .hmslist ul li:hover{background-color: #F2F2F2;}
+.jedate .jedate-time .hmslist ul li.action,.jedate-time .hmslist ul li.action:hover{background-color: #00A680;color:#fff;}
+.jedate .jedate-time .hmslist ul li.disabled{ background-color: #fbfbfb;color:#ccc;}
+.jedate .jedate-time .hmslist ul li.disabled.action{ background-color: #00A680;color:#FFFFFF;filter:Alpha(opacity=30);opacity:.3; }
+
+.jedate .jedate-footbtn{height: 36px;padding: 0 6px;border-top: 1px #e9e9e9 solid;overflow: hidden;}
+.jedate .jedate-footbtn .timecon{line-height:28px;padding:0 5px;background-color:#00A680;color:#fff;display:block;float: left;font-size: 12px;margin-top:4px;border-radius:4px;overflow: hidden;}
+.jedate .jedate-footbtn .btnscon{line-height:28px;margin-top:4px;display:block;float: right;font-size: 12px;border-radius:4px;overflow: hidden;}
+.jedate .jedate-footbtn .btnscon span{float:left; padding:0 5px;border-right: 1px #fff solid;background-color:#00A680;color:#fff;display:block;height:28px;line-height:28px;text-align:center;overflow:hidden;}
+.jedate .jedate-footbtn .btnscon span:last-child{border-right:none;}

File diff suppressed because it is too large
+ 0 - 0
static/css/layui.css


+ 105 - 0
static/css/login.css

@@ -0,0 +1,105 @@
+/*
+* @Author: xuebingsi
+* @Date:   2019-04-01 13:37:17
+* @Last Modified by:   zhibinm
+* @Last Modified time: 2019-04-01 13:37:19
+*/
+.login-bg{
+    /*background: #eeeeee url() 0 0 no-repeat;*/
+     background:url(../images/bg.png) no-repeat center;
+    background-size: cover;
+    overflow: hidden;
+}
+.login{
+    margin: 120px auto 0 auto;
+    min-height: 420px;
+    max-width: 420px;
+    padding: 40px;
+    background-color: #ffffff;
+    margin-left: auto;
+    margin-right: auto;
+    border-radius: 4px;
+    /* overflow-x: hidden; */
+    box-sizing: border-box;
+}
+.login a.logo{
+    display: block;
+    height: 58px;
+    width: 167px;
+    margin: 0 auto 30px auto;
+    background-size: 167px 42px;
+}
+.login .message {
+    margin: 10px 0 0 -58px;
+    padding: 18px 10px 18px 60px;
+    background: rgba(0, 184, 255, 0.3);
+    position: relative;
+    color: #fff;
+    font-size: 16px;
+}
+.login #darkbannerwrap {
+    background: url(../images/aiwrap.png);
+    width: 18px;
+    height: 10px;
+    margin: 0 0 20px -58px;
+    position: relative;
+}
+
+.login input[type=text],
+.login input[type=file],
+.login input[type=password],
+.login input[type=email], select {
+    border: 1px solid #DCDEE0;
+    vertical-align: middle;
+    border-radius: 3px;
+    height: 50px;
+    padding: 0px 16px;
+    font-size: 14px;
+    color: #555555;
+    outline:none;
+    width:100%;
+    box-sizing: border-box;
+}
+.login input[type=text]:focus,
+.login input[type=file]:focus,
+.login input[type=password]:focus,
+.login input[type=email]:focus, select:focus {
+    border: 1px solid rgba(0, 184, 255, 0.3);
+}
+.login input[type=submit],
+.login input[type=button]{
+    display: inline-block;
+    vertical-align: middle;
+    padding: 12px 24px;
+    margin: 0px;
+    font-size: 18px;
+    line-height: 24px;
+    text-align: center;
+    white-space: nowrap;
+    vertical-align: middle;
+    cursor: pointer;
+    color: #ffffff;
+    background-color: rgba(0, 184, 255, 0.3);
+    border-radius: 3px;
+    border: none;
+    -webkit-appearance: none;
+    outline:none;
+    width:100%;
+}
+.login hr {
+    background: #fff  0 0 no-repeat;
+}
+.login hr.hr15 {
+    height: 15px;
+    border: none;
+    margin: 0px;
+    padding: 0px;
+    width: 100%;
+}
+.login hr.hr20 {
+    height: 20px;
+    border: none;
+    margin: 0px;
+    padding: 0px;
+    width: 100%;
+}

+ 21 - 0
static/css/theme1.css

@@ -0,0 +1,21 @@
+body{
+    background:#F2F1F2;
+}
+.container{
+    background:#41a6ff;
+}
+.left-nav{
+    background:#1A1B20;
+}
+
+.left-nav a{
+    color:rgba(255,255,255,.7);
+}
+.left-nav a.active{
+    background: #009688 !important;
+    color: #fff;
+}
+.left-nav a:hover{
+    background: #009688 !important;
+    color: #fff;
+}

+ 21 - 0
static/css/theme2.css

@@ -0,0 +1,21 @@
+body{
+    background:#EEF5F9;
+}
+.container{
+    background:#41a6ff;
+}
+.left-nav{
+    background:#fff;
+}
+
+.left-nav a{
+    color:#686a76;
+}
+.left-nav a.active{
+    background: #786AED !important;
+    color: #fff;
+}
+.left-nav a:hover{
+    background: #786AED !important;
+    color: #fff;
+}

+ 22 - 0
static/css/theme3.css

@@ -0,0 +1,22 @@
+body{
+    background:#E8E8E8;
+}
+.container{
+    background:#F34743;
+}
+
+.left-nav{
+    background:#F4F4F4;
+}
+
+.left-nav a{
+    color:#686a76;
+}
+.left-nav a.active{
+    background: #FEFEFE !important;
+    color: #F34743;
+}
+.left-nav a:hover{
+    background: #FEFEFE !important;
+    color: #F34743;
+}

+ 21 - 0
static/css/theme4.css

@@ -0,0 +1,21 @@
+body{
+    background:#E4E4E4;
+}
+.container{
+    background:#019587;
+}
+.left-nav{
+    background:#263035;
+}
+
+.left-nav a{
+    color:#fff;
+}
+.left-nav a.active{
+    background: #212525 !important;
+    color: #fff !important;
+}
+.left-nav a:hover{
+    background: #212525 !important;
+    color: #fff !important;
+}

+ 27 - 0
static/css/theme5.css

@@ -0,0 +1,27 @@
+body{
+    background:#EEF5F9 !important;
+}
+.container{
+    background:linear-gradient(to left, #7b4397, #2196f3);
+}
+
+.left-nav{
+    background:#fff !important;
+}
+
+.left-nav a{
+    color:#686a76 !important;
+}
+.left-nav a.active{
+    background: linear-gradient(to left, #7c8ce4, #2196f3) !important;
+    color: #fff !important;
+    border-color:  #7b4397 !important;
+}
+.left-nav a:hover{
+    background: linear-gradient(to left, #7c8ce4, #2196f3) !important;
+    color: #fff !important;
+    border-color:  #7b4397 !important;
+}
+.container .logo a{
+    background: rgba(0,0,0,0) !important;
+}

+ 533 - 0
static/css/xadmin.css

@@ -0,0 +1,533 @@
+@charset "utf-8";
+@import url(../lib/layui/css/layui.css);
+*{
+    margin: 0px;
+    padding: 0px;
+    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+a{
+    text-decoration: none;
+}
+html{
+    width: 100%;
+    height: 100%;
+    overflow-x:hidden; 
+    overflow-y:auto;
+}
+body{
+    width: 100%;
+    min-height: 100%;
+    background: #f1f1f1;
+    /*background: #fff;*/
+}
+.x-red{
+    color: red;
+}
+
+.layui-form-switch{
+    margin-top: 0px;
+}
+.layui-input:focus, .layui-textarea:focus {
+    border-color: rgba(0, 184, 255, 0.3)!important;
+}
+
+.layui-fluid{
+    padding:15px;
+}
+.x-nav{
+    padding: 0 20px;
+    position: relative;
+    z-index: 99;
+    border-bottom: 1px solid #e5e5e5;
+    line-height: 39px;
+    height: 39px;
+    overflow: hidden;
+    background: #fff;
+}
+.page{
+    text-align: center;
+
+}
+.page a{
+    display: inline-block;
+    background: #fff;
+    color: #888;
+    padding: 5px;
+    min-width: 15px;
+    border: 1px solid #E2E2E2;
+
+}
+.page span{
+    display: inline-block;
+    padding: 5px;
+    min-width: 15px;
+    border: 1px solid #E2E2E2;
+}
+.page span.current{
+    display: inline-block;
+    background: rgba(0, 184, 255, 0.3);
+    color: #fff;
+    padding: 5px;
+    min-width: 15px;
+    border: 1px solid rgba(0, 184, 255, 0.3);
+}
+.page .pagination li{
+    display: inline-block;
+    margin-right: 5px;
+    text-align: center;
+}
+.page .pagination li.active span{
+    background: rgba(0, 184, 255, 0.3);
+    color: #fff;
+    border: 1px solid rgba(0, 184, 255, 0.3);
+
+}
+
+/*登录样式*/
+/*头部*/
+.container{
+    width: 100%;
+    height: 5px;
+    background:linear-gradient(to left, #38ff1c, rgba(0, 184, 255, 0.3))
+}
+.container a,.layui-nav .layui-nav-item a{
+    color: #fff;
+}
+.container .logo a{
+    background-color: rgba(0,0,0,0);
+}
+.container .logo a{
+    float: left;
+    font-size: 18px;
+    padding-left: 20px;
+    line-height: 45px;
+    width: 200px;
+}
+.container .right{
+    background-color:rgba(0,0,0,0);
+    float: right;
+
+}
+.container .left_open{
+    height: 45px;
+    float: left;
+    margin-left: 10px;
+}
+.container .left_open i{
+    display: block;
+    background: rgba(255,255,255,0.1);
+    width: 32px;
+    height: 32px;
+    line-height: 32px;
+    border-radius: 3px;
+    text-align: center;
+    margin-top: 7px;
+    cursor: pointer;
+}
+.container .left_open i:hover{
+    background: rgba(255,255,255,0.3);
+}
+
+.container .left{
+    background-color:rgba(0,0,0,0);
+    float: left;
+
+}
+.container .layui-nav-item{
+    line-height: 45px;
+}
+.container .layui-nav-more{
+    top: 20px;
+}
+.container .layui-nav-child{
+    top: 50px;
+}
+.container .layui-nav-child i{
+    margin-right: 10px;
+}
+.layui-nav .layui-nav-item a{
+    cursor: pointer;
+}
+.layui-nav .layui-nav-child a{
+    color: #333;
+    cursor: pointer;
+}
+.left-nav{
+    position: absolute;
+    top: 45px;
+    bottom: 0px;
+    /*bottom: 42px;*/
+    left: 0;
+    z-index: 2;
+    padding-top: 10px;
+    background-color: #EEEEEE;
+    width: 220px;
+    max-width: 220px;
+    overflow: auto;
+    overflow-x:hidden;
+    overflow: hidden;
+
+    /*width: 0px;*/
+}
+#side-nav{
+    width: 220px;
+}
+
+.left-nav #nav li:hover > a{
+    /*color: blue;*/
+}
+.left-nav #nav .current{
+    background-color: rgba(0, 0, 0, 0.3);
+}
+.left-nav #nav li a{
+    font-size: 14px;
+    padding: 10px 15px 10px 15px;
+    display: block;
+    cursor: pointer;
+    border-left: 4px solid transparent;
+    transition: all 0.3s;
+}
+.left-nav a.active{
+    background: rgba(0, 184, 255, 0.3) !important;
+    color: #fff;
+}
+.left-nav a:hover{
+    background: rgba(0, 184, 255, 0.3) !important;
+    color: #fff;
+}
+
+.left-nav #nav li a cite{
+    font-size: 14px;
+}
+
+.left-nav #nav li .sub-menu{
+    display: none;
+}
+.left-nav #nav li .opened{
+    display: block;
+}
+.left-nav #nav li .opened:hover{
+    /*background: #fff ;*/
+}
+.left-nav #nav li .opened .current{
+    
+}
+.left-nav #nav li .sub-menu li:hover{
+    /*color: blue;*/
+     /*background: #fff ;*/
+}
+.left-nav #nav li .sub-menu li a{
+    padding: 12px 15px 12px 30px;
+    font-size: 14px;
+    cursor: pointer;
+}
+.left-nav #nav li .sub-menu li .sub-menu li a{
+    padding-left: 45px;
+}
+/*.left-nav #nav li .sub-menu li a:hover{
+    color: #148cf1;
+}*/
+.left-nav #nav li .sub-menu li a i{
+    font-size: 12px;
+}
+.left-nav #nav li a i{
+    padding-right: 10px;
+    line-height: 14px;
+}
+.left-nav #nav li .nav_right{
+    float: right;
+    font-size: 16px;
+}
+.x-slide_left {
+    width: 17px;
+    height: 61px;
+    background: url(../images/icon.png) 0 0 no-repeat;
+    position: absolute;
+    top: 200px;
+    left: 220px;
+    cursor: pointer;
+    z-index: 3;
+}
+.page-content{
+    position: absolute;
+    top: 2px;
+    right: 0;
+    /*bottom: 42px;*/
+    bottom: 0px;
+    left: 0px;
+    overflow: hidden;
+    z-index: 1;
+}
+.page-content-bg{
+    position: absolute;
+    top: 45px;
+    right: 0;
+    /*bottom: 42px;*/
+    bottom: 0px;
+    left: 220px;
+    background: rgba(0,0,0,0.5);
+    overflow: hidden;
+    z-index: 100;
+    display: none;
+}
+
+.page-content .tab{
+    height: 100%;
+    width: 100%;
+    /*background: #EFEEF0;*/
+    margin: 0px;
+}
+.page-content .layui-tab-title{
+    /*padding-top: 5px;*/
+    height: 35px;
+    background: #EFEEF0 ;
+    position: relative;
+    z-index: 100;
+}
+.page-content .layui-tab-title li.home i{
+    padding-right: 5px;
+}
+.page-content .layui-tab-title li.home .layui-tab-close{
+    display: none;
+}
+.page-content .layui-tab-title li{
+    line-height: 35px;
+}
+.page-content .layui-tab-title .layui-this:after{
+    height: 36px;
+}
+.page-content .layui-tab-title li .layui-tab-close{
+    border-radius: 50%;
+}
+.page-content .layui-tab-title .layui-this{
+    background: #fff ;
+}
+.page-content .layui-tab-bar{
+    height:34px;
+    line-height: 35px;
+}
+.page-content .layui-tab-content{
+    position: absolute;
+    top: 36px;
+    bottom: 0px;
+    width: 100%;
+    padding: 0px;
+    overflow: hidden;
+}
+.page-content .layui-tab-content .layui-tab-item{
+    width: 100%;
+    height: 100%;
+    
+}
+.page-content .layui-tab-content .layui-tab-item iframe{
+    width: 100%;
+    height: 100%;
+
+}
+.x-admin-carousel,.layui-carousel,.x-admin-carousel>[carousel-item]>* {
+    background-color:#fff
+}
+
+.x-admin-backlog .x-admin-backlog-body {
+    display:block;
+    padding:10px 15px;
+    background-color:#f8f8f8;
+    color:#999;
+    border-radius:2px;
+    transition:all .3s;
+    -webkit-transition:all .3s
+}
+.x-admin-backlog-body h3 {
+    padding-bottom:10px;
+    font-size:12px
+}
+.x-admin-backlog-body p cite {
+    font-style:normal;
+    font-size:30px;
+    font-weight:300;
+    color:rgba(0, 184, 255, 0.3)
+}
+.x-admin-backlog-body:hover {
+    background-color:#CFCFCF;
+    color:#888
+}
+
+.layui-table td, .layui-table th{
+    min-width: 80px;
+}
+
+table th, table td {
+    word-break: break-all;
+}
+
+/*404页面样式*/
+.fly-panel {
+    margin-bottom: 15px;
+    border-radius: 2px;
+    /*background-color: #fff;*/
+    box-shadow: 0 1px 2px 0 rgba(0,0,0,.05);
+}
+.fly-none {
+    min-height: 600px;
+    text-align: center;
+    padding-top: 50px;
+    color: #999;
+}
+.fly-none .layui-icon {
+    line-height: 300px;
+    font-size: 300px;
+    color: #393D49;
+}
+.fly-none p {
+    margin-top: 50px;
+    padding: 0 15px;
+    font-size: 20px;
+    color: #999;
+    font-weight: 300;
+}
+#tab_right{
+    display: none;
+    width: 80px;
+    position: absolute;
+    top: 35px;
+    left: 0px;
+}
+#tab_right dl{
+    top: 0px;
+}
+#tab_show{
+    position: absolute;
+    top: 36px;
+    bottom: 0px;
+    width: 100%;
+    background:rgb(255, 255, 255,0);
+    padding: 0px;
+    overflow: hidden;
+    display: none;
+}
+
+
+@media screen and (max-width: 768px){
+    .fast-add{
+        display: none;
+    }
+    .layui-nav .to-index{
+        display: none;
+    }
+    .container .logo a{
+        width: 140px;
+    }
+    .container .left_open {
+        /*float: right;*/
+    }
+    .left-nav{
+        width: 60px;
+    }
+    .left-nav #nav li a i{
+        font-size: 18px;
+    }
+    .left-nav cite,.left-nav .nav_right{
+        display: none;
+    }
+    .page-content{
+        left: 60px;
+    }
+    .page-content .layui-tab-content .layui-tab-item{
+        -webkit-overflow-scrolling: touch; 
+        overflow-y: scroll; 
+    }
+    .x-so input.layui-input{
+        width: 100%;
+        margin: 10px;
+    }
+}
+
+/*精细版样式*/
+
+.x-admin-sm{
+    font-size: 12px;
+}
+.x-admin-sm body{
+    font-size: 12px;
+}
+/*登录页面样式*/
+.x-admin-sm .login input[type=submit],.x-admin-sm .login input[type=button]{
+    font-size: 14px;
+}
+.x-admin-sm .login input[type=text],
+.x-admin-sm .login input[type=file],
+.x-admin-sm .login input[type=password],
+.x-admin-sm .login input[type=email], .x-admin-sm select {
+    font-size: 12px;
+}
+.x-admin-sm .login .message{
+    font-size: 14px;
+}
+
+.x-admin-sm .layui-table td, .x-admin-sm .layui-table th{
+    font-size: 12px;
+}
+.x-admin-sm .layui-elem-field legend{
+    font-size: 18px;
+}
+
+.x-admin-sm .x-admin-backlog-body p cite{
+    font-size: 24px;
+}
+.x-admin-sm .left-nav #nav li a cite{
+    font-size: 12px;
+}
+.x-admin-sm .iconfont{
+    font-size: 14px;
+}
+.x-admin-sm .layui-tab-title li{
+    font-size: 12px;
+}
+.x-admin-sm .layui-icon{
+    font-size: 14px;
+}
+.x-admin-sm .layui-nav *{
+    font-size: 12px;
+}
+.x-admin-sm  .layui-breadcrumb>*{
+   font-size: 12px; 
+}
+.x-admin-sm  .layui-btn,.x-admin-sm .layui-btn-xs,.x-admin-sm .layui-btn-sm{
+    font-size: 12px;
+}
+
+.x-admin-sm .layui-laydate{
+    font-size: 12px;
+}
+.x-admin-sm  .layui-btn{
+    height: 30px;
+    line-height: 30px;
+    padding: 0 10px;
+}
+
+.x-admin-sm .layui-btn-lg{
+    height: 38px;
+    line-height: 38px;
+    padding: 0 18px;
+    font-size: 14px;
+}
+.x-admin-sm .layui-layer-title,.x-admin-sm .layui-layer-dialog .layui-layer-content{
+    font-size: 12px;
+}
+.x-admin-sm .layui-input,.x-admin-sm .layui-select,.x-admin-sm .layui-textarea{
+    height: 30px;
+}
+
+.x-admin-sm .layui-form-pane .layui-form-label{
+    height: 30px;
+    line-height: 14px;
+}
+.x-admin-sm .layui-form-checkbox span{
+    font-size: 12px;
+}
+.x-admin-sm .fly-none .layui-icon {
+    line-height: 300px;
+    font-size: 300px;
+    color: #393D49;
+}
+

+ 18 - 0
static/css/xcConfirm.css

@@ -0,0 +1,18 @@
+/*垂直居中*/
+.verticalAlign{ vertical-align:middle; display:inline-block; height:100%; margin-left:-1px;}
+
+.xcConfirm .xc_layer{position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: #666666; opacity: 0.5; z-index: 2147000000;}
+.xcConfirm .popBox{position: fixed; left: 50%; top: 50%; background-color: #ffffff; z-index: 2147000001; width: 570px; height: 300px; margin-left: -285px; margin-top: -150px; border-radius: 5px; font-weight: bold; color: #535e66;}
+.xcConfirm .popBox .ttBox{height: 30px; line-height: 30px; padding: 14px 30px; border-bottom: solid 1px #eef0f1;}
+.xcConfirm .popBox .ttBox .tt{font-size: 18px; display: block; float: left; height: 30px; position: relative;}
+.xcConfirm .popBox .ttBox .clsBtn{display: block; cursor: pointer; width: 12px; height: 12px; position: absolute; top: 22px; right: 30px; background: url(../img/icons.png) -48px -96px no-repeat;}
+.xcConfirm .popBox .txtBox{margin: 40px 100px; height: 100px; overflow: hidden;}
+.xcConfirm .popBox .txtBox .bigIcon{float: left; margin-right: 20px; width: 48px; height: 48px; background-image: url(../img/icons.png); background-repeat: no-repeat; background-position: 48px 0;}
+.xcConfirm .popBox .txtBox p{ height: 84px; margin-top: 16px; line-height: 26px; overflow-x: hidden; overflow-y: auto;}
+.xcConfirm .popBox .txtBox p input{width: 364px; height: 30px; border: solid 1px #eef0f1; font-size: 18px; margin-top: 6px;}
+.xcConfirm .popBox .btnArea{border-top: solid 1px #eef0f1;}
+.xcConfirm .popBox .btnGroup{float: right;}
+.xcConfirm .popBox .btnGroup .sgBtn{margin-top: 14px; margin-right: 10px;}
+.xcConfirm .popBox .sgBtn{display: block; cursor: pointer; float: left; width: 95px; height: 35px; line-height: 35px; text-align: center; color: #FFFFFF; border-radius: 5px;}
+.xcConfirm .popBox .sgBtn.ok{background-color: #0095d9; color: #FFFFFF;}
+.xcConfirm .popBox .sgBtn.cancel{background-color: #546a79; color: #FFFFFF;}

+ 596 - 0
static/essjksh/css/index.css

@@ -0,0 +1,596 @@
+body{
+    line-height: 1.15;
+    font-size: 0.5rem;
+    margin: 0;
+    padding: 0;
+    background-repeat: no-repeat;
+    background-position: 0 0 / cover;
+    background-color: #101129;
+}
+*{
+    margin: 0;
+    padding: 0;
+    font-weight: normal;
+}
+ul{
+    list-style: none;
+}
+a{
+    text-decoration: none;
+}
+.viewport {
+    /* 限定大小 */
+    min-width: 1024px;
+    max-width: 1920px;
+    min-height: 780px;
+    margin: 0 auto;
+    background: url(../images/logo.png) no-repeat 0 0 / contain;
+    display: flex;
+    padding: 3.667rem 0.833rem 0;
+}
+.column{
+    flex: 3;
+    position: relative;
+}
+.column:nth-child(2){
+    flex: 4;
+    margin: 1.333rem 0.833rem 0;
+}
+.panel {
+    /* 边框 */
+    box-sizing: border-box;
+    border: 2px solid red;
+    border-image: url(../images/border.png) 51 38 21 132;
+    border-width: 2.125rem 1.583rem 0.875rem 5.5rem;
+    position: relative;
+    margin-bottom: 0.833rem;
+}
+.panel .inner {
+    /* 装内容 */
+    /* height: 60px; */
+    position: absolute;
+    top: -2.125rem;
+    right: -1.583rem;
+    bottom: -0.875rem;
+    left: -5.5rem;
+    padding: 1rem 1.5rem;
+}
+.panel h3{
+    font-size: 0.833rem;
+    color: #fff;
+}
+/* 概览区域 */
+.overview{
+    height: 4.583rem;
+  }
+  .overview .inner{
+    display: flex;
+    justify-content: space-between;
+  }
+  .overview h4{
+    font-size: 1.167rem;
+    padding-left: 0.2rem;
+    color: #fff;
+    margin-bottom: 0.333rem
+  }
+  .overview span{
+    font-size: 0.667rem;
+    color: #4c9bfd;
+}
+/* 监控 */
+.monitor{
+	height: 20rem;
+  }
+  .monitor .inner{
+	padding: 1rem 0;
+	display: flex;
+	flex-direction: column;
+  }
+  .monitor .tabs{
+	padding: 0 1.5rem;
+	margin-bottom: 0.75rem;
+  }
+  .monitor .tabs a{
+	color: #1950c4;
+	font-size: 0.75rem;
+	padding: 0 1.125rem;
+  }
+  
+  .monitor .tabs a:first-child{
+	border-right: 0.083rem solid #00f2f1;
+	padding-left: 0;
+  }
+  
+  .monitor .tabs a.active{
+	color: #fff;
+  }
+  .monitor .content{
+	flex: 1;
+	display: none;
+	position: relative;
+  }
+  .monitor .head{
+	background: rgba(255, 255, 255, 0.1);
+	font-size: 0.583rem;
+	padding: 0.5rem 1.5rem;
+	color: #68d8fe;
+	display: flex;
+	justify-content: space-between;
+	line-height: 1.05;
+  }
+  .monitor .col:nth-child(1) {
+	width: 3.2rem;
+  }
+  .monitor .col:nth-child(2) {
+	width: 8.4rem;
+	/* 不换行  一行省略*/
+	white-space: nowrap;
+	overflow: hidden;
+	text-overflow: ellipsis;
+  }
+  .monitor .col:nth-child(3) {
+	width: 3.2rem;
+  }
+  .monitor .marquee-view{
+  position: absolute;
+  top: 1.6rem;
+  bottom: 0; 
+  width: 100%; 
+  overflow: hidden;
+}
+
+.monitor .row{
+  line-height: 1.05;
+  padding: 0.5rem 1.5rem;
+  color: #61a8ff;
+  font-size: 0.5rem;
+  position: relative;
+  display: flex;
+  justify-content: space-between;
+}
+.monitor .row:hover{
+  color:#68d8ff;
+  background: rgba(255, 255, 255, 0.1);
+}
+.monitor .row:hover .icon-dot{
+  opacity: 1;
+}
+
+.monitor .icon-dot{
+  position: absolute;
+  left: 0.64rem;
+  opacity: 0;
+}
+.monitor .marquee-view{
+	position: absolute;
+	top: 1.6rem;
+	bottom: 0; 
+	width: 100%; 
+	overflow: hidden;
+  }
+  
+  .monitor .row{
+	line-height: 1.05;
+	padding: 0.5rem 1.5rem;
+	color: #61a8ff;
+	font-size: 0.5rem;
+	position: relative; 
+	display: flex;
+	justify-content: space-between;
+  }
+  .monitor .row:hover{
+	color:#68d8ff;
+	background: rgba(255, 255, 255, 0.1);
+  }
+  .monitor .row:hover .icon-dot{
+	opacity: 1;
+  }
+  
+  .monitor .icon-dot{
+	position: absolute;
+	left: 0.64rem;
+	opacity: 0;
+}
+/* ------------------------------------------------------------动画 */
+@keyframes row{
+  0%{}
+  100%{
+    transform: translateY(-50%);
+  }
+}
+/* 调用动画 */
+.monitor .marquee {
+  /* //infinite永久调用动画 */
+  animation: row  10s linear infinite;
+}
+/*鼠标划入 停止动画  */
+.monitor .marquee:hover {
+  animation-play-state: paused;
+}
+/* 点位 */
+.point {
+  height: 14.167rem;
+}
+.point .chart {
+  display: flex;
+  margin-top: 1rem;
+  justify-content: space-between;
+}
+.point .pie {
+  width: 13rem;
+  height: 10rem;
+  margin-left: -0.4rem;
+}
+.point .data {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  width: 7rem;
+  padding: 1.5rem 1.25rem;
+  box-sizing: border-box;
+  background-image: url(../images/rect.png);
+  background-size: cover;
+}
+.point h4 {
+  margin-bottom: 0.5rem;
+  font-size: 1.167rem;
+  color: #fff;
+}
+.point span {
+  display: block;
+  color: #4c9bfd;
+  font-size: 0.667rem;
+}
+/* 地图  */
+.map {
+  height: 24.1rem;
+  margin-bottom: 0.833rem;
+  display: flex;
+  flex-direction: column;
+}
+.map h3 {
+  line-height: 1;
+  padding: 0.667rem 0;
+  margin: 0;
+  font-size: 0.833rem;
+  color: #fff;
+}
+.map .icon-cube {
+  color: #68d8fe;
+}
+.map .chart {
+  flex: 1;
+  background-color: rgba(255, 255, 255, 0.05);
+}
+.map .geo {
+  width: 100%;
+  height: 100%;
+}
+/* 用户模块 */
+.users {
+  height: 14.167rem;
+  display: flex;
+}
+.users .chart {
+  display: flex;
+  margin-top: 1rem;
+}
+.users .bar {
+  width: 24.5rem;
+  height: 10rem;
+}
+.users .data {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  width: 7rem;
+  padding: 1.5rem 1.25rem;
+  box-sizing: border-box;
+  background-image: url(../images/rect.png);
+  background-size: cover;
+}
+.users h4 {
+  margin-bottom: 0.5rem;
+  font-size: 1.167rem;
+  color: #fff;
+}
+.users span {
+  display: block;
+  color: #4c9bfd;
+  font-size: 0.667rem;
+}
+/* 订单 */
+.order {
+  height: 6.167rem;
+}
+.order .filter {
+  display: flex;
+}
+.order .filter a {
+  display: block;
+  height: 0.75rem;
+  line-height: 1;
+  padding: 0 0.75rem;
+  color: #1950c4;
+  font-size: 0.75rem;
+  border-right: 0.083rem solid #00f2f1;
+}
+.order .filter a:first-child {
+  padding-left: 0;
+}
+.order .filter a:last-child {
+  border-right: none;
+}
+.order .filter a.active {
+  color: #fff;
+  font-size: 0.833rem;
+}
+.order .data {
+  display: flex;
+  margin-top: 0.833rem;
+}
+.order .item {
+  width: 50%;
+}
+.order h4 {
+  font-size: 1.167rem;
+  color: #fff;
+  margin-bottom: 0.417rem;
+}
+.order span {
+  display: block;
+  color: #4c9bfd;
+  font-size: 0.667rem;
+}
+/* 销售区域 */
+.sales {
+  height: 10.333rem;
+}
+.sales .caption {
+  display: flex;
+  line-height: 1;
+}
+.sales h3 {
+  height: 0.75rem;
+  padding-right: 0.75rem;
+  border-right: 0.083rem solid #00f2f1;
+}
+.sales a {
+  padding: 0.167rem;
+  font-size: 0.667rem;
+  margin: -0.125rem 0 0 0.875rem;
+  border-radius: 0.125rem;
+  color: #0bace6;
+}
+.sales a.active {
+  background-color: #4c9bfd;
+  color: #fff;
+}
+.sales .inner {
+  display: flex;
+  flex-direction: column;
+}
+.sales .chart {
+  flex: 1;
+  padding-top: 0.6rem;
+  position: relative;
+}
+.sales .label {
+  position: absolute;
+  left: 1.75rem;
+  top: 0.75rem;
+  color: #4996f5;
+  font-size: 0.583rem;
+}
+.sales .line {
+  width: 100%;
+  height: 100%;
+}
+/* 渠道区块 */
+.wrap {
+  display: flex;
+}
+.channel,
+.quarter {
+  flex: 1;
+  height: 9.667rem;
+}
+.channel {
+  margin-right: 0.833rem;
+}
+.channel .data {
+  overflow: hidden;
+}
+.channel .item {
+  margin-top: 0.85rem;
+}
+.channel .item:first-child {
+  float: left;
+}
+.channel .item:last-child {
+  float: right;
+}
+.channel h4 {
+  color: #fff;
+  font-size: 1.333rem;
+  margin-bottom: 0.2rem;
+}
+.channel small {
+  font-size: 50%;
+}
+.channel span {
+  display: block;
+  color: #4c9bfd;
+  font-size: 0.583rem;
+}
+/* 季度区块 */
+.quarter .inner {
+  display: flex;
+  flex-direction: column;
+  margin: 0 -0.25rem;
+}
+.quarter .chart {
+  flex: 1;
+  padding-top: 0.75rem;
+}
+.quarter .box {
+  position: relative;
+}
+.quarter .label {
+  transform: translate(-50%, -30%);
+  color: #fff;
+  font-size: 1.25rem;
+  position: absolute;
+  left: 50%;
+  top: 50%;
+}
+.quarter .label small {
+  font-size: 50%;
+}
+.quarter .gauge {
+  height: 3.5rem;
+}
+.quarter .data {
+  display: flex;
+  justify-content: space-between;
+}
+.quarter .item {
+  width: 50%;
+}
+.quarter h4 {
+  color: #fff;
+  font-size: 1rem;
+  margin-bottom: 0.4rem;
+}
+.quarter span {
+  display: block;
+  width: 100%;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  color: #4c9bfd;
+  font-size: 0.583rem;
+}
+/* 排行榜 */
+.top {
+  height: 11.8rem;
+}
+.top .inner {
+  display: flex;
+}
+.top .all {
+  display: flex;
+  flex-direction: column;
+  width: 7rem;
+  color: #4c9bfd;
+  font-size: 0.6rem;
+  vertical-align: middle;
+}
+.top .all ul {
+  padding-left: 0.5rem;
+  margin-top: 0.5rem;
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+}
+.top .all li {
+  overflow: hidden;
+}
+.top .all [class^="icon-"] {
+  font-size: 1.5rem;
+  vertical-align: middle;
+  margin-right: 0.5rem;
+}
+.top .province {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  color: #fff;
+}
+.top .province i {
+  padding: 0 0.5rem;
+  margin-top: 0.208rem;
+  float: right;
+  font-style: normal;
+  font-size: 0.583rem;
+  color: #0bace6;
+}
+.top .province s {
+  display: inline-block;
+  transform: scale(0.8);
+  text-decoration: none;
+}
+.top .province .icon-up {
+  color: #dc3c33;
+}
+.top .province .icon-down {
+  color: #36be90;
+}
+.top .province .data {
+  flex: 1;
+  display: flex;
+  margin-top: 0.6rem;
+}
+.top .province ul {
+  flex: 1;
+  line-height: 1;
+  margin-bottom: 0.25rem;
+}
+.top .province ul li {
+  display: flex;
+  justify-content: space-between;
+}
+.top .province ul span {
+  display: block;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.top .province ul.sup {
+  font-size: 0.583rem;
+}
+.top .province ul.sup li {
+  color: #4995f4;
+  padding: 0.5rem;
+}
+.top .province ul.sup li.active {
+  color: #a3c6f2;
+  background-color: rgba(10, 67, 188, 0.2);
+}
+.top .province ul.sub {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  font-size: 0.5rem;
+  background-color: rgba(10, 67, 188, 0.2);
+}
+.top .province ul.sub li {
+  color: #52ffff;
+  padding: 0.417rem 0.6rem;
+}
+.clock {
+  position: absolute;
+  top: -1.5rem;
+  right: 1.667rem;
+  font-size: 0.833rem;
+  color: #0bace6;
+}
+.clock i {
+  margin-right: 5px;
+  font-size: 0.833rem;
+}
+@media screen and (max-width: 1600px) {
+  .top span {
+    transform: scale(0.9);
+  }
+  .top .province ul.sup li {
+    padding: 0.4rem 0.5rem;
+  }
+  .top .province ul.sub li {
+    padding: 0.23rem 0.5rem;
+  }
+  .quarter span {
+    transform: scale(0.9);
+  }
+}

+ 438 - 0
static/essjksh/data.html

@@ -0,0 +1,438 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <title>地图数据可视化</title>
+    <link rel="stylesheet" href="./css/index.css">
+    <link rel="stylesheet" href="./fonts/icomoon.css">
+</head>
+
+<body>
+    <div class="viewport">
+        <div class="column">
+            <!--概览-->
+            <div class="overview panel">
+                <div class="inner">
+                    <div class="item">
+                        <h4>2,190</h4>
+                        <span>
+                            <i class="icon-dot" style="color: #006cff"></i>
+                            设备总数
+                        </span>
+                    </div>
+                    <div class="item">
+                        <h4>190</h4>
+                        <span>
+                            <i class="icon-dot" style="color: #6acca3"></i>
+                            季度新增
+                        </span>
+                    </div>
+                    <div class="item">
+                        <h4>3,001</h4>
+                        <span>
+                            <i class="icon-dot" style="color: #6acca3"></i>
+                            运营设备
+                        </span>
+                    </div>
+                    <div class="item">
+                        <h4>108</h4>
+                        <span>
+                            <i class="icon-dot" style="color: #ed3f35"></i>
+                            异常设备
+                        </span>
+                    </div>
+                </div>
+            </div>
+            <!--监控-->
+            <div class="monitor panel">
+                <div class="inner">
+                    <div class="tabs">
+                        <a href="javascript:;" data-index="0" class="active">故障设备监控</a>
+                        <a href="javascript:;" data-index="1">异常设备监控</a>
+                    </div>
+                    <div class="content" style="display: block;">
+                        <div class="head">
+                            <span class="col">故障时间</span>
+                            <span class="col">设备地址</span>
+                            <span class="col">异常代码</span>
+                        </div>
+                        <div class="marquee-view">
+                            <div class="marquee">
+                                <div class="row">
+                                    <span class="col">20180701</span>
+                                    <span class="col">11北京市昌平西路金燕龙写字楼</span>
+                                    <span class="col">1000001</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190601</span>
+                                    <span class="col">北京市昌平区城西路金燕龙写字楼</span>
+                                    <span class="col">1000002</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190704</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000003</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20180701</span>
+                                    <span class="col">北京市昌平区建路金燕龙写字楼</span>
+                                    <span class="col">1000004</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190701</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000005</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190701</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000006</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190701</span>
+                                    <span class="col">北京市昌平区建西路金燕龙写字楼</span>
+                                    <span class="col">1000007</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190701</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000008</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190701</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000009</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190710</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000010</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="content">
+                        <div class="head">
+                            <span class="col">异常时间</span>
+                            <span class="col">设备地址</span>
+                            <span class="col">异常代码</span>
+                        </div>
+                        <div class="marquee-view">
+                            <div class="marquee">
+                                <div class="row">
+                                    <span class="col">20190701</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000001</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190701</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000002</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190703</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000002</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190704</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000002</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190705</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000002</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190706</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000002</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190707</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000002</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190708</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000002</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190709</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000002</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                                <div class="row">
+                                    <span class="col">20190710</span>
+                                    <span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
+                                    <span class="col">1000002</span>
+                                    <span class="icon-dot"></span>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <!--点位-->
+            <div class="point panel">
+                <div class="inner">
+                    <h3>点位分布统计</h3>
+                    <div class="chart">
+                        <div class="pie"></div>
+                        <div class="data">
+                            <div class="item">
+                                <h4>320,11</h4>
+                                <span>
+                                    <i class="icon-dot" style="color: #ed3f35"></i>
+                                    点位总数
+                                </span>
+                            </div>
+                            <div class="item">
+                                <h4>418</h4>
+                                <span>
+                                    <i class="icon-dot" style="color: #eacf19"></i>
+                                    本月新增
+                                </span>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="column">
+            <!-- 地图 -->
+            <div class="map">
+                <h3>
+                    <span class="icon-cube"></span>
+                    设备数据统计
+                </h3>
+                <div class="chart">
+                    <div class="geo"></div>
+                </div>
+            </div>
+            <!-- 用户 -->
+            <div class="users panel">
+                <div class="inner">
+                    <h3>全国用户总量统计</h3>
+                    <div class="chart">
+                        <div class="bar"></div>
+                        <div class="data">
+                            <div class="item">
+                                <h4>120,899</h4>
+                                <span>
+                                    <i class="icon-dot" style="color: #ed3f35"></i>
+                                    用户总量
+                                </span>
+                            </div>
+                            <div class="item">
+                                <h4>248</h4>
+                                <span>
+                                    <i class="icon-dot" style="color: #eacf19"></i>
+                                    本月新增
+                                </span>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="column">
+            <!-- 订单 -->
+            <div class="order panel">
+                <div class="inner">
+                    <!-- 筛选 -->
+                    <div class="filter">
+                        <a href="javascript:;" data-key="day365" class="active">365天</a>
+                        <a href="javascript:;" data-key="day90">90天</a>
+                        <a href="javascript:;" data-key="day30">30天</a>
+                        <a href="javascript:;" data-key="day1">24小时</a>
+                    </div>
+                    <!-- 数据 -->
+                    <div class="data">
+                        <div class="item">
+                            <h4>20,301,987</h4>
+                            <span>
+                                <i class="icon-dot" style="color: #ed3f35;"></i>
+                                订单量
+                            </span>
+                        </div>
+                        <div class="item">
+                            <h4>99834</h4>
+                            <span>
+                                <i class="icon-dot" style="color: #eacf19;"></i>
+                                销售额(万元)
+                            </span>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <!-- 销售额 -->
+            <div class="sales panel">
+                <div class="inner">
+                    <div class="caption">
+                        <h3>销售额统计</h3>
+                        <a href="javascript:;" class="active" data-type="year">年</a>
+                        <a href="javascript:;" data-type="quarter">季</a>
+                        <a href="javascript:;" data-type="month">月</a>
+                        <a href="javascript:;" data-type="week">周</a>
+                    </div>
+                    <div class="chart">
+                        <div class="label">单位:万</div>
+                        <div class="line"></div>
+                    </div>
+                </div>
+            </div>
+            <!-- 渠道 季度 -->
+            <div class="wrap">
+                <div class="channel panel">
+                    <div class="inner">
+                        <h3>渠道分布</h3>
+                        <div class="data">
+                            <div class="item">
+                                <h4>39 <small>%</small></h4>
+                                <span>
+                                    <i class="icon-plane"></i>
+                                    机场
+                                </span>
+                            </div>
+                            <div class="item">
+                                <h4>28 <small>%</small></h4>
+                                <span>
+                                    <i class="icon-bag"></i>
+                                    商场
+                                </span>
+                            </div>
+                        </div>
+                        <div class="data">
+                            <div class="item">
+                                <h4>20 <small>%</small></h4>
+                                <span>
+                                    <i class="icon-train"></i>
+                                    地铁
+                                </span>
+                            </div>
+                            <div class="item">
+                                <h4>13 <small>%</small></h4>
+                                <span>
+                                    <i class="icon-bus"></i>
+                                    火车站
+                                </span>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="quarter panel">
+                    <div class="inner">
+                        <h3>一季度销售进度</h3>
+                        <div class="chart">
+                            <div class="box">
+                                <div class="gauge"></div>
+                                <div class="label">75<small> %</small></div>
+                            </div>
+                            <div class="data">
+                                <div class="item">
+                                    <h4>1,321</h4>
+                                    <span>
+                                        <i class="icon-dot" style="color: #6acca3"></i>
+                                        销售额(万元)
+                                    </span>
+                                </div>
+                                <div class="item">
+                                    <h4>150%</h4>
+                                    <span>
+                                        <i class="icon-dot" style="color: #ed3f35"></i>
+                                        同比增长
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <!-- 排行榜 -->
+            <div class="top panel">
+                <div class="inner">
+                    <div class="all">
+                        <h3>全国热榜</h3>
+                        <ul>
+                            <li>
+                                <i class="icon-cup1" style="color: #d93f36;"></i>
+                                可爱多
+                            </li>
+                            <li>
+                                <i class="icon-cup2" style="color: #68d8fe;"></i>
+                                娃哈啥
+                            </li>
+                            <li>
+                                <i class="icon-cup3" style="color: #4c9bfd;"></i>
+                                喜之郎
+                            </li>
+                        </ul>
+                    </div>
+                    <div class="province">
+                        <h3>各省热销 <i class="date">// 近30日 //</i></h3>
+                        <div class="data">
+                            <ul class="sup">
+                                <li>
+                                    <span>北京</span>
+                                    <span>25,179 <s class="icon-up"></s></span>
+                                </li>
+                                <li>
+                                    <span>河北</span>
+                                    <span>23,252 <s class="icon-down"></s></span>
+                                </li>
+                                <li>
+                                    <span>上海</span>
+                                    <span>20,760 <s class="icon-up"></s></span>
+                                </li>
+                                <li>
+                                    <span>江苏</span>
+                                    <span>23,252 <s class="icon-down"></s></span>
+                                </li>
+                                <li>
+                                    <span>山东</span>
+                                    <span>20,760 <s class="icon-up"></s></span>
+                                </li>
+                            </ul>
+                            <ul class="sub">
+                                <!-- <li><span>数据</span><span> 数据<s class="icon-up"></s></span></li> -->
+                            </ul>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</body>
+<script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script>
+<script src="https://www.jq22.com/jquery/echarts-4.2.1.min.js"></script>
+<script src="./js/index.js"></script>
+
+<script src="./js/china.js"></script>
+<script src="./js/mymap.js"></script>
+
+</html>

+ 62 - 0
static/essjksh/fonts/icomoon.css

@@ -0,0 +1,62 @@
+@font-face {
+  font-family: 'icomoon';
+  src:  url('icomoon.eot');
+  src:  url('icomoon.eot#iefix') format('embedded-opentype'),
+    url('icomoon.ttf') format('truetype'),
+    url('icomoon.woff') format('woff'),
+    url('icomoon.svg#icomoon') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+
+[class^="icon-"], [class*=" icon-"] {
+  /* use !important to prevent issues with browser extensions that change fonts */
+  font-family: 'icomoon' !important;
+  speak: none;
+  font-style: normal;
+  font-weight: normal;
+  font-variant: normal;
+  text-transform: none;
+  line-height: 1;
+
+  /* Better Font Rendering =========== */
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-dot:before {
+  content: "\e900";
+}
+.icon-cup1:before {
+  content: "\e901";
+}
+.icon-cup2:before {
+  content: "\e902";
+}
+.icon-cup3:before {
+  content: "\e903";
+}
+.icon-clock:before {
+  content: "\e904";
+}
+.icon-down:before {
+  content: "\e905";
+}
+.icon-cube:before {
+  content: "\e906";
+}
+.icon-plane:before {
+  content: "\e907";
+}
+.icon-train:before {
+  content: "\e908";
+}
+.icon-bus:before {
+  content: "\e909";
+}
+.icon-bag:before {
+  content: "\e90a";
+}
+.icon-up:before {
+  content: "\e90b";
+}

BIN
static/essjksh/fonts/icomoon.eot


+ 22 - 0
static/essjksh/fonts/icomoon.svg

@@ -0,0 +1,22 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>Generated by IcoMoon</metadata>
+<defs>
+<font id="icomoon" horiz-adv-x="1024">
+<font-face units-per-em="1024" ascent="857.6" descent="-166.4" />
+<missing-glyph horiz-adv-x="1024" />
+<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
+<glyph unicode="&#xe900;" glyph-name="dot" d="M510-44.4v0c-109.2 0-198.8 89.2-198.8 198.8v395.2c0 109.2 89.2 198.8 198.8 198.8v0c109.2 0 198.8-89.2 198.8-198.8v-395.6c0-109.2-89.6-198.4-198.8-198.4z" />
+<glyph unicode="&#xe901;" glyph-name="cup1" d="M824.4 674c0 68.8-56.4 124.8-124.8 124.8h-375.6c-68.8 0-124.8-56.4-124.8-124.8-214 0-187.6 0-187.6-124.8 0-103.2 84.4-187.6 187.6-187.6 8 0 14 1.6 22 1.6 42-122 140.8-232.8 259.2-250v-145.2h-93.6c-17.2 0-31.2-14-31.2-31.2s14-31.2 31.2-31.2h250c17.2 0 31.2 14 31.2 31.2s-14 31.2-31.2 31.2h-93.6v145.2c118.8 17.2 217.2 126.4 259.2 250 6.4 0 14-1.6 22-1.6 103.2 0 187.6 84.4 187.6 187.6-2 124.8 24.8 124.8-187.6 124.8zM199.2 424c-68.8 0-125.2 56-125.2 124.8s1.6 62.4 124.8 62.4l0.4-187.2zM578.8 296h-94.4v202.4c0 29.2-0.8 46.8-2 52.8-1.6 6-5.2 10.4-11.6 13.6s-20.4 4.4-42 4.4h-9.2v44c45.6 10 80 30 103.6 60.4h55.6v-377.6zM824.4 424v187.2c123.6 0 124.8 6.4 124.8-62.4-1.6-68.8-56.4-124.8-124.8-124.8z" />
+<glyph unicode="&#xe902;" glyph-name="cup2" d="M824.4 674c0 68.8-56.4 124.8-124.8 124.8h-375.6c-68.8 0-124.8-56.4-124.8-124.8-214 0-187.6 0-187.6-124.8 0-103.2 84.4-187.6 187.6-187.6 8 0 14 1.6 22 1.6 42-122 140.8-232.8 259.2-250v-145.2h-93.6c-17.2 0-31.2-14-31.2-31.2s14-31.2 31.2-31.2h250c17.2 0 31.2 14 31.2 31.2s-14 31.2-31.2 31.2h-93.6v145.2c118.8 17.2 217.2 126.4 259.2 250 6.4 0 14-1.6 22-1.6 103.2 0 187.6 84.4 187.6 187.6-2 124.8 24.8 124.8-187.6 124.8zM74 548.8c0 68.8 1.6 62.4 124.8 62.4l0.4-187.2c-68.8 0-125.2 56-125.2 124.8zM618 359.2v-63.6h-205.2v53.2c60.8 99.6 96.8 161.2 108.4 184.8s17.2 42 17.2 55.2c0 10-1.6 17.6-5.2 22.8s-8.8 7.6-16 7.6-12.4-2.8-16-8.4c-3.6-5.6-5.2-16.4-5.2-33.2v-35.6h-83.6v14c0 20.8 1.2 37.6 3.2 49.6s7.6 24 16 35.6 19.6 20.4 33.2 26.4 29.6 9.2 48.8 9.2c37.2 0 65.2-9.2 84-27.6 19.2-18.4 28.4-41.6 28.4-70 0-21.6-5.2-44-16-68s-42.4-74.4-94.4-152h102.4zM824.4 424v187.2c123.6 0 124.8 6.4 124.8-62.4-1.6-68.8-56.4-124.8-124.8-124.8z" />
+<glyph unicode="&#xe903;" glyph-name="cup3" d="M824.4 674c0 68.8-56.4 124.8-124.8 124.8h-375.6c-68.8 0-124.8-56.4-124.8-124.8-214 0-187.6 0-187.6-124.8 0-103.2 84.4-187.6 187.6-187.6 8 0 14 1.6 22 1.6 42-122 140.8-232.8 259.2-250v-145.2h-93.6c-17.2 0-31.2-14-31.2-31.2s14-31.2 31.2-31.2h250c17.2 0 31.2 14 31.2 31.2s-14 31.2-31.2 31.2h-93.6v145.2c118.8 17.2 217.2 126.4 259.2 250 6.4 0 14-1.6 22-1.6 103.2 0 187.6 84.4 187.6 187.6-2 124.8 24.8 124.8-187.6 124.8zM74 548.8c0 68.8 1.6 62.4 124.8 62.4l0.4-187.2c-68.8 0-125.2 56-125.2 124.8zM620 337.2c-6.8-16.4-18.4-28.8-35.2-37.6-16.8-8.4-38-12.8-64-12.8-29.6 0-52.8 4.8-69.6 14.8s-28 22-33.2 36.4-8 39.2-8 74.8v29.6h93.2v-60.8c0-16 0.8-26.4 2.8-30.8s6-6.4 12.8-6.4c7.2 0 12 2.8 14.4 8.4s3.6 20 3.6 43.6v26c0 14.4-1.6 24.8-4.8 31.6s-8 10.8-14.4 13.2c-6.4 2-18.4 3.2-36.8 3.6v53.6c22 0 36 0.8 41.2 2.4s9.2 5.2 11.2 11.2c2.4 5.6 3.6 14.8 3.6 26.8v20.8c0 13.2-1.2 21.6-4 26-2.8 4-6.8 6.4-12.4 6.4-6.4 0-10.8-2-13.2-6.4s-3.6-13.6-3.6-28v-30.8h-93.2v32c0 35.6 8 60 24.4 72.4s42.4 18.8 78 18.8c44.4 0 74.8-8.8 90.4-26 16-17.2 23.6-41.6 23.6-72.4 0-20.8-2.8-36-8.4-45.2s-15.6-18-30-25.6c14-4.8 24.8-12.4 31.6-23.6 6.8-10.8 10.4-36.4 10.4-76.4-0.4-30.4-3.6-53.2-10.4-69.6zM824.4 424v187.2c123.6 0 124.8 6.4 124.8-62.4-1.6-68.8-56.4-124.8-124.8-124.8z" />
+<glyph unicode="&#xe904;" glyph-name="clock" d="M502.898 788.907c-245.76 0-443.733-197.973-443.733-443.733s200.249-443.733 443.733-443.733c245.76 0 443.733 197.973 443.733 443.733s-200.249 443.733-443.733 443.733zM791.893 210.916c-6.827-13.653-18.204-20.48-31.858-20.48-4.551 0-9.102 0-13.653 2.276l-261.689 118.329c-11.378 4.551-20.48 18.204-20.48 31.858v245.76c0 18.204 15.929 34.133 34.133 34.133s34.133-15.929 34.133-34.133v-225.28l241.209-109.227c18.204-6.827 25.031-25.031 18.204-43.236z" />
+<glyph unicode="&#xe905;" glyph-name="down" d="M174.56 163.976l288.192-242.864c26.864-22.384 70.512-22.384 97.368 0l288.192 242.864c43.088 36.936 12.312 99.608-48.128 99.608h-110.24v448.8c0 49.248-40.288 89.536-89.536 89.536h-179.072c-49.248 0-89.536-40.288-89.536-89.536v-448.8h-109.12c-61-0.56-91.216-63.232-48.128-99.608z" />
+<glyph unicode="&#xe906;" glyph-name="cube" d="M930.8 632.4c-2 1.2-4.4 2.4-6.4 3.2l-378 219.6c-21.2 12-47.2 12-68.4 0l-384.8-222.8c-21.2-12.4-34.4-34.8-34-59.2l1.2-442.4c0-24.4 12.8-47.2 34-59.2l378.4-219.6c1.6-1.2 3.2-2 4.8-3.2 3.6-2 7.6-3.6 11.6-5.2 0 0 0.4 0 0.4 0 0.4 0 1.2-0.4 1.6-0.4 6.4-2 12.8-3.2 19.6-3.2 0 0 0 0 0 0 0.4 0 0.8 0 0.8 0v0c12 0 23.6 2.8 34 8.8l385.2 222.4c21.2 12.4 34.4 34.8 34 59.2v442.8c0.4 24.4-12.8 47.2-34 59.2zM512.4 716.4l246.4-143.2-248.4-143.2-61.6 36-184.8 107.2 248.4 143.2zM829.2 169.6l-249.2-143.2v285.2l249.2 143.2v-285.2z" />
+<glyph unicode="&#xe907;" glyph-name="plane" d="M937.2 777.6c-22 18.4-53.2 20.8-93.6 7.6s-76.8-36-108.8-68.4l-101.2-101.2-421.6 100.8c-7.2 1.6-13.2 0.8-19.2-5.2l-80.8-81.2c-4.4-4.4-6.4-10-5.6-17.2 1.2-6.8 5.2-12 10.8-15.2l321.6-176.8-164-164-122.8 33.6c-0.8 0.8-2.4 0.8-5.2 0.8-5.6 0-10.8-2-14.4-5.6l-61.2-61.6c-4.8-4.8-6.4-10-5.6-16 0.8-6.8 4-11.2 8.4-14.4l159.6-119.6 119.6-159.6c3.6-4.8 8.8-7.6 15.2-8.4h1.2c5.6 0 10.8 2 14.4 5.6l60.8 60.8c5.6 5.6 6.8 12.8 5.2 19.6l-33.6 122.8 164 164 176.8-321.6c3.2-5.6 6.8-8.8 13.2-10 1.2-0.8 2.4-0.8 4.4-0.8 5.2 0 8.8 1.2 12 4l81.2 60.8c7.2 5.6 9.6 12.8 7.6 20.8l-101.2 440.8 102 102c32.4 32.4 55.2 68.4 68.4 108.8 13.2 40.8 10.8 72-7.6 94z" />
+<glyph unicode="&#xe908;" glyph-name="train" d="M576 237.2v-256h277.2c35.2 0 64-28.8 64-64s-28.8-64-64-64h-682.4c-35.2 0-64 28.8-64 64s28.8 64 64 64h277.2v256h-64c-35.2 0-64 28.8-64 64s28.8 64 64 64h256c35.2 0 64-28.8 64-64s-28.8-64-64-64h-64zM427.6 784c7.2 46.4 50.8 78.4 97.6 71.2 36.8-5.6 65.2-34.4 71.2-71.2 88-16.8 169.2-59.6 232.4-123.2 174.8-174.8 174.8-458.4 0-633.6-24.8-24.8-65.6-24.8-90.4 0s-24.8 65.6 0 90.4v0c124.8 124.8 124.8 327.6 0 452.4s-327.6 124.8-452.4 0-124.8-327.6 0-452.4c0 0 0 0 0 0 24.8-24.8 24.8-65.6 0-90.4s-65.6-24.8-90.4 0c-175.2 174.8-175.2 458.4-0.4 633.6 63.2 63.2 144.4 106.4 232.4 123.2v0z" />
+<glyph unicode="&#xe909;" glyph-name="bus" d="M203.902 20.316c-76.37 13.852-131.4 80.862-131.026 158.354l3.744 479.182c0.748 87.6 72.252 158.354 159.852 158.354h551.058c87.6 0 159.104-70.754 159.852-158.354l3.744-479.182c0.374-69.631-43.8-131.4-110.062-153.114l31.072-53.534c16.846-28.452 7.112-65.138-21.338-81.984s-65.138-7.112-81.984 21.338c0 0.374-0.374 0.374-0.374 0.748l-59.898 103.698c-0.374 0.748-0.748 1.124-1.124 1.872h-366.874c-0.374-0.748-0.748-1.498-1.124-1.872l-59.898-103.698c-16.472-28.826-52.784-38.934-81.61-22.462s-38.934 52.784-22.462 81.61c0 0.374 0.374 0.374 0.374 0.748l28.077 48.292zM452.102 656.354h-279.648c-10.856 0-19.842-8.984-19.842-19.842v0-239.59c0-10.856 8.984-19.842 19.842-19.842v0h279.648c10.856 0 19.842 8.984 19.842 19.842v0 239.59c0 10.856-8.984 19.842-19.842 19.842 0 0 0 0 0 0zM851.544 656.354h-279.648c-10.856 0-19.842-8.984-19.842-19.842v0-239.59c0-10.856 8.984-19.842 19.842-19.842 0 0 0 0 0 0h279.648c10.856 0 19.842 8.984 19.842 19.842v0 239.59c0 10.856-8.984 19.842-19.842 19.842 0 0 0 0 0 0zM731.75 296.97c-32.944 0-59.898-26.954-59.898-59.898s26.954-59.898 59.898-59.898 59.898 26.954 59.898 59.898-26.954 59.898-59.898 59.898zM292.25 296.97c-32.944 0-59.898-26.954-59.898-59.898s26.954-59.898 59.898-59.898 59.898 26.954 59.898 59.898-26.58 59.898-59.898 59.898z" />
+<glyph unicode="&#xe90a;" glyph-name="bag" d="M816.928 591.86h-87.137c0 120.346-97.563 218.028-217.791 218.028s-217.791-97.681-217.791-218.028h-87.137c-47.902 0-86.659-39.26-86.659-87.231l-0.478-523.315c0.109-48.101 39.043-87.067 87.119-87.231h609.844c48.090 0.163 87.028 39.13 87.137 87.222v523.299c-0.109 48.101-39.043 87.067-87.119 87.231h-0.017zM512 722.682c0.034 0 0.079 0 0.119 0 72.12 0 130.585-58.465 130.585-130.585 0-0.084 0-0.168 0-0.252v0.011h-261.406c0 0.069 0 0.153 0 0.237 0 72.12 58.465 130.585 130.585 130.585 0.040 0 0.084 0 0.124 0h-0.006zM512 286.577c-120.228 0-217.791 97.681-217.791 218.077h87.112c0-0.079 0-0.17 0-0.261 0-72.12 58.465-130.585 130.585-130.585 0.040 0 0.084 0 0.124 0h-0.006c0.022 0 0.048 0 0.074 0 72.12 0 130.585 58.465 130.585 130.585 0 0.084 0 0.168 0 0.252v-0.011h87.137c0-120.371-97.588-218.052-217.816-218.052z" />
+<glyph unicode="&#xe90b;" glyph-name="up" d="M848.728 541.856l-288.368 242.696c-26.864 22.392-70.752 22.392-97.616 0l-288.368-242.696c-42.984-36.72-12.536-99.408 48.36-99.408h110.152c0 0 0-0.896 0-0.896v-447.776c0-49.256 40.296-89.552 89.552-89.552h179.112c49.256 0 89.552 40.296 89.552 89.552v447.776c0 0 0 0.896 0 0.896h109.256c60.896 0 91.344 62.688 48.36 99.408z" />
+</font></defs></svg>

BIN
static/essjksh/fonts/icomoon.ttf


BIN
static/essjksh/fonts/icomoon.woff


BIN
static/essjksh/images/border.png


BIN
static/essjksh/images/line.png


BIN
static/essjksh/images/logo.png


BIN
static/essjksh/images/rect.png


BIN
static/essjksh/images/智慧大屏.rar


File diff suppressed because it is too large
+ 44 - 0
static/essjksh/js/china.js


+ 445 - 0
static/essjksh/js/index.js

@@ -0,0 +1,445 @@
+//自调用函数
+(function () {
+    // 1、页面一加载就要知道页面宽度计算
+    var setFont = function () {
+        // 因为要定义变量可能和别的变量相互冲突,污染,所有用自调用函数
+        var html = document.documentElement;// 获取html
+        // 获取宽度
+        var width = html.clientWidth;
+
+        // 判断
+        if (width < 1024) width = 1024
+        if (width > 1920) width = 1920
+        // 设置html的基准值
+        var fontSize = width / 80 + 'px';
+        // 设置给html
+        html.style.fontSize = fontSize;
+    }
+    setFont();
+    // 2、页面改变的时候也需要设置
+    // 尺寸改变事件
+    window.onresize = function () {
+        setFont();
+    }
+})();
+
+(function () {
+    //事件委托
+    $('.monitor').on('click', ' a', function () {
+        //点击当前的a 加类名 active  他的兄弟删除类名
+        $(this).addClass('active').siblings().removeClass('active');
+        //获取一一对应的下标 
+        var index = $(this).index();
+        //选取content 然后狗日对应下标的 显示   当前的兄弟.content隐藏
+        $('.content').eq(index).show().siblings('.content').hide();
+    });
+    //滚动
+    //原理:把marquee下面的子盒子都复制一遍 加入到marquee中
+    //      然后动画向上滚动,滚动到一半重新开始滚动
+    //因为选取的是两个marquee  所以要遍历
+    $('.monitor .marquee').each(function (index, dom) {
+        //将每个 的所有子级都复制一遍
+        var rows = $(dom).children().clone();
+        //再将新的到的加入原来的
+        $(dom).append(rows);
+    });
+
+})();
+(function () {
+    var myechart = echarts.init($('.pie')[0]);
+    option = {
+        // 控制提示
+        tooltip: {
+            // 非轴图形,使用item的意思是放到数据对应图形上触发提示
+            trigger: 'item',
+            // 格式化提示内容:
+            // a 代表图表名称 b 代表数据名称 c 代表数据  d代表  当前数据/总数据的比例
+            formatter: "{a} <br/>{b} : {c} ({d}%)"
+        },
+        // 控制图表
+        series: [
+            {
+                // 图表名称
+                name: '地区',
+                // 图表类型
+                type: 'pie',
+                // 南丁格尔玫瑰图 有两个圆  内圆半径10%  外圆半径70%
+                // 百分比基于  图表DOM容器的半径
+                radius: ['10%', '70%'],
+                // 图表中心位置 left 50%  top 50% 距离图表DOM容器
+                center: ['50%', '50%'],
+                // 半径模式,另外一种是 area 面积模式
+                roseType: 'radius',
+                // 数据集 value 数据的值 name 数据的名称
+                data: [
+                    { value: 20, name: '云南' },
+                    { value: 5, name: '北京' },
+                    { value: 15, name: '山东' },
+                    { value: 25, name: '河北' },
+                    { value: 20, name: '江苏' },
+                    { value: 35, name: '浙江' },
+                    { value: 30, name: '四川' },
+                    { value: 40, name: '湖北' }
+                ],
+                //文字调整
+                label: {
+                    fontSize: 10
+                },
+                //引导线
+                labelLine: {
+                    length: 8,
+                    length2: 10
+                }
+            }
+        ],
+        color: ['#006cff', '#60cda0', '#ed8884', '#ff9f7f', '#0096ff', '#9fe6b8', '#32c5e9', '#1d9dff']
+    };
+    myechart.setOption(option);
+})();
+// 用户
+(function () {
+    // 中间省略的数据  准备三项
+    var item = {
+        name: '',
+        value: 1200,
+        // 柱子颜色
+        itemStyle: {
+            color: '#254065'
+        },
+        // 鼠标经过柱子颜色
+        emphasis: {
+            itemStyle: {
+                color: '#254065'
+            }
+        },
+        // 工具提示隐藏
+        tooltip: {
+            extraCssText: 'opacity:0'
+        }
+    };
+    option = {
+        // 工具提示
+        tooltip: {
+            // 触发类型  经过轴触发axis  经过轴触发item
+            trigger: 'item',
+            // 轴触发提示才有效
+            axisPointer: {
+                // 默认为直线,可选为:'line' 线效果 | 'shadow' 阴影效果       
+                type: 'shadow'
+            }
+        },
+        // 图表边界控制
+        grid: {
+            // 距离 上右下左 的距离
+            left: '0',
+            right: '3%',
+            bottom: '3%',
+            top: '5%',
+            // 大小是否包含文本【类似于boxsizing】
+            containLabel: true,
+            //显示边框
+            show: true,
+            //边框颜色
+            borderColor: 'rgba(0, 240, 255, 0.3)'
+        },
+        // 控制x轴
+        xAxis: [
+            {
+                // 使用类目,必须有data属性
+                type: 'category',
+                // 使用 data 中的数据设为刻度文字
+                data: ['上海', '广州', '北京', '深圳', '合肥', '', '......', '', '杭州', '厦门', '济南', '成都', '重庆'],
+                // 刻度设置
+                axisTick: {
+                    // true意思:图形在刻度中间
+                    // false意思:图形在刻度之间
+                    alignWithLabel: false,
+                    show: false
+                },
+                //文字
+                axisLabel: {
+                    color: '#4c9bfd'
+                }
+            }
+        ],
+        // 控制y轴
+        yAxis: [
+            {
+                // 使用数据的值设为刻度文字
+                type: 'value',
+                axisTick: {
+                    // true意思:图形在刻度中间
+                    // false意思:图形在刻度之间
+                    alignWithLabel: false,
+                    show: false
+                },
+                //文字
+                axisLabel: {
+                    color: '#4c9bfd'
+                },
+                splitLine: {
+                    lineStyle: {
+                        color: 'rgba(0, 240, 255, 0.3)'
+                    }
+                },
+            }
+        ],
+        // 控制x轴
+        series: [
+
+            {
+                // series配置
+                // 颜色
+                itemStyle: {
+                    // 提供的工具函数生成渐变颜色
+                    color: new echarts.graphic.LinearGradient(
+                        // (x1,y2) 点到点 (x2,y2) 之间进行渐变
+                        0, 0, 0, 1,
+                        [
+                            { offset: 0, color: '#00fffb' }, // 0 起始颜色
+                            { offset: 1, color: '#0061ce' }  // 1 结束颜色
+                        ]
+                    )
+                },
+                // 图表数据名称
+                name: '用户统计',
+                // 图表类型
+                type: 'bar',
+                // 柱子宽度
+                barWidth: '60%',
+                // 数据
+                data: [2100, 1900, 1700, 1560, 1400, item, item, item, 900, 750, 600, 480, 240]
+            }
+        ]
+    };
+    var myechart = echarts.init($('.users .bar')[0]);
+    myechart.setOption(option);
+})();
+
+//订单
+(function () {
+    var data = {
+        day365: { orders: '20,301,987', amount: '99834' },
+        day90: { orders: '301,987', amount: '9834' },
+        day30: { orders: '1,987', amount: '3834' },
+        day1: { orders: '987', amount: '834' }
+    }
+    //点击事件
+    $('.order').on('click', '.filter a', function () {
+        //点击之后加类名
+        $(this).addClass('active').siblings().removeClass('active');
+        // 先获取点击a的 data-key自定义属性
+        var key = $(this).attr('data-key');
+        //获取自定义属性
+        // data{}==>data.shuxing data['shuxing]
+        key = data[key];//
+        $('.order .item h4:eq(0)').text(key.orders);
+        $('.order .item h4:eq(1)').text(key.amount);
+    });
+    //定时器
+    var index = 0;
+    var aclick = $('.order a');
+    setInterval(function () {
+        index++;
+        if (index > 3) {
+            index = 0;
+        }
+        //每san秒调用点击事件
+        aclick.eq(index).click();
+    }, 3000);
+})();
+//销售
+(function () {
+    var option = {
+        //鼠标提示工具
+        tooltip: {
+            trigger: 'axis'
+        },
+        xAxis: {
+            // 类目类型                                  
+            type: 'category',
+            // x轴刻度文字                                  
+            data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
+            axisTick: {
+                show: false//去除刻度线
+            },
+            axisLabel: {
+                color: '#4c9bfd'//文本颜色
+            },
+            axisLine: {
+                show: false//去除轴线  
+            },
+            boundaryGap: false//去除轴内间距
+        },
+        yAxis: {
+            // 数据作为刻度文字                                  
+            type: 'value',
+            axisTick: {
+                show: false//去除刻度线
+            },
+            axisLabel: {
+                color: '#4c9bfd'//文本颜色
+            },
+            axisLine: {
+                show: false//去除轴线  
+            },
+            boundaryGap: false//去除轴内间距
+        },
+        //图例组件
+        legend: {
+            textStyle: {
+                color: '#4c9bfd' // 图例文字颜色
+
+            },
+            right: '10%'//距离右边10%
+        },
+        // 设置网格样式
+        grid: {
+            show: true,// 显示边框
+            top: '20%',
+            left: '3%',
+            right: '4%',
+            bottom: '3%',
+            borderColor: '#012f4a',// 边框颜色
+            containLabel: true // 包含刻度文字在内
+        },
+        series: [{
+            name: '预期销售额',
+            // 数据                                  
+            data: [24, 40, 101, 134, 90, 230, 210, 230, 120, 230, 210, 120],
+            // 图表类型                                  
+            type: 'line',
+            // 圆滑连接                                  
+            smooth: true,
+            itemStyle: {
+                color: '#00f2f1'  // 线颜色
+            }
+        },
+        {
+            name: '实际销售额',
+            // 数据                                  
+            data: [40, 64, 191, 324, 290, 330, 310, 213, 180, 200, 180, 79],
+            // 图表类型                                  
+            type: 'line',
+            // 圆滑连接                                  
+            smooth: true,
+            itemStyle: {
+                color: '#ed3f35'  // 线颜色
+            }
+        }]
+    };
+    var myechart = echarts.init($('.line')[0]);
+    myechart.setOption(option);
+
+    //点击效果
+    var data = {
+        year: [
+            [24, 40, 101, 134, 90, 230, 210, 230, 120, 230, 210, 120],
+            [40, 64, 191, 324, 290, 330, 310, 213, 180, 200, 180, 79]
+        ],
+        quarter: [
+            [23, 75, 12, 97, 21, 67, 98, 21, 43, 64, 76, 38],
+            [43, 31, 65, 23, 78, 21, 82, 64, 43, 60, 19, 34]
+        ],
+        month: [
+            [34, 87, 32, 76, 98, 12, 32, 87, 39, 36, 29, 36],
+            [56, 43, 98, 21, 56, 87, 43, 12, 43, 54, 12, 98]
+        ],
+        week: [
+            [43, 73, 62, 54, 91, 54, 84, 43, 86, 43, 54, 53],
+            [32, 54, 34, 87, 32, 45, 62, 68, 93, 54, 54, 24]
+        ]
+    }
+    $('.sales ').on('click', '.caption a', function () {
+        $(this).addClass('active').siblings('a').removeClass('active');
+        //option series   data
+        //获取自定义属性值
+        var key = $(this).attr('data-type');
+        //取出对应的值
+        key = data[key];
+        //将值设置到 图表中
+        option.series[0].data = key[0];
+        option.series[1].data = key[1];
+        //再次调用才能在页面显示
+        myechart.setOption(option);
+    });
+    //定时器
+    var index = 0;
+    var timer = setInterval(function () {
+        index++;
+        if (index > 4) {
+            index = 0;
+        };
+        $('.sales .caption a').eq(index).click();
+    }, 2000);
+})();
+(function () {
+    var option = {
+        series: [
+            {
+                type: 'pie',
+                radius: ['130%', '150%'],  // 放大图形
+                center: ['50%', '80%'],    // 往下移动  套住75%文字
+                label: {
+                    show: false,
+                },
+                startAngle: 180,
+                hoverOffset: 0,  // 鼠标经过不变大
+                data: [
+                    {
+                        value: 100,
+                        itemStyle: { // 颜色渐变#00c9e0->#005fc1
+                            color: {
+                                type: 'linear',
+                                x: 0,
+                                y: 0,
+                                x2: 0,
+                                y2: 1,
+                                colorStops: [
+                                    { offset: 0, color: '#00c9e0' },
+                                    { offset: 1, color: '#005fc1' }
+                                ]
+                            }
+                        }
+                    },
+                    { value: 100, itemStyle: { color: '#12274d' } }, // 颜色#12274d
+
+                    { value: 200, itemStyle: { color: 'transparent' } }// 透明隐藏第三块区域
+                ]
+            }
+        ]
+    };
+    var myechart = echarts.init($('.gauge')[0]);
+    myechart.setOption(option);
+})();
+(function () {
+    var data = [
+        { name: '可爱多', num: '9,086' },
+        { name: '娃哈哈', num: '8,341' },
+        { name: '喜之郎', num: '7,407' },
+        { name: '八喜', num: '6,080' },
+        { name: '小洋人', num: '6,724' },
+        { name: '好多鱼', num: '2,170' },
+    ]
+    $('.inner').on('mouseenter', '.sup li', function () {
+        $(this).addClass('active').siblings().removeClass('active');
+        //获取随机的值  sort方法 是给数组排序 a-b是从小到大
+        //.5-随机0-1的数 可能为正可能为负 排序就会随机
+        var radomData = data.sort(function (a, b) { return 0.5 - Math.random() });
+        var html = '';
+        radomData.forEach(function (item) {
+            html += `<li><span>${item.name}</span><span>${item.num} <s class="icon-up"></s></span></li>`;
+        });
+        //渲染
+        $('.sub').html(html);
+    });
+    $('.province .sup li').eq(0).mouseenter();
+    var index = 0;
+    var timer = setInterval(() => {
+        index++;
+        if (index > 5) {
+            index = 0;
+        }
+        $('.sup li').eq(index).mouseenter();
+    }, 2000);
+})();

File diff suppressed because it is too large
+ 1 - 0
static/essjksh/js/jquery.min.js


+ 492 - 0
static/essjksh/js/mymap.js

@@ -0,0 +1,492 @@
+var geoCoordMap = {
+    '新疆玛纳斯基地': [86.22, 44.30],
+    '九江': [116.00, 29.70],
+    '新乡': [116.402217, 35.311657],
+    ' ': [79.92, 37.12],
+    '  ': [86.85, 47.70],
+    '若羌县': [88.17, 39.02],
+    '上海': [121.4648, 31.2891],
+    '东莞': [113.8953, 22.901],
+    '东营': [118.7073, 37.5513],
+    '中山': [113.4229, 22.478],
+    '临汾': [111.4783, 36.1615],
+    '临沂': [118.3118, 35.2936],
+    '丹东': [124.541, 40.4242],
+    '丽水': [119.5642, 28.1854],
+    '乌鲁木齐': [87.9236, 43.5883],
+    '佛山': [112.8955, 23.1097],
+    '保定': [115.0488, 39.0948],
+    '兰州': [103.5901, 36.3043],
+    '包头': [110.3467, 41.4899],
+    '北京': [116.4551, 40.2539],
+    '北海': [109.314, 21.6211],
+    '南京': [118.8062, 31.9208],
+    '南宁': [108.479, 23.1152],
+    '南昌': [116.0046, 28.6633],
+    '南通': [121.1023, 32.1625],
+    '厦门': [118.1689, 24.6478],
+    '台州': [121.1353, 28.6688],
+    '合肥': [117.29, 32.0581],
+    '呼和浩特': [111.4124, 40.4901],
+    '咸阳': [108.4131, 34.8706],
+    '哈尔滨': [127.9688, 45.368],
+    '唐山': [118.4766, 39.6826],
+    '嘉兴': [120.9155, 30.6354],
+    '大同': [113.7854, 39.8035],
+    '大连': [122.2229, 39.4409],
+    '天津': [117.4219, 39.4189],
+    '太原': [112.3352, 37.9413],
+    '威海': [121.9482, 37.1393],
+    '宁波': [121.5967, 29.6466],
+    '宝鸡': [107.1826, 34.3433],
+    '宿迁': [118.5535, 33.7775],
+    '常州': [119.4543, 31.5582],
+    '广州': [113.5107, 23.2196],
+    '廊坊': [116.521, 39.0509],
+    '延安': [109.1052, 36.4252],
+    '张家口': [115.1477, 40.8527],
+    '徐州': [117.5208, 34.3268],
+    '德州': [116.6858, 37.2107],
+    '惠州': [114.6204, 23.1647],
+    '成都': [103.9526, 30.7617],
+    '扬州': [119.4653, 32.8162],
+    '承德': [117.5757, 41.4075],
+    '拉萨': [91.1865, 30.1465],
+    '无锡': [120.3442, 31.5527],
+    '日照': [119.2786, 35.5023],
+    '昆明': [102.9199, 25.4663],
+    '杭州': [119.5313, 29.8773],
+    '枣庄': [117.323, 34.8926],
+    '柳州': [109.3799, 24.9774],
+    '株洲': [113.5327, 27.0319],
+    '武汉': [114.3896, 30.6628],
+    '汕头': [117.1692, 23.3405],
+    '江门': [112.6318, 22.1484],
+    '沈阳': [123.1238, 42.1216],
+    '沧州': [116.8286, 38.2104],
+    '河源': [114.917, 23.9722],
+    '泉州': [118.3228, 25.1147],
+    '泰安': [117.0264, 36.0516],
+    '泰州': [120.0586, 32.5525],
+    '济南': [117.1582, 36.8701],
+    '济宁': [116.8286, 35.3375],
+    '海口': [110.3893, 19.8516],
+    '淄博': [118.0371, 36.6064],
+    '淮安': [118.927, 33.4039],
+    '深圳': [114.5435, 22.5439],
+    '清远': [112.9175, 24.3292],
+    '温州': [120.498, 27.8119],
+    '渭南': [109.7864, 35.0299],
+    '湖州': [119.8608, 30.7782],
+    '湘潭': [112.5439, 27.7075],
+    '滨州': [117.8174, 37.4963],
+    '潍坊': [119.0918, 36.524],
+    '烟台': [120.7397, 37.5128],
+    '玉溪': [101.9312, 23.8898],
+    '珠海': [113.7305, 22.1155],
+    '盐城': [120.2234, 33.5577],
+    '盘锦': [121.9482, 41.0449],
+    '石家庄': [114.4995, 38.1006],
+    '福州': [119.4543, 25.9222],
+    '秦皇岛': [119.2126, 40.0232],
+    '绍兴': [120.564, 29.7565],
+    '聊城': [115.9167, 36.4032],
+    '肇庆': [112.1265, 23.5822],
+    '舟山': [122.2559, 30.2234],
+    '苏州': [120.6519, 31.3989],
+    '莱芜': [117.6526, 36.2714],
+    '菏泽': [115.6201, 35.2057],
+    '营口': [122.4316, 40.4297],
+    '葫芦岛': [120.1575, 40.578],
+    '衡水': [115.8838, 37.7161],
+    '衢州': [118.6853, 28.8666],
+    '西宁': [101.4038, 36.8207],
+    '西安': [109.1162, 34.2004],
+    '贵阳': [106.6992, 26.7682],
+    '连云港': [119.1248, 34.552],
+    '邢台': [114.8071, 37.2821],
+    '邯郸': [114.4775, 36.535],
+    '郑州': [113.4668, 34.6234],
+    '鄂尔多斯': [108.9734, 39.2487],
+    '重庆': [107.7539, 30.1904],
+    '金华': [120.0037, 29.1028],
+    '铜川': [109.0393, 35.1947],
+    '银川': [106.3586, 38.1775],
+    '镇江': [119.4763, 31.9702],
+    '长春': [125.8154, 44.2584],
+    '长沙': [113.0823, 28.2568],
+    '长治': [112.8625, 36.4746],
+    '阳泉': [113.4778, 38.0951],
+    '青岛': [120.4651, 36.3373],
+    '韶关': [113.7964, 24.7028]
+};
+
+var BJData = [
+    [{
+        name: '新乡'
+    }, {
+        name: '新乡',
+        value: 200
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '呼和浩特',
+        value: 90
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '哈尔滨',
+        value: 90
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '石家庄',
+        value: 90
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '昆明',
+        value: 30
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '北京',
+        value: 100
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '长春',
+        value: 40
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '重庆',
+        value: 40
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '贵阳',
+        value: 50
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '南宁',
+        value: 30
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '济南',
+        value: 10
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '太原',
+        value: 40
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '西安',
+        value: 60
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '武汉',
+        value: 50
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '合肥',
+        value: 40
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '南京',
+        value: 30
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '沈阳',
+        value: 20
+    }],
+    [{
+        name: '新乡'
+    }, {
+        name: '成都',
+        value: 10
+    }]
+];
+
+var SHData = [
+    [{
+        name: '九江'
+    }, {
+        name: '九江',
+        value: 200
+    }],
+
+    [{
+        name: '九江'
+    }, {
+        name: '长沙',
+        value: 95
+    }],
+    [{
+        name: '九江'
+    }, {
+        name: '武汉',
+        value: 30
+    }],
+    [{
+        name: '九江'
+    }, {
+        name: '南昌',
+        value: 20
+    }],
+    [{
+        name: '九江'
+    }, {
+        name: '合肥',
+        value: 70
+    }],
+    [{
+        name: '九江'
+    }, {
+        name: '南京',
+        value: 60
+    }],
+    [{
+        name: '九江'
+    }, {
+        name: '福州',
+        value: 50
+    }],
+    [{
+        name: '九江'
+    }, {
+        name: '上海',
+        value: 100
+    }],
+    [{
+        name: '九江'
+    }, {
+        name: '深圳',
+        value: 100
+    }],
+
+];
+
+var GZData = [
+    [{
+        name: '新疆玛纳斯基地'
+    }, {
+        name: '新疆玛纳斯基地',
+        value: 200
+    }],
+    [{
+        name: '新疆玛纳斯基地'
+    }, {
+        name: '  ',
+        value: 90
+    }],
+    [{
+        name: '新疆玛纳斯基地'
+    }, {
+        name: ' ',
+        value: 40
+    }],
+    [{
+        name: '新疆玛纳斯基地'
+    }, {
+        name: '呼和浩特',
+        value: 90
+    }],
+    [{
+        name: '新疆玛纳斯基地'
+    }, {
+        name: '昆明',
+        value: 40
+    }],
+    [{
+        name: '新疆玛纳斯基地'
+    }, {
+        name: '成都',
+        value: 10
+    }],
+    [{
+        name: '新疆玛纳斯基地'
+    }, {
+        name: '兰州',
+        value: 95
+    }],
+    [{
+        name: '新疆玛纳斯基地'
+    }, {
+        name: '银川',
+        value: 90
+    }],
+    [{
+        name: '新疆玛纳斯基地'
+    }, {
+        name: '西宁',
+        value: 80
+    }],
+
+];
+
+var planePath = 'path://M.6,1318.313v-89.254l-319.9-221.799l0.073-208.063c0.521-84.662-26.629-121.796-63.961-121.491c-37.332-0.305-64.482,36.829-63.961,121.491l0.073,208.063l-319.9,221.799v89.254l330.343-157.288l12.238,241.308l-134.449,92.931l0.531,42.034l175.125-42.917l175.125,42.917l0.531-42.034l-134.449-92.931l12.238-241.308L1705';
+
+var convertData = function (data) {
+    var res = [];
+    for (var i = 0; i < data.length; i++) {
+        var dataItem = data[i];
+        var fromCoord = geoCoordMap[dataItem[0].name];
+        var toCoord = geoCoordMap[dataItem[1].name];
+        if (fromCoord && toCoord) {
+            res.push([{
+                coord: fromCoord
+            }, {
+                coord: toCoord
+            }]);
+        }
+    }
+    return res;
+};
+
+var color = ['#3ed4ff', '#ffa022', '#a6c84c'];
+var series = [];
+[
+    ['新乡', BJData],
+    ['九江', SHData],
+    ['新疆', GZData]
+].forEach(function (item, i) {
+    series.push({
+        name: item[0] + ' Top10',
+        type: 'lines',
+        zlevel: 1,
+        effect: {
+            show: true,
+            period: 6,
+            trailLength: 0.7,
+            color: '#fff',
+            symbolSize: 3
+        },
+        lineStyle: {
+            normal: {
+                color: color[i],
+                width: 0,
+                curveness: 0.2
+            }
+        },
+        data: convertData(item[1])
+    }, {
+        name: item[0] + ' Top10',
+        type: 'lines',
+        zlevel: 2,
+        effect: {
+            show: true,
+            period: 6,
+            trailLength: 0,
+            symbol: planePath,
+            symbolSize: 15
+        },
+        lineStyle: {
+            normal: {
+                color: color[i],
+                width: 1,
+                opacity: 0.4,
+                curveness: 0.2
+            }
+        },
+        data: convertData(item[1])
+    }, {
+        name: item[0] + ' Top10',
+        type: 'effectScatter',
+        coordinateSystem: 'geo',
+        zlevel: 2,
+        rippleEffect: {
+            brushType: 'stroke'
+        },
+        label: {
+            normal: {
+                show: true,
+                position: 'right',
+                formatter: '{b}'
+            }
+        },
+        symbolSize: function (val) {
+            return val[2] / 8;
+        },
+        itemStyle: {
+            normal: {
+                color: color[i]
+            }
+        },
+        data: item[1].map(function (dataItem) {
+            return {
+                name: dataItem[1].name,
+                value: geoCoordMap[dataItem[1].name].concat([dataItem[1].value])
+            };
+        })
+    });
+});
+
+option = {
+    backgroundColor: '#080a20',
+    title: {
+        left: 'left',
+        textStyle: {
+            color: '#fff'
+        }
+    },
+    tooltip: {
+        trigger: 'item'
+    },
+    legend: {
+        orient: 'vertical',
+        top: 'bottom',
+        left: 'right',
+        data: ['北京 Top10', '上海 Top10', '广州 Top10'],
+        textStyle: {
+            color: '#fff'
+        },
+        selectedMode: 'single'
+    },
+    geo: {
+        map: 'china',
+        zoom: 1.2,
+        label: {
+            emphasis: {
+                show: false
+            }
+        },
+        roam: true,
+        itemStyle: {
+            normal: {
+                areaColor: '#142957',
+                borderColor: '#0692a4'
+            },
+            emphasis: {
+                areaColor: '#0b1c2d'
+            }
+        }
+    },
+    series: series
+};
+var myecharts = echarts.init($('.map .geo')[0])
+myecharts.setOption(option)

BIN
static/favicon.ico


BIN
static/fonts/iconfont.eot


File diff suppressed because it is too large
+ 44 - 0
static/fonts/iconfont.svg


BIN
static/fonts/iconfont.ttf


BIN
static/fonts/iconfont.woff


BIN
static/images/aiwrap.png


BIN
static/images/bg.png


BIN
static/images/bg1.png


Some files were not shown because too many files changed in this diff