浏览代码

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	db/confrontation-training.db
develoven 1 年之前
父节点
当前提交
88b6113ae2

+ 1 - 0
.gitignore

@@ -2,3 +2,4 @@
 /.idea/workspace.xml
 /.idea/modules.xml
 /.idea/confrontation-training.iml
+/logs/

+ 5 - 5
api/chat/answer.go

@@ -2,18 +2,18 @@ package chat
 
 import (
 	errmsg "confrontation-training/err"
-	"confrontation-training/models"
+	"confrontation-training/models/chat"
 	"confrontation-training/response"
-	"confrontation-training/service"
+	serviceChat "confrontation-training/service/chat"
 	"fmt"
 	"github.com/gin-gonic/gin"
 )
 
 type AnswerService struct {
-	service.AnswerService
+	serviceChat.AnswerService
 }
 
-func GteAnswerService() *AnswerService {
+func GetAnswerService() *AnswerService {
 	return &AnswerService{}
 }
 
@@ -54,7 +54,7 @@ func (a *AnswerService) CreateAnswer(c *gin.Context) {
 // @Accept json
 // @Produce json
 // @Success 200 {string} string "ok"
-// @Router /v1/ chat/get/chat [get]
+// @Router /v1/chat/get/answer [get]
 func (a *AnswerService) GetAnswer(c *gin.Context) {
 
 	var id uint8

+ 4 - 4
api/chat/question.go

@@ -2,15 +2,15 @@ package chat
 
 import (
 	errmsg "confrontation-training/err"
-	"confrontation-training/models"
+	modelsChat "confrontation-training/models/chat"
 	"confrontation-training/response"
-	"confrontation-training/service"
+	serviceChat "confrontation-training/service/chat"
 	"fmt"
 	"github.com/gin-gonic/gin"
 )
 
 type QuestionService struct {
-	service.QuestionService
+	serviceChat.QuestionService
 }
 
 func GetQuestionService() *QuestionService {
@@ -59,7 +59,7 @@ func (q *QuestionService) GetQuestion(c *gin.Context) {
 // @Success 200 {string} string "ok"
 // @Router /v1/chat/create/chat [post]
 func (q *QuestionService) CreateQuestion(c *gin.Context) {
-	var param models.CreateQuestion
+	var param modelsChat.CreateQuestion
 	if err := c.ShouldBindJSON(&param); err != nil {
 		fmt.Printf("参数绑定异常:%s", err.Error())
 		response.Failed(errmsg.ParamInvalid, c)

+ 50 - 0
api/gateway/device.go

@@ -0,0 +1,50 @@
+package gateway
+
+import (
+	errmsg "confrontation-training/err"
+	deviceModel "confrontation-training/models/gateway"
+	"confrontation-training/response"
+	deviceService "confrontation-training/service/device"
+	"fmt"
+	"github.com/gin-gonic/gin"
+)
+
+type DeviceService struct {
+	deviceService.DeviceService
+}
+
+func GetDeviceService() *DeviceService {
+	return &DeviceService{}
+}
+
+// DeviceAdd
+// PingExample confrontation-training
+// @Summary 新增设备
+// @Schemes
+// @Description 新增设备
+// @Tags 设备管理
+// @Param device body string true "type:类型 0脑电1心电;mac:设备MAC地址"
+// @Accept json
+// @Produce json
+// @Success 200 {string} string "ok"
+// @Router /v1/device/add [post]
+func (d *DeviceService) DeviceAdd(c *gin.Context) {
+	var param deviceModel.DeviceAddParam
+	err := c.ShouldBindJSON(&param)
+	if err != nil {
+		fmt.Printf("参数格式化异常:%s", err.Error())
+		response.Failed(errmsg.ParamInvalid, c)
+		return
+	}
+	if _, count := d.FindDeviceByMac(param.Mac); count > 0 {
+		response.Failed(errmsg.DeviceAddFailed, c)
+		return
+	}
+	if result := d.CreateDevice(param); result.Error == nil {
+		response.Success(errmsg.DeviceAddSuccess, result.RowsAffected, c)
+		return
+	} else {
+		response.Failed(errmsg.UserRegisterFailed+"数据库错:"+result.Error.Error(), c)
+		return
+	}
+}

+ 18 - 2
api/gateway/gateway.go

@@ -7,6 +7,7 @@ import (
 	"confrontation-training/global"
 	"confrontation-training/http"
 	"confrontation-training/models"
+	"confrontation-training/models/gateway"
 	"confrontation-training/response"
 	"encoding/hex"
 	"encoding/json"
@@ -28,7 +29,7 @@ import (
 // @Success 200 {string} string "ok"
 // @Router /v1/device/scan [get]
 func ScanDevice(c *gin.Context) {
-	var param models.DeviceScanParam
+	var param gateway.DeviceScanParam
 	err := c.ShouldBindJSON(&param)
 	if err != nil {
 		fmt.Printf("参数格式化异常:%s", err.Error())
@@ -40,6 +41,21 @@ func ScanDevice(c *gin.Context) {
 		paramMap["chip"] = param.Chip
 	}
 	if param.FilterName != "" {
+		//查询设备mac过滤信息
+		filterMac := ""
+		deviceInfos, count := GetDeviceService().DeviceService.FindDeviceByType(param.FilterName)
+		if count > 0 {
+			for i := range deviceInfos {
+				filterMac += deviceInfos[i].Mac + ","
+			}
+		}
+		if len(filterMac) > 0 {
+			if strings.HasSuffix(filterMac, ",") {
+				filterMac = filterMac[0 : len(filterMac)-1]
+			}
+			paramMap["filter_mac"] = filterMac
+		}
+
 		if param.FilterName == "0" {
 			paramMap["filter_name"] = constant.FilterNameEEG
 		} else if param.FilterName == "1" {
@@ -77,7 +93,7 @@ func ScanDevice(c *gin.Context) {
 // @Success 200 {string} string "ok"
 // @Router /v1/device/connection [get]
 func ConnectDevice(c *gin.Context) {
-	var param models.DeviceConnParam
+	var param gateway.DeviceConnParam
 	err := c.ShouldBindJSON(&param)
 	if err != nil {
 		fmt.Printf("参数格式化异常:%s", err.Error())

+ 5 - 5
api/gateway/sse.go

@@ -4,7 +4,7 @@ import (
 	"confrontation-training/constant"
 	errmsg "confrontation-training/err"
 	"confrontation-training/global"
-	"confrontation-training/models"
+	"confrontation-training/models/gateway"
 	"encoding/json"
 	"fmt"
 	"github.com/gorilla/websocket"
@@ -17,7 +17,7 @@ import (
 func SseScanDevice(paramMap map[string]string) {
 	var scanUrl = global.Config.Gateway.BaseUrl + global.Config.Gateway.ScanUrl
 
-	deviceMap := make(map[string]models.DeviceScanned)
+	deviceMap := make(map[string]gateway.DeviceScanned)
 	if len(paramMap) > 0 {
 		for key, value := range paramMap {
 			scanUrl += "&" + key + "=" + value
@@ -33,13 +33,13 @@ func SseScanDevice(paramMap map[string]string) {
 		//}
 		err := client.SubscribeRaw(func(msg *sse.Event) {
 			//fmt.Println(string(msg.Data))
-			var data models.DeviceScannedFromGateway
+			var data gateway.DeviceScannedFromGateway
 			err := json.Unmarshal(msg.Data, &data)
 			if err != nil {
 				fmt.Printf("SSE数据转换异常:%s", err.Error())
 				return
 			}
-			deviceScanned := models.DeviceScanned{}
+			deviceScanned := gateway.DeviceScanned{}
 			deviceScanned.Name = data.Name
 			deviceScanned.Rssi = data.Rssi
 			deviceScanned.MAC = data.Bdaddrs[0].Bdaddr
@@ -104,7 +104,7 @@ func SseOpenNotify() {
 			//websocket 通知数据
 			//msgMap := make(map[string]string)
 			//msgMap[]
-			var receiveData models.DeviceDataReceived
+			var receiveData gateway.DeviceDataReceived
 			errJson := json.Unmarshal(msg.Data, &receiveData)
 			if errJson != nil {
 				fmt.Println("receive data parse error:" + errJson.Error())

+ 6 - 2
common/time.go

@@ -8,8 +8,12 @@ import (
 )
 
 // NowTime 时间格式化
-func NowTime() string {
-	return time.Now().Format(`2006-01-02 15:04:05`)
+//func NowTime() string {
+//	return time.Now().Format(`2006-01-02 15:04:05`)
+//}
+
+func NowTime(format string) string {
+	return time.Now().Format(format)
 }
 
 // GetHexTimeStr 时间16进制字符串

+ 5 - 0
config/application.yaml

@@ -31,6 +31,11 @@ gateway:
   openChannel: /gatt/nodes/MAC/handle/36/value/0100
   disconnectUrl: /gap/nodes/MAC/connection
   scanSecond: 1000 #蓝牙数据推送时间间隔
+#日志系统
+log2file:
+  filePath: ./logs/
+#  fileName: confrontation_training
+#  fileSuffix: .log
 
 
 

+ 7 - 0
config/config.go

@@ -19,6 +19,7 @@ type Config struct {
 	Upload    Upload    `mapstructure:"upload"`
 	Websocket Websocket `mapstructure:"websocket"`
 	Gateway   Gateway   `mapstructure:"gateway"`
+	Log2File  Log2File  `mapstructure:"log2file"`
 }
 
 // Server 服务启动端口配置
@@ -45,3 +46,9 @@ type Upload struct {
 type Websocket struct {
 	WSUrl string `mapstructure:"ws-url"`
 }
+
+type Log2File struct {
+	FilePath   string `mapstructure:"filePath"`
+	FileName   string `mapstructure:"FileName"`
+	FileSuffix string `mapstructure:"FileSuffix"`
+}

+ 3 - 0
constant/constant.go

@@ -23,4 +23,7 @@ const (
 	// MessageTypeDeviceScanned websocket 消息类型 扫描到设备
 	MessageTypeDeviceScanned = "device"
 	MessageTypeData          = "data"
+	// DefaultKey 3des
+	DefaultKey = "240262447423713749922240"
+	DefaultIv  = "12345678"
 )

二进制
db/confrontation-training.db


+ 157 - 1
docs/docs.go

@@ -18,7 +18,106 @@ const docTemplate = `{
     "host": "{{.Host}}",
     "basePath": "{{.BasePath}}",
     "paths": {
-        "/v1/chat/getQuestion": {
+        "/v1/chat/create/answer": {
+            "post": {
+                "description": "录入答案",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "问答管理"
+                ],
+                "summary": "录入答案",
+                "parameters": [
+                    {
+                        "description": "questionNo:问题编号;NextQuestionNo:下一个问题编号;answer:答案",
+                        "name": "q",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "ok",
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
+        "/v1/chat/create/chat": {
+            "post": {
+                "description": "录入问题",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "问答管理"
+                ],
+                "summary": "录入问题",
+                "parameters": [
+                    {
+                        "description": "chat:问题;nextQuestionNo:下一个问题编号:如果此编号不为空,则说明此问题为陈述,没有答案信息;questionType:题目类型:0选择题;1填空题",
+                        "name": "q",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "ok",
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
+        "/v1/chat/get/answer": {
+            "get": {
+                "description": "查询答案",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "问答管理"
+                ],
+                "summary": "查询答案",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "id:问题主键",
+                        "name": "id",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "ok",
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
+        "/v1/chat/get/chat": {
             "get": {
                 "description": "查询问题",
                 "consumes": [
@@ -49,6 +148,29 @@ const docTemplate = `{
                 }
             }
         },
+        "/v1/device/:mac/disconnect": {
+            "delete": {
+                "description": "断开连接",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "设备管理"
+                ],
+                "summary": "断开连接",
+                "responses": {
+                    "200": {
+                        "description": "ok",
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
         "/v1/device/:mac/stop/collect": {
             "get": {
                 "description": "停止采集",
@@ -95,6 +217,40 @@ const docTemplate = `{
                 }
             }
         },
+        "/v1/device/add": {
+            "post": {
+                "description": "新增设备",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "设备管理"
+                ],
+                "summary": "新增设备",
+                "parameters": [
+                    {
+                        "description": "type:类型 0脑电1心电;mac:设备MAC地址",
+                        "name": "device",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "ok",
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
         "/v1/device/connection": {
             "get": {
                 "description": "连接设备",

+ 157 - 1
docs/swagger.json

@@ -9,7 +9,106 @@
         "version": "1.0"
     },
     "paths": {
-        "/v1/chat/getQuestion": {
+        "/v1/chat/create/answer": {
+            "post": {
+                "description": "录入答案",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "问答管理"
+                ],
+                "summary": "录入答案",
+                "parameters": [
+                    {
+                        "description": "questionNo:问题编号;NextQuestionNo:下一个问题编号;answer:答案",
+                        "name": "q",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "ok",
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
+        "/v1/chat/create/chat": {
+            "post": {
+                "description": "录入问题",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "问答管理"
+                ],
+                "summary": "录入问题",
+                "parameters": [
+                    {
+                        "description": "chat:问题;nextQuestionNo:下一个问题编号:如果此编号不为空,则说明此问题为陈述,没有答案信息;questionType:题目类型:0选择题;1填空题",
+                        "name": "q",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "ok",
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
+        "/v1/chat/get/answer": {
+            "get": {
+                "description": "查询答案",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "问答管理"
+                ],
+                "summary": "查询答案",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "id:问题主键",
+                        "name": "id",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "ok",
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
+        "/v1/chat/get/chat": {
             "get": {
                 "description": "查询问题",
                 "consumes": [
@@ -40,6 +139,29 @@
                 }
             }
         },
+        "/v1/device/:mac/disconnect": {
+            "delete": {
+                "description": "断开连接",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "设备管理"
+                ],
+                "summary": "断开连接",
+                "responses": {
+                    "200": {
+                        "description": "ok",
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
         "/v1/device/:mac/stop/collect": {
             "get": {
                 "description": "停止采集",
@@ -86,6 +208,40 @@
                 }
             }
         },
+        "/v1/device/add": {
+            "post": {
+                "description": "新增设备",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "设备管理"
+                ],
+                "summary": "新增设备",
+                "parameters": [
+                    {
+                        "description": "type:类型 0脑电1心电;mac:设备MAC地址",
+                        "name": "device",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "ok",
+                        "schema": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
         "/v1/device/connection": {
             "get": {
                 "description": "连接设备",

+ 102 - 1
docs/swagger.yaml

@@ -5,7 +5,71 @@ info:
   title: 对抗训练
   version: "1.0"
 paths:
-  /v1/chat/getQuestion:
+  /v1/chat/create/answer:
+    post:
+      consumes:
+      - application/json
+      description: 录入答案
+      parameters:
+      - description: questionNo:问题编号;NextQuestionNo:下一个问题编号;answer:答案
+        in: body
+        name: q
+        required: true
+        schema:
+          type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: ok
+          schema:
+            type: string
+      summary: 录入答案
+      tags:
+      - 问答管理
+  /v1/chat/create/chat:
+    post:
+      consumes:
+      - application/json
+      description: 录入问题
+      parameters:
+      - description: chat:问题;nextQuestionNo:下一个问题编号:如果此编号不为空,则说明此问题为陈述,没有答案信息;questionType:题目类型:0选择题;1填空题
+        in: body
+        name: q
+        required: true
+        schema:
+          type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: ok
+          schema:
+            type: string
+      summary: 录入问题
+      tags:
+      - 问答管理
+  /v1/chat/get/answer:
+    get:
+      consumes:
+      - application/json
+      description: 查询答案
+      parameters:
+      - description: id:问题主键
+        in: query
+        name: id
+        type: integer
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: ok
+          schema:
+            type: string
+      summary: 查询答案
+      tags:
+      - 问答管理
+  /v1/chat/get/chat:
     get:
       consumes:
       - application/json
@@ -25,6 +89,21 @@ paths:
       summary: 查询问题
       tags:
       - 问答管理
+  /v1/device/:mac/disconnect:
+    delete:
+      consumes:
+      - application/json
+      description: 断开连接
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: ok
+          schema:
+            type: string
+      summary: 断开连接
+      tags:
+      - 设备管理
   /v1/device/:mac/stop/collect:
     get:
       consumes:
@@ -55,6 +134,28 @@ paths:
       summary: 停止传输
       tags:
       - 设备管理
+  /v1/device/add:
+    post:
+      consumes:
+      - application/json
+      description: 新增设备
+      parameters:
+      - description: type:类型 0脑电1心电;mac:设备MAC地址
+        in: body
+        name: device
+        required: true
+        schema:
+          type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: ok
+          schema:
+            type: string
+      summary: 新增设备
+      tags:
+      - 设备管理
   /v1/device/connection:
     get:
       consumes:

+ 3 - 0
err/errMsg.go

@@ -29,4 +29,7 @@ const (
 	QuestionCreateFailed      = "创建问题失败"
 	AnswerCreateFailed        = "创建答案失败"
 	FindAnswerFailed          = "查询答案信息失败"
+	FindCategoryFailed        = "类别查询失败"
+	DeviceAddFailed           = "新增设备信息失败"
+	DeviceAddSuccess          = "新增设备信息成功"
 )

+ 15 - 8
go.mod

@@ -7,19 +7,24 @@ require (
 	github.com/golang-jwt/jwt v3.2.2+incompatible
 	github.com/google/uuid v1.1.2
 	github.com/gorilla/websocket v1.5.0
+	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
 	github.com/r3labs/sse/v2 v2.10.0
+	github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
+	github.com/sirupsen/logrus v1.9.3
 	github.com/spf13/viper v1.16.0
 	github.com/swaggo/files v1.0.1
 	github.com/swaggo/gin-swagger v1.6.0
+	github.com/swaggo/swag v1.16.1
 	gorm.io/driver/sqlite v1.5.2
 	gorm.io/gorm v1.25.2
 )
 
 require (
 	github.com/KyleBanks/depth v1.2.1 // indirect
-	github.com/bytedance/sonic v1.10.0-rc3 // indirect
+	github.com/bytedance/sonic v1.10.0 // indirect
 	github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
 	github.com/chenzhuoyu/iasm v0.9.0 // indirect
+	github.com/forgoer/openssl v1.6.0 // indirect
 	github.com/fsnotify/fsnotify v1.6.0 // indirect
 	github.com/gabriel-vasile/mimetype v1.4.2 // indirect
 	github.com/gin-contrib/sse v0.1.0 // indirect
@@ -29,15 +34,17 @@ require (
 	github.com/go-openapi/swag v0.22.4 // indirect
 	github.com/go-playground/locales v0.14.1 // indirect
 	github.com/go-playground/universal-translator v0.18.1 // indirect
-	github.com/go-playground/validator/v10 v10.14.1 // indirect
+	github.com/go-playground/validator/v10 v10.15.1 // indirect
 	github.com/goccy/go-json v0.10.2 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
+	github.com/jonboulle/clockwork v0.4.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/klauspost/cpuid/v2 v2.2.5 // indirect
 	github.com/leodido/go-urn v1.2.4 // indirect
+	github.com/lestrrat-go/strftime v1.0.6 // indirect
 	github.com/magiconair/properties v1.8.7 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/mattn/go-isatty v0.0.19 // indirect
@@ -46,20 +53,20 @@ require (
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.9 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
 	github.com/spf13/afero v1.9.5 // indirect
 	github.com/spf13/cast v1.5.1 // indirect
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/subosito/gotenv v1.4.2 // indirect
-	github.com/swaggo/swag v1.16.1 // indirect
 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
 	github.com/ugorji/go/codec v1.2.11 // indirect
 	golang.org/x/arch v0.4.0 // indirect
-	golang.org/x/crypto v0.11.0 // indirect
-	golang.org/x/net v0.12.0 // indirect
-	golang.org/x/sys v0.10.0 // indirect
-	golang.org/x/text v0.11.0 // indirect
-	golang.org/x/tools v0.11.0 // indirect
+	golang.org/x/crypto v0.12.0 // indirect
+	golang.org/x/net v0.14.0 // indirect
+	golang.org/x/sys v0.11.0 // indirect
+	golang.org/x/text v0.12.0 // indirect
+	golang.org/x/tools v0.12.0 // indirect
 	google.golang.org/protobuf v1.31.0 // indirect
 	gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect

+ 30 - 14
go.sum

@@ -42,8 +42,8 @@ github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc
 github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
 github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
 github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
-github.com/bytedance/sonic v1.10.0-rc3 h1:uNSnscRapXTwUgTyOF0GVljYD08p9X/Lbr9MweSV3V0=
-github.com/bytedance/sonic v1.10.0-rc3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
+github.com/bytedance/sonic v1.10.0 h1:qtNZduETEIWJVIyDl01BeNxur2rW9OwTQ/yBqFRkKEk=
+github.com/bytedance/sonic v1.10.0/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
 github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
@@ -68,6 +68,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
 github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/forgoer/openssl v1.6.0 h1:IueL+UfH0hKo99xFPojHLlO3QzRBQqFY+Cht0WwtOC0=
+github.com/forgoer/openssl v1.6.0/go.mod h1:9DZ4yOsQmveP0aXC/BpQ++Y5TKaz5yR9+emcxmIZNZs=
 github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
 github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
@@ -101,8 +103,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
 github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
 github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
 github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
-github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
-github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
+github.com/go-playground/validator/v10 v10.15.1 h1:BSe8uhN+xQ4r5guV/ywQI4gO59C2raYcGffYWZEjZzM=
+github.com/go-playground/validator/v10 v10.15.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
 github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
@@ -178,6 +180,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
 github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
+github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@@ -199,6 +203,12 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
 github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
+github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
+github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
+github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
+github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
 github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
 github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -220,6 +230,7 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
 github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -227,8 +238,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0=
 github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I=
+github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo=
+github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
 github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
 github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
@@ -288,8 +303,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
-golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
+golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
+golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -360,8 +375,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
-golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
+golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
+golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -418,12 +433,13 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.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/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
+golang.org/x/sys v0.11.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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -436,8 +452,8 @@ golang.org/x/text v0.3.4/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.7.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/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
+golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -489,8 +505,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
-golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
+golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
+golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
 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=

+ 8 - 4
initialize/router.go

@@ -3,10 +3,12 @@ package initialize
 import (
 	"confrontation-training/api/chat"
 	"confrontation-training/api/gateway"
+	_ "confrontation-training/docs"
 	"confrontation-training/global"
 	_ "confrontation-training/global"
 	"confrontation-training/middleware"
 	"confrontation-training/models"
+	modelsChat "confrontation-training/models/chat"
 	"fmt"
 	"github.com/gin-gonic/gin"
 	swaggerFiles "github.com/swaggo/files"
@@ -17,7 +19,7 @@ import (
 func Router() {
 
 	//初始化表格
-	initTableErr := global.Db.AutoMigrate(&models.User{}, &models.Question{}, &models.Answer{})
+	initTableErr := global.Db.AutoMigrate(&models.User{}, &modelsChat.Question{}, &modelsChat.Answer{})
 	if initTableErr != nil {
 		fmt.Printf("初始化表格异常:%s", initTableErr.Error())
 		return
@@ -26,12 +28,14 @@ func Router() {
 	engine := gin.Default()
 	//解决跨域
 	engine.Use(middleware.Cors())
+	engine.Use(middleware.LoggerToFile())
+	// 静态资源请求映射
+	engine.Static("/image", global.Config.Upload.SavePath)
 
 	//404 NOT FOUND
 	engine.NoRoute(func(context *gin.Context) {
 		context.String(http.StatusNotFound, "404 not found")
 	})
-
 	//swag
 	engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
 	engine.Static("/file", "./files")
@@ -55,11 +59,11 @@ func Router() {
 	device.GET("/:mac/stop/trans/", gateway.StopTrans)
 	device.GET("/:mac/stop/collect/", gateway.StopCollect)
 	device.GET("/:mac/disconnect/", gateway.Disconnect)
+	device.POST("/add/", gateway.GetDeviceService().DeviceAdd)
 	chats := v1.Group("/chat")
 	chats.GET("/get/chat/", chat.GetQuestionService().GetQuestion)
 	chats.POST("/create/chat/", chat.GetQuestionService().CreateQuestion)
-	chats.GET("/get/answer/", chat.GteAnswerService().CreateAnswer)
-
+	chats.GET("/get/answer/", chat.GetAnswerService().GetAnswer)
 	//
 	//record := v1.Group("/record")
 	//record.POST("/create", api.GetRecord().SaveRecord)

+ 1 - 1
initialize/run.go

@@ -1,7 +1,7 @@
 package initialize
 
 func Run() {
-	//SwagInit()
+	SwagInit()
 	LoadConfig()
 	SQLite()
 	go Manager.Start()

+ 1 - 1
initialize/swag.go

@@ -7,7 +7,7 @@ import (
 	"os/exec"
 )
 
-// SwagInit 初始化swag
+// SwagInit 初始化swag  http://localhost:8000/swagger/index.html
 func SwagInit() {
 	cmd := exec.Command("swag", "init")
 	fmt.Println("Cmd", cmd.Args)

+ 0 - 1
main.go

@@ -10,5 +10,4 @@ import "confrontation-training/initialize"
 //contact.url https://www.cnblogs.com/wormworm
 func main() {
 	initialize.Run()
-
 }

+ 128 - 0
middleware/log_2_file.go

@@ -0,0 +1,128 @@
+package middleware
+
+import (
+	"confrontation-training/common"
+	"confrontation-training/global"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
+	"github.com/rifflock/lfshook"
+	"github.com/sirupsen/logrus"
+	"os"
+	"path"
+	"time"
+)
+
+// LoggerToFile 日志记录到文件
+func LoggerToFile() gin.HandlerFunc {
+
+	logFilePath := global.Config.Log2File.FilePath + common.NowTime("2006-01-02")
+	logFileName := global.Config.Log2File.FileName + global.Config.Log2File.FileSuffix
+
+	// 日志文件
+	fileName := path.Join(logFilePath, logFileName)
+	// 写入文件
+	//src, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.ModeAppend)
+	src, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModeAppend)
+	if err != nil {
+		fmt.Println("err", err)
+	}
+
+	// 实例化
+	logger := logrus.New()
+
+	// 设置输出
+	logger.Out = src
+
+	// 设置日志级别
+	logger.SetLevel(logrus.DebugLevel)
+	logger.SetFormatter(&logrus.JSONFormatter{TimestampFormat: "2006-01-02 15:04:05"})
+
+	// 设置 rotatelogs
+	logWriter, err := rotatelogs.New(
+		// 分割后的文件名称
+		fileName+".%Y%m%d.log",
+
+		// 生成软链,指向最新日志文件
+		rotatelogs.WithLinkName(fileName),
+
+		// 设置最大保存时间(7天)
+		rotatelogs.WithMaxAge(7*24*time.Hour),
+
+		// 设置日志切割时间间隔(1天)
+		rotatelogs.WithRotationTime(24*time.Hour),
+	)
+
+	writeMap := lfshook.WriterMap{
+		logrus.InfoLevel:  logWriter,
+		logrus.FatalLevel: logWriter,
+		logrus.DebugLevel: logWriter,
+		logrus.WarnLevel:  logWriter,
+		logrus.ErrorLevel: logWriter,
+		logrus.PanicLevel: logWriter,
+	}
+
+	lfHook := lfshook.NewHook(writeMap, &logrus.JSONFormatter{
+		TimestampFormat: "2006-01-02 15:04:05",
+	})
+
+	// 新增 Hook
+	logger.AddHook(lfHook)
+
+	return func(c *gin.Context) {
+		// 开始时间
+		startTime := time.Now()
+
+		// 处理请求
+		c.Next()
+
+		// 结束时间
+		endTime := time.Now()
+
+		// 执行时间
+		latencyTime := endTime.Sub(startTime)
+
+		// 请求方式
+		reqMethod := c.Request.Method
+
+		// 请求路由
+		reqUri := c.Request.RequestURI
+
+		// 状态码
+		statusCode := c.Writer.Status()
+
+		// 请求IP
+		//clientIP := c.ClientIP()
+		clientIP := c.RemoteIP()
+
+		// 日志格式
+		logger.WithFields(logrus.Fields{
+			"status_code":  statusCode,
+			"latency_time": latencyTime,
+			"client_ip":    clientIP,
+			"req_method":   reqMethod,
+			"req_uri":      reqUri,
+		}).Info()
+	}
+}
+
+// LoggerToMongo 日志记录到 MongoDB
+func LoggerToMongo() gin.HandlerFunc {
+	return func(c *gin.Context) {
+
+	}
+}
+
+// LoggerToES 日志记录到 ES
+func LoggerToES() gin.HandlerFunc {
+	return func(c *gin.Context) {
+
+	}
+}
+
+// LoggerToMQ 日志记录到 MQ
+func LoggerToMQ() gin.HandlerFunc {
+	return func(c *gin.Context) {
+
+	}
+}

+ 0 - 0
models/answer.go → models/chat/answer.go


+ 0 - 0
models/question.go → models/chat/question.go


+ 13 - 1
models/device.go → models/gateway/device.go

@@ -1,4 +1,6 @@
-package models
+package gateway
+
+import "gorm.io/gorm"
 
 type DeviceScanParam struct {
 	Chip       string `json:"chip"`       //芯片 0和1
@@ -7,6 +9,16 @@ type DeviceScanParam struct {
 	FilterMac  string `json:"filterMac"`  //过滤Mac地址,以","分割,如 61-Dg-89-22-39-3b,80-kD-0E-40-57-8A
 }
 
+type DeviceAddParam struct {
+	Type string `json:"type" binding:"required" `
+	Mac  string `json:"mac" binding:"required" `
+}
+type DeviceInfo struct {
+	gorm.Model
+	Type string `gorm:"type type:varchar(2) not null comment '分类:0脑电;1心电'"`
+	Mac  string `gorm:"mac type:varchar(20) not null comment 'Mac 地址'"`
+}
+
 type DeviceConnParam struct {
 	Chip       string `json:"chip" binding:"required" `      //芯片 0/1
 	AddrType   string `json:"addrType" binding:"required"`   //地址类型 public/random

+ 21 - 0
security/Desded.go

@@ -0,0 +1,21 @@
+package security
+
+import (
+	"confrontation-training/constant"
+	"encoding/base64"
+	"github.com/forgoer/openssl"
+)
+
+func Encrypt(src string) string {
+	encrypt, _ := openssl.Des3CBCEncrypt([]byte(src), []byte(constant.DefaultKey), []byte(constant.DefaultIv), openssl.PKCS5_PADDING)
+	return base64.StdEncoding.EncodeToString(encrypt)
+}
+
+func Decrypt(src string) string {
+	decodeString, err := base64.StdEncoding.DecodeString(src)
+	if err != nil {
+		return ""
+	}
+	decrypt, err := openssl.Des3CBCDecrypt(decodeString, []byte(constant.DefaultKey), []byte(constant.DefaultIv), openssl.PKCS5_PADDING)
+	return string(decrypt)
+}

+ 2 - 2
service/answerService.go → service/chat/answerService.go

@@ -1,8 +1,8 @@
-package service
+package chat
 
 import (
 	"confrontation-training/global"
-	"confrontation-training/models"
+	"confrontation-training/models/chat"
 )
 
 type AnswerService struct {

+ 2 - 2
service/questionService.go → service/chat/questionService.go

@@ -1,8 +1,8 @@
-package service
+package chat
 
 import (
 	"confrontation-training/global"
-	"confrontation-training/models"
+	"confrontation-training/models/chat"
 )
 
 type QuestionService struct {

+ 28 - 0
service/device/device.go

@@ -0,0 +1,28 @@
+package device
+
+import (
+	"confrontation-training/global"
+	deviceModel "confrontation-training/models/gateway"
+	"gorm.io/gorm"
+)
+
+type DeviceService struct {
+}
+
+func (d *DeviceService) FindDeviceByMac(mac string) (deviceModel.DeviceInfo, int64) {
+	info := deviceModel.DeviceInfo{}
+	count := global.Db.Where(" mac = ?", mac).First(&info).RowsAffected
+	return info, count
+}
+func (d *DeviceService) FindDeviceByType(deviceType string) ([]deviceModel.DeviceInfo, int64) {
+	var deviceList = make([]deviceModel.DeviceInfo, 0)
+	count := global.Db.Where("type = ?", deviceType).Find(&deviceList).RowsAffected
+	return deviceList, count
+}
+func (d *DeviceService) CreateDevice(param deviceModel.DeviceAddParam) *gorm.DB {
+	addParam := deviceModel.DeviceAddParam{
+		Type: param.Type,
+		Mac:  param.Mac,
+	}
+	return global.Db.Create(addParam)
+}

+ 1 - 1
service/userService.go

@@ -74,7 +74,7 @@ func (u *UserService) GetUserList(param models.UserListParam) ([]models.User, in
 		PageSize: param.PageSize,
 	}
 	userList := make([]models.User, 0)
-	rows := common.RestPage(page, "user", query, "", &userList, &[]models.User{})
+	rows := common.RestPage(page, "ct_users", query, "", &userList, &[]models.User{})
 	return userList, rows
 }