Browse Source

合并Tab

siked 1 year ago
parent
commit
bc65fd09b7

+ 46 - 46
Handle/Handle.go

@@ -1,44 +1,44 @@
 package Handle
 
 import (
-	"Yunlot/Handle/MqttServer"
-	"Yunlot/conf"
 	"Yunlot/logs"
 	"Yunlot/models/Device"
 	"Yunlot/models/Product"
 	"fmt"
 	"go.mongodb.org/mongo-driver/bson"
-	"plugin"
 	"reflect"
 )
 
-func AnalysisMap(Device_r Device.Device, ProductType_r Product.ProductType, ArticleSlide map[string]interface{}, JointTab string) {
+func AnalysisMap(Device_r *Device.Device, ProductType_r Product.ProductType, ArticleSlide map[string]interface{}, JointTab string) {
 	//JointTab += "."
 	T_r := make(map[string]interface{})
 	for key, value := range ArticleSlide {
 		//fmt.Println(reflect.TypeOf(value).String())
 		switch reflect.TypeOf(value).String() {
 		case "map[string]interface {}":
-			AnalysisMap(Device_r, ProductType_r, value.(map[string]interface{}), JointTab+key+"_")
+			AnalysisMap(Device_r, ProductType_r, value.(map[string]interface{}), JointTab+key+".")
 			break
 		case "[]interface {}":
 			for _, valuex := range value.([]interface{}) {
 				if reflect.TypeOf(valuex).String() == "map[string]interface {}" {
-					AnalysisMap(Device_r, ProductType_r, valuex.(map[string]interface{}), JointTab+key+"_")
+					AnalysisMap(Device_r, ProductType_r, valuex.(map[string]interface{}), JointTab+key+".")
 				}
 			}
 			break
 		default:
 			T_r[key] = value
+			// 根 TAB
 			if len(JointTab) == 0 {
-				Device.Data_Add("202300000001_"+key, &bson.M{key: value})
+				Device.Data_Add(Device_r.T_sn+"_"+key, &bson.M{key: value})
 			}
+
 			break
 		}
 	}
 	if len(JointTab) == 0 {
 		return
 	}
+	// 多级 TAB
 	JointTab = JointTab[:len(JointTab)-1]
 	fmt.Println(JointTab, "-------")
 	bson_r := bson.M{}
@@ -48,10 +48,10 @@ func AnalysisMap(Device_r Device.Device, ProductType_r Product.ProductType, Arti
 	}
 
 	// 消息转发
-	Relay(Device_r, ProductType_r, JointTab, ArticleSlide)
+	//Relay(Device_r, ProductType_r, JointTab, ArticleSlide)
 
 	// 数据存储
-	Device.Data_Add("202300000001_"+JointTab, &bson_r)
+	Device.Data_Add(Device_r.T_sn+"_"+JointTab, &bson_r)
 
 }
 
@@ -67,45 +67,45 @@ func T(Device_r Device.Device, topic string, message []byte) {
 	// 设备协议
 	ProductProt_r := Product.ProductProt{Id: ProductType_r.T_prot}
 	if !ProductProt_r.Read() {
-		logs.Println("MqttServer", Device_r.T_sn+"|"+Device_r.T_ProductID+"-"+ fmt.Sprintf("%d",ProductType_r.T_prot)+" 设备协议找不到!")
+		logs.Println("MqttServer", Device_r.T_sn+"|"+Device_r.T_ProductID+"-"+fmt.Sprintf("%d", ProductType_r.T_prot)+" 设备协议找不到!")
 		return
 	}
-
-	// 根据库的存放路径加载库
-	p, err := plugin.Open(conf.Analysis_Dir + ProductProt_r.T_analysis)
-	if err != nil {
-		println(err)
-		panic(any(err))
-	}
-
-	// 查找库导出信息
-	s, err := p.Lookup("T")
-	if err != nil {
-		println(err)
-		panic(any(err))
-	}
-	// 类型转换
-	f := s.(func(b []byte) []byte)(message)
-
-	//0:Mqtt  1:http  2:tcp  3:CoAP  4:websocket
-	switch ProductProt_r.T_mode {
-	case 0: //Mqtt
-		MqttServer.Mqtt_publish(topic, f) // 返回数据
-		break
-	case 1: //http
-
-		break
-	case 2: //tcp
-
-		break
-	case 3: //CoAP
-
-		break
-	case 4: //websocket
-
-		break
-
-	}
+	//
+	//// 根据库的存放路径加载库
+	//p, err := plugin.Open(conf.Analysis_Dir + ProductProt_r.T_analysis)
+	//if err != nil {
+	//	println(err)
+	//	panic(any(err))
+	//}
+	//
+	//// 查找库导出信息
+	//s, err := p.Lookup("T")
+	//if err != nil {
+	//	println(err)
+	//	panic(any(err))
+	//}
+	//// 类型转换
+	//f := s.(func(b []byte) []byte)(message)
+
+	////0:Mqtt  1:http  2:tcp  3:CoAP  4:websocket
+	//switch ProductProt_r.T_mode {
+	//case 0: //Mqtt
+	//	MqttServer.Mqtt_publish(topic, f) // 返回数据
+	//	break
+	//case 1: //http
+	//
+	//	break
+	//case 2: //tcp
+	//
+	//	break
+	//case 3: //CoAP
+	//
+	//	break
+	//case 4: //websocket
+	//
+	//	break
+	//
+	//}
 
 	return
 

+ 100 - 63
Handle/MqttServer/Server.go

@@ -1,6 +1,7 @@
 package MqttServer
 
 import (
+	"Yunlot/Handle"
 	"Yunlot/conf"
 	"Yunlot/lib"
 	"Yunlot/logs"
@@ -64,7 +65,7 @@ func Run_MqttServer() {
 
 		return
 	}
-
+	logs.Println("MqttServer", "连接成功!")
 	// Subscribe to topics.
 	err = cli.Subscribe(&client.SubscribeOptions{
 		SubReqs: []*client.SubReq{
@@ -73,8 +74,15 @@ func Run_MqttServer() {
 				QoS:         mqtt.QoS0,
 				// Define the processing of the message handler.
 				Handler: func(topicName, message []byte) {
-					logs.PrintlnMqtt("<-" + string(topicName) + " " + string(message))
+					_, exists := lib.TopicMap[string(topicName)]
+					if exists {
+						//logs.Println("跳过:",string(topicName))
+						return // 这个 订阅号 平台->设备,跳过
+					}
+					start := time.Now()
 					messagePubHandler(string(topicName), message)
+					elapsed := time.Since(start)
+					fmt.Printf("代码运行时间:%s\n", elapsed)
 				},
 			},
 			&client.SubReq{ // 设备断开
@@ -236,8 +244,9 @@ func MQTT_Gin_Run() {
 
 // 开始处理
 func messagePubHandler(topicName string, message []byte) {
+
 	// 本地测试
-	logs.Println("=", "============= Mqtt2 JSON =============")
+	logs.Println("", "============= Mqtt JSON =============")
 	logs.Println("<-"+topicName, string(message))
 
 	// 过滤
@@ -280,89 +289,117 @@ func messagePubHandler(topicName string, message []byte) {
 		return
 	}
 
-	// 根据库的存放路径加载库
+	// Plugin 指针添加到 MAP,不知道能不能提高速度
+	//_, exists := lib.TopicMap[string(topicName)]
+	//if exists {
+	//	//logs.Println("跳过:",string(topicName))
+	//	return // 这个 订阅号 平台->设备,跳过
+	//}
+	//p, p_is := lib.PluginMap[ProductProt_r.T_analysis]
+	//if !p_is {
+	//	var err error
+	//	// 根据库的存放路径加载库
+	//	p_p, err := plugin.Open(conf.Analysis_Dir + ProductProt_r.T_analysis + ".so")
+	//	if err != nil {
+	//		logs.PrintlnError("打开 SO 失败:", err)
+	//		return
+	//	}
+	//	p = p_p
+	//	lib.PluginMap[ProductProt_r.T_analysis] = p
+	//	logs.Println("NEW Plugin 地址:",&p_p)
+	//}
+
+	// 加载 SO 文件
 	p, err := plugin.Open(conf.Analysis_Dir + ProductProt_r.T_analysis + ".so")
 	if err != nil {
-		println(err)
 		logs.PrintlnError("打开 SO 失败:", err)
+		return
 	}
+	logs.Println("Plugin 地址:", &p)
 
-	if topicName[len(topicName)-6:] == "_reply" {
-		// 返回数据
-		s, err := p.Lookup("T_reply")
+	var Rt_r = lib.Rt{Status: 200, Msg: "ok"}
+	// 查找库导出信息
+	s, err := p.Lookup("T")
+	if err != nil {
+		logs.Println("", err)
+		panic(any(err))
+	}
+	// 类型转换
+	f := s.(func(t string, b []byte) string)(topicName, message)
+
+	// 开始处理
+	logs.Println("协议后:", f)
+	//logs.Println("首字符:", string(f[0]))
+	if f[0] == '{' {
+		//结构体
+		var json_r map[string]interface{}
+		err = json.Unmarshal([]byte(f), &json_r)
 		if err != nil {
-			println(err)
-			panic(any(err))
+			Rt_r.Status = 203
+			Rt_r.Msg = "json E!"
+			goto Mreturn
 		}
-		// 类型转换
-		f := s.(func(b []byte) []byte)(message)
 
-		// 开始处理
-		println(f)
+		Handle.AnalysisMap(&Device_r, ProductType_r, json_r, "")
+
+		// 合并json
+		Device_r.Read_Tidy() // 提前最新的
+		logs.Println("Device_r.T_data:", Device_r.T_data)
+		if len(Device_r.T_data) > 5 {
+			json.Unmarshal([]byte(Device_r.T_data), &json_r)
+		}
+		Device_r.T_dataJson = json_r
+		Device_r.UpdateTime.NowDbTime()
+		Device_r.Update("T_data", "UpdateTime")
 
 	} else {
-		var Rt_r = lib.Rt{Status: 200, Msg: "ok"}
-		// 查找库导出信息
-		s, err := p.Lookup("R")
+		//列表
+		var json_lr []map[string]interface{}
+		err = json.Unmarshal([]byte(f), &json_lr)
 		if err != nil {
-			println(err)
-			panic(any(err))
+			Rt_r.Status = 204
+			Rt_r.Msg = "[]json E!"
+			goto Mreturn
+		}
+		for _, value := range json_lr {
+			Handle.AnalysisMap(&Device_r, ProductType_r, value, "")
 		}
-		// 类型转换
-		f := s.(func(b []byte) []byte)(message)
-
-		// 开始处理
-		println(f)
-		a := string(f[0])
-		println("首字符:", a)
-		if a != "{" {
-			//结构体
-			var json_r map[string]interface{}
-			err = json.Unmarshal(f, &json_r)
-			if err != nil {
-				Rt_r.Status = 203
-				goto Mreturn
-			}
-
-			//Handle.AnalysisMap(Device_r, ProductType_r, json_r, "")
-
-		} else {
-			//列表
-			var json_lr []map[string]interface{}
-			err = json.Unmarshal(f, &json_lr)
-			if err != nil {
-				Rt_r.Status = 203
-				goto Mreturn
-			}
-			//for _, value := range json_lr {
-			//	//Handle.AnalysisMap(Device_r, ProductType_r, value, "")
-			//}
 
+		// 合并json
+		Device_r.Read_Tidy() // 提前最新的
+		if len(Device_r.T_data) > 5 {
+			json.Unmarshal([]byte(Device_r.T_data), &json_lr[len(json_lr)-1])
 		}
+		Device_r.T_dataJson = json_lr[len(json_lr)-1]
+		Device_r.UpdateTime.NowDbTime()
+		Device_r.Update("T_data", "UpdateTime")
+	}
 
-		// 返回
-	Mreturn:
-		data, _ := json.Marshal(Rt_r)
-		fmt.Println(string(data))
+	// 返回
+Mreturn:
+	data, _ := json.Marshal(Rt_r)
+	fmt.Println(string(data))
 
-		// 查找库导出信息
-		s, err = p.Lookup("R_reply")
-		if err != nil {
-			println(err)
-			panic(any(err))
-		}
-		// 类型转换
-		f = s.(func(b []byte) []byte)(data)
+	// 查找库导出信息
+	s, err = p.Lookup("R")
+	if err != nil {
+		logs.Println("", err)
+		panic(any(err))
+	}
+	// 转换
+	t, b := s.(func(t string, b string) (string, []byte))(topicName, string(data))
 
+	// 订阅号 与 内容 必须有数据
+	if len(t) > 0 && len(b) > 0 {
 		// 返回数据
-		Mqtt_publish(topicName+"_reply", f)
+		Mqtt_publish(t, b)
 	}
 
 }
 
 // 发送数据
 func Mqtt_publish(topic string, b []byte) {
-
+	lib.TopicMap[topic] = true
 	// Publish a message.
 	err := cli.Publish(&client.PublishOptions{
 		QoS:       mqtt.QoS0,
@@ -370,7 +407,7 @@ func Mqtt_publish(topic string, b []byte) {
 		Message:   b,
 	})
 
-	logs.PrintlnMqtt("-> " + topic + "_reply " + string(b))
+	logs.PrintlnMqtt("-> " + topic + ":" + string(b))
 	if err != nil {
 		logs.PrintlnError("MqttServer", "发送消息失败 [Mqtt_publish]", "-> "+topic+" "+string(b))
 	}

+ 30 - 0
Nats/NatsServer/Device.go

@@ -50,4 +50,34 @@ func NatsServer_Device() {
 		_ = lib.Nats.Publish(m.Reply, b)
 	})
 
+	// 请求-响应
+	_, _ = lib.Nats.Subscribe("/Device/Device/Data", func(m *nats.Msg) {
+		logs.Println("Nats /Device/Device/Data: %s\n", string(m.Data))
+
+		var DeviceData_Form Device.DeviceData_Form
+		err := msgpack.Unmarshal(m.Data, &DeviceData_Form)
+		if err != nil {
+			logs.PrintlnError("Nats:", err)
+			b, _ := msgpack.Marshal(&lib.JSONR{Code: lib.Error, Msg: "解析错误!"})
+			_ = lib.Nats.Publish(m.Reply, b)
+			return
+		}
+		if len(DeviceData_Form.T_sn) < 1 {
+			logs.PrintlnError("Nats:", err)
+			b, _ := msgpack.Marshal(&lib.JSONR{Code: lib.Error, Msg: "解析错误!"})
+			_ = lib.Nats.Publish(m.Reply, b)
+			return
+		}
+
+		if len(DeviceData_Form.T_jointTab) < 1 {
+			logs.PrintlnError("Nats:", err)
+			b, _ := msgpack.Marshal(&lib.JSONR{Code: lib.Error, Msg: "解析错误!"})
+			_ = lib.Nats.Publish(m.Reply, b)
+			return
+		}
+
+		JSONR_r := Device.Data_List(DeviceData_Form.T_sn+"_"+DeviceData_Form.T_jointTab, DeviceData_Form.T_jsonFind, DeviceData_Form.T_jsonSort, DeviceData_Form.PageIndex, DeviceData_Form.PageSize)
+		b, _ := msgpack.Marshal(&lib.JSONR{Code: lib.Success, Msg: "ok!", Data: JSONR_r})
+		_ = lib.Nats.Publish(m.Reply, b)
+	})
 }

+ 2 - 44
Nats/NatsServer/Product.go

@@ -85,50 +85,8 @@ func NatsServer_Product() {
 	})
 
 	// 产品协议 - 列表
-	_, _ = lib.Nats.Subscribe("/Product/ProductType/List", func(m *nats.Msg) {
-		logs.Println("Nats /Product/ProductType/List: %s\n", string(m.Data))
-
-		var ProductProt Product.ProductProt
-		err := msgpack.Unmarshal(m.Data, &ProductProt)
-		if err != nil {
-			logs.PrintlnError("Nats:", err)
-			b, _ := msgpack.Marshal(&lib.JSONR{Code: lib.Error, Msg: "解析错误!"})
-			_ = lib.Nats.Publish(m.Reply, b)
-			return
-		}
-
-		ProductProt_list := ProductProt.Lists_All()
-
-		b, _ := msgpack.Marshal(&lib.JSONR{Code: lib.Success, Msg: "ok!", Data: ProductProt_list})
-		_ = lib.Nats.Publish(m.Reply, b)
-	})
-
-	//  产品协议 - 获取
-	_, _ = lib.Nats.Subscribe("/Product/ProductProt/Get", func(m *nats.Msg) {
-		logs.Println("Nats /Product/ProductProt/Get: %s\n", string(m.Data))
-
-		var ProductProt Product.ProductProt
-		err := msgpack.Unmarshal(m.Data, &ProductProt)
-		if err != nil {
-			logs.PrintlnError("Nats:", err)
-			b, _ := msgpack.Marshal(&lib.JSONR{Code: lib.Error, Msg: "解析错误!"})
-			_ = lib.Nats.Publish(m.Reply, b)
-			return
-		}
-
-		if !ProductProt.Read() {
-			b, _ := msgpack.Marshal(&lib.JSONR{Code: lib.Error, Msg: "ID E!"})
-			_ = lib.Nats.Publish(m.Reply, b)
-			return
-		}
-
-		b, _ := msgpack.Marshal(&lib.JSONR{Code: lib.Success, Msg: "ok!", Data: ProductProt})
-		_ = lib.Nats.Publish(m.Reply, b)
-	})
-
-	// 产品协议 - 列表
-	_, _ = lib.Nats.Subscribe("/Product/ProductType/List", func(m *nats.Msg) {
-		logs.Println("Nats /Product/ProductType/List: %s\n", string(m.Data))
+	_, _ = lib.Nats.Subscribe("/Product/ProductProt/List", func(m *nats.Msg) {
+		logs.Println("Nats /Product/ProductProt/List: %s\n", string(m.Data))
 
 		var ProductProt Product.ProductProt
 		err := msgpack.Unmarshal(m.Data, &ProductProt)

+ 3 - 3
RunCode/config/docker_config.json

@@ -5,9 +5,9 @@
     "go": {
       "ext": "go",
       "filename": "main.go",
-      "image": "yunlot-golang:v1.1",
-      "cmd": "go run main.go",
-      "build": "go build -buildmode=plugin -o so/{name}.so main.go"
+      "image": "yunlot-golang:v1.5",
+      "cmd": "/usr/local/go/bin/./go run main.go",
+      "build": "/usr/local/go/bin/./go build -buildmode=plugin -o so/{name}.so main.go"
     }
   }
 }

+ 2 - 3
RunCode/service/docker.go

@@ -12,7 +12,6 @@ import (
 	"os/exec"
 	"regexp"
 	"strings"
-	"syscall"
 	"time"
 )
 
@@ -134,7 +133,7 @@ func (dr dockerRunner) Exec(ctx context2.Context, runnerName string, code string
 	log.Println("tmp file path: " + tmpFile.Name())
 	defer func() {
 		//println("删除:", tmpFile.Name())
-		_ = syscall.Unlink(tmpFile.Name())
+		//_ = syscall.Unlink(tmpFile.Name())
 	}()
 	cmdStr := strings.Clone(dr.DockerBase)
 	cmdStr = strings.Replace(cmdStr, "{tmp_file}", tmpFile.Name(), 1)
@@ -204,7 +203,7 @@ func (dr dockerRunner) Build(ctx context2.Context, namerand int64, runnerName st
 	log.Println("tmp file path: " + tmpFile.Name())
 	defer func() {
 		//println("删除:", tmpFile.Name())
-		_ = syscall.Unlink(tmpFile.Name())
+		//_ = syscall.Unlink(tmpFile.Name())
 	}()
 	cmdStr := strings.Clone(dr.DockerBase)
 	cmdStr = strings.Replace(cmdStr, "{tmp_file}", tmpFile.Name(), 1)

+ 34 - 0
RunCode/打包镜像.MD

@@ -0,0 +1,34 @@
+
+
+docker pull centos8
+docker run -t -i centos:8 /bin/bash
+
+    cd /etc/yum.repos.d/
+    sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
+    sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
+    yum makecache
+    yum update -y
+    yum install -y wget
+    yum -y install gcc  
+    yum -y install gcc-c++ 
+    wget https://dl.google.com/go/go1.19.1.linux-amd64.tar.gz
+    tar -C /usr/local -xzf go1.19.1.linux-amd64.tar.gz
+    // echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.bashrc
+    vim /etc/profile
+
+        #go语言安装主根目录
+        export GOROOT=/usr/local/go #替换你的目录
+        #GOPATH 是自己的go项目路径,自定义设置
+        export GOPATH=/Users/ding/go_workspace #替换你的目录
+        #GOBIN 当我们使用go install命令编译后并且安装的二进制程序目录
+        export GOBIN=$GOPATH/bin
+        # 启用 Go Modules 功能
+        export GO111MODULE=on
+        # 配置 GOPROXY 环境变量
+        export GOPROXY=https://goproxy.cn,direct
+        export PATH=$PATH:$GOROOT/bin:$GOBIN
+
+    source /etc/profile
+
+docker commit 3674ff56646a yunlot-golang:v1.x
+

+ 3 - 3
conf/app.conf

@@ -19,9 +19,9 @@ MysqlServer_MaxIdleConnections = 10
 MysqlServer_MaxOpenConnections = 200
 
 # Mongodb
-Mongodb_Url = "mongodb://172.17.0.3:27017"
-Mongodb_DB = "admin"
-Mongodb_Username = "yunlot"
+Mongodb_Url = "mongodb://127.0.0.1:27017"
+Mongodb_DB = "yunlot"
+Mongodb_Username = "yunlot8"
 Mongodb_Password = "yunlot123"
 
 

+ 24 - 0
controllers/Device.go

@@ -119,3 +119,27 @@ func (c *DeviceController) Get() {
 	c.ServeJSON()
 	return
 }
+
+func (c *DeviceController) DataList() {
+
+	DeviceData_Form := Device.DeviceData_Form{}
+	c.ParseForm(&DeviceData_Form)
+
+	if len(DeviceData_Form.T_sn) < 1 {
+		c.Data["json"] = lib.JSONR{Code: lib.Error, Msg: "T_sn !"}
+		c.ServeJSON()
+		return
+	}
+
+	if len(DeviceData_Form.T_jointTab) < 1 {
+		c.Data["json"] = lib.JSONR{Code: lib.Error, Msg: "T_jointTab !"}
+		c.ServeJSON()
+		return
+	}
+
+	JSONR_r := Device.Data_List(DeviceData_Form.T_sn+"_"+DeviceData_Form.T_jointTab, DeviceData_Form.T_jsonFind, DeviceData_Form.T_jsonSort, DeviceData_Form.PageIndex, DeviceData_Form.PageSize)
+
+	c.Data["json"] = JSONR_r
+	c.ServeJSON()
+	return
+}

+ 0 - 68
controllers/ProductTab.go

@@ -1,68 +0,0 @@
-package controllers
-
-import (
-	"Yunlot/lib"
-	"Yunlot/models/Product"
-	beego "github.com/beego/beego/v2/server/web"
-)
-
-type ProductTabController struct {
-	beego.Controller
-}
-
-func (c *ProductTabController) List() {
-	PageIndex, _ := c.GetInt("PageIndex", 0)
-	PageSize, _ := c.GetInt("PageSize", 10)
-
-	ProductTabr := Product.ProductTab{}
-	c.ParseForm(&ProductTabr)
-
-	ProductTab_r, Total := ProductTabr.Lists(PageIndex, PageSize)
-
-	c.Data["json"] = lib.JSONR{Code: lib.Success, Msg: "ok!", Data: lib.C_Page(ProductTab_r, PageIndex, PageSize, Total)}
-	c.ServeJSON()
-	return
-}
-
-func (c *ProductTabController) Add() {
-	ProductTab_r := Product.ProductTab{}
-	c.ParseForm(&ProductTab_r)
-	ProductTab_r.Id = 0
-	ProductTab_r.Add()
-
-	c.Data["json"] = lib.JSONR{Code: lib.Success, Msg: "ok!", Data: ProductTab_r}
-	c.ServeJSON()
-	return
-}
-
-func (c *ProductTabController) Update() {
-	ProductTabr := Product.ProductTab{}
-	c.ParseForm(&ProductTabr)
-
-	if !ProductTabr.Update("T_name", "T_tab", "T_type", "T_attr", "T_text") {
-		c.Data["json"] = lib.JSONR{Code: lib.Error, Msg: "E!"}
-		c.ServeJSON()
-		return
-	}
-
-	c.Data["json"] = lib.JSONR{Code: lib.Success, Msg: "ok!"}
-	c.ServeJSON()
-	return
-}
-
-func (c *ProductTabController) Delete() {
-	ProductTabr := Product.ProductTab{}
-	c.ParseForm(&ProductTabr)
-
-	if !ProductTabr.Delete() {
-		c.Data["json"] = lib.JSONR{Code: lib.Error, Msg: "E!"}
-		c.ServeJSON()
-		return
-	}
-
-	c.Data["json"] = lib.JSONR{Code: lib.Success, Msg: "ok!"}
-	c.ServeJSON()
-	return
-}
-
-

+ 1 - 1
controllers/ProductType.go

@@ -57,7 +57,7 @@ func (c *ProductTypeController) Update() {
 	ProductTyper := Product.ProductType{}
 	c.ParseForm(&ProductTyper)
 
-	if !ProductTyper.Update("T_name", "T_img", "T_prot") {
+	if !ProductTyper.Update("T_name", "T_img", "T_prot", "T_TabData") {
 		c.Data["json"] = lib.JSONR{Code: lib.Error, Msg: "E!"}
 		c.ServeJSON()
 		return

+ 10 - 12
lib/lib.go

@@ -12,6 +12,7 @@ import (
 	"golang.org/x/text/transform"
 	"io/ioutil"
 	"math/rand"
+	"plugin"
 	"runtime"
 	"strconv"
 	"strings"
@@ -19,14 +20,13 @@ import (
 	"unicode/utf8"
 )
 
-type Cl_ struct {
-	Uuid_list map[string]string // 泛型
-}
-
 var Nats *nats.Conn
+var TopicMap map[string]bool
+var PluginMap map[string]*plugin.Plugin
 
 func init() {
-
+	TopicMap = make(map[string]bool)
+	PluginMap = make(map[string]*plugin.Plugin)
 }
 
 const Success = 200
@@ -407,7 +407,8 @@ func GetRandstring(length int, char string, rand_x int64) string {
 	rchar := charArr[:length]
 	return strings.Join(rchar, "")
 }
-//Sha256加密
+
+// Sha256加密
 func Sha256(src string) string {
 	m := sha256.New()
 	m.Write([]byte(src))
@@ -415,7 +416,7 @@ func Sha256(src string) string {
 	return res
 }
 
-//判断时间是当年的第几周
+// 判断时间是当年的第几周
 func WeekByDate() string {
 	t := time.Now()
 	yearDay := t.YearDay()
@@ -429,12 +430,9 @@ func WeekByDate() string {
 	}
 	var week int
 	if yearDay <= firstWeekDays {
-		week =  1
+		week = 1
 	} else {
 		week = (yearDay-firstWeekDays)/7 + 2
 	}
-	return fmt.Sprintf("%d%02d", t.Year(), week)   // 202253
+	return fmt.Sprintf("%d%02d", t.Year(), week) // 202253
 }
-
-
-

+ 5 - 6
logs/LogPrintln.go

@@ -69,17 +69,16 @@ func PrintlnError(format string, v ...interface{}) {
 }
 
 func PrintlnMqtt(str string) {
-	if Test {
-		fmt.Println(str)
-	}
+	fmt.Println(str)
+
 	logxMqtt.Info(str)
 
 }
 
 func PrintlnData(str string) {
-	if Test {
-		fmt.Println(str)
-	}
+
+	fmt.Println(str)
+
 	logxData.Info(str)
 }
 

+ 4 - 3
models/Account/User.go

@@ -3,6 +3,7 @@ package Account
 import (
 	"Yunlot/conf"
 	"Yunlot/logs"
+	"Yunlot/models"
 	"encoding/json"
 	"fmt"
 	"github.com/astaxie/beego/cache"
@@ -18,9 +19,9 @@ type User struct {
 	T_pass string `orm:"size(256);null"` // 密码
 	T_hash string `orm:"size(256);null"` // hash
 
-	T_State    int       `orm:"size(200);1"`                                           //  1 正常   2 删除\禁用
-	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 第一次保存时才设置时间
+	T_State    int         `orm:"size(200);1"`                                           //  1 正常   2 删除\禁用
+	CreateTime models.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now 每次 model 保存时都会对时间自动更新
+	UpdateTime models.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now_add 第一次保存时才设置时间
 }
 type VCode struct {
 	T_Code string

+ 49 - 11
models/Device/Device.go

@@ -4,6 +4,8 @@ import (
 	"Yunlot/conf"
 	"Yunlot/lib"
 	"Yunlot/logs"
+	"Yunlot/models"
+	"Yunlot/models/Product"
 	"encoding/json"
 	"fmt"
 	"github.com/astaxie/beego/cache"
@@ -16,14 +18,17 @@ import (
 
 // 设备
 type Device struct {
-	T_sn        string `orm:"size(256);pk" json:"T_sn" form:"T_sn"`                     // Sn
-	T_password  string `orm:"size(256);" json:"T_password" form:"T_password"`           // 密码
-	T_online    int    `orm:"size(1);index;default(0)" json:"T_online" form:"T_online"` // 在线状态  0 离线  1 在线   3 无效
-	T_ProductID string `orm:"size(8);index" json:"T_ProductID" form:"T_ProductID"`      // 产品类型
-
-	T_state    int       `orm:"size(2);default(0);index" json:"T_state" form:"T_state"` // 0 未激活   1 正常  2 禁用\删除
-	CreateTime time.Time `orm:"column(create_time);type(timestamp);auto_now_add"`
-	UpdateTime time.Time `orm:"column(update_time);type(timestamp);auto_now"`
+	T_sn          string                 `orm:"size(256);pk" json:"T_sn" form:"T_sn"`                     // Sn
+	T_password    string                 `orm:"size(256);" json:"T_password" form:"T_password"`           // 密码
+	T_online      int                    `orm:"size(1);index;default(0)" json:"T_online" form:"T_online"` // 在线状态  0 离线  1 在线   3 无效
+	T_ProductID   string                 `orm:"size(8);index" json:"T_ProductID" form:"T_ProductID"`      // 产品类型
+	T_ProductJson Product.ProductType    `orm:"-" json:"T_ProductJson"`                                   // 产品类型 json
+	T_data        string                 `orm:"column(t_data);type(text);default('')" json:"T_data" `     // 设备数据
+	T_dataJson    map[string]interface{} `orm:"-" json:"T_dataJson"`                                      // 设备数据
+
+	T_state    int         `orm:"size(2);default(0);index" json:"T_state" form:"T_state"` // 0 未激活   1 正常  2 禁用\删除
+	CreateTime models.Time `orm:"column(create_time);type(timestamp);auto_now_add"`
+	UpdateTime models.Time `orm:"column(update_time);type(timestamp);auto_now"`
 }
 
 func (t *Device) TableName() string {
@@ -48,6 +53,17 @@ func init() {
 
 // ---------------- Redis -------------------
 func (t *Device) redis_Set() (err error) {
+
+	if len(t.T_data) > 5 {
+		var T_datajson map[string]interface{}
+		json.Unmarshal([]byte(t.T_data), &T_datajson)
+		t.T_dataJson = T_datajson
+	}
+	if len(t.T_ProductID) > 0 {
+		t.T_ProductJson.T_ProductID = t.T_ProductID
+		t.T_ProductJson.Read()
+	}
+
 	//json序列化
 	str, err := json.Marshal(t)
 	if err != nil {
@@ -88,7 +104,6 @@ func (t *Device) redis_DelK() (err error) {
 // 获取
 func (t *Device) Read() (is bool) {
 	o := orm.NewOrm()
-
 	err := o.Read(t) // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
 	if err != nil {
 		return false
@@ -161,6 +176,9 @@ func (t *Device) Add() (is bool) {
 
 // 修改
 func (t *Device) Update(cols ...string) bool {
+	data, _ := json.Marshal(t.T_dataJson)
+	t.T_data = string(data)
+
 	o := orm.NewOrm()
 	if num, err := o.Update(t, cols...); err == nil {
 		logs.Println("Number of records updated in database:", num)
@@ -206,7 +224,17 @@ func (t *Device) Lists(PageIndex int, PageSize int) (r []Device, Total int64) {
 	// 执行
 	qs.Limit(PageSize, offset).SetCond((*orm2.Condition)(cond)).All(&r)
 	Total, _ = qs.SetCond((*orm2.Condition)(cond)).Count()
-
+	for i, _ := range r {
+		if len(r[i].T_ProductID) > 0 {
+			r[i].T_ProductJson.T_ProductID = r[i].T_ProductID
+			r[i].T_ProductJson.Read()
+		}
+		if len(t.T_data) > 5 {
+			var T_datajson map[string]interface{}
+			json.Unmarshal([]byte(t.T_data), &T_datajson)
+			t.T_dataJson = T_datajson
+		}
+	}
 	return r, Total
 }
 
@@ -226,6 +254,16 @@ func (t *Device) Lists_All() (r []Device) {
 
 	// 执行
 	qs.SetCond((*orm2.Condition)(cond)).All(&r)
-
+	for i, _ := range r {
+		if len(r[i].T_ProductID) > 0 {
+			r[i].T_ProductJson.T_ProductID = r[i].T_ProductID
+			r[i].T_ProductJson.Read()
+		}
+		if len(t.T_data) > 5 {
+			var T_datajson map[string]interface{}
+			json.Unmarshal([]byte(t.T_data), &T_datajson)
+			t.T_dataJson = T_datajson
+		}
+	}
 	return r
 }

+ 138 - 46
models/Device/DeviceData.go

@@ -2,7 +2,9 @@ package Device
 
 import (
 	"Yunlot/conf"
+	"Yunlot/lib"
 	"Yunlot/logs"
+	"Yunlot/models"
 	"context"
 	"encoding/json"
 	"fmt"
@@ -12,68 +14,60 @@ import (
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/mongo"
 	"go.mongodb.org/mongo-driver/mongo/options"
-	"log"
 	"strconv"
 	"time"
 )
 
 // 模板
-type DeviceData_R1 struct {
-	T_tab      string    `orm:"size(256);index" json:"T_Rtab"`                         //转发 TAB 标识 拼接:AAAA.BBBB.   对象后面加点
-	T_type     int       `orm:"size(200);null"`                                        // 数据类型  (1,'bool'),(2,'u8'),(3,'u16'),(4,'float'),(5,'str'),(6,'object'),(7,'u8'[模式图片]);
-	T_value    string    `orm:"type(text);size(200);null"`                             // 值
-	T_time     time.Time `orm:"type(timestamp);null;"`                                 // 采集时间
-	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
-}
-
-// 模板
 type DeviceData_R struct {
-	T_tab      string    `orm:"size(256);index" json:"T_Rtab"`                         //转发 TAB 标识 拼接:AAAA.BBBB.   对象后面加点
-	T_type     int       `orm:"size(200);default(4)"`                                  // 数据类型  (1,'bool'),(2,'int'),(3,'float'),(4,'str'),(5,'time'),(7,'u8'[模式图片]);
-	T_bool     bool      `orm:"type(text);size(200);"`                                 // 值
-	T_int      int       `orm:"type(text);size(200);null"`                             // 值
-	T_float    float64   `orm:"type(text);size(200);null"`                             // 值
-	T_time     time.Time `orm:"type(timestamp);null;"`                                 // 采集时间
-	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
+	T_tab      string      `orm:"size(256);index" json:"T_Rtab"`                         //转发 TAB 标识 拼接:AAAA.BBBB.   对象后面加点
+	T_type     int         `orm:"size(200);default(4)"`                                  // 数据类型  (1,'bool'),(2,'int'),(3,'float'),(4,'str'),(5,'time'),(7,'u8'[模式图片]);
+	T_bool     bool        `orm:"type(text);size(200);"`                                 // 值
+	T_int      int         `orm:"type(text);size(200);null"`                             // 值
+	T_float    float64     `orm:"type(text);size(200);null"`                             // 值
+	T_time     models.Time `orm:"type(timestamp);null;"`                                 // 采集时间
+	CreateTime models.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
 }
 
-type DeviceData_old struct {
-	T_t    float32
-	T_rh   float32
-	T_site string
-	T_sp   int
+// 表单
+type DeviceData_Form struct {
+	T_sn       string `json:"T_sn" form:"T_sn"`             // Sn
+	T_jointTab string `json:"T_jointTab" form:"T_jointTab"` // 标签路径
+	T_jsonFind string `json:"T_jsonFind" form:"T_jsonFind"` // 条件
+	T_jsonSort string `json:"T_jsonSort" form:"T_jsonSort"` // 排序
+	PageIndex  int    `json:"PageIndex" form:"PageIndex"`   // 当前页码
+	PageSize   int    `json:"PageSize" form:"PageSize"`     // 每页文档数量
 }
 
 var redis_DeviceData cache.Cache
+var Mongodb_client *mongo.Client
+var Mongodb_DB *mongo.Database
 
 func init() {
+	credential := options.Credential{
+		//AuthSource: conf.Mongodb_DB,
+		Username: conf.Mongodb_Username,
+		Password: conf.Mongodb_Password,
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	var err error
+	Mongodb_client, err = mongo.Connect(ctx, options.Client().ApplyURI(conf.Mongodb_Url).SetAuth(credential).SetMaxPoolSize(200))
+	if err != nil {
+		logs.PrintlnError("Mongodb 连接错误!", err)
+		panic(any(err))
+	}
+	Mongodb_DB = Mongodb_client.Database(conf.Mongodb_DB)
 
 	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
 		"redis_DeviceData", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
 	logs.Println(config)
-	var err error
+
 	redis_DeviceData, err = cache.NewCache("redis", config)
 	if err != nil || redis_DeviceData == nil {
 		errMsg := "failed to init redis"
 		logs.Println(errMsg, err)
 	}
-}
-func Connect() (*mongo.Database, error) {
-
-	credential := options.Credential{
-		AuthSource: conf.Mongodb_DB,
-		Username:   conf.Mongodb_Username,
-		Password:   conf.Mongodb_Password,
-	}
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	defer cancel()
-	client, err := mongo.Connect(ctx, options.Client().ApplyURI(conf.Mongodb_Url).SetAuth(credential).SetMaxPoolSize(10))
-	if err != nil {
-		log.Print(err)
-	}
-
-	return client.Database(conf.Mongodb_DB), err
 
 }
 
@@ -88,7 +82,7 @@ func RedisDeviceData_Set(T_sn string, T_id int, r DeviceData_R) (err error) {
 		json.Unmarshal(v.([]byte), &t)
 		// 防止时间溢出
 		if time.Now().Unix() <= r.T_time.Unix() {
-			r.T_time = time.Now()
+			r.T_time.NowDbTime()
 		}
 		// 提前最新数据
 		if t.T_time.Unix() > r.T_time.Unix() {
@@ -121,17 +115,115 @@ func RedisDeviceData_Get(key string) (r DeviceData_R, is bool) {
 
 // ----------------
 func Data_Add(JointTab string, bson_r *bson.M) {
-	// 连接到MongoDB
-	DB, err := Connect()
+
+	logs.Println("JointTab:", JointTab, *bson_r)
+	collection := Mongodb_DB.Collection(JointTab)
+
+	_, err := collection.InsertOne(context.TODO(), bson_r)
 	if err != nil {
 		panic(any(err))
 	}
-	//fmt.Println("JointTab:", JointTab)
-	collection := DB.Collection(JointTab)
 
-	_, err = collection.InsertOne(context.TODO(), bson_r)
+}
+
+// db.getCollection("2023445039284316_params_varData").find({ $and : [{"name" : "TempSet"}, {"value" : "26"}] }).limit(1000).skip(0)
+// ----------------
+func Data_Read(JointTab string, bson_r *bson.M) {
+
+	logs.Println("JointTab:", JointTab, *bson_r)
+	collection := Mongodb_DB.Collection(JointTab)
+
+	_, err := collection.InsertOne(context.TODO(), bson_r)
 	if err != nil {
 		panic(any(err))
 	}
 
 }
+
+/*
+----------------
+// 数据列表
+JointTab:2023445039284316_params_varData
+// 条件 jsonFind := `{"$or":[{"name":"TempSet"},{"value":"26"}]}`
+// 排序 jsonSort := `{"value": 1}`
+// 当前页码 page := 2
+// 每页文档数量 pageSize := 2
+*/
+func Data_List(JointTab, jsonFind, jsonSort string, page, pageSize int) (JSONr lib.JSONR) {
+	var err error
+	// 初始化 Mongodb_DB
+	collection := Mongodb_DB.Collection(JointTab)
+	if page < 1 {
+		page = 1
+	}
+	// 限制 过小、过大
+	if pageSize < 1 || pageSize > 9999 {
+		page = 10
+	}
+	// 分页
+	options := options.Find().SetSkip(int64((page - 1) * pageSize)).SetLimit(int64(pageSize))
+	// 排序
+	if len(jsonSort) != 0 {
+		// 解码JSON
+		var jsonSortMap map[string]interface{}
+		err = json.Unmarshal([]byte(jsonSort), &jsonSortMap)
+		if err != nil {
+			logs.PrintlnError("解码JSON 错误", err)
+			JSONr.Code = lib.Error
+			JSONr.Msg = "排序 解码JSON 错误!"
+			return
+		}
+
+		options = options.SetSort(bson.M(jsonSortMap))
+	}
+	// 条件
+	jsonFind_M := bson.M{}
+	if len(jsonFind) != 0 {
+		// 解码JSON
+		var jsonFindMap map[string]interface{}
+		err = json.Unmarshal([]byte(jsonFind), &jsonFindMap)
+		if err != nil {
+			logs.PrintlnError("解码JSON 错误", err)
+			JSONr.Code = lib.Error
+			JSONr.Msg = "条件 解码JSON 错误!"
+			return
+		}
+		jsonFind_M = jsonFindMap
+	}
+
+	cursor, err := collection.Find(context.Background(), jsonFind_M, options)
+	if err != nil {
+		logs.PrintlnError("Find 错误", err)
+		JSONr.Code = lib.Error
+		JSONr.Msg = "Find 错误!"
+		return
+	}
+	defer cursor.Close(context.Background())
+
+	var results []bson.M
+	if err = cursor.All(context.Background(), &results); err != nil {
+		logs.PrintlnError("cursor.All 错误", err)
+		JSONr.Code = lib.Error
+		JSONr.Msg = "cursor.All 错误!"
+		return
+	}
+
+	// 执行计数操作
+	count, err := collection.CountDocuments(context.Background(), jsonFind_M)
+	if err != nil {
+		logs.PrintlnError("Count 错误", err)
+		JSONr.Code = lib.Error
+		JSONr.Msg = "Count 错误!"
+		return
+	}
+
+	JSONr.Data = lib.JSONS{
+		List:      results,
+		Total:     int16(count),
+		PageIndex: page,
+		PageSize:  pageSize,
+	}
+	JSONr.Code = lib.Success
+	JSONr.Msg = "ok!"
+	return
+}

+ 52 - 15
models/GTime.go

@@ -1,33 +1,70 @@
 package models
 
 import (
-	"database/sql/driver"
+	"encoding/json"
 	"fmt"
+	orm2 "github.com/beego/beego/v2/client/orm"
 	"time"
 )
 
-type JsonTime struct {
+type Time 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
+// MarshalJSON 序列化为JSON
+func (t Time) MarshalJSON() ([]byte, error) {
+	if t.IsZero() {
+		return []byte("\"\""), nil
+	}
+	stamp := fmt.Sprintf("\"%s\"", t.Format("2006-01-02 15:04:05"))
+	return []byte(stamp), nil
+}
+
+// UnmarshalJSON 反序列化为JSON
+func (t *Time) UnmarshalJSON(data []byte) error {
+	var err error
+	t.Time, err = time.Parse("2006-01-02 15:04:05", string(data)[1:20])
+	return err
 }
 
-func (t JsonTime) Value() (driver.Value, error) {
-	var zeroTime time.Time
-	if t.Time.UnixNano() == zeroTime.UnixNano() {
-		return nil, nil
+func (t *Time) String() string {
+	data, _ := json.Marshal(t)
+	return string(data)
+}
+
+func (t *Time) FieldType() int {
+	return orm2.TypeDateTimeField
+}
+
+func (t *Time) SetRaw(value interface{}) error {
+	switch value.(type) {
+	case time.Time:
+		t.Time = value.(time.Time)
 	}
-	return t.Time, nil
+	return nil
 }
 
-func (t *JsonTime) Scan(v interface{}) error {
-	value, ok := v.(time.Time)
-	if ok {
-		*t = JsonTime{Time: value}
+func (t *Time) RawValue() interface{} {
+	str := t.Format("2006-01-02 15:04:05")
+	if str == "0001-01-01 00:00:00" {
 		return nil
 	}
-	return fmt.Errorf("error %v", v)
+	return str
+}
+
+func (t *Time) NowDbTime() Time {
+	dbTime := Time{}
+	dbTime.Time = time.Now()
+	return dbTime
+}
+func (t *Time) AddDates(years int, months int, days int) Time {
+	dbTime := Time{}
+	dbTime.Time = t.Time.AddDate(years, months, days)
+	return dbTime
+}
+func TimeParse(value string) (Time, error) {
+	dbTime := Time{}
+	times, err := time.Parse("2006-01-02 15:04:05", value)
+	dbTime.Time = times
+	return dbTime, err
 }

+ 6 - 1
models/Product/ProductProt.go

@@ -101,8 +101,13 @@ func (t *ProductProt) Read() (bool bool) {
 	if t.redis_Get(fmt.Sprintf("%d", t.Id)) {
 		return true
 	}
+
+	if !(t.Id > 0) {
+		logs.Println("ProductProt.Id:", t.Id)
+		return false
+	}
 	o := orm.NewOrm()
-	err := o.Read(&t) // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
+	err := o.Read(t) // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
 	if err != nil {
 		return false
 	}

+ 0 - 185
models/Product/ProductTab.go

@@ -1,185 +0,0 @@
-package Product
-
-import (
-	"Yunlot/conf"
-	"Yunlot/logs"
-	"encoding/json"
-	"fmt"
-	"github.com/astaxie/beego/cache"
-	_ "github.com/astaxie/beego/cache/redis"
-	"github.com/beego/beego/v2/adapter/orm"
-	orm2 "github.com/beego/beego/v2/client/orm"
-	_ "github.com/go-sql-driver/mysql"
-	"time"
-)
-
-// 模板
-type ProductTab struct {
-	Id          int    `orm:"column(ID);size(11);auto;pk" json:"Id" form:"Id"`
-	T_ProductID string `orm:"size(8);index" json:"T_ProductID" form:"T_ProductID"` // 产品型号 随机生成(8位)
-	T_fid       int    `orm:"size(11);index" json:"T_fid" form:"T_fid"`            // 父级ID,0为根
-
-	T_name string `orm:"size(256);" json:"T_name" form:"T_name"`      // 名称
-	T_tab  string `orm:"size(32);" json:"T_tab" form:"T_tab"`         // 标签
-	T_type int    `orm:"size(6);" json:"T_type" form:"T_type"`        // 数据类型  1 数值  2 文本  3 枚举
-	T_attr string `orm:"size(200);" json:"T_attr" form:"T_attr"`      // 属性
-	T_text string `orm:"size(200);" json:"T_text" form:"T_text"`      // 说明
-	T_read bool   `orm:"default(false);" json:"T_read" form:"T_read"` // 只读
-
-	// T_attr属性  定义
-	/*
-		1 数值
-			unit 单位
-			dvalue 默认值
-			accuracy 精度
-			min 最小值
-			max 最大值
-
-		2 文本
-			dvalue 默认值
-
-		3 枚举
-			map [] 枚举
-				value 值
-				text 描述
-
-	*/
-}
-
-func (t *ProductTab) TableName() string {
-	return "ProductTab" // 数据库名称   // ************** 替换 FormulaList **************
-}
-
-var redis_ProductTab cache.Cache
-
-func init() {
-
-	//注册模型
-	orm.RegisterModel(new(ProductTab))
-
-	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
-		"redis_ProductTab", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
-	var err error
-	redis_ProductTab, err = cache.NewCache("redis", config)
-	if err != nil || redis_ProductTab == nil {
-		logs.Println(config)
-		panic(any(err))
-	}
-}
-
-// ---------------- Redis -------------------
-func (t *ProductTab) redis_Set() (err error) {
-	//json序列化
-	str, err := json.Marshal(t)
-	if err != nil {
-		logs.PrintlnError("Redis_Set", err)
-		return
-	}
-
-	err = redis_ProductTab.Put(t.T_ProductID, str, 24*time.Hour)
-	if err != nil {
-		logs.Println("set key:", t.T_ProductID, ",value:", str, err)
-	}
-	return
-}
-func (t *ProductTab) redis_Get(key string) (is bool) {
-	if redis_ProductTab.IsExist(key) {
-		//println("找到key:",key)
-		v := redis_ProductTab.Get(key)
-		if v == nil {
-			return false
-		}
-		json.Unmarshal(v.([]byte), t)
-
-		return true
-	}
-	//println("没有 找到key:",key)
-	return false
-}
-func (t *ProductTab) redis_DelK() (err error) {
-	err = redis_ProductTab.Delete(t.T_ProductID)
-	return
-}
-
-// ---------------- 方法 -------------------
-
-// 添加
-func (t *ProductTab) Add() (is bool) {
-	o := orm.NewOrm()
-
-	id, err := o.Insert(t)
-	if err != nil {
-		return false
-	}
-	println(id)
-	t.redis_Set()
-	return true
-}
-
-// 获取
-func (t *ProductTab) Read(T_type string) (bool bool) {
-	if t.redis_Get(T_type) {
-		return true
-	}
-	o := orm.NewOrm()
-	t.T_ProductID = T_type
-	err := o.Read(&t) // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
-	if err != nil {
-		return false
-	}
-	t.redis_Set() // Redis 更新缓存
-	return true
-}
-
-// 修改
-func (t *ProductTab) Update(cols ...string) bool {
-	o := orm.NewOrm()
-	if num, err := o.Update(t, cols...); err == nil {
-		logs.Println("Number of records updated in database:", num)
-		t.redis_Set() // Redis 更新缓存
-		return true
-	}
-	return false
-}
-
-// 删除
-func (t *ProductTab) Delete() bool {
-	o := orm.NewOrm()
-	if num, err := o.Delete(t); err == nil {
-		logs.Println("Number of records deleted in database:", num)
-	} else {
-		return false
-	}
-
-	t.redis_DelK()
-	return true
-}
-
-// 获取列表
-func (t *ProductTab) Lists(PageIndex int, PageSize int) (r []ProductTab, Total int64) {
-
-	o := orm.NewOrm()
-
-	// 也可以直接使用 Model 结构体作为表名
-	qs := o.QueryTable(new(ProductTab))
-	var offset int64
-	if PageIndex <= 1 {
-		offset = 0
-	} else {
-		offset = int64((PageIndex - 1) * PageSize)
-	}
-
-	// 筛选参数
-	cond := orm.NewCondition()
-	if len(t.T_ProductID) > 0 {
-		cond = cond.And("T_ProductID", t.T_ProductID) // .AndNot("status__in", 1).Or("profile__age__gt", 2000)
-	}
-
-	cond = cond.And("T_fid", t.T_fid) // .AndNot("status__in", 1).Or("profile__age__gt", 2000)
-
-	// 执行
-	qs.Limit(PageSize, offset).SetCond((*orm2.Condition)(cond)).All(&r)
-	Total, _ = qs.SetCond((*orm2.Condition)(cond)).Count()
-
-	return r, Total
-}

+ 83 - 3
models/Product/ProductType.go

@@ -3,6 +3,7 @@ package Product
 import (
 	"Yunlot/conf"
 	"Yunlot/logs"
+	"Yunlot/models"
 	"encoding/json"
 	"fmt"
 	"github.com/astaxie/beego/cache"
@@ -15,17 +16,73 @@ import (
 
 // 产品类型
 type ProductType struct {
-	//Id      int64    `orm:"column(ID);size(11);auto;pk" `
 	T_ProductID string `orm:"size(8);pk" json:"T_ProductID" form:"T_ProductID"` // 产品型号 随机生成(8位)
 	T_name      string `orm:"size(256);" json:"T_name" form:"T_name"`           // 产品名称
 	T_img       string `orm:"size(200);" json:"T_img" form:"T_img"`             // 图片
 	T_akey      string `orm:"size(56);" json:"T_akey" `                         // 授权密钥
 	T_prot      int    `orm:"size(10);default(0)" json:"T_prot" form:"T_prot"`  //接入协议ID  0:统一协议
 
-	CreateTime time.Time `orm:"column(create_time);type(timestamp);auto_now_add"`
-	UpdateTime time.Time `orm:"column(update_time);type(timestamp);auto_now"`
+	T_TabData     string                   `orm:"type(text);default('')" json:"T_TabData" form:"T_TabData"` // 产品模型
+	T_TabDataJson []map[string]interface{} `orm:"-" json:"T_TabDataJson"`                                   // 产品模型json
+
+	CreateTime models.Time `orm:"column(create_time);type(timestamp);auto_now_add"`
+	UpdateTime models.Time `orm:"column(update_time);type(timestamp);auto_now"`
 }
 
+/*
+	T_TabData、T_TabDataJson
+
+[
+
+	{
+		"T_name": "温度",
+		"T_tab": "Tt",
+		"T_type": 1,
+		"T_attr": {
+					"unit": "C",
+					"dvalue": 0,
+					"accuracy": 1,
+					"min": 2,
+					"max": 8,
+					},
+		"T_text": "温度温度温度",
+		"T_read": true,
+		"children":[{
+			"T_name": "采样率",
+			"T_tab": "Tt_speed",
+			"T_type": 1,
+			"T_attr": {
+						"unit": "s",
+						"dvalue": 15,
+						"accuracy": 1,
+						"min": 0,
+						"max": 30,
+						},
+			"T_text": "数据采集速度",
+			"T_read": false,
+			"children":[]
+		}]
+	}
+
+]
+
+// T_attr属性  定义
+
+	1 数值
+		unit 单位
+		dvalue 默认值
+		accuracy 精度
+		min 最小值
+		max 最大值
+
+	2 文本
+		dvalue 默认值
+
+	3 枚举
+		map [] 枚举
+			value 值
+			text 描述
+*/
 func (t *ProductType) TableName() string {
 	return "ProductType" // 数据库名称   // ************** 替换 FormulaList **************
 }
@@ -48,6 +105,13 @@ func init() {
 
 // ---------------- Redis -------------------
 func (t *ProductType) redis_Set() (err error) {
+
+	if len(t.T_TabData) > 0 {
+		var T_datajson []map[string]interface{}
+		json.Unmarshal([]byte(t.T_TabData), &T_datajson)
+		t.T_TabDataJson = T_datajson
+	}
+
 	//json序列化
 	str, err := json.Marshal(t)
 	if err != nil {
@@ -161,6 +225,15 @@ func (t *ProductType) Lists(PageIndex int, PageSize int) (r []ProductType, Total
 	qs.Limit(PageSize, offset).SetCond((*orm2.Condition)(cond)).All(&r)
 	Total, _ = qs.SetCond((*orm2.Condition)(cond)).Count()
 
+	for i, _ := range r {
+		if len(r[i].T_TabData) > 0 {
+			var T_datajson []map[string]interface{}
+			json.Unmarshal([]byte(r[i].T_TabData), &T_datajson)
+			r[i].T_TabDataJson = T_datajson
+			logs.Println("T_datajson", r[i].T_TabDataJson)
+		}
+
+	}
 	return r, Total
 }
 
@@ -183,6 +256,13 @@ func (t *ProductType) Lists_All() (r []ProductType) {
 
 	// 执行
 	qs.SetCond((*orm2.Condition)(cond)).All(&r)
+	for i, _ := range r {
+		if len(r[i].T_TabData) > 0 {
+			var T_datajson []map[string]interface{}
+			json.Unmarshal([]byte(r[i].T_TabData), &T_datajson)
+			r[i].T_TabDataJson = T_datajson
+		}
 
+	}
 	return r
 }

+ 2 - 0
routers/Device.go

@@ -15,4 +15,6 @@ func init() {
 	beego.Router(prefix+"/Device/Update", &controllers.DeviceController{}, "*:Update") // 获取未读消息
 	beego.Router(prefix+"/Device/Delete", &controllers.DeviceController{}, "*:Delete") // 获取未读消息
 
+	beego.Router(prefix+"/Device/Data", &controllers.DeviceController{}, "*:DataList") // 获取未读消息
+
 }

+ 0 - 6
routers/Product.go

@@ -24,12 +24,6 @@ func init() {
 	beego.Router(prefix+"/ProductProt/Update", &controllers.ProductProtController{}, "*:Update") // 获取未读消息
 	beego.Router(prefix+"/ProductProt/Delete", &controllers.ProductProtController{}, "*:Delete") // 获取未读消息
 
-	// 产品协议 -标签
-	beego.Router(prefix+"/ProductTab/Add", &controllers.ProductTabController{}, "*:Add")       // 获取未读消息
-	beego.Router(prefix+"/ProductTab/List", &controllers.ProductTabController{}, "*:List")     // 获取未读消息
-	beego.Router(prefix+"/ProductTab/Update", &controllers.ProductTabController{}, "*:Update") // 获取未读消息
-	beego.Router(prefix+"/ProductTab/Delete", &controllers.ProductTabController{}, "*:Delete") // 获取未读消息
-
 	// 消息转发
 	beego.Router(prefix+"/ProductRelay/Add", &controllers.ProductRelayController{}, "*:Add")       // 获取未读消息
 	beego.Router(prefix+"/ProductRelay/List", &controllers.ProductRelayController{}, "*:List")     // 获取未读消息

+ 1 - 1
tests/hello/aaaa.go → tests/C/aaaa.go

@@ -1,4 +1,4 @@
-package hello
+package C
 
 /*
 // C 标志io头文件,你也可以使用里面提供的函数

+ 0 - 0
tests/hello/hello.c → tests/C/hello.c


+ 1 - 1
tests/hello/hello.go → tests/C/hello.go

@@ -1,4 +1,4 @@
-package hello
+package C
 
 /*
 #include "hello.h"

+ 0 - 0
tests/hello/hello.h → tests/C/hello.h


+ 37 - 0
tests/json_test.go

@@ -0,0 +1,37 @@
+package test
+
+import (
+	"encoding/json"
+	"fmt"
+	"testing"
+)
+
+func Test_json(t *testing.T) {
+	articleStrings := `{
+	"clientID": "869023065073597",
+	"msgID": "24152",
+	"paramsb": {
+		"typeCode": "123",
+		"typeCode2": "123"
+	},
+	"paramslist": [{
+		"typeCode": "123",
+		"typeCode2": "123"
+	}],
+	"params": [{
+		"typeCode": "123",
+		"typeCode2": "123",
+		"varData": [{
+			"name": "TempSet",
+			"value": "27"
+		}]
+	}]
+}`
+	var articleSlide map[string]interface{}
+	multiErr := json.Unmarshal([]byte(articleStrings), &articleSlide)
+	if multiErr != nil {
+		fmt.Println("转换出错:", multiErr)
+	}
+
+	println("articleSlide:", articleSlide)
+}

+ 71 - 7
tests/mongodb_test.go

@@ -2,28 +2,29 @@ package test
 
 import (
 	"context"
+	"encoding/json"
 	"fmt"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/mongo"
 	"go.mongodb.org/mongo-driver/mongo/options"
+
 	"log"
 	"testing"
 	"time"
 )
 
 var (
-	Mongodb_Url      = "mongodb://192.168.11.77:27017"
-	Mongodb_DB       = "aaa"
-	Mongodb_Username = "aaa"
-	Mongodb_Password = "aaaaaaaaa"
+	Mongodb_Url      = "mongodb://192.168.11.112:27017"
+	Mongodb_DB       = "yunlot"
+	Mongodb_Username = "yunlot8"
+	Mongodb_Password = "yunlot123"
 )
 
 func Connect() (*mongo.Database, error) {
 
 	credential := options.Credential{
-		AuthSource: Mongodb_DB,
-		Username:   Mongodb_Username,
-		Password:   Mongodb_Password,
+		Username: Mongodb_Username,
+		Password: Mongodb_Password,
 	}
 
 	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
@@ -60,6 +61,69 @@ func TestNamex(t *testing.T) {
 	fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs)
 
 }
+
+// 根据 条件、排序、分页 获取列表
+func TestMongodb_list(t *testing.T) {
+
+	// 连接到MongoDB
+	DB, err := Connect()
+	if err != nil {
+		panic(any(err))
+	}
+	collection := DB.Collection("2023445039284316_params_varData")
+
+	// 条件
+	jsonFind := `{"$or":[{"name":"TempSet"},{"value":"26"}]}`
+	// 排序
+	jsonSort := `{"value": 1}`
+	// 分页
+	page := 2     // 当前页码
+	pageSize := 2 // 每页文档数量
+
+	// 解码JSON
+	var jsonFindMap map[string]interface{}
+	err = json.Unmarshal([]byte(jsonFind), &jsonFindMap)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// 解码JSON
+	var jsonSortMap map[string]interface{}
+	err = json.Unmarshal([]byte(jsonSort), &jsonSortMap)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	options := options.Find().SetSkip(int64((page - 1) * pageSize)).SetLimit(int64(pageSize))
+
+	options = options.SetSort(bson.M(jsonSortMap))
+
+	cursor, err := collection.Find(context.Background(), bson.M(jsonFindMap), options)
+	if err != nil {
+		panic(any(err))
+	}
+	defer cursor.Close(context.Background())
+
+	var results []bson.M
+	if err = cursor.All(context.Background(), &results); err != nil {
+		panic(any(err))
+	}
+
+	jsonBytes, err := json.MarshalIndent(results, "", "  ")
+	if err != nil {
+		panic(any(err))
+	}
+
+	fmt.Println(string(jsonBytes))
+
+	// 执行计数操作
+	count, err := collection.CountDocuments(context.Background(), bson.M(jsonFindMap))
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Println("Count:", count)
+}
+
 func Data_Add(JointTab string, bson_r *bson.M) {
 	// 连接到MongoDB
 	DB, err := Connect()

+ 30 - 0
tests/plugin_test.go

@@ -0,0 +1,30 @@
+package test
+
+import (
+	"Yunlot/logs"
+	"plugin"
+	"testing"
+)
+
+func TestNameplugin(t *testing.T) {
+	// 根据库的存放路径加载库
+	p, err := plugin.Open("/var/lib/docker/volumes/yunlotso/_data/1698289330654.so")
+	if err != nil {
+		println(err)
+		logs.PrintlnError("打开 SO 失败:", err)
+	}
+
+	// 查找库导出信息
+	s, err := p.Lookup("T")
+	if err != nil {
+		println(err)
+		panic(any(err))
+	}
+	// 类型转换
+	f := s.(func(t string, b []byte) string)("aaaaaaa", []byte("1234567"))
+
+	// 开始处理
+	// 开始处理
+	logs.Println("协议后:", f)
+	logs.Println("首字符:", string("123"[0]))
+}

+ 1 - 1
tests/zhuan_test.go

@@ -36,7 +36,7 @@ func TestZHUANHUAN(t *testing.T) {
 	"EXXX": ["E1","E2","E3"]
 	
 }`
-
+	articleStrings = `{"clientID":"869023065073597","msgID":"24152","params":[{"typeCode":"123","varData":[{"name":"TempSet","value":"27"}]}]}`
 	var articleSlide map[string]interface{}
 	multiErr := json.Unmarshal([]byte(articleStrings), &articleSlide)
 	if multiErr != nil {

+ 5 - 6
说明.md

@@ -14,15 +14,14 @@ docker run -p 3306:3306 --name mysql --restart=always --privileged=true \
 -v /etc/localtime:/etc/localtime:ro \
 
 
-docker run -itd --name mongo  -p 27017:27017 mongo:4.4 --auth
-
--v /docker_volume/mongodb/data:/data/db
 
+##Mongodb
+docker run -d --restart=always -p 27017:27017 --name mongo mongo:4.4.6 --auth
+                                -v /docker_volume/mongodb/data:/data/db
 docker exec -it mongo mongo admin
-db.createUser({ user:'yunlot',pwd:'yunlot123',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},'readWriteAnyDatabase']});
-db.auth('yunlot', 'yunlot123')
-
+db.createUser({ user: "yunlot" , pwd: "yunlot123", roles: ["root"]})
 
+##yunlot
 docker run -it --name yunlot -p 6200:6202 yunlot:latest \
 --restart=always --privileged \
 -v /var/run/docker.sock:/var/run/docker.sock \