commit 07847a2d9ed2f487389b1c1de2c302a26f7f5bba
Author: hucan <951870319@qq.com>
Date:   Thu Feb 6 11:14:33 2025 +0800
    1
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..24cb16d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,23 @@
+.idea
+.vscode
+*/.DS_Store
+static/uploadfile
+main.exe
+*.exe
+go-admin
+go-admin.exe
+temp/
+!temp
+vendor
+config/settings.dev.yml
+config/settings.dev.*.yml
+config/settings.dev.*.yml.log
+temp/logs
+config/settings.dev.yml.log
+config/settings.b.dev.yml
+cmd/migrate/migration/version-local/*
+!cmd/migrate/migration/version-local/doc.go
+
+# go sum
+go.sum
+config/settings.deva.yml
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..fb3e023
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,18 @@
+FROM alpine
+
+# ENV GOPROXY https://goproxy.cn/
+
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
+
+RUN apk update --no-cache
+RUN apk add --update gcc g++ libc6-compat
+RUN apk add --no-cache ca-certificates
+RUN apk add --no-cache tzdata
+ENV TZ Asia/Shanghai
+
+COPY ./main /main
+COPY ./config/settings.demo.yml /config/settings.yml
+COPY ./go-admin-db.db /go-admin-db.db
+EXPOSE 8000
+RUN  chmod +x /main
+CMD ["/main","server","-c", "/config/settings.yml"]
\ No newline at end of file
diff --git a/Dockerfilebak b/Dockerfilebak
new file mode 100644
index 0000000..c5e33a5
--- /dev/null
+++ b/Dockerfilebak
@@ -0,0 +1,28 @@
+FROM golang:alpine as builder
+
+MAINTAINER lwnmengjing
+
+ENV GOPROXY https://goproxy.cn/
+
+WORKDIR /go/release
+#RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk update && apk add tzdata
+
+COPY go.mod ./go.mod
+RUN go mod tidy
+COPY . .
+RUN pwd && ls
+
+RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -a -installsuffix cgo -o go-admin .
+
+FROM alpine
+
+COPY --from=builder /go/release/go-admin /
+
+COPY --from=builder /go/release/config/settings.yml /config/settings.yml
+
+COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+
+EXPOSE 8000
+
+CMD ["/go-admin","server","-c", "/config/settings.yml"]
\ No newline at end of file
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..36b35f4
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 go-admin-team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..afdb1a1
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,54 @@
+PROJECT:=go-admin
+
+.PHONY: build
+build:
+	CGO_ENABLED=0 go build -ldflags="-w -s" -a -installsuffix "" -o go-admin .
+
+# make build-linux
+build-linux:
+	@docker build -t go-admin:latest .
+	@echo "build successful"
+
+build-sqlite:
+	go build -tags sqlite3 -ldflags="-w -s" -a -installsuffix -o go-admin .
+
+# make run
+run:
+    # delete go-admin-api container
+	@if [ $(shell docker ps -aq --filter name=go-admin --filter publish=8000) ]; then docker rm -f go-admin; fi
+
+    # 启动方法一 run go-admin-api container  docker-compose 启动方式
+    # 进入到项目根目录 执行 make run 命令
+	@docker-compose up -d
+
+	# 启动方式二 docker run  这里注意-v挂载的宿主机的地址改为部署时的实际决对路径
+    #@docker run --name=go-admin -p 8000:8000 -v /home/code/go/src/go-admin/go-admin/config:/go-admin-api/config  -v /home/code/go/src/go-admin/go-admin-api/static:/go-admin/static -v /home/code/go/src/go-admin/go-admin/temp:/go-admin-api/temp -d --restart=always go-admin:latest
+
+	@echo "go-admin service is running..."
+
+	# delete Tag= 的镜像
+	@docker image prune -f
+	@docker ps -a | grep "go-admin"
+
+stop:
+    # delete go-admin-api container
+	@if [ $(shell docker ps -aq --filter name=go-admin --filter publish=8000) ]; then docker-compose down; fi
+	#@if [ $(shell docker ps -aq --filter name=go-admin --filter publish=8000) ]; then docker rm -f go-admin; fi
+	#@echo "go-admin stop success"
+
+
+#.PHONY: test
+#test:
+#	go test -v ./... -cover
+
+#.PHONY: docker
+#docker:
+#	docker build . -t go-admin:latest
+
+# make deploy
+deploy:
+
+	#@git checkout master
+	#@git pull origin master
+	make build-linux
+	make run
diff --git a/README.Zh-cn.md b/README.Zh-cn.md
new file mode 100644
index 0000000..f7acfb8
--- /dev/null
+++ b/README.Zh-cn.md
@@ -0,0 +1,352 @@
+# go-admin
+
+  
+  
+    wenjianzhang  
+  
+    Wechat 
+    Wechat公众号🔥🔥🔥 
+    bilibili🔥🔥🔥 
+   
+
+
+## 💎 Contributors
+
+GO-ADMIN欢迎您 
+
+
+
+
+
+
+
+
+`
+
+func GoAdmin(c *gin.Context) {
+	c.Header("Content-Type", "text/html; charset=utf-8")
+	c.String(200, INDEX)
+}
diff --git a/app/admin/apis/line_account_setting.go b/app/admin/apis/line_account_setting.go
new file mode 100644
index 0000000..a82da5f
--- /dev/null
+++ b/app/admin/apis/line_account_setting.go
@@ -0,0 +1,191 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineAccountSetting struct {
+	api.Api
+}
+
+// GetPage 获取登录账户管理列表
+// @Summary 获取登录账户管理列表
+// @Description 获取登录账户管理列表
+// @Tags 登录账户管理
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineAccountSetting}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-account-setting [get]
+// @Security Bearer
+func (e LineAccountSetting) GetPage(c *gin.Context) {
+    req := dto.LineAccountSettingGetPageReq{}
+    s := service.LineAccountSetting{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineAccountSetting, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取登录账户管理失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取登录账户管理
+// @Summary 获取登录账户管理
+// @Description 获取登录账户管理
+// @Tags 登录账户管理
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineAccountSetting} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-account-setting/{id} [get]
+// @Security Bearer
+func (e LineAccountSetting) Get(c *gin.Context) {
+	req := dto.LineAccountSettingGetReq{}
+	s := service.LineAccountSetting{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineAccountSetting
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取登录账户管理失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建登录账户管理
+// @Summary 创建登录账户管理
+// @Description 创建登录账户管理
+// @Tags 登录账户管理
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineAccountSettingInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-account-setting [post]
+// @Security Bearer
+func (e LineAccountSetting) Insert(c *gin.Context) {
+    req := dto.LineAccountSettingInsertReq{}
+    s := service.LineAccountSetting{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建登录账户管理失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改登录账户管理
+// @Summary 修改登录账户管理
+// @Description 修改登录账户管理
+// @Tags 登录账户管理
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineAccountSettingUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-account-setting/{id} [put]
+// @Security Bearer
+func (e LineAccountSetting) Update(c *gin.Context) {
+    req := dto.LineAccountSettingUpdateReq{}
+    s := service.LineAccountSetting{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改登录账户管理失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除登录账户管理
+// @Summary 删除登录账户管理
+// @Description 删除登录账户管理
+// @Tags 登录账户管理
+// @Param data body dto.LineAccountSettingDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-account-setting [delete]
+// @Security Bearer
+func (e LineAccountSetting) Delete(c *gin.Context) {
+    s := service.LineAccountSetting{}
+    req := dto.LineAccountSettingDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除登录账户管理失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_api_group.go b/app/admin/apis/line_api_group.go
new file mode 100644
index 0000000..ab7b91d
--- /dev/null
+++ b/app/admin/apis/line_api_group.go
@@ -0,0 +1,192 @@
+package apis
+
+import (
+	"fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineApiGroup struct {
+	api.Api
+}
+
+// GetPage 获取用户绑定从属关系表列表
+// @Summary 获取用户绑定从属关系表列表
+// @Description 获取用户绑定从属关系表列表
+// @Tags 用户绑定从属关系表
+// @Param groupName query string false "用户组名称"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineApiGroup}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-api-group [get]
+// @Security Bearer
+func (e LineApiGroup) GetPage(c *gin.Context) {
+	req := dto.LineApiGroupGetPageReq{}
+	s := service.LineApiGroup{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineApiGroup, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取用户绑定从属关系表失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取用户绑定从属关系表
+// @Summary 获取用户绑定从属关系表
+// @Description 获取用户绑定从属关系表
+// @Tags 用户绑定从属关系表
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineApiGroup} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-api-group/{id} [get]
+// @Security Bearer
+func (e LineApiGroup) Get(c *gin.Context) {
+	req := dto.LineApiGroupGetReq{}
+	s := service.LineApiGroup{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineApiGroup
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取用户绑定从属关系表失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert 创建用户绑定从属关系表
+// @Summary 创建用户绑定从属关系表
+// @Description 创建用户绑定从属关系表
+// @Tags 用户绑定从属关系表
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineApiGroupInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-api-group [post]
+// @Security Bearer
+func (e LineApiGroup) Insert(c *gin.Context) {
+	req := dto.LineApiGroupInsertReq{}
+	s := service.LineApiGroup{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建用户绑定从属关系表失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改用户绑定从属关系表
+// @Summary 修改用户绑定从属关系表
+// @Description 修改用户绑定从属关系表
+// @Tags 用户绑定从属关系表
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineApiGroupUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-api-group/{id} [put]
+// @Security Bearer
+func (e LineApiGroup) Update(c *gin.Context) {
+	req := dto.LineApiGroupUpdateReq{}
+	s := service.LineApiGroup{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改用户绑定从属关系表失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "修改成功")
+}
+
+// Delete 删除用户绑定从属关系表
+// @Summary 删除用户绑定从属关系表
+// @Description 删除用户绑定从属关系表
+// @Tags 用户绑定从属关系表
+// @Param data body dto.LineApiGroupDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-api-group [delete]
+// @Security Bearer
+func (e LineApiGroup) Delete(c *gin.Context) {
+	s := service.LineApiGroup{}
+	req := dto.LineApiGroupDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除用户绑定从属关系表失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_api_user.go b/app/admin/apis/line_api_user.go
new file mode 100644
index 0000000..71a7983
--- /dev/null
+++ b/app/admin/apis/line_api_user.go
@@ -0,0 +1,267 @@
+package apis
+
+import (
+	"fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineApiUser struct {
+	api.Api
+}
+
+// GetPage 获取api用户管理列表
+// @Summary 获取api用户管理列表
+// @Description 获取api用户管理列表
+// @Tags api用户管理
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineApiUser}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-api-user [get]
+// @Security Bearer
+func (e LineApiUser) GetPage(c *gin.Context) {
+	req := dto.LineApiUserGetPageReq{}
+	s := service.LineApiUser{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineApiUser, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取api用户管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	for i, apiUser := range list {
+		if apiUser.UserId <= 0 {
+			list[i].OpenStatus = 1
+		}
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取api用户管理
+// @Summary 获取api用户管理
+// @Description 获取api用户管理
+// @Tags api用户管理
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineApiUser} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-api-user/{id} [get]
+// @Security Bearer
+func (e LineApiUser) Get(c *gin.Context) {
+	req := dto.LineApiUserGetReq{}
+	s := service.LineApiUser{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineApiUser
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取api用户管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert 创建api用户管理
+// @Summary 创建api用户管理
+// @Description 创建api用户管理
+// @Tags api用户管理
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineApiUserInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-api-user [post]
+// @Security Bearer
+func (e LineApiUser) Insert(c *gin.Context) {
+	req := dto.LineApiUserInsertReq{}
+	s := service.LineApiUser{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建api用户管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改api用户管理
+// @Summary 修改api用户管理
+// @Description 修改api用户管理
+// @Tags api用户管理
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineApiUserUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-api-user/{id} [put]
+// @Security Bearer
+func (e LineApiUser) Update(c *gin.Context) {
+	req := dto.LineApiUserUpdateReq{}
+	s := service.LineApiUser{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改api用户管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "修改成功")
+}
+
+// Delete 删除api用户管理
+// @Summary 删除api用户管理
+// @Description 删除api用户管理
+// @Tags api用户管理
+// @Param data body dto.LineApiUserDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-api-user [delete]
+// @Security Bearer
+func (e LineApiUser) Delete(c *gin.Context) {
+	s := service.LineApiUser{}
+	req := dto.LineApiUserDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除api用户管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+func (e LineApiUser) Bind(c *gin.Context) {
+	s := service.LineApiUser{}
+	req := dto.LineApiUserBindSubordinateReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Bind(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("绑定api用户关系失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(nil, "操作成功")
+}
+
+func (e LineApiUser) GetUser(c *gin.Context) {
+	s := service.LineApiUser{}
+	req := dto.LineApiUserBindSubordinateReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	//p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineApiUser, 0)
+	err = s.GetUser(&list)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(list, "操作成功")
+}
+
+// GetMainUser 获取主账号
+func (e LineApiUser) GetMainUser(c *gin.Context) {
+	s := service.LineApiUser{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	//p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineApiUser, 0)
+	err = s.GetMainUser(&list)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(list, "操作成功")
+}
diff --git a/app/admin/apis/line_coinnetwork.go b/app/admin/apis/line_coinnetwork.go
new file mode 100644
index 0000000..1a85256
--- /dev/null
+++ b/app/admin/apis/line_coinnetwork.go
@@ -0,0 +1,191 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineCoinnetwork struct {
+	api.Api
+}
+
+// GetPage 获取【币种网络】列表
+// @Summary 获取【币种网络】列表
+// @Description 获取【币种网络】列表
+// @Tags 【币种网络】
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineCoinnetwork}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-coinnetwork [get]
+// @Security Bearer
+func (e LineCoinnetwork) GetPage(c *gin.Context) {
+    req := dto.LineCoinnetworkGetPageReq{}
+    s := service.LineCoinnetwork{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineCoinnetwork, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取【币种网络】失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取【币种网络】
+// @Summary 获取【币种网络】
+// @Description 获取【币种网络】
+// @Tags 【币种网络】
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineCoinnetwork} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-coinnetwork/{id} [get]
+// @Security Bearer
+func (e LineCoinnetwork) Get(c *gin.Context) {
+	req := dto.LineCoinnetworkGetReq{}
+	s := service.LineCoinnetwork{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineCoinnetwork
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取【币种网络】失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建【币种网络】
+// @Summary 创建【币种网络】
+// @Description 创建【币种网络】
+// @Tags 【币种网络】
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineCoinnetworkInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-coinnetwork [post]
+// @Security Bearer
+func (e LineCoinnetwork) Insert(c *gin.Context) {
+    req := dto.LineCoinnetworkInsertReq{}
+    s := service.LineCoinnetwork{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建【币种网络】失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改【币种网络】
+// @Summary 修改【币种网络】
+// @Description 修改【币种网络】
+// @Tags 【币种网络】
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineCoinnetworkUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-coinnetwork/{id} [put]
+// @Security Bearer
+func (e LineCoinnetwork) Update(c *gin.Context) {
+    req := dto.LineCoinnetworkUpdateReq{}
+    s := service.LineCoinnetwork{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改【币种网络】失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除【币种网络】
+// @Summary 删除【币种网络】
+// @Description 删除【币种网络】
+// @Tags 【币种网络】
+// @Param data body dto.LineCoinnetworkDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-coinnetwork [delete]
+// @Security Bearer
+func (e LineCoinnetwork) Delete(c *gin.Context) {
+    s := service.LineCoinnetwork{}
+    req := dto.LineCoinnetworkDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除【币种网络】失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_cointonetwork.go b/app/admin/apis/line_cointonetwork.go
new file mode 100644
index 0000000..2a067a2
--- /dev/null
+++ b/app/admin/apis/line_cointonetwork.go
@@ -0,0 +1,191 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineCointonetwork struct {
+	api.Api
+}
+
+// GetPage 获取币种与网络关系列表
+// @Summary 获取币种与网络关系列表
+// @Description 获取币种与网络关系列表
+// @Tags 币种与网络关系
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineCointonetwork}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-cointonetwork [get]
+// @Security Bearer
+func (e LineCointonetwork) GetPage(c *gin.Context) {
+    req := dto.LineCointonetworkGetPageReq{}
+    s := service.LineCointonetwork{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineCointonetwork, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取币种与网络关系失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取币种与网络关系
+// @Summary 获取币种与网络关系
+// @Description 获取币种与网络关系
+// @Tags 币种与网络关系
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineCointonetwork} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-cointonetwork/{id} [get]
+// @Security Bearer
+func (e LineCointonetwork) Get(c *gin.Context) {
+	req := dto.LineCointonetworkGetReq{}
+	s := service.LineCointonetwork{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineCointonetwork
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取币种与网络关系失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建币种与网络关系
+// @Summary 创建币种与网络关系
+// @Description 创建币种与网络关系
+// @Tags 币种与网络关系
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineCointonetworkInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-cointonetwork [post]
+// @Security Bearer
+func (e LineCointonetwork) Insert(c *gin.Context) {
+    req := dto.LineCointonetworkInsertReq{}
+    s := service.LineCointonetwork{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建币种与网络关系失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改币种与网络关系
+// @Summary 修改币种与网络关系
+// @Description 修改币种与网络关系
+// @Tags 币种与网络关系
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineCointonetworkUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-cointonetwork/{id} [put]
+// @Security Bearer
+func (e LineCointonetwork) Update(c *gin.Context) {
+    req := dto.LineCointonetworkUpdateReq{}
+    s := service.LineCointonetwork{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改币种与网络关系失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除币种与网络关系
+// @Summary 删除币种与网络关系
+// @Description 删除币种与网络关系
+// @Tags 币种与网络关系
+// @Param data body dto.LineCointonetworkDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-cointonetwork [delete]
+// @Security Bearer
+func (e LineCointonetwork) Delete(c *gin.Context) {
+    s := service.LineCointonetwork{}
+    req := dto.LineCointonetworkDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除币种与网络关系失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_direction.go b/app/admin/apis/line_direction.go
new file mode 100644
index 0000000..0d50b35
--- /dev/null
+++ b/app/admin/apis/line_direction.go
@@ -0,0 +1,240 @@
+package apis
+
+import (
+	"fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineDirection struct {
+	api.Api
+}
+
+// GetPage 获取预估方向管理列表
+// @Summary 获取预估方向管理列表
+// @Description 获取预估方向管理列表
+// @Tags 预估方向管理
+// @Param symbol query string false "交易对"
+// @Param type query int64 false "交易对类型:1=现货,2=合约"
+// @Param direction query string false "预估方向"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineDirection}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-direction [get]
+// @Security Bearer
+func (e LineDirection) GetPage(c *gin.Context) {
+	req := dto.LineDirectionGetPageReq{}
+	s := service.LineDirection{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineDirection, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取预估方向管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取预估方向管理
+// @Summary 获取预估方向管理
+// @Description 获取预估方向管理
+// @Tags 预估方向管理
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineDirection} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-direction/{id} [get]
+// @Security Bearer
+func (e LineDirection) Get(c *gin.Context) {
+	req := dto.LineDirectionGetReq{}
+	s := service.LineDirection{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineDirection
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取预估方向管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert 创建预估方向管理
+// @Summary 创建预估方向管理
+// @Description 创建预估方向管理
+// @Tags 预估方向管理
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineDirectionInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-direction [post]
+// @Security Bearer
+func (e LineDirection) Insert(c *gin.Context) {
+	req := dto.LineDirectionInsertReq{}
+	s := service.LineDirection{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建预估方向管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改预估方向管理
+// @Summary 修改预估方向管理
+// @Description 修改预估方向管理
+// @Tags 预估方向管理
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineDirectionUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-direction/{id} [put]
+// @Security Bearer
+func (e LineDirection) Update(c *gin.Context) {
+	req := dto.LineDirectionUpdateReq{}
+	s := service.LineDirection{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改预估方向管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "修改成功")
+}
+
+// Delete 删除预估方向管理
+// @Summary 删除预估方向管理
+// @Description 删除预估方向管理
+// @Tags 预估方向管理
+// @Param data body dto.LineDirectionDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-direction [delete]
+// @Security Bearer
+func (e LineDirection) Delete(c *gin.Context) {
+	s := service.LineDirection{}
+	req := dto.LineDirectionDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除预估方向管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+// AddDirection 新增预估方向
+func (e LineDirection) AddDirection(c *gin.Context) {
+	s := service.LineDirection{}
+	req := dto.AddDirectionReq{}
+
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = s.AddDirection(req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("生成预估方向失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(nil, "操作成功")
+}
+
+// 重新统计分组信息
+func (e LineDirection) ReloadGroupData(c *gin.Context) {
+	s := service.LineDirection{}
+
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	if err := s.ReloadGroup(); err != nil {
+		e.Error(500, err, fmt.Sprintf("重新统计分组信息失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(nil, "操作成功")
+}
diff --git a/app/admin/apis/line_order_template_logs.go b/app/admin/apis/line_order_template_logs.go
new file mode 100644
index 0000000..7160a1e
--- /dev/null
+++ b/app/admin/apis/line_order_template_logs.go
@@ -0,0 +1,194 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineOrderTemplateLogs struct {
+	api.Api
+}
+
+// GetPage 获取委托下单模板列表
+// @Summary 获取委托下单模板列表
+// @Description 获取委托下单模板列表
+// @Tags 委托下单模板
+// @Param name query string false "模板名称"
+// @Param userId query int64 false "用户id"
+// @Param type query int64 false "模板类型:1=单独添加;2=批量添加"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineOrderTemplateLogs}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-order-template-logs [get]
+// @Security Bearer
+func (e LineOrderTemplateLogs) GetPage(c *gin.Context) {
+    req := dto.LineOrderTemplateLogsGetPageReq{}
+    s := service.LineOrderTemplateLogs{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineOrderTemplateLogs, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取委托下单模板失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取委托下单模板
+// @Summary 获取委托下单模板
+// @Description 获取委托下单模板
+// @Tags 委托下单模板
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineOrderTemplateLogs} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-order-template-logs/{id} [get]
+// @Security Bearer
+func (e LineOrderTemplateLogs) Get(c *gin.Context) {
+	req := dto.LineOrderTemplateLogsGetReq{}
+	s := service.LineOrderTemplateLogs{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineOrderTemplateLogs
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取委托下单模板失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建委托下单模板
+// @Summary 创建委托下单模板
+// @Description 创建委托下单模板
+// @Tags 委托下单模板
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineOrderTemplateLogsInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-order-template-logs [post]
+// @Security Bearer
+func (e LineOrderTemplateLogs) Insert(c *gin.Context) {
+    req := dto.LineOrderTemplateLogsInsertReq{}
+    s := service.LineOrderTemplateLogs{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建委托下单模板失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改委托下单模板
+// @Summary 修改委托下单模板
+// @Description 修改委托下单模板
+// @Tags 委托下单模板
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineOrderTemplateLogsUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-order-template-logs/{id} [put]
+// @Security Bearer
+func (e LineOrderTemplateLogs) Update(c *gin.Context) {
+    req := dto.LineOrderTemplateLogsUpdateReq{}
+    s := service.LineOrderTemplateLogs{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改委托下单模板失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除委托下单模板
+// @Summary 删除委托下单模板
+// @Description 删除委托下单模板
+// @Tags 委托下单模板
+// @Param data body dto.LineOrderTemplateLogsDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-order-template-logs [delete]
+// @Security Bearer
+func (e LineOrderTemplateLogs) Delete(c *gin.Context) {
+    s := service.LineOrderTemplateLogs{}
+    req := dto.LineOrderTemplateLogsDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除委托下单模板失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_pre_order.go b/app/admin/apis/line_pre_order.go
new file mode 100644
index 0000000..735983a
--- /dev/null
+++ b/app/admin/apis/line_pre_order.go
@@ -0,0 +1,613 @@
+package apis
+
+import (
+	"fmt"
+	"go-admin/common/const/rediskey"
+	"go-admin/common/global"
+	"go-admin/common/helper"
+	"strings"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LinePreOrder struct {
+	api.Api
+}
+
+// GetPage 获取委托管理列表
+// @Summary 获取委托管理列表
+// @Description 获取委托管理列表
+// @Tags 委托管理
+// @Param apiId query string false "api用户"
+// @Param symbol query string false "交易对"
+// @Param quoteSymbol query string false "计较货币"
+// @Param signPriceType query string false "对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"
+// @Param rate query string false "下单百分比"
+// @Param site query string false "购买方向:BUY=买;SELL=卖"
+// @Param orderSn query string false "订单号"
+// @Param orderType query string false "订单类型:1=现货;2=合约;3=合约止盈;4=合约止损;5=现货止盈;6=现货止损;7=止损补仓;8=现货加仓;9=现货平仓;10 = 合约止损补仓,11=合约加仓;12=合约平仓"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LinePreOrder}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-pre-order [get]
+// @Security Bearer
+func (e LinePreOrder) GetPage(c *gin.Context) {
+	req := dto.LinePreOrderGetPageReq{}
+	s := service.LinePreOrder{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LinePreOrder, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取委托管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// GetOrderPage 获取LinePreOrder列表
+func (e LinePreOrder) GetOrderPage(c *gin.Context) {
+	req := dto.LinePreOrderGetPageReq{}
+	s := service.LinePreOrder{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LinePreOrder, 0)
+	var count int64
+
+	err = s.GetOrderPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取委托管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+func (e LinePreOrder) GetChildOrderList(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.GetChildOrderReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	if req.Id <= 0 {
+		e.Error(500, err, "参数错误")
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LinePreOrder, 0)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = s.GetChildList(&req, p, &list)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取子订单信息失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(list, "操作成功")
+}
+
+// Get 获取委托管理
+// @Summary 获取委托管理
+// @Description 获取委托管理
+// @Tags 委托管理
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LinePreOrder} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-pre-order/{id} [get]
+// @Security Bearer
+func (e LinePreOrder) Get(c *gin.Context) {
+	req := dto.LinePreOrderGetReq{}
+	s := service.LinePreOrder{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LinePreOrder
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取委托管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert 创建委托管理
+// @Summary 创建委托管理
+// @Description 创建委托管理
+// @Tags 委托管理
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LinePreOrderInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-pre-order [post]
+// @Security Bearer
+func (e LinePreOrder) Insert(c *gin.Context) {
+	req := dto.LinePreOrderInsertReq{}
+	s := service.LinePreOrder{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建委托管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改委托管理
+// @Summary 修改委托管理
+// @Description 修改委托管理
+// @Tags 委托管理
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LinePreOrderUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-pre-order/{id} [put]
+// @Security Bearer
+func (e LinePreOrder) Update(c *gin.Context) {
+	req := dto.LinePreOrderUpdateReq{}
+	s := service.LinePreOrder{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改委托管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "修改成功")
+}
+
+// Delete 删除委托管理
+// @Summary 删除委托管理
+// @Description 删除委托管理
+// @Tags 委托管理
+// @Param data body dto.LinePreOrderDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-pre-order [delete]
+// @Security Bearer
+func (e LinePreOrder) Delete(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.LinePreOrderDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除委托管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+// AddPreOrder 单个添加
+func (e LinePreOrder) AddPreOrder(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.LineAddPreOrderReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = req.CheckParams()
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	errs := make([]error, 0)
+	errStr := make([]string, 0)
+	var tickerSymbol string
+	if req.SymbolType == global.SYMBOL_SPOT {
+		tickerSymbol = helper.DefaultRedis.Get(rediskey.SpotSymbolTicker).Val()
+	} else {
+		tickerSymbol = helper.DefaultRedis.Get(rediskey.FutSymbolTicker).Val()
+	}
+	s.AddPreOrder(&req, p, &errs, tickerSymbol)
+
+	if len(errs) > 0 {
+		//e.Logger.Error(err)
+		for _, err2 := range errs {
+			errStr = append(errStr, err2.Error())
+		}
+		e.Error(500, nil, strings.Join(errStr, ","))
+		return
+	}
+	e.OK(nil, "操作成功")
+}
+
+// BatchAddOrder 批量添加
+func (e LinePreOrder) BatchAddOrder(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.LineBatchAddPreOrderReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = req.CheckParams()
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	errs := make([]error, 0)
+	errStr := make([]string, 0)
+	s.AddBatchPreOrder(&req, p, &errs)
+	if len(errs) > 0 {
+		//e.Logger.Error(err)
+		for _, err2 := range errs {
+			errStr = append(errStr, err2.Error())
+		}
+		e.Error(500, nil, strings.Join(errStr, ","))
+		return
+	}
+	e.OK(nil, "操作成功")
+}
+
+// QuickAddPreOrder 模板快速下单
+func (e LinePreOrder) QuickAddPreOrder(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.QuickAddPreOrderReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	if req.Ids == "" {
+		e.Error(500, err, "参数错误")
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	errs := make([]error, 0)
+	errStr := make([]string, 0)
+	err = s.QuickAddPreOrder(&req, p, &errs)
+	if len(errs) > 0 {
+		//e.Logger.Error(err)
+		for _, err2 := range errs {
+			errStr = append(errStr, err2.Error())
+		}
+		e.Error(500, nil, strings.Join(errStr, ","))
+		return
+	}
+	e.OK(nil, "操作成功")
+
+}
+
+// Lever 设置杠杆
+func (e LinePreOrder) Lever(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.LeverReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = req.CheckParams()
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	errs := make([]error, 0)
+	errStr := make([]string, 0)
+	p := actions.GetPermissionFromContext(c)
+
+	s.Lever(&req, p, &errs)
+	if len(errs) > 0 {
+		for _, err2 := range errs {
+			errStr = append(errStr, err2.Error())
+		}
+		e.Error(500, nil, strings.Join(errStr, ","))
+		return
+	}
+	e.OK(nil, "操作成功")
+}
+
+// MarginType 设置仓位模式
+func (e LinePreOrder) MarginType(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.MarginTypeReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = req.CheckParams()
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	errs := make([]error, 0)
+	errStr := make([]string, 0)
+	p := actions.GetPermissionFromContext(c)
+
+	s.MarginType(&req, p, &errs)
+	if len(errs) > 0 {
+		for _, err2 := range errs {
+			errStr = append(errStr, err2.Error())
+		}
+		e.Error(500, nil, strings.Join(errStr, ","))
+		return
+	}
+	e.OK(nil, "操作成功")
+}
+
+// CancelOpenOrder 取消指定交易对的委托
+func (e LinePreOrder) CancelOpenOrder(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.CancelOpenOrderReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	if req.ApiId <= 0 {
+		e.Error(500, err, "参数错误")
+		return
+	}
+	errs := make([]error, 0)
+	errStr := make([]string, 0)
+	s.CancelOpenOrder(&req, &errs)
+	if len(errs) > 0 {
+		for _, err2 := range errs {
+			errStr = append(errStr, err2.Error())
+		}
+		e.Error(500, nil, strings.Join(errStr, ","))
+		return
+	}
+	e.OK(nil, "操作成功")
+}
+
+// ClearAll 一键清除数据
+func (e LinePreOrder) ClearAll(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.MarginTypeReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = s.ClearAll()
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(nil, "操作成功")
+}
+
+// ManuallyCover 手动加仓
+func (e LinePreOrder) ManuallyCover(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.ManuallyCover{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = req.CheckParams()
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	errs := make([]error, 0)
+	errStr := make([]string, 0)
+
+	s.ManuallyCover(req, p, &errs)
+	if len(errs) > 0 {
+		for _, err2 := range errs {
+			errStr = append(errStr, err2.Error())
+		}
+		e.Error(500, nil, strings.Join(errStr, ","))
+		return
+	}
+	e.OK(nil, "操作成功")
+}
+
+// ClosePosition 平仓
+func (e LinePreOrder) ClosePosition(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.ClosePosition{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = req.CheckParams()
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	errs := make([]error, 0)
+	errStr := make([]string, 0)
+	if req.CloseType == 1 {
+		s.SpotClosePosition(&req, &errs)
+	} else {
+		s.FutClosePosition(&req, &errs)
+	}
+	if len(errs) > 0 {
+		for _, err2 := range errs {
+			errStr = append(errStr, err2.Error())
+		}
+		e.Error(500, nil, strings.Join(errStr, ","))
+		return
+	}
+	e.OK(nil, "操作成功")
+}
+
+// ClearUnTriggered 清除待触发的交易对
+func (e LinePreOrder) ClearUnTriggered(c *gin.Context) {
+	s := service.LinePreOrder{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	err = s.ClearUnTriggered()
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(nil, "操作成功")
+}
+
+func (e LinePreOrder) QueryOrder(c *gin.Context) {
+	s := service.LinePreOrder{}
+	req := dto.QueryOrderReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	res, err := s.QueryOrder(&req)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(res, "操作成功")
+}
diff --git a/app/admin/apis/line_pre_order_status.go b/app/admin/apis/line_pre_order_status.go
new file mode 100644
index 0000000..2388989
--- /dev/null
+++ b/app/admin/apis/line_pre_order_status.go
@@ -0,0 +1,191 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LinePreOrderStatus struct {
+	api.Api
+}
+
+// GetPage 获取订单状态信息列表
+// @Summary 获取订单状态信息列表
+// @Description 获取订单状态信息列表
+// @Tags 订单状态信息
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LinePreOrderStatus}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-pre-order-status [get]
+// @Security Bearer
+func (e LinePreOrderStatus) GetPage(c *gin.Context) {
+    req := dto.LinePreOrderStatusGetPageReq{}
+    s := service.LinePreOrderStatus{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LinePreOrderStatus, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取订单状态信息失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取订单状态信息
+// @Summary 获取订单状态信息
+// @Description 获取订单状态信息
+// @Tags 订单状态信息
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LinePreOrderStatus} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-pre-order-status/{id} [get]
+// @Security Bearer
+func (e LinePreOrderStatus) Get(c *gin.Context) {
+	req := dto.LinePreOrderStatusGetReq{}
+	s := service.LinePreOrderStatus{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LinePreOrderStatus
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取订单状态信息失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建订单状态信息
+// @Summary 创建订单状态信息
+// @Description 创建订单状态信息
+// @Tags 订单状态信息
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LinePreOrderStatusInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-pre-order-status [post]
+// @Security Bearer
+func (e LinePreOrderStatus) Insert(c *gin.Context) {
+    req := dto.LinePreOrderStatusInsertReq{}
+    s := service.LinePreOrderStatus{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建订单状态信息失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改订单状态信息
+// @Summary 修改订单状态信息
+// @Description 修改订单状态信息
+// @Tags 订单状态信息
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LinePreOrderStatusUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-pre-order-status/{id} [put]
+// @Security Bearer
+func (e LinePreOrderStatus) Update(c *gin.Context) {
+    req := dto.LinePreOrderStatusUpdateReq{}
+    s := service.LinePreOrderStatus{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改订单状态信息失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除订单状态信息
+// @Summary 删除订单状态信息
+// @Description 删除订单状态信息
+// @Tags 订单状态信息
+// @Param data body dto.LinePreOrderStatusDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-pre-order-status [delete]
+// @Security Bearer
+func (e LinePreOrderStatus) Delete(c *gin.Context) {
+    s := service.LinePreOrderStatus{}
+    req := dto.LinePreOrderStatusDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除订单状态信息失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_pre_script.go b/app/admin/apis/line_pre_script.go
new file mode 100644
index 0000000..3fbfc6d
--- /dev/null
+++ b/app/admin/apis/line_pre_script.go
@@ -0,0 +1,193 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LinePreScript struct {
+	api.Api
+}
+
+// GetPage 获取委托下单脚本记录表列表
+// @Summary 获取委托下单脚本记录表列表
+// @Description 获取委托下单脚本记录表列表
+// @Tags 委托下单脚本记录表
+// @Param apiId query int64 false "api用户"
+// @Param status query string false "执行状态:0=等待执行,1=执行中,2=执行结束"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LinePreScript}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-pre-script [get]
+// @Security Bearer
+func (e LinePreScript) GetPage(c *gin.Context) {
+    req := dto.LinePreScriptGetPageReq{}
+    s := service.LinePreScript{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LinePreScript, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取委托下单脚本记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取委托下单脚本记录表
+// @Summary 获取委托下单脚本记录表
+// @Description 获取委托下单脚本记录表
+// @Tags 委托下单脚本记录表
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LinePreScript} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-pre-script/{id} [get]
+// @Security Bearer
+func (e LinePreScript) Get(c *gin.Context) {
+	req := dto.LinePreScriptGetReq{}
+	s := service.LinePreScript{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LinePreScript
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取委托下单脚本记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建委托下单脚本记录表
+// @Summary 创建委托下单脚本记录表
+// @Description 创建委托下单脚本记录表
+// @Tags 委托下单脚本记录表
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LinePreScriptInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-pre-script [post]
+// @Security Bearer
+func (e LinePreScript) Insert(c *gin.Context) {
+    req := dto.LinePreScriptInsertReq{}
+    s := service.LinePreScript{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建委托下单脚本记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改委托下单脚本记录表
+// @Summary 修改委托下单脚本记录表
+// @Description 修改委托下单脚本记录表
+// @Tags 委托下单脚本记录表
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LinePreScriptUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-pre-script/{id} [put]
+// @Security Bearer
+func (e LinePreScript) Update(c *gin.Context) {
+    req := dto.LinePreScriptUpdateReq{}
+    s := service.LinePreScript{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改委托下单脚本记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除委托下单脚本记录表
+// @Summary 删除委托下单脚本记录表
+// @Description 删除委托下单脚本记录表
+// @Tags 委托下单脚本记录表
+// @Param data body dto.LinePreScriptDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-pre-script [delete]
+// @Security Bearer
+func (e LinePreScript) Delete(c *gin.Context) {
+    s := service.LinePreScript{}
+    req := dto.LinePreScriptDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除委托下单脚本记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_price_limit.go b/app/admin/apis/line_price_limit.go
new file mode 100644
index 0000000..e59b546
--- /dev/null
+++ b/app/admin/apis/line_price_limit.go
@@ -0,0 +1,213 @@
+package apis
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LinePriceLimit struct {
+	api.Api
+}
+
+// GetPage 获取涨跌幅列表
+// @Summary 获取涨跌幅列表
+// @Description 获取涨跌幅列表
+// @Tags 涨跌幅
+// @Param symbol query string false "交易对"
+// @Param type query string false "类型:1=现货,2=合约"
+// @Param directionStatus query string false "方向:1=涨,2=跌"
+// @Param range query string false "幅度"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LinePriceLimit}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-price-limit [get]
+// @Security Bearer
+func (e LinePriceLimit) GetPage(c *gin.Context) {
+	req := dto.LinePriceLimitGetPageReq{}
+	s := service.LinePriceLimit{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LinePriceLimit, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取涨跌幅失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取涨跌幅
+// @Summary 获取涨跌幅
+// @Description 获取涨跌幅
+// @Tags 涨跌幅
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LinePriceLimit} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-price-limit/{id} [get]
+// @Security Bearer
+func (e LinePriceLimit) Get(c *gin.Context) {
+	req := dto.LinePriceLimitGetReq{}
+	s := service.LinePriceLimit{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LinePriceLimit
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取涨跌幅失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert 创建涨跌幅
+// @Summary 创建涨跌幅
+// @Description 创建涨跌幅
+// @Tags 涨跌幅
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LinePriceLimitInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-price-limit [post]
+// @Security Bearer
+func (e LinePriceLimit) Insert(c *gin.Context) {
+	req := dto.LinePriceLimitInsertReq{}
+	s := service.LinePriceLimit{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建涨跌幅失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改涨跌幅
+// @Summary 修改涨跌幅
+// @Description 修改涨跌幅
+// @Tags 涨跌幅
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LinePriceLimitUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-price-limit/{id} [put]
+// @Security Bearer
+func (e LinePriceLimit) Update(c *gin.Context) {
+	req := dto.LinePriceLimitUpdateReq{}
+	s := service.LinePriceLimit{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改涨跌幅失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "修改成功")
+}
+
+// Delete 删除涨跌幅
+// @Summary 删除涨跌幅
+// @Description 删除涨跌幅
+// @Tags 涨跌幅
+// @Param data body dto.LinePriceLimitDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-price-limit [delete]
+// @Security Bearer
+func (e LinePriceLimit) Delete(c *gin.Context) {
+	s := service.LinePriceLimit{}
+	req := dto.LinePriceLimitDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除涨跌幅失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+func (e LinePriceLimit) UpRange(c *gin.Context) {
+	s := service.LinePriceLimit{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = s.UpRange()
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("更新涨跌幅失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(nil, "操作成功")
+}
diff --git a/app/admin/apis/line_recharge.go b/app/admin/apis/line_recharge.go
new file mode 100644
index 0000000..45c7cfc
--- /dev/null
+++ b/app/admin/apis/line_recharge.go
@@ -0,0 +1,191 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineRecharge struct {
+	api.Api
+}
+
+// GetPage 获取充值记录表列表
+// @Summary 获取充值记录表列表
+// @Description 获取充值记录表列表
+// @Tags 充值记录表
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineRecharge}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-recharge [get]
+// @Security Bearer
+func (e LineRecharge) GetPage(c *gin.Context) {
+    req := dto.LineRechargeGetPageReq{}
+    s := service.LineRecharge{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineRecharge, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取充值记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取充值记录表
+// @Summary 获取充值记录表
+// @Description 获取充值记录表
+// @Tags 充值记录表
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineRecharge} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-recharge/{id} [get]
+// @Security Bearer
+func (e LineRecharge) Get(c *gin.Context) {
+	req := dto.LineRechargeGetReq{}
+	s := service.LineRecharge{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineRecharge
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取充值记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建充值记录表
+// @Summary 创建充值记录表
+// @Description 创建充值记录表
+// @Tags 充值记录表
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineRechargeInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-recharge [post]
+// @Security Bearer
+func (e LineRecharge) Insert(c *gin.Context) {
+    req := dto.LineRechargeInsertReq{}
+    s := service.LineRecharge{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建充值记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改充值记录表
+// @Summary 修改充值记录表
+// @Description 修改充值记录表
+// @Tags 充值记录表
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineRechargeUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-recharge/{id} [put]
+// @Security Bearer
+func (e LineRecharge) Update(c *gin.Context) {
+    req := dto.LineRechargeUpdateReq{}
+    s := service.LineRecharge{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改充值记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除充值记录表
+// @Summary 删除充值记录表
+// @Description 删除充值记录表
+// @Tags 充值记录表
+// @Param data body dto.LineRechargeDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-recharge [delete]
+// @Security Bearer
+func (e LineRecharge) Delete(c *gin.Context) {
+    s := service.LineRecharge{}
+    req := dto.LineRechargeDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除充值记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_symbol.go b/app/admin/apis/line_symbol.go
new file mode 100644
index 0000000..6aff8df
--- /dev/null
+++ b/app/admin/apis/line_symbol.go
@@ -0,0 +1,497 @@
+package apis
+
+import (
+	"errors"
+	"fmt"
+	"go-admin/common/const/rediskey"
+	"go-admin/common/global"
+	"go-admin/common/helper"
+	"go-admin/config/serverinit"
+	models2 "go-admin/models"
+	"go-admin/pkg/utility"
+	"go-admin/services/binanceservice"
+	"strings"
+
+	"github.com/bytedance/sonic"
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"github.com/shopspring/decimal"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineSymbol struct {
+	api.Api
+}
+
+// GetPage 获取交易对管理列表
+// @Summary 获取交易对管理列表
+// @Description 获取交易对管理列表
+// @Tags 交易对管理
+// @Param symbol query string false "交易对"
+// @Param baseAsset query string false "基础货币"
+// @Param quoteAsset query string false "计价货币"
+// @Param type query string false "交易对类型"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineSymbol}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-symbol [get]
+// @Security Bearer
+func (e LineSymbol) GetPage(c *gin.Context) {
+	req := dto.LineSymbolGetPageReq{}
+	s := service.LineSymbol{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineSymbol, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取交易对管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取交易对管理
+// @Summary 获取交易对管理
+// @Description 获取交易对管理
+// @Tags 交易对管理
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineSymbol} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-symbol/{id} [get]
+// @Security Bearer
+func (e LineSymbol) Get(c *gin.Context) {
+	req := dto.LineSymbolGetReq{}
+	s := service.LineSymbol{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineSymbol
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取交易对管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert 创建交易对管理
+// @Summary 创建交易对管理
+// @Description 创建交易对管理
+// @Tags 交易对管理
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineSymbolInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-symbol [post]
+// @Security Bearer
+func (e LineSymbol) Insert(c *gin.Context) {
+	req := dto.LineSymbolInsertReq{}
+	s := service.LineSymbol{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建交易对管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改交易对管理
+// @Summary 修改交易对管理
+// @Description 修改交易对管理
+// @Tags 交易对管理
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineSymbolUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-symbol/{id} [put]
+// @Security Bearer
+func (e LineSymbol) Update(c *gin.Context) {
+	req := dto.LineSymbolUpdateReq{}
+	s := service.LineSymbol{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改交易对管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "修改成功")
+}
+
+// Delete 删除交易对管理
+// @Summary 删除交易对管理
+// @Description 删除交易对管理
+// @Tags 交易对管理
+// @Param data body dto.LineSymbolDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-symbol [delete]
+// @Security Bearer
+func (e LineSymbol) Delete(c *gin.Context) {
+	s := service.LineSymbol{}
+	req := dto.LineSymbolDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除交易对管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+// SyncSpotSymbol  同步交易对
+func (e LineSymbol) SyncSpotSymbol(c *gin.Context) {
+	s := service.LineSymbol{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	tradeSets, deleteSymbols := serverinit.SpotCurrencyInit()
+	symbols := make([]models.LineSymbol, 0)
+
+	sysConfig := service.SysConfig{Service: s.Service}
+	var req = new(dto.SysConfigByKeyReq)
+	var resp = new(dto.GetSysConfigByKEYForServiceResp)
+	req.ConfigKey = "quote_volume_24hr"
+	sysConfig.GetWithKey(req, resp)
+	symbolBlack := make([]models.LineSymbolBlack, 0)
+	e.Orm.Model(&models.LineSymbolBlack{}).Where("type = 1").Find(&symbolBlack)
+
+	type Ticker struct {
+		Symbol string `json:"symbol"`
+		Price  string `json:"price"`
+	}
+	tickerSymbol := helper.DefaultRedis.Get(rediskey.SpotSymbolTicker).Val()
+	tickerSymbolMaps := make([]Ticker, 0)
+	sonic.Unmarshal([]byte(tickerSymbol), &tickerSymbolMaps)
+
+	for symbol, tradeSet := range tradeSets {
+		var lineSymbol models.LineSymbol
+		err := e.Orm.Model(&models.LineSymbol{}).Where("symbol = ? AND type = 1", symbol).Find(&lineSymbol).Error
+		if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+			continue
+		}
+		key := fmt.Sprintf("%s:%s", global.TICKER_SPOT, symbol)
+
+		//判断是否在黑名单里面
+		for _, black := range symbolBlack {
+			if black.Symbol == symbol {
+				helper.DefaultRedis.DeleteString(key)
+				deleteSymbols = append(deleteSymbols, symbol)
+				continue
+			}
+		}
+		val := helper.DefaultRedis.Get(key).Val()
+		var spotTicker24h models2.TradeSet
+		sonic.Unmarshal([]byte(val), &spotTicker24h)
+		//成交量
+		if spotTicker24h.Currency == "USDT" {
+			if utility.StringToFloat64(spotTicker24h.QuoteVolume) < utility.StringToFloat64(resp.ConfigValue) {
+				helper.DefaultRedis.DeleteString(key)
+				deleteSymbols = append(deleteSymbols, symbol)
+				continue
+			}
+		} else {
+
+			var tickerPrice decimal.Decimal
+			for _, symbolMap := range tickerSymbolMaps {
+				if symbolMap.Symbol == strings.ToUpper(spotTicker24h.Currency+"USDT") {
+					tickerPrice, _ = decimal.NewFromString(symbolMap.Price)
+				}
+			}
+			if tickerPrice.GreaterThan(decimal.Zero) {
+				mul := decimal.NewFromFloat(utility.StringToFloat64(spotTicker24h.QuoteVolume)).Mul(tickerPrice)
+				if mul.LessThan(decimal.NewFromFloat(utility.StringToFloat64(resp.ConfigValue))) {
+					helper.DefaultRedis.DeleteString(key)
+					deleteSymbols = append(deleteSymbols, symbol)
+					continue
+				}
+			}
+		}
+		if lineSymbol.Id <= 0 {
+			lineSymbol.Symbol = symbol
+			lineSymbol.BaseAsset = tradeSet.Coin
+			lineSymbol.QuoteAsset = tradeSet.Currency
+			lineSymbol.Switch = "1"
+			lineSymbol.Type = "1"
+			if lineSymbol.Symbol == "" {
+				continue
+			}
+			symbols = append(symbols, lineSymbol)
+		}
+	}
+	if len(deleteSymbols) > 0 {
+		for _, symbol := range deleteSymbols {
+			//如果在交易对组里面
+			//var symbolGroup []models.LineSymbolGroup
+			groups := make([]models.LineSymbolGroup, 0)
+			e.Orm.Model(&models.LineSymbolGroup{}).Find(&groups)
+			for _, group := range groups {
+				if group.Id > 0 && strings.Contains(group.Symbol, symbol) {
+					split := strings.Split(group.Symbol, ",")
+					value := utility.RemoveByValue(split, symbol)
+					join := strings.Join(value, ",")
+					e.Orm.Model(&models.LineSymbolGroup{}).Where("id = ?", group.Id).Update("symbol", join)
+				}
+			}
+			e.Orm.Model(&models.LineSymbol{}).Where("symbol = ? AND type = 1", symbol).Unscoped().Delete(&models.LineSymbol{})
+		}
+	}
+
+	if len(symbols) > 0 {
+		err = e.Orm.Model(&models.LineSymbol{}).Omit("api_id").Create(&symbols).Error
+		if err != nil {
+			e.Error(500, err, err.Error())
+			return
+		}
+	}
+	e.OK(nil, "操作成功")
+}
+
+// SyncFutSymbol 更新合约交易对
+func (e LineSymbol) SyncFutSymbol(c *gin.Context) {
+	s := service.LineSymbol{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	tradeSets := make(map[string]models2.TradeSet, 0)
+	//获取交易对
+	err = binanceservice.GetAndReloadSymbols(&tradeSets)
+	//获取交易对24小时行情
+	deleteSymbols, err := binanceservice.InitSymbolsTicker24h(&tradeSets)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	sysConfig := service.SysConfig{Service: s.Service}
+	var req = new(dto.SysConfigByKeyReq)
+	var resp = new(dto.GetSysConfigByKEYForServiceResp)
+	req.ConfigKey = "quote_volume_24hr"
+	sysConfig.GetWithKey(req, resp)
+	symbols := make([]models.LineSymbol, 0)
+	symbolBlack := make([]models.LineSymbolBlack, 0)
+
+	type Ticker struct {
+		Symbol string `json:"symbol"`
+		Price  string `json:"price"`
+	}
+	tickerSymbol := helper.DefaultRedis.Get(rediskey.FutSymbolTicker).Val()
+	tickerSymbolMaps := make([]Ticker, 0)
+	sonic.Unmarshal([]byte(tickerSymbol), &tickerSymbolMaps)
+
+	e.Orm.Model(&models.LineSymbolBlack{}).Where("type = 1").Find(&symbolBlack)
+	for symbol, tradeSet := range tradeSets {
+		var lineSymbol models.LineSymbol
+		err := e.Orm.Model(&models.LineSymbol{}).Where("symbol = ? AND type = 2", symbol).Find(&lineSymbol).Error
+		if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+			continue
+		}
+		key := fmt.Sprintf("%s:%s", global.TICKER_FUTURES, symbol)
+
+		//判断是否在黑名单里面
+		for _, black := range symbolBlack {
+			if black.Symbol == symbol {
+				helper.DefaultRedis.DeleteString(key)
+				deleteSymbols = append(deleteSymbols, symbol)
+				continue
+			}
+		}
+		val := helper.DefaultRedis.Get(key).Val()
+		var spotTicker24h models2.TradeSet
+		sonic.Unmarshal([]byte(val), &spotTicker24h)
+		//成交量
+		if spotTicker24h.Currency == "USDT" {
+			if utility.StringToFloat64(spotTicker24h.QuoteVolume) < utility.StringToFloat64(resp.ConfigValue) {
+				helper.DefaultRedis.DeleteString(key)
+				deleteSymbols = append(deleteSymbols, symbol)
+				continue
+			}
+		} else {
+			var tickerPrice decimal.Decimal
+			for _, symbolMap := range tickerSymbolMaps {
+				if symbolMap.Symbol == strings.ToUpper(spotTicker24h.Currency+"USDT") {
+					tickerPrice, _ = decimal.NewFromString(symbolMap.Price)
+				}
+			}
+			if tickerPrice.GreaterThan(decimal.Zero) {
+				mul := decimal.NewFromFloat(utility.StringToFloat64(spotTicker24h.QuoteVolume)).Mul(tickerPrice)
+				if mul.LessThan(decimal.NewFromFloat(utility.StringToFloat64(resp.ConfigValue))) {
+					helper.DefaultRedis.DeleteString(key)
+					deleteSymbols = append(deleteSymbols, symbol)
+					continue
+				}
+			}
+		}
+
+		if lineSymbol.Id <= 0 {
+			lineSymbol.Symbol = symbol
+			lineSymbol.BaseAsset = tradeSet.Coin
+			lineSymbol.QuoteAsset = tradeSet.Currency
+			lineSymbol.Switch = "1"
+			lineSymbol.Type = "2"
+			if lineSymbol.Symbol == "" {
+				continue
+			}
+			symbols = append(symbols, lineSymbol)
+		}
+	}
+
+	if len(deleteSymbols) > 0 {
+		for _, symbol := range deleteSymbols {
+			//如果在交易对组里面
+			groups := make([]models.LineSymbolGroup, 0)
+			//var symbolGroup []models.LineSymbolGroup
+			sql := "SELECT * FROM line_symbol_group WHERE FIND_IN_SET( ? , symbol) AND type = 2 AND deleted_at is NULL;"
+			e.Orm.Model(&models.LineSymbolGroup{}).Exec(sql, symbol).Find(&groups)
+			for _, group := range groups {
+				if group.Id > 0 {
+					split := strings.Split(group.Symbol, ",")
+					value := utility.RemoveByValue(split, symbol)
+					join := strings.Join(value, ",")
+					e.Orm.Model(&models.LineSymbolGroup{}).Where("id = ?", group.Id).Update("symbol", join)
+				}
+			}
+			e.Orm.Model(&models.LineSymbol{}).Where("symbol = ? AND type = 2", symbol).Unscoped().Delete(&models.LineSymbol{})
+		}
+	}
+
+	if len(symbols) > 0 {
+		err = e.Orm.Model(&models.LineSymbol{}).Omit("api_id").Create(&symbols).Error
+		if err != nil {
+			e.Error(500, err, err.Error())
+			return
+		}
+	}
+	e.OK(nil, "操作成功")
+}
+
+// GetSymbol 获取现货和合约都有的交易对
+func (e LineSymbol) GetSymbol(c *gin.Context) {
+	s := service.LineSymbol{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	data, err := s.GetSymbol()
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(data, "操作成功")
+}
+
+// GetSameSymbol 获取现货和合约都有的交易对
+func (e LineSymbol) GetSameSymbol(c *gin.Context) {
+	req := dto.LineSymbolGetPageReq{}
+	s := service.LineSymbol{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineSymbol, 0)
+	var count int64
+
+	err = s.GetSamePage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取交易对管理失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
diff --git a/app/admin/apis/line_symbol_black.go b/app/admin/apis/line_symbol_black.go
new file mode 100644
index 0000000..6c1c95a
--- /dev/null
+++ b/app/admin/apis/line_symbol_black.go
@@ -0,0 +1,193 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineSymbolBlack struct {
+	api.Api
+}
+
+// GetPage 获取交易对黑名单列表
+// @Summary 获取交易对黑名单列表
+// @Description 获取交易对黑名单列表
+// @Tags 交易对黑名单
+// @Param symbol query string false "交易对"
+// @Param type query string false "类型:1=现货,2=合约"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineSymbolBlack}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-symbol-black [get]
+// @Security Bearer
+func (e LineSymbolBlack) GetPage(c *gin.Context) {
+    req := dto.LineSymbolBlackGetPageReq{}
+    s := service.LineSymbolBlack{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineSymbolBlack, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取交易对黑名单失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取交易对黑名单
+// @Summary 获取交易对黑名单
+// @Description 获取交易对黑名单
+// @Tags 交易对黑名单
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineSymbolBlack} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-symbol-black/{id} [get]
+// @Security Bearer
+func (e LineSymbolBlack) Get(c *gin.Context) {
+	req := dto.LineSymbolBlackGetReq{}
+	s := service.LineSymbolBlack{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineSymbolBlack
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取交易对黑名单失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建交易对黑名单
+// @Summary 创建交易对黑名单
+// @Description 创建交易对黑名单
+// @Tags 交易对黑名单
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineSymbolBlackInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-symbol-black [post]
+// @Security Bearer
+func (e LineSymbolBlack) Insert(c *gin.Context) {
+    req := dto.LineSymbolBlackInsertReq{}
+    s := service.LineSymbolBlack{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建交易对黑名单失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改交易对黑名单
+// @Summary 修改交易对黑名单
+// @Description 修改交易对黑名单
+// @Tags 交易对黑名单
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineSymbolBlackUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-symbol-black/{id} [put]
+// @Security Bearer
+func (e LineSymbolBlack) Update(c *gin.Context) {
+    req := dto.LineSymbolBlackUpdateReq{}
+    s := service.LineSymbolBlack{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改交易对黑名单失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除交易对黑名单
+// @Summary 删除交易对黑名单
+// @Description 删除交易对黑名单
+// @Tags 交易对黑名单
+// @Param data body dto.LineSymbolBlackDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-symbol-black [delete]
+// @Security Bearer
+func (e LineSymbolBlack) Delete(c *gin.Context) {
+    s := service.LineSymbolBlack{}
+    req := dto.LineSymbolBlackDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除交易对黑名单失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_symbol_group.go b/app/admin/apis/line_symbol_group.go
new file mode 100644
index 0000000..2dc803d
--- /dev/null
+++ b/app/admin/apis/line_symbol_group.go
@@ -0,0 +1,192 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineSymbolGroup struct {
+	api.Api
+}
+
+// GetPage 获取交易对组列表列表
+// @Summary 获取交易对组列表列表
+// @Description 获取交易对组列表列表
+// @Tags 交易对组列表
+// @Param type query string false "类型:1=现货,2=合约"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineSymbolGroup}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-symbol-group [get]
+// @Security Bearer
+func (e LineSymbolGroup) GetPage(c *gin.Context) {
+    req := dto.LineSymbolGroupGetPageReq{}
+    s := service.LineSymbolGroup{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineSymbolGroup, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取交易对组列表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取交易对组列表
+// @Summary 获取交易对组列表
+// @Description 获取交易对组列表
+// @Tags 交易对组列表
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineSymbolGroup} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-symbol-group/{id} [get]
+// @Security Bearer
+func (e LineSymbolGroup) Get(c *gin.Context) {
+	req := dto.LineSymbolGroupGetReq{}
+	s := service.LineSymbolGroup{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineSymbolGroup
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取交易对组列表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建交易对组列表
+// @Summary 创建交易对组列表
+// @Description 创建交易对组列表
+// @Tags 交易对组列表
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineSymbolGroupInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-symbol-group [post]
+// @Security Bearer
+func (e LineSymbolGroup) Insert(c *gin.Context) {
+    req := dto.LineSymbolGroupInsertReq{}
+    s := service.LineSymbolGroup{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建交易对组列表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改交易对组列表
+// @Summary 修改交易对组列表
+// @Description 修改交易对组列表
+// @Tags 交易对组列表
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineSymbolGroupUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-symbol-group/{id} [put]
+// @Security Bearer
+func (e LineSymbolGroup) Update(c *gin.Context) {
+    req := dto.LineSymbolGroupUpdateReq{}
+    s := service.LineSymbolGroup{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改交易对组列表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除交易对组列表
+// @Summary 删除交易对组列表
+// @Description 删除交易对组列表
+// @Tags 交易对组列表
+// @Param data body dto.LineSymbolGroupDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-symbol-group [delete]
+// @Security Bearer
+func (e LineSymbolGroup) Delete(c *gin.Context) {
+    s := service.LineSymbolGroup{}
+    req := dto.LineSymbolGroupDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除交易对组列表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_system_setting.go b/app/admin/apis/line_system_setting.go
new file mode 100644
index 0000000..bbe1ee3
--- /dev/null
+++ b/app/admin/apis/line_system_setting.go
@@ -0,0 +1,191 @@
+package apis
+
+import (
+	"fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineSystemSetting struct {
+	api.Api
+}
+
+// GetPage 获取挂单配置列表
+// @Summary 获取挂单配置列表
+// @Description 获取挂单配置列表
+// @Tags 挂单配置
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineSystemSetting}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-system-setting [get]
+// @Security Bearer
+func (e LineSystemSetting) GetPage(c *gin.Context) {
+	req := dto.LineSystemSettingGetPageReq{}
+	s := service.LineSystemSetting{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineSystemSetting, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取挂单配置失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取挂单配置
+// @Summary 获取挂单配置
+// @Description 获取挂单配置
+// @Tags 挂单配置
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineSystemSetting} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-system-setting/{id} [get]
+// @Security Bearer
+func (e LineSystemSetting) Get(c *gin.Context) {
+	req := dto.LineSystemSettingGetReq{}
+	s := service.LineSystemSetting{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineSystemSetting
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取挂单配置失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert 创建挂单配置
+// @Summary 创建挂单配置
+// @Description 创建挂单配置
+// @Tags 挂单配置
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineSystemSettingInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-system-setting [post]
+// @Security Bearer
+func (e LineSystemSetting) Insert(c *gin.Context) {
+	req := dto.LineSystemSettingInsertReq{}
+	s := service.LineSystemSetting{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建挂单配置失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改挂单配置
+// @Summary 修改挂单配置
+// @Description 修改挂单配置
+// @Tags 挂单配置
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineSystemSettingUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-system-setting/{id} [put]
+// @Security Bearer
+func (e LineSystemSetting) Update(c *gin.Context) {
+	req := dto.LineSystemSettingUpdateReq{}
+	s := service.LineSystemSetting{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改挂单配置失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "修改成功")
+}
+
+// Delete 删除挂单配置
+// @Summary 删除挂单配置
+// @Description 删除挂单配置
+// @Tags 挂单配置
+// @Param data body dto.LineSystemSettingDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-system-setting [delete]
+// @Security Bearer
+func (e LineSystemSetting) Delete(c *gin.Context) {
+	s := service.LineSystemSetting{}
+	req := dto.LineSystemSettingDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除挂单配置失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_uduncoin.go b/app/admin/apis/line_uduncoin.go
new file mode 100644
index 0000000..91da4a2
--- /dev/null
+++ b/app/admin/apis/line_uduncoin.go
@@ -0,0 +1,191 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineUduncoin struct {
+	api.Api
+}
+
+// GetPage 获取【u盾支持的币种信息】列表
+// @Summary 获取【u盾支持的币种信息】列表
+// @Description 获取【u盾支持的币种信息】列表
+// @Tags 【u盾支持的币种信息】
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineUduncoin}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-uduncoin [get]
+// @Security Bearer
+func (e LineUduncoin) GetPage(c *gin.Context) {
+    req := dto.LineUduncoinGetPageReq{}
+    s := service.LineUduncoin{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineUduncoin, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取【u盾支持的币种信息】失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取【u盾支持的币种信息】
+// @Summary 获取【u盾支持的币种信息】
+// @Description 获取【u盾支持的币种信息】
+// @Tags 【u盾支持的币种信息】
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineUduncoin} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-uduncoin/{id} [get]
+// @Security Bearer
+func (e LineUduncoin) Get(c *gin.Context) {
+	req := dto.LineUduncoinGetReq{}
+	s := service.LineUduncoin{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineUduncoin
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取【u盾支持的币种信息】失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建【u盾支持的币种信息】
+// @Summary 创建【u盾支持的币种信息】
+// @Description 创建【u盾支持的币种信息】
+// @Tags 【u盾支持的币种信息】
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineUduncoinInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-uduncoin [post]
+// @Security Bearer
+func (e LineUduncoin) Insert(c *gin.Context) {
+    req := dto.LineUduncoinInsertReq{}
+    s := service.LineUduncoin{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建【u盾支持的币种信息】失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改【u盾支持的币种信息】
+// @Summary 修改【u盾支持的币种信息】
+// @Description 修改【u盾支持的币种信息】
+// @Tags 【u盾支持的币种信息】
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineUduncoinUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-uduncoin/{id} [put]
+// @Security Bearer
+func (e LineUduncoin) Update(c *gin.Context) {
+    req := dto.LineUduncoinUpdateReq{}
+    s := service.LineUduncoin{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改【u盾支持的币种信息】失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除【u盾支持的币种信息】
+// @Summary 删除【u盾支持的币种信息】
+// @Description 删除【u盾支持的币种信息】
+// @Tags 【u盾支持的币种信息】
+// @Param data body dto.LineUduncoinDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-uduncoin [delete]
+// @Security Bearer
+func (e LineUduncoin) Delete(c *gin.Context) {
+    s := service.LineUduncoin{}
+    req := dto.LineUduncoinDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除【u盾支持的币种信息】失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_user.go b/app/admin/apis/line_user.go
new file mode 100644
index 0000000..bdeef5d
--- /dev/null
+++ b/app/admin/apis/line_user.go
@@ -0,0 +1,191 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineUser struct {
+	api.Api
+}
+
+// GetPage 获取会员表列表
+// @Summary 获取会员表列表
+// @Description 获取会员表列表
+// @Tags 会员表
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineUser}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-user [get]
+// @Security Bearer
+func (e LineUser) GetPage(c *gin.Context) {
+    req := dto.LineUserGetPageReq{}
+    s := service.LineUser{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineUser, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取会员表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取会员表
+// @Summary 获取会员表
+// @Description 获取会员表
+// @Tags 会员表
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineUser} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-user/{id} [get]
+// @Security Bearer
+func (e LineUser) Get(c *gin.Context) {
+	req := dto.LineUserGetReq{}
+	s := service.LineUser{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineUser
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取会员表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建会员表
+// @Summary 创建会员表
+// @Description 创建会员表
+// @Tags 会员表
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineUserInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-user [post]
+// @Security Bearer
+func (e LineUser) Insert(c *gin.Context) {
+    req := dto.LineUserInsertReq{}
+    s := service.LineUser{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建会员表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改会员表
+// @Summary 修改会员表
+// @Description 修改会员表
+// @Tags 会员表
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineUserUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-user/{id} [put]
+// @Security Bearer
+func (e LineUser) Update(c *gin.Context) {
+    req := dto.LineUserUpdateReq{}
+    s := service.LineUser{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改会员表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除会员表
+// @Summary 删除会员表
+// @Description 删除会员表
+// @Tags 会员表
+// @Param data body dto.LineUserDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-user [delete]
+// @Security Bearer
+func (e LineUser) Delete(c *gin.Context) {
+    s := service.LineUser{}
+    req := dto.LineUserDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除会员表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_user_funding_trend.go b/app/admin/apis/line_user_funding_trend.go
new file mode 100644
index 0000000..d034be4
--- /dev/null
+++ b/app/admin/apis/line_user_funding_trend.go
@@ -0,0 +1,191 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineUserFundingTrend struct {
+	api.Api
+}
+
+// GetPage 获取用户资金走势列表
+// @Summary 获取用户资金走势列表
+// @Description 获取用户资金走势列表
+// @Tags 用户资金走势
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineUserFundingTrend}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-user-funding-trend [get]
+// @Security Bearer
+func (e LineUserFundingTrend) GetPage(c *gin.Context) {
+    req := dto.LineUserFundingTrendGetPageReq{}
+    s := service.LineUserFundingTrend{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineUserFundingTrend, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取用户资金走势失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取用户资金走势
+// @Summary 获取用户资金走势
+// @Description 获取用户资金走势
+// @Tags 用户资金走势
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineUserFundingTrend} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-user-funding-trend/{id} [get]
+// @Security Bearer
+func (e LineUserFundingTrend) Get(c *gin.Context) {
+	req := dto.LineUserFundingTrendGetReq{}
+	s := service.LineUserFundingTrend{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineUserFundingTrend
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取用户资金走势失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建用户资金走势
+// @Summary 创建用户资金走势
+// @Description 创建用户资金走势
+// @Tags 用户资金走势
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineUserFundingTrendInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-user-funding-trend [post]
+// @Security Bearer
+func (e LineUserFundingTrend) Insert(c *gin.Context) {
+    req := dto.LineUserFundingTrendInsertReq{}
+    s := service.LineUserFundingTrend{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建用户资金走势失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改用户资金走势
+// @Summary 修改用户资金走势
+// @Description 修改用户资金走势
+// @Tags 用户资金走势
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineUserFundingTrendUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-user-funding-trend/{id} [put]
+// @Security Bearer
+func (e LineUserFundingTrend) Update(c *gin.Context) {
+    req := dto.LineUserFundingTrendUpdateReq{}
+    s := service.LineUserFundingTrend{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改用户资金走势失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除用户资金走势
+// @Summary 删除用户资金走势
+// @Description 删除用户资金走势
+// @Tags 用户资金走势
+// @Param data body dto.LineUserFundingTrendDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-user-funding-trend [delete]
+// @Security Bearer
+func (e LineUserFundingTrend) Delete(c *gin.Context) {
+    s := service.LineUserFundingTrend{}
+    req := dto.LineUserFundingTrendDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除用户资金走势失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_user_profit_logs.go b/app/admin/apis/line_user_profit_logs.go
new file mode 100644
index 0000000..de17c12
--- /dev/null
+++ b/app/admin/apis/line_user_profit_logs.go
@@ -0,0 +1,196 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineUserProfitLogs struct {
+	api.Api
+}
+
+// GetPage 获取会员盈利记录表列表
+// @Summary 获取会员盈利记录表列表
+// @Description 获取会员盈利记录表列表
+// @Tags 会员盈利记录表
+// @Param userId query int64 false "line_user 表的id"
+// @Param apiId query int64 false "line_apiuser 表的id"
+// @Param preOrderId query int64 false "line_pre_order 主订单id"
+// @Param num query string false "成交数量"
+// @Param symbol query string false "交易对"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineUserProfitLogs}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-user-profit-logs [get]
+// @Security Bearer
+func (e LineUserProfitLogs) GetPage(c *gin.Context) {
+    req := dto.LineUserProfitLogsGetPageReq{}
+    s := service.LineUserProfitLogs{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineUserProfitLogs, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取会员盈利记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取会员盈利记录表
+// @Summary 获取会员盈利记录表
+// @Description 获取会员盈利记录表
+// @Tags 会员盈利记录表
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineUserProfitLogs} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-user-profit-logs/{id} [get]
+// @Security Bearer
+func (e LineUserProfitLogs) Get(c *gin.Context) {
+	req := dto.LineUserProfitLogsGetReq{}
+	s := service.LineUserProfitLogs{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineUserProfitLogs
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取会员盈利记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建会员盈利记录表
+// @Summary 创建会员盈利记录表
+// @Description 创建会员盈利记录表
+// @Tags 会员盈利记录表
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineUserProfitLogsInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-user-profit-logs [post]
+// @Security Bearer
+func (e LineUserProfitLogs) Insert(c *gin.Context) {
+    req := dto.LineUserProfitLogsInsertReq{}
+    s := service.LineUserProfitLogs{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建会员盈利记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改会员盈利记录表
+// @Summary 修改会员盈利记录表
+// @Description 修改会员盈利记录表
+// @Tags 会员盈利记录表
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineUserProfitLogsUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-user-profit-logs/{id} [put]
+// @Security Bearer
+func (e LineUserProfitLogs) Update(c *gin.Context) {
+    req := dto.LineUserProfitLogsUpdateReq{}
+    s := service.LineUserProfitLogs{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改会员盈利记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除会员盈利记录表
+// @Summary 删除会员盈利记录表
+// @Description 删除会员盈利记录表
+// @Tags 会员盈利记录表
+// @Param data body dto.LineUserProfitLogsDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-user-profit-logs [delete]
+// @Security Bearer
+func (e LineUserProfitLogs) Delete(c *gin.Context) {
+    s := service.LineUserProfitLogs{}
+    req := dto.LineUserProfitLogsDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除会员盈利记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/line_wallet.go b/app/admin/apis/line_wallet.go
new file mode 100644
index 0000000..f3e5531
--- /dev/null
+++ b/app/admin/apis/line_wallet.go
@@ -0,0 +1,191 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type LineWallet struct {
+	api.Api
+}
+
+// GetPage 获取用户钱包地址列表
+// @Summary 获取用户钱包地址列表
+// @Description 获取用户钱包地址列表
+// @Tags 用户钱包地址
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.LineWallet}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-wallet [get]
+// @Security Bearer
+func (e LineWallet) GetPage(c *gin.Context) {
+    req := dto.LineWalletGetPageReq{}
+    s := service.LineWallet{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.LineWallet, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取用户钱包地址失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取用户钱包地址
+// @Summary 获取用户钱包地址
+// @Description 获取用户钱包地址
+// @Tags 用户钱包地址
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.LineWallet} "{"code": 200, "data": [...]}"
+// @Router /api/v1/line-wallet/{id} [get]
+// @Security Bearer
+func (e LineWallet) Get(c *gin.Context) {
+	req := dto.LineWalletGetReq{}
+	s := service.LineWallet{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.LineWallet
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取用户钱包地址失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建用户钱包地址
+// @Summary 创建用户钱包地址
+// @Description 创建用户钱包地址
+// @Tags 用户钱包地址
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.LineWalletInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/line-wallet [post]
+// @Security Bearer
+func (e LineWallet) Insert(c *gin.Context) {
+    req := dto.LineWalletInsertReq{}
+    s := service.LineWallet{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建用户钱包地址失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改用户钱包地址
+// @Summary 修改用户钱包地址
+// @Description 修改用户钱包地址
+// @Tags 用户钱包地址
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.LineWalletUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/line-wallet/{id} [put]
+// @Security Bearer
+func (e LineWallet) Update(c *gin.Context) {
+    req := dto.LineWalletUpdateReq{}
+    s := service.LineWallet{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改用户钱包地址失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除用户钱包地址
+// @Summary 删除用户钱包地址
+// @Description 删除用户钱包地址
+// @Tags 用户钱包地址
+// @Param data body dto.LineWalletDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/line-wallet [delete]
+// @Security Bearer
+func (e LineWallet) Delete(c *gin.Context) {
+    s := service.LineWallet{}
+    req := dto.LineWalletDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除用户钱包地址失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/sys_api.go b/app/admin/apis/sys_api.go
new file mode 100644
index 0000000..c2d3474
--- /dev/null
+++ b/app/admin/apis/sys_api.go
@@ -0,0 +1,148 @@
+package apis
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type SysApi struct {
+	api.Api
+}
+
+// GetPage 获取接口管理列表
+// @Summary 获取接口管理列表
+// @Description 获取接口管理列表
+// @Tags 接口管理
+// @Param name query string false "名称"
+// @Param title query string false "标题"
+// @Param path query string false "地址"
+// @Param action query string false "类型"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.SysApi}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-api [get]
+// @Security Bearer
+func (e SysApi) GetPage(c *gin.Context) {
+	s := service.SysApi{}
+	req := dto.SysApiGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	//数据权限检查
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.SysApi, 0)
+	var count int64
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取接口管理
+// @Summary 获取接口管理
+// @Description 获取接口管理
+// @Tags 接口管理
+// @Param id path string false "id"
+// @Success 200 {object} response.Response{data=models.SysApi} "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-api/{id} [get]
+// @Security Bearer
+func (e SysApi) Get(c *gin.Context) {
+	req := dto.SysApiGetReq{}
+	s := service.SysApi{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	var object models.SysApi
+	err = s.Get(&req, p, &object).Error
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.OK(object, "查询成功")
+}
+
+// Update 修改接口管理
+// @Summary 修改接口管理
+// @Description 修改接口管理
+// @Tags 接口管理
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.SysApiUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/sys-api/{id} [put]
+// @Security Bearer
+func (e SysApi) Update(c *gin.Context) {
+	req := dto.SysApiUpdateReq{}
+	s := service.SysApi{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, "更新失败")
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// DeleteSysApi 删除接口管理
+// @Summary 删除接口管理
+// @Description 删除接口管理
+// @Tags 接口管理
+// @Param data body dto.SysApiDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/sys-api [delete]
+// @Security Bearer
+func (e SysApi) DeleteSysApi(c *gin.Context) {
+	req := dto.SysApiDeleteReq{}
+	s := service.SysApi{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, "删除失败")
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
\ No newline at end of file
diff --git a/app/admin/apis/sys_config.go b/app/admin/apis/sys_config.go
new file mode 100644
index 0000000..0a95c8b
--- /dev/null
+++ b/app/admin/apis/sys_config.go
@@ -0,0 +1,313 @@
+package apis
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+)
+
+type SysConfig struct {
+	api.Api
+}
+
+// GetPage 获取配置管理列表
+// @Summary 获取配置管理列表
+// @Description 获取配置管理列表
+// @Tags 配置管理
+// @Param configName query string false "名称"
+// @Param configKey query string false "key"
+// @Param configType query string false "类型"
+// @Param isFrontend query int false "是否前端"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.SysApi}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-config [get]
+// @Security Bearer
+func (e SysConfig) GetPage(c *gin.Context) {
+	s := service.SysConfig{}
+	req := dto.SysConfigGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+
+	list := make([]models.SysConfig, 0)
+	var count int64
+	err = s.GetPage(&req, &list, &count)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取配置管理
+// @Summary 获取配置管理
+// @Description 获取配置管理
+// @Tags 配置管理
+// @Param id path string false "id"
+// @Success 200 {object} response.Response{data=models.SysConfig} "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-config/{id} [get]
+// @Security Bearer
+func (e SysConfig) Get(c *gin.Context) {
+	req := dto.SysConfigGetReq{}
+	s := service.SysConfig{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.SysConfig
+
+	err = s.Get(&req, &object)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert 创建配置管理
+// @Summary 创建配置管理
+// @Description 创建配置管理
+// @Tags 配置管理
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.SysConfigControl true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "创建成功"}"
+// @Router /api/v1/sys-config [post]
+// @Security Bearer
+func (e SysConfig) Insert(c *gin.Context) {
+	s := service.SysConfig{}
+	req := dto.SysConfigControl{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, "创建失败")
+		return
+	}
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改配置管理
+// @Summary 修改配置管理
+// @Description 修改配置管理
+// @Tags 配置管理
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.SysConfigControl true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/sys-config/{id} [put]
+// @Security Bearer
+func (e SysConfig) Update(c *gin.Context) {
+	s := service.SysConfig{}
+	req := dto.SysConfigControl{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	err = s.Update(&req)
+	if err != nil {
+		e.Error(500, err, "更新失败")
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// Delete 删除配置管理
+// @Summary 删除配置管理
+// @Description 删除配置管理
+// @Tags 配置管理
+// @Param ids body []int false "ids"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/sys-config [delete]
+// @Security Bearer
+func (e SysConfig) Delete(c *gin.Context) {
+	s := service.SysConfig{}
+	req := dto.SysConfigDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+
+	err = s.Remove(&req)
+	if err != nil {
+		e.Error(500, err, "删除失败")
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+// Get2SysApp 获取系统配置信息
+// @Summary 获取系统前台配置信息,主要注意这里不在验证权限
+// @Description 获取系统配置信息,主要注意这里不在验证权限
+// @Tags 配置管理
+// @Success 200 {object} response.Response{data=map[string]string} "{"code": 200, "data": [...]}"
+// @Router /api/v1/app-config [get]
+func (e SysConfig) Get2SysApp(c *gin.Context) {
+	req := dto.SysConfigGetToSysAppReq{}
+	s := service.SysConfig{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+	// 控制只读前台的数据
+	req.IsFrontend = "1"
+	list := make([]models.SysConfig, 0)
+	err = s.GetWithKeyList(&req, &list)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	mp := make(map[string]string)
+	for i := 0; i < len(list); i++ {
+		key := list[i].ConfigKey
+		if key != "" {
+			mp[key] = list[i].ConfigValue
+		}
+	}
+	e.OK(mp, "查询成功")
+}
+
+// Get2Set 获取配置
+// @Summary 获取配置
+// @Description 界面操作设置配置值的获取
+// @Tags 配置管理
+// @Accept application/json
+// @Product application/json
+// @Success 200 {object} response.Response{data=map[string]interface{}}	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/set-config [get]
+// @Security Bearer
+func (e SysConfig) Get2Set(c *gin.Context) {
+	s := service.SysConfig{}
+	req := make([]dto.GetSetSysConfigReq, 0)
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = s.GetForSet(&req)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	m := make(map[string]interface{}, 0)
+	for _, v := range req {
+		m[v.ConfigKey] = v.ConfigValue
+	}
+	e.OK(m, "查询成功")
+}
+
+// Update2Set 设置配置
+// @Summary 设置配置
+// @Description 界面操作设置配置值
+// @Tags 配置管理
+// @Accept application/json
+// @Product application/json
+// @Param data body []dto.GetSetSysConfigReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/set-config [put]
+// @Security Bearer
+func (e SysConfig) Update2Set(c *gin.Context) {
+	s := service.SysConfig{}
+	req := make([]dto.GetSetSysConfigReq, 0)
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	err = s.UpdateForSet(&req)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	e.OK("", "更新成功")
+}
+
+// GetSysConfigByKEYForService 根据Key获取SysConfig的Service
+// @Summary 根据Key获取SysConfig的Service
+// @Description 根据Key获取SysConfig的Service
+// @Tags 配置管理
+// @Param configKey path string false "configKey"
+// @Success 200 {object} response.Response{data=dto.SysConfigByKeyReq} "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-config/{id} [get]
+// @Security Bearer
+func (e SysConfig) GetSysConfigByKEYForService(c *gin.Context) {
+	var s = new(service.SysConfig)
+	var req = new(dto.SysConfigByKeyReq)
+	var resp = new(dto.GetSysConfigByKEYForServiceResp)
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(req, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	err = s.GetWithKey(req, resp)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(resp, s.Msg)
+}
diff --git a/app/admin/apis/sys_dept.go b/app/admin/apis/sys_dept.go
new file mode 100644
index 0000000..8f1663f
--- /dev/null
+++ b/app/admin/apis/sys_dept.go
@@ -0,0 +1,238 @@
+package apis
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"go-admin/app/admin/models"
+
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+)
+
+type SysDept struct {
+	api.Api
+}
+
+// GetPage
+// @Summary 分页部门列表数据
+// @Description 分页列表
+// @Tags 部门
+// @Param deptName query string false "deptName"
+// @Param deptId query string false "deptId"
+// @Param position query string false "position"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/dept [get]
+// @Security Bearer
+func (e SysDept) GetPage(c *gin.Context) {
+	s := service.SysDept{}
+	req := dto.SysDeptGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	list := make([]models.SysDept, 0)
+	list, err = s.SetDeptPage(&req)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.OK(list, "查询成功")
+}
+
+// Get
+// @Summary 获取部门数据
+// @Description 获取JSON
+// @Tags 部门
+// @Param deptId path string false "deptId"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/dept/{deptId} [get]
+// @Security Bearer
+func (e SysDept) Get(c *gin.Context) {
+	s := service.SysDept{}
+	req := dto.SysDeptGetReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.SysDept
+
+	err = s.Get(&req, &object)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert 添加部门
+// @Summary 添加部门
+// @Description 获取JSON
+// @Tags 部门
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysDeptInsertReq true "data"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/v1/dept [post]
+// @Security Bearer
+func (e SysDept) Insert(c *gin.Context) {
+	s := service.SysDept{}
+	req := dto.SysDeptInsertReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, "创建失败")
+		return
+	}
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update
+// @Summary 修改部门
+// @Description 获取JSON
+// @Tags 部门
+// @Accept  application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.SysDeptUpdateReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/v1/dept/{deptId} [put]
+// @Security Bearer
+func (e SysDept) Update(c *gin.Context) {
+	s := service.SysDept{}
+	req := dto.SysDeptUpdateReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	err = s.Update(&req)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// Delete
+// @Summary 删除部门
+// @Description 删除数据
+// @Tags 部门
+// @Param data body dto.SysDeptDeleteReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "删除成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "删除失败"}"
+// @Router /api/v1/dept [delete]
+// @Security Bearer
+func (e SysDept) Delete(c *gin.Context) {
+	s := service.SysDept{}
+	req := dto.SysDeptDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	err = s.Remove(&req)
+	if err != nil {
+		e.Error(500, err, "删除失败")
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+// Get2Tree 用户管理 左侧部门树
+func (e SysDept) Get2Tree(c *gin.Context) {
+	s := service.SysDept{}
+	req := dto.SysDeptGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	list := make([]dto.DeptLabel, 0)
+	list, err = s.SetDeptTree(&req)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.OK(list, "")
+}
+
+// GetDeptTreeRoleSelect TODO: 此接口需要调整不应该将list和选中放在一起
+func (e SysDept) GetDeptTreeRoleSelect(c *gin.Context) {
+	s := service.SysDept{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	id, err := pkg.StringToInt(c.Param("roleId"))
+	result, err := s.SetDeptLabel()
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	menuIds := make([]int, 0)
+	if id != 0 {
+		menuIds, err = s.GetWithRoleId(id)
+		if err != nil {
+			e.Error(500, err, err.Error())
+			return
+		}
+	}
+	e.OK(gin.H{
+		"depts":       result,
+		"checkedKeys": menuIds,
+	}, "")
+}
diff --git a/app/admin/apis/sys_dict_data.go b/app/admin/apis/sys_dict_data.go
new file mode 100644
index 0000000..049fe99
--- /dev/null
+++ b/app/admin/apis/sys_dict_data.go
@@ -0,0 +1,220 @@
+package apis
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"go-admin/app/admin/models"
+
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+)
+
+type SysDictData struct {
+	api.Api
+}
+
+// GetPage
+// @Summary 字典数据列表
+// @Description 获取JSON
+// @Tags 字典数据
+// @Param status query string false "status"
+// @Param dictCode query string false "dictCode"
+// @Param dictType query string false "dictType"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/dict/data [get]
+// @Security Bearer
+func (e SysDictData) GetPage(c *gin.Context) {
+	s := service.SysDictData{}
+	req := dto.SysDictDataGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	list := make([]models.SysDictData, 0)
+	var count int64
+	err = s.GetPage(&req, &list, &count)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get
+// @Summary 通过编码获取字典数据
+// @Description 获取JSON
+// @Tags 字典数据
+// @Param dictCode path int true "字典编码"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/dict/data/{dictCode} [get]
+// @Security Bearer
+func (e SysDictData) Get(c *gin.Context) {
+	s := service.SysDictData{}
+	req := dto.SysDictDataGetReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	var object models.SysDictData
+
+	err = s.Get(&req, &object)
+	if err != nil {
+		e.Logger.Warnf("Get error: %s", err.Error())
+		e.Error(500, err, "查询失败")
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert
+// @Summary 添加字典数据
+// @Description 获取JSON
+// @Tags 字典数据
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysDictDataInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/dict/data [post]
+// @Security Bearer
+func (e SysDictData) Insert(c *gin.Context) {
+	s := service.SysDictData{}
+	req := dto.SysDictDataInsertReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetCreateBy(user.GetUserId(c))
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, "创建失败")
+		return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update
+// @Summary 修改字典数据
+// @Description 获取JSON
+// @Tags 字典数据
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysDictDataUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/dict/data/{dictCode} [put]
+// @Security Bearer
+func (e SysDictData) Update(c *gin.Context) {
+	s := service.SysDictData{}
+	req := dto.SysDictDataUpdateReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	err = s.Update(&req)
+	if err != nil {
+		e.Error(500, err, "更新失败")
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// Delete
+// @Summary 删除字典数据
+// @Description 删除数据
+// @Tags 字典数据
+// @Param dictCode body dto.SysDictDataDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/dict/data [delete]
+// @Security Bearer
+func (e SysDictData) Delete(c *gin.Context) {
+	s := service.SysDictData{}
+	req := dto.SysDictDataDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	err = s.Remove(&req)
+	if err != nil {
+		e.Error(500, err, "删除失败")
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+// GetAll 数据字典根据key获取 业务页面使用
+// @Summary 数据字典根据key获取
+// @Description 数据字典根据key获取
+// @Tags 字典数据
+// @Param dictType query int true "dictType"
+// @Success 200 {object} response.Response{data=[]dto.SysDictDataGetAllResp}  "{"code": 200, "data": [...]}"
+// @Router /api/v1/dict-data/option-select [get]
+// @Security Bearer
+func (e SysDictData) GetAll(c *gin.Context) {
+	s := service.SysDictData{}
+	req := dto.SysDictDataGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	list := make([]models.SysDictData, 0)
+	err = s.GetAll(&req, &list)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	l := make([]dto.SysDictDataGetAllResp, 0)
+	for _, i := range list {
+		d := dto.SysDictDataGetAllResp{}
+		e.Translate(i, &d)
+		l = append(l, d)
+	}
+
+	e.OK(l,"查询成功")
+}
diff --git a/app/admin/apis/sys_dict_type.go b/app/admin/apis/sys_dict_type.go
new file mode 100644
index 0000000..b93035e
--- /dev/null
+++ b/app/admin/apis/sys_dict_type.go
@@ -0,0 +1,210 @@
+package apis
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"go-admin/app/admin/models"
+
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+)
+
+type SysDictType struct {
+	api.Api
+}
+
+// GetPage 字典类型列表数据
+// @Summary 字典类型列表数据
+// @Description 获取JSON
+// @Tags 字典类型
+// @Param dictName query string false "dictName"
+// @Param dictId query string false "dictId"
+// @Param dictType query string false "dictType"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/dict/type [get]
+// @Security Bearer
+func (e SysDictType) GetPage(c *gin.Context) {
+	s := service.SysDictType{}
+	req :=dto.SysDictTypeGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	list := make([]models.SysDictType, 0)
+	var count int64
+	err = s.GetPage(&req, &list, &count)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 字典类型通过字典id获取
+// @Summary 字典类型通过字典id获取
+// @Description 获取JSON
+// @Tags 字典类型
+// @Param dictId path int true "字典类型编码"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/dict/type/{dictId} [get]
+// @Security Bearer
+func (e SysDictType) Get(c *gin.Context) {
+	s := service.SysDictType{}
+	req :=dto.SysDictTypeGetReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.SysDictType
+	err = s.Get(&req, &object)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.OK(object, "查询成功")
+}
+
+//Insert 字典类型创建
+// @Summary 添加字典类型
+// @Description 获取JSON
+// @Tags 字典类型
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysDictTypeInsertReq true "data"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/dict/type [post]
+// @Security Bearer
+func (e SysDictType) Insert(c *gin.Context) {
+	s := service.SysDictType{}
+	req :=dto.SysDictTypeInsertReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetCreateBy(user.GetUserId(c))
+	err = s.Insert(&req)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err,fmt.Sprintf(" 创建字典类型失败,详情:%s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update
+// @Summary 修改字典类型
+// @Description 获取JSON
+// @Tags 字典类型
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysDictTypeUpdateReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/dict/type/{dictId} [put]
+// @Security Bearer
+func (e SysDictType) Update(c *gin.Context) {
+	s := service.SysDictType{}
+	req :=dto.SysDictTypeUpdateReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Error(500, err, err.Error())
+		e.Logger.Error(err)
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	err = s.Update(&req)
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// Delete
+// @Summary 删除字典类型
+// @Description 删除数据
+// @Tags 字典类型
+// @Param dictCode body dto.SysDictTypeDeleteReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/dict/type [delete]
+// @Security Bearer
+func (e SysDictType) Delete(c *gin.Context) {
+	s := service.SysDictType{}
+	req :=dto.SysDictTypeDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	err = s.Remove(&req)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+// GetAll
+// @Summary 字典类型全部数据 代码生成使用接口
+// @Description 获取JSON
+// @Tags 字典类型
+// @Param dictName query string false "dictName"
+// @Param dictId query string false "dictId"
+// @Param dictType query string false "dictType"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/dict/type-option-select [get]
+// @Security Bearer
+func (e SysDictType) GetAll(c *gin.Context) {
+	s := service.SysDictType{}
+	req :=dto.SysDictTypeGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	list := make([]models.SysDictType, 0)
+	err = s.GetAll(&req, &list)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(list, "查询成功")
+}
\ No newline at end of file
diff --git a/app/admin/apis/sys_login_log.go b/app/admin/apis/sys_login_log.go
new file mode 100644
index 0000000..6b6b4af
--- /dev/null
+++ b/app/admin/apis/sys_login_log.go
@@ -0,0 +1,110 @@
+package apis
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"go-admin/app/admin/models"
+
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+)
+
+type SysLoginLog struct {
+	api.Api
+}
+
+// GetPage 登录日志列表
+// @Summary 登录日志列表
+// @Description 获取JSON
+// @Tags 登录日志
+// @Param username query string false "用户名"
+// @Param ipaddr query string false "ip地址"
+// @Param loginLocation  query string false "归属地"
+// @Param status query string false "状态"
+// @Param beginTime query string false "开始时间"
+// @Param endTime query string false "结束时间"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-login-log [get]
+// @Security Bearer
+func (e SysLoginLog) GetPage(c *gin.Context) {
+	s := service.SysLoginLog{}
+	req :=dto.SysLoginLogGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	list := make([]models.SysLoginLog, 0)
+	var count int64
+	err = s.GetPage(&req, &list, &count)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 登录日志通过id获取
+// @Summary 登录日志通过id获取
+// @Description 获取JSON
+// @Tags 登录日志
+// @Param id path string false "id"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-login-log/{id} [get]
+// @Security Bearer
+func (e SysLoginLog) Get(c *gin.Context) {
+	s := service.SysLoginLog{}
+	req :=dto.SysLoginLogGetReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.SysLoginLog
+	err = s.Get(&req, &object)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.OK(object, "查询成功")
+}
+
+// Delete 登录日志删除
+// @Summary 登录日志删除
+// @Description 登录日志删除
+// @Tags 登录日志
+// @Param data body dto.SysLoginLogDeleteReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-login-log [delete]
+// @Security Bearer
+func (e SysLoginLog) Delete(c *gin.Context) {
+	s := service.SysLoginLog{}
+	req :=dto.SysLoginLogDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = s.Remove(&req)
+	if err != nil {
+		e.Error(500, err, "删除失败")
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
\ No newline at end of file
diff --git a/app/admin/apis/sys_menu.go b/app/admin/apis/sys_menu.go
new file mode 100644
index 0000000..d6eab24
--- /dev/null
+++ b/app/admin/apis/sys_menu.go
@@ -0,0 +1,287 @@
+package apis
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	"go-admin/app/admin/models"
+
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+)
+
+type SysMenu struct {
+	api.Api
+}
+
+// GetPage Menu列表数据
+// @Summary Menu列表数据
+// @Description 获取JSON
+// @Tags 菜单
+// @Param menuName query string false "menuName"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/menu [get]
+// @Security Bearer
+func (e SysMenu) GetPage(c *gin.Context) {
+	s := service.SysMenu{}
+	req := dto.SysMenuGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var list = make([]models.SysMenu, 0)
+	err = s.GetPage(&req, &list).Error
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.OK(list, "查询成功")
+}
+
+// Get 获取菜单详情
+// @Summary Menu详情数据
+// @Description 获取JSON
+// @Tags 菜单
+// @Param id path string false "id"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/menu/{id} [get]
+// @Security Bearer
+func (e SysMenu) Get(c *gin.Context) {
+	req := dto.SysMenuGetReq{}
+	s := new(service.SysMenu)
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object = models.SysMenu{}
+
+	err = s.Get(&req, &object).Error
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.OK(object, "查询成功")
+}
+
+// Insert 创建菜单
+// @Summary 创建菜单
+// @Description 获取JSON
+// @Tags 菜单
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysMenuInsertReq true "data"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/menu [post]
+// @Security Bearer
+func (e SysMenu) Insert(c *gin.Context) {
+	req := dto.SysMenuInsertReq{}
+	s := new(service.SysMenu)
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+	err = s.Insert(&req).Error
+	if err != nil {
+		e.Error(500, err, "创建失败")
+		return
+	}
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改菜单
+// @Summary 修改菜单
+// @Description 获取JSON
+// @Tags 菜单
+// @Accept  application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.SysMenuUpdateReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/menu/{id} [put]
+// @Security Bearer
+func (e SysMenu) Update(c *gin.Context) {
+	req := dto.SysMenuUpdateReq{}
+	s := new(service.SysMenu)
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	req.SetUpdateBy(user.GetUserId(c))
+	err = s.Update(&req).Error
+	if err != nil {
+		e.Error(500, err, "更新失败")
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// Delete 删除菜单
+// @Summary 删除菜单
+// @Description 删除数据
+// @Tags 菜单
+// @Param data body dto.SysMenuDeleteReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/menu [delete]
+// @Security Bearer
+func (e SysMenu) Delete(c *gin.Context) {
+	control := new(dto.SysMenuDeleteReq)
+	s := new(service.SysMenu)
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(control, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = s.Remove(control).Error
+	if err != nil {
+		e.Logger.Errorf("RemoveSysMenu error, %s", err)
+		e.Error(500, err, "删除失败")
+		return
+	}
+	e.OK(control.GetId(), "删除成功")
+}
+
+// GetMenuRole 根据登录角色名称获取菜单列表数据(左菜单使用)
+// @Summary 根据登录角色名称获取菜单列表数据(左菜单使用)
+// @Description 获取JSON
+// @Tags 菜单
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/menurole [get]
+// @Security Bearer
+func (e SysMenu) GetMenuRole(c *gin.Context) {
+	s := new(service.SysMenu)
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	result, err := s.SetMenuRole(user.GetRoleName(c))
+
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+
+	e.OK(result, "")
+}
+
+//// GetMenuIDS 获取角色对应的菜单id数组
+//// @Summary 获取角色对应的菜单id数组,设置角色权限使用
+//// @Description 获取JSON
+//// @Tags 菜单
+//// @Param id path int true "id"
+//// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+//// @Router /api/v1/menuids/{id} [get]
+//// @Security Bearer
+//func (e SysMenu) GetMenuIDS(c *gin.Context) {
+//	s := new(service.SysMenu)
+//	r := service.SysRole{}
+//	m := dto.SysRoleByName{}
+//	err := e.MakeContext(c).
+//		MakeOrm().
+//		Bind(&m, binding.JSON).
+//		MakeService(&s.Service).
+//		MakeService(&r.Service).
+//		Errors
+//	if err != nil {
+//		e.Logger.Error(err)
+//		e.Error(500, err, err.Error())
+//		return
+//	}
+//	var data models.SysRole
+//	err = r.GetWithName(&m, &data).Error
+//
+//	//data.RoleName = c.GetString("role")
+//	//data.UpdateBy = user.GetUserId(c)
+//	//result, err := data.GetIDS(s.Orm)
+//
+//	if err != nil {
+//		e.Logger.Errorf("GetIDS error, %s", err.Error())
+//		e.Error(500, err, "获取失败")
+//		return
+//	}
+//	e.OK(result, "")
+//}
+
+// GetMenuTreeSelect 根据角色ID查询菜单下拉树结构
+// @Summary 角色修改使用的菜单列表
+// @Description 获取JSON
+// @Tags 菜单
+// @Accept  application/json
+// @Product application/json
+// @Param roleId path int true "roleId"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/menuTreeselect/{roleId} [get]
+// @Security Bearer
+func (e SysMenu) GetMenuTreeSelect(c *gin.Context) {
+	m := service.SysMenu{}
+	r := service.SysRole{}
+	req :=dto.SelectRole{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&m.Service).
+		MakeService(&r.Service).
+		Bind(&req, nil).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	result, err := m.SetLabel()
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+
+	menuIds := make([]int, 0)
+	if req.RoleId != 0 {
+		menuIds, err = r.GetRoleMenuId(req.RoleId)
+		if err != nil {
+			e.Error(500, err, "")
+			return
+		}
+	}
+	e.OK(gin.H{
+		"menus":       result,
+		"checkedKeys": menuIds,
+	}, "获取成功")
+}
\ No newline at end of file
diff --git a/app/admin/apis/sys_opera_log.go b/app/admin/apis/sys_opera_log.go
new file mode 100644
index 0000000..2803924
--- /dev/null
+++ b/app/admin/apis/sys_opera_log.go
@@ -0,0 +1,118 @@
+package apis
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+)
+
+type SysOperaLog struct {
+	api.Api
+}
+
+// GetPage 操作日志列表
+// @Summary 操作日志列表
+// @Description 获取JSON
+// @Tags 操作日志
+// @Param title query string false "title"
+// @Param method query string false "method"
+// @Param requestMethod  query string false "requestMethod"
+// @Param operUrl query string false "operUrl"
+// @Param operIp query string false "operIp"
+// @Param status query string false "status"
+// @Param beginTime query string false "beginTime"
+// @Param endTime query string false "endTime"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-opera-log [get]
+// @Security Bearer
+func (e SysOperaLog) GetPage(c *gin.Context) {
+	s := service.SysOperaLog{}
+	req := new(dto.SysOperaLogGetPageReq)
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	list := make([]models.SysOperaLog, 0)
+	var count int64
+
+	err = s.GetPage(req, &list, &count)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 操作日志通过id获取
+// @Summary 操作日志通过id获取
+// @Description 获取JSON
+// @Tags 操作日志
+// @Param id path string false "id"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-opera-log/{id} [get]
+// @Security Bearer
+func (e SysOperaLog) Get(c *gin.Context) {
+	s := new(service.SysOperaLog)
+	req :=dto.SysOperaLogGetReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.SysOperaLog
+	err = s.Get(&req, &object)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+	e.OK(object, "查询成功")
+}
+
+// Delete 操作日志删除
+// DeleteSysMenu 操作日志删除
+// @Summary 删除操作日志
+// @Description 删除数据
+// @Tags 操作日志
+// @Param data body dto.SysOperaLogDeleteReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-opera-log [delete]
+// @Security Bearer
+func (e SysOperaLog) Delete(c *gin.Context) {
+	s := new(service.SysOperaLog)
+	req :=dto.SysOperaLogDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	err = s.Remove(&req)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500,err, fmt.Sprintf("删除失败!错误详情:%s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
diff --git a/app/admin/apis/sys_post.go b/app/admin/apis/sys_post.go
new file mode 100644
index 0000000..a12d54a
--- /dev/null
+++ b/app/admin/apis/sys_post.go
@@ -0,0 +1,184 @@
+package apis
+
+import (
+	"fmt"
+	
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+)
+
+type SysPost struct {
+	api.Api
+}
+
+// GetPage
+// @Summary 岗位列表数据
+// @Description 获取JSON
+// @Tags 岗位
+// @Param postName query string false "postName"
+// @Param postCode query string false "postCode"
+// @Param postId query string false "postId"
+// @Param status query string false "status"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/post [get]
+// @Security Bearer
+func (e SysPost) GetPage(c *gin.Context) {
+	s := service.SysPost{}
+	req :=dto.SysPostPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	list := make([]models.SysPost, 0)
+	var count int64
+
+	err = s.GetPage(&req, &list, &count)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get
+// @Summary 获取岗位信息
+// @Description 获取JSON
+// @Tags 岗位
+// @Param id path int true "编码"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/post/{postId} [get]
+// @Security Bearer
+func (e SysPost) Get(c *gin.Context) {
+	s := service.SysPost{}
+	req :=dto.SysPostGetReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.SysPost
+
+	err = s.Get(&req, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("岗位信息获取失败!错误详情:%s", err.Error()))
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert
+// @Summary 添加岗位
+// @Description 获取JSON
+// @Tags 岗位
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysPostInsertReq true "data"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/post [post]
+// @Security Bearer
+func (e SysPost) Insert(c *gin.Context) {
+	s := service.SysPost{}
+	req :=dto.SysPostInsertReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetCreateBy(user.GetUserId(c))
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("新建岗位失败!错误详情:%s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update
+// @Summary 修改岗位
+// @Description 获取JSON
+// @Tags 岗位
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysPostUpdateReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/post/{id} [put]
+// @Security Bearer
+func (e SysPost) Update(c *gin.Context) {
+	s := service.SysPost{}
+	req :=dto.SysPostUpdateReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	req.SetUpdateBy(user.GetUserId(c))
+
+	err = s.Update(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("岗位更新失败!错误详情:%s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// Delete
+// @Summary 删除岗位
+// @Description 删除数据
+// @Tags 岗位
+// @Param id body dto.SysPostDeleteReq true "请求参数"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/post [delete]
+// @Security Bearer
+func (e SysPost) Delete(c *gin.Context) {
+	s := service.SysPost{}
+	req :=dto.SysPostDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	err = s.Remove(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("岗位删除失败!错误详情:%s", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
\ No newline at end of file
diff --git a/app/admin/apis/sys_role.go b/app/admin/apis/sys_role.go
new file mode 100644
index 0000000..d7ee1e7
--- /dev/null
+++ b/app/admin/apis/sys_role.go
@@ -0,0 +1,284 @@
+package apis
+
+import (
+	"fmt"
+	"go-admin/common/global"
+	"net/http"
+
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"go-admin/app/admin/models"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+)
+
+type SysRole struct {
+	api.Api
+}
+
+// GetPage
+// @Summary 角色列表数据
+// @Description Get JSON
+// @Tags 角色/Role
+// @Param roleName query string false "roleName"
+// @Param status query string false "status"
+// @Param roleKey query string false "roleKey"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/role [get]
+// @Security Bearer
+func (e SysRole) GetPage(c *gin.Context) {
+	s := service.SysRole{}
+	req := dto.SysRoleGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Form).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	list := make([]models.SysRole, 0)
+	var count int64
+
+	err = s.GetPage(&req, &list, &count)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get
+// @Summary 获取Role数据
+// @Description 获取JSON
+// @Tags 角色/Role
+// @Param roleId path string false "roleId"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/role/{id} [get]
+// @Security Bearer
+func (e SysRole) Get(c *gin.Context) {
+	s := service.SysRole{}
+	req := dto.SysRoleGetReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, fmt.Sprintf(" %s ", err.Error()))
+		return
+	}
+
+	var object models.SysRole
+
+	err = s.Get(&req, &object)
+	if err != nil {
+		e.Error(http.StatusUnprocessableEntity, err, "查询失败")
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert
+// @Summary 创建角色
+// @Description 获取JSON
+// @Tags 角色/Role
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysRoleInsertReq true "data"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/role [post]
+// @Security Bearer
+func (e SysRole) Insert(c *gin.Context) {
+	s := service.SysRole{}
+	req := dto.SysRoleInsertReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// 设置创建人
+	req.CreateBy = user.GetUserId(c)
+	if req.Status == "" {
+		req.Status = "2"
+	}
+	cb := sdk.Runtime.GetCasbinKey(c.Request.Host)
+	err = s.Insert(&req, cb)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, "创建失败,"+err.Error())
+		return
+	}
+	_, err = global.LoadPolicy(c)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, "创建失败,"+err.Error())
+		return
+	}
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改用户角色
+// @Summary 修改用户角色
+// @Description 获取JSON
+// @Tags 角色/Role
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysRoleUpdateReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/role/{id} [put]
+// @Security Bearer
+func (e SysRole) Update(c *gin.Context) {
+	s := service.SysRole{}
+	req := dto.SysRoleUpdateReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, nil, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	cb := sdk.Runtime.GetCasbinKey(c.Request.Host)
+
+	req.SetUpdateBy(user.GetUserId(c))
+
+	err = s.Update(&req, cb)
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+
+	_, err = global.LoadPolicy(c)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, "更新失败,"+err.Error())
+		return
+	}
+
+	e.OK(req.GetId(), "更新成功")
+}
+
+// Delete
+// @Summary 删除用户角色
+// @Description 删除数据
+// @Tags 角色/Role
+// @Param data body dto.SysRoleDeleteReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/role [delete]
+// @Security Bearer
+func (e SysRole) Delete(c *gin.Context) {
+	s := new(service.SysRole)
+	req := dto.SysRoleDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, fmt.Sprintf("删除角色 %v 失败,\r\n失败信息 %s", req.Ids, err.Error()))
+		return
+	}
+
+	cb := sdk.Runtime.GetCasbinKey(c.Request.Host)
+	err = s.Remove(&req, cb)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, "")
+		return
+	}
+
+	e.OK(req.GetId(), fmt.Sprintf("删除角色角色 %v 状态成功!", req.GetId()))
+}
+
+// Update2Status 修改用户角色状态
+// @Summary 修改用户角色
+// @Description 获取JSON
+// @Tags 角色/Role
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.UpdateStatusReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/role-status/{id} [put]
+// @Security Bearer
+func (e SysRole) Update2Status(c *gin.Context) {
+	s := service.SysRole{}
+	req := dto.UpdateStatusReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, fmt.Sprintf("更新角色状态失败,失败原因:%s ", err.Error()))
+		return
+	}
+	req.SetUpdateBy(user.GetUserId(c))
+	err = s.UpdateStatus(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("更新角色状态失败,失败原因:%s ", err.Error()))
+		return
+	}
+	e.OK(req.GetId(), fmt.Sprintf("更新角色 %v 状态成功!", req.GetId()))
+}
+
+// Update2DataScope 更新角色数据权限
+// @Summary 更新角色数据权限
+// @Description 获取JSON
+// @Tags 角色/Role
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.RoleDataScopeReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/role-status/{id} [put]
+// @Security Bearer
+func (e SysRole) Update2DataScope(c *gin.Context) {
+	s := service.SysRole{}
+	req := dto.RoleDataScopeReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	data := &models.SysRole{
+		RoleId:    req.RoleId,
+		DataScope: req.DataScope,
+		DeptIds:   req.DeptIds,
+	}
+	data.UpdateBy = user.GetUserId(c)
+	err = s.UpdateDataScope(&req).Error
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("更新角色数据权限失败!错误详情:%s", err.Error()))
+		return
+	}
+	e.OK(nil, "操作成功")
+}
diff --git a/app/admin/apis/sys_user.go b/app/admin/apis/sys_user.go
new file mode 100644
index 0000000..0cf6fc0
--- /dev/null
+++ b/app/admin/apis/sys_user.go
@@ -0,0 +1,459 @@
+package apis
+
+import (
+	"github.com/gin-gonic/gin/binding"
+	"go-admin/app/admin/models"
+	"golang.org/x/crypto/bcrypt"
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"github.com/google/uuid"
+
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type SysUser struct {
+	api.Api
+}
+
+// GetPage
+// @Summary 列表用户信息数据
+// @Description 获取JSON
+// @Tags 用户
+// @Param username query string false "username"
+// @Success 200 {string} {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-user [get]
+// @Security Bearer
+func (e SysUser) GetPage(c *gin.Context) {
+	s := service.SysUser{}
+	req := dto.SysUserGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	//数据权限检查
+	p := actions.GetPermissionFromContext(c)
+
+	list := make([]models.SysUser, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, "查询失败")
+		return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get
+// @Summary 获取用户
+// @Description 获取JSON
+// @Tags 用户
+// @Param userId path int true "用户编码"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-user/{userId} [get]
+// @Security Bearer
+func (e SysUser) Get(c *gin.Context) {
+	s := service.SysUser{}
+	req := dto.SysUserById{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.SysUser
+	//数据权限检查
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(http.StatusUnprocessableEntity, err, "查询失败")
+		return
+	}
+	e.OK(object, "查询成功")
+}
+
+// Insert
+// @Summary 创建用户
+// @Description 获取JSON
+// @Tags 用户
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysUserInsertReq true "用户数据"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-user [post]
+// @Security Bearer
+func (e SysUser) Insert(c *gin.Context) {
+	s := service.SysUser{}
+	req := dto.SysUserInsertReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+	err = s.Insert(&req)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update
+// @Summary 修改用户数据
+// @Description 获取JSON
+// @Tags 用户
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.SysUserUpdateReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-user/{userId} [put]
+// @Security Bearer
+func (e SysUser) Update(c *gin.Context) {
+	s := service.SysUser{}
+	req := dto.SysUserUpdateReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	req.SetUpdateBy(user.GetUserId(c))
+
+	//数据权限检查
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// Delete
+// @Summary 删除用户数据
+// @Description 删除数据
+// @Tags 用户
+// @Param userId path int true "userId"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys-user/{userId} [delete]
+// @Security Bearer
+func (e SysUser) Delete(c *gin.Context) {
+	s := service.SysUser{}
+	req := dto.SysUserById{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// 设置编辑人
+	req.SetUpdateBy(user.GetUserId(c))
+
+	// 数据权限检查
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+// InsetAvatar
+// @Summary 修改头像
+// @Description 获取JSON
+// @Tags 个人中心
+// @Accept multipart/form-data
+// @Param file formData file true "file"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/user/avatar [post]
+// @Security Bearer
+func (e SysUser) InsetAvatar(c *gin.Context) {
+	s := service.SysUser{}
+	req := dto.UpdateSysUserAvatarReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	// 数据权限检查
+	p := actions.GetPermissionFromContext(c)
+	form, _ := c.MultipartForm()
+	files := form.File["upload[]"]
+	guid := uuid.New().String()
+	filPath := "static/uploadfile/" + guid + ".jpg"
+	for _, file := range files {
+		e.Logger.Debugf("upload avatar file: %s", file.Filename)
+		// 上传文件至指定目录
+		err = c.SaveUploadedFile(file, filPath)
+		if err != nil {
+			e.Logger.Errorf("save file error, %s", err.Error())
+			e.Error(500, err, "")
+			return
+		}
+	}
+	req.UserId = p.UserId
+	req.Avatar = "/" + filPath
+
+	err = s.UpdateAvatar(&req, p)
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+	e.OK(filPath, "修改成功")
+}
+
+// UpdateStatus 修改用户状态
+// @Summary 修改用户状态
+// @Description 获取JSON
+// @Tags 用户
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.UpdateSysUserStatusReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/user/status [put]
+// @Security Bearer
+func (e SysUser) UpdateStatus(c *gin.Context) {
+	s := service.SysUser{}
+	req := dto.UpdateSysUserStatusReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	req.SetUpdateBy(user.GetUserId(c))
+
+	//数据权限检查
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.UpdateStatus(&req, p)
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// ResetPwd 重置用户密码
+// @Summary 重置用户密码
+// @Description 获取JSON
+// @Tags 用户
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.ResetSysUserPwdReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/user/pwd/reset [put]
+// @Security Bearer
+func (e SysUser) ResetPwd(c *gin.Context) {
+	s := service.SysUser{}
+	req := dto.ResetSysUserPwdReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	req.SetUpdateBy(user.GetUserId(c))
+
+	//数据权限检查
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.ResetPwd(&req, p)
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// UpdatePwd
+// @Summary 修改密码
+// @Description 获取JSON
+// @Tags 用户
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.PassWord true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/user/pwd/set [put]
+// @Security Bearer
+func (e SysUser) UpdatePwd(c *gin.Context) {
+	s := service.SysUser{}
+	req := dto.PassWord{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// 数据权限检查
+	p := actions.GetPermissionFromContext(c)
+	var hash []byte
+	if hash, err = bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost); err != nil {
+		req.NewPassword = string(hash)
+	}
+
+	err = s.UpdatePwd(user.GetUserId(c), req.OldPassword, req.NewPassword, p)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(http.StatusForbidden, err, "密码修改失败")
+		return
+	}
+
+	e.OK(nil, "密码修改成功")
+}
+
+// GetProfile
+// @Summary 获取个人中心用户
+// @Description 获取JSON
+// @Tags 个人中心
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/user/profile [get]
+// @Security Bearer
+func (e SysUser) GetProfile(c *gin.Context) {
+	s := service.SysUser{}
+	req := dto.SysUserById{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	req.Id = user.GetUserId(c)
+
+	sysUser := models.SysUser{}
+	roles := make([]models.SysRole, 0)
+	posts := make([]models.SysPost, 0)
+	err = s.GetProfile(&req, &sysUser, &roles, &posts)
+	if err != nil {
+		e.Logger.Errorf("get user profile error, %s", err.Error())
+		e.Error(500, err, "获取用户信息失败")
+		return
+	}
+	e.OK(gin.H{
+		"user":  sysUser,
+		"roles": roles,
+		"posts": posts,
+	}, "查询成功")
+}
+
+// GetInfo
+// @Summary 获取个人信息
+// @Description 获取JSON
+// @Tags 个人中心
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/getinfo [get]
+// @Security Bearer
+func (e SysUser) GetInfo(c *gin.Context) {
+	req := dto.SysUserById{}
+	s := service.SysUser{}
+	r := service.SysRole{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&r.Service).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	var roles = make([]string, 1)
+	roles[0] = user.GetRoleName(c)
+	var permissions = make([]string, 1)
+	permissions[0] = "*:*:*"
+	var buttons = make([]string, 1)
+	buttons[0] = "*:*:*"
+
+	var mp = make(map[string]interface{})
+	mp["roles"] = roles
+	if user.GetRoleName(c) == "admin" || user.GetRoleName(c) == "系统管理员" {
+		mp["permissions"] = permissions
+		mp["buttons"] = buttons
+	} else {
+		list, _ := r.GetById(user.GetRoleId(c))
+		mp["permissions"] = list
+		mp["buttons"] = list
+	}
+	sysUser := models.SysUser{}
+	req.Id = user.GetUserId(c)
+	err = s.Get(&req, p, &sysUser)
+	if err != nil {
+		e.Error(http.StatusUnauthorized, err, "登录失败")
+		return
+	}
+	mp["introduction"] = " am a super administrator"
+	mp["avatar"] = "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
+	if sysUser.Avatar != "" {
+		mp["avatar"] = sysUser.Avatar
+	}
+	mp["userName"] = sysUser.Username
+	mp["userId"] = sysUser.UserId
+	mp["deptId"] = sysUser.DeptId
+	mp["name"] = sysUser.NickName
+	mp["code"] = 200
+	e.OK(mp, "")
+}
diff --git a/app/admin/apis/vts_recharge.go b/app/admin/apis/vts_recharge.go
new file mode 100644
index 0000000..8f36528
--- /dev/null
+++ b/app/admin/apis/vts_recharge.go
@@ -0,0 +1,194 @@
+package apis
+
+import (
+    "fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+)
+
+type VtsRecharge struct {
+	api.Api
+}
+
+// GetPage 获取coinGate充值记录表列表
+// @Summary 获取coinGate充值记录表列表
+// @Description 获取coinGate充值记录表列表
+// @Tags coinGate充值记录表
+// @Param coinCode query string false "币种"
+// @Param orderNo query string false "订单号"
+// @Param adUserId query int64 false "用户id"
+// @Param pageSize query int false "页条数"
+// @Param pageIndex query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]models.VtsRecharge}} "{"code": 200, "data": [...]}"
+// @Router /api/v1/vts-recharge [get]
+// @Security Bearer
+func (e VtsRecharge) GetPage(c *gin.Context) {
+    req := dto.VtsRechargeGetPageReq{}
+    s := service.VtsRecharge{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+   	if err != nil {
+   		e.Logger.Error(err)
+   		e.Error(500, err, err.Error())
+   		return
+   	}
+
+	p := actions.GetPermissionFromContext(c)
+	list := make([]models.VtsRecharge, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取coinGate充值记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 获取coinGate充值记录表
+// @Summary 获取coinGate充值记录表
+// @Description 获取coinGate充值记录表
+// @Tags coinGate充值记录表
+// @Param id path int false "id"
+// @Success 200 {object} response.Response{data=models.VtsRecharge} "{"code": 200, "data": [...]}"
+// @Router /api/v1/vts-recharge/{id} [get]
+// @Security Bearer
+func (e VtsRecharge) Get(c *gin.Context) {
+	req := dto.VtsRechargeGetReq{}
+	s := service.VtsRecharge{}
+    err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object models.VtsRecharge
+
+	p := actions.GetPermissionFromContext(c)
+	err = s.Get(&req, p, &object)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("获取coinGate充值记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK( object, "查询成功")
+}
+
+// Insert 创建coinGate充值记录表
+// @Summary 创建coinGate充值记录表
+// @Description 创建coinGate充值记录表
+// @Tags coinGate充值记录表
+// @Accept application/json
+// @Product application/json
+// @Param data body dto.VtsRechargeInsertReq true "data"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}"
+// @Router /api/v1/vts-recharge [post]
+// @Security Bearer
+func (e VtsRecharge) Insert(c *gin.Context) {
+    req := dto.VtsRechargeInsertReq{}
+    s := service.VtsRecharge{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("创建coinGate充值记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改coinGate充值记录表
+// @Summary 修改coinGate充值记录表
+// @Description 修改coinGate充值记录表
+// @Tags coinGate充值记录表
+// @Accept application/json
+// @Product application/json
+// @Param id path int true "id"
+// @Param data body dto.VtsRechargeUpdateReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}"
+// @Router /api/v1/vts-recharge/{id} [put]
+// @Security Bearer
+func (e VtsRecharge) Update(c *gin.Context) {
+    req := dto.VtsRechargeUpdateReq{}
+    s := service.VtsRecharge{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+	req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("修改coinGate充值记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "修改成功")
+}
+
+// Delete 删除coinGate充值记录表
+// @Summary 删除coinGate充值记录表
+// @Description 删除coinGate充值记录表
+// @Tags coinGate充值记录表
+// @Param data body dto.VtsRechargeDeleteReq true "body"
+// @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}"
+// @Router /api/v1/vts-recharge [delete]
+// @Security Bearer
+func (e VtsRecharge) Delete(c *gin.Context) {
+    s := service.VtsRecharge{}
+    req := dto.VtsRechargeDeleteReq{}
+    err := e.MakeContext(c).
+        MakeOrm().
+        Bind(&req).
+        MakeService(&s.Service).
+        Errors
+    if err != nil {
+        e.Logger.Error(err)
+        e.Error(500, err, err.Error())
+        return
+    }
+
+	// req.SetUpdateBy(user.GetUserId(c))
+	p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("删除coinGate充值记录表失败,\r\n失败信息 %s", err.Error()))
+        return
+	}
+	e.OK( req.GetId(), "删除成功")
+}
diff --git a/app/admin/fronted/line_user.go b/app/admin/fronted/line_user.go
new file mode 100644
index 0000000..8cc610a
--- /dev/null
+++ b/app/admin/fronted/line_user.go
@@ -0,0 +1,581 @@
+package fronted
+
+import (
+	"errors"
+	"fmt"
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/models/sysmodel"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/aduserdb"
+	"go-admin/app/admin/service/common"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/const/rediskey"
+	"go-admin/common/helper"
+	"go-admin/common/service/sysservice/authservice"
+	"go-admin/common/service/sysservice/sysstatuscode"
+	statuscode "go-admin/common/status_code"
+	ext "go-admin/config"
+	"go-admin/models/coingatedto"
+	"go-admin/pkg/cryptohelper/inttostring"
+	"go-admin/pkg/utility"
+	"go-admin/services/binanceservice"
+	"go-admin/services/udunservice"
+
+	"github.com/bytedance/sonic"
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/shopspring/decimal"
+	"gorm.io/gorm"
+)
+
+type LineUserApi struct {
+	api.Api
+}
+
+// Register 用户注册
+func (e LineUserApi) Register(c *gin.Context) {
+	s := service.LineUser{}
+	req := sysmodel.FrontedUserRegisterReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	//校验参数
+	code := req.CheckParams()
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	// 注册前校验
+	pid, code := authservice.UserRegisterBefore(e.Orm, req)
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	req.Pid = pid
+	req.IP = utility.GetIp(c)
+	ok, user := authservice.UserRegister(e.Orm, req)
+	if ok != statuscode.OK {
+		e.Error(ok, nil, sysstatuscode.GetStatusCodeDescription(c, ok))
+		return
+	}
+	resp := map[string]interface{}{
+		"email":      req.Email,
+		"mobile":     req.Phone,
+		"status":     "verify",
+		"login_type": 2,
+		"jwt_token":  "",
+		"jwt_expire": "",
+	}
+	if req.RegisterType == sysmodel.TSmsCode {
+		if req.Pid > 0 {
+			updateSql := `UPDATE line_user SET recommend_num = recommend_num + 1 WHERE id = ?`
+			if err := e.Orm.Exec(updateSql, req.Pid).Error; err != nil {
+				e.Logger.Error(err)
+			}
+		}
+		token, expire, _ := authservice.GenerateToken(user.Id, 1, user.Mobile, user.Mobile, user.Email, req.IP, "PC")
+		resp["jwt_token"] = token
+		resp["jwt_expire"] = expire
+		resp["status"] = "normal"
+	}
+
+	e.OK(resp, "success")
+}
+
+// VerifyEmail 验证邮箱
+func (e LineUserApi) VerifyEmail(c *gin.Context) {
+	s := service.LineUser{}
+	req := dto.FrontedUserVerifyEmailReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	if req.VerifyCode == "" || req.Email == "" {
+		e.Error(statuscode.ParameterInvalid, nil, sysstatuscode.GetStatusCodeDescription(c, statuscode.ParameterInvalid))
+		return
+	}
+	// 核验邮箱验证码
+	code := authservice.UserVerifyEmail(req.Email, req.VerifyCode, e.Orm)
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	ok := s.UserVerifyEmail(req.Email)
+	if ok != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	e.OK(nil, "success")
+
+}
+
+// SendVerifyEmail 发送注册校验邮箱
+func (e LineUserApi) SendVerifyEmail(c *gin.Context) {
+	s := service.LineUser{}
+	req := dto.FrontedSendVerifyEmailReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	code := req.CheckParams()
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	emailCode := inttostring.GenerateRandomString(10)
+	code = authservice.SendRegisterEmail(req.Email, emailCode)
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	e.OK(nil, "success")
+
+}
+
+// SendRegisterSms 发送注册短信
+func (e LineUserApi) SendRegisterSms(c *gin.Context) {
+	s := service.LineUser{}
+	req := dto.FrontedSendVerifySmsReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	code := req.CheckParams()
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+
+	user, _ := aduserdb.GetUserByPhone(e.Orm, req.PhoneAreaCode, req.Phone)
+	if user.Id > 0 {
+		e.Error(statuscode.TheAccountIsAlreadyRegistered, nil, sysstatuscode.GetStatusCodeDescription(c, statuscode.TheAccountIsAlreadyRegistered))
+		return
+	}
+
+	code = authservice.SendGoToneSms(req.Phone, req.PhoneAreaCode)
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	e.OK(nil, "success")
+
+}
+
+// Login 登录
+func (e LineUserApi) Login(c *gin.Context) {
+	s := service.LineUser{}
+	req := dto.FrontedLoginReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	code := req.CheckParams()
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	// 登录前校验
+	user, code, langArg := authservice.UserPwdLoginBefore(e.Orm, req)
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDiscreptionArgs(c, code, langArg))
+		return
+	}
+	token, expire, code := authservice.GenerateToken(user.Id, 1, user.Email, user.Mobile, user.Email, utility.GetIp(c), "PC")
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+		// return app.Fail(ctx, code)
+	}
+	resp := map[string]interface{}{
+		"email":      req.Email,
+		"mobile":     "",
+		"status":     user.Status,
+		"login_type": 2,
+		"jwt_token":  token,
+		"jwt_expire": expire,
+	}
+	e.OK(resp, "success")
+
+}
+
+func (e LineUserApi) UserInfo(c *gin.Context) {
+	userId := common.GetUserId(c)
+	var user models.LineUser
+	err := e.Orm.Model(&models.LineUser{}).Where("id = ?", userId).Find(&user).Error
+	if err != nil && !errors.Is(err, gorm.ErrNotImplemented) {
+		e.Error(statuscode.UserIdInvalid, nil, sysstatuscode.GetStatusCodeDescription(c, statuscode.UserIdInvalid))
+		return
+	}
+
+	if user.Status == "verify" {
+		e.Error(statuscode.UserNotVerify, nil, sysstatuscode.GetStatusCodeDescription(c, statuscode.UserNotVerify))
+		return
+	}
+
+	e.OK(nil, "success")
+}
+
+// AddApiKey 用户手动添加apikey
+func (e LineUserApi) AddApiKey(c *gin.Context) {
+	s := service.LineUser{}
+	req := dto.AddApiKeyReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	code := req.CheckParams()
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+
+	code = s.AddApiKey(common.GetUserId(c), &req)
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	e.OK(nil, "success")
+}
+
+// UpdateApiKey 修改apikey
+func (e LineUserApi) UpdateApiKey(c *gin.Context) {
+	s := service.LineUser{}
+	req := dto.AddApiKeyReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	code := req.CheckParams()
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	code = s.UpdateApiKey(common.GetUserId(c), &req)
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	e.OK(nil, "success")
+
+}
+
+// GetWhiteIp 用户手动获取ip
+func (e LineUserApi) GetWhiteIp(c *gin.Context) {
+	//s := service.LineUser{}
+	configS := service.SysConfig{}
+	//req := dto.AddApiKeyReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&configS.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req := dto.SysConfigByKeyReq{ConfigKey: "sys_user_white_ip"}
+	var resp dto.GetSysConfigByKEYForServiceResp
+	err = configS.GetWithKey(&req, &resp)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	e.OK(resp.ConfigValue, "success")
+
+}
+
+// Info 用户中心
+func (e LineUserApi) Info(c *gin.Context) {
+	s := service.LineUser{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	userId := common.GetUserId(c)
+	binanceAccount := service.BinanceAccount{Service: s.Service}
+
+	//获取用户资金账户资产
+	resp, err := binanceAccount.GetFundingAsset(userId)
+	if err != nil {
+		e.Logger.Error(500, err, err.Error())
+		return
+	}
+	//用户u的余额
+	var tickerData []binanceservice.Ticker
+	val := helper.DefaultRedis.Get(rediskey.SpotSymbolTicker).Val()
+	if val != "" {
+		sonic.Unmarshal([]byte(val), &tickerData)
+	}
+	var usdtBalance decimal.Decimal
+	for i, asset := range resp {
+		symbol := asset.Asset + "USDT"
+		for _, datum := range tickerData {
+			if datum.Symbol == symbol {
+				mul := utility.StringToDecimal(datum.Price).Mul(utility.StringToDecimal(asset.Free))
+				usdtBalance = usdtBalance.Add(mul)
+				resp[i].UsdtValuation = datum.Price
+			}
+		}
+		//if asset.Asset == "USDT" {
+		//	usdt = asset.Free
+		//}
+	}
+
+	// 邀请人数
+	//var inviteNum int64
+	var userinfo models.LineUser
+	e.Orm.Model(&models.LineUser{}).Where("id = ?", userId).Find(&userinfo)
+
+	var apiUserinfo models.LineApiUser
+	e.Orm.Model(&models.LineApiUser{}).Where("user_id = ?", userId).Find(&apiUserinfo)
+	var isAuth bool
+	if apiUserinfo.ApiKey != "" && apiUserinfo.ApiSecret != "" {
+		isAuth = true
+	}
+	//持仓分布
+	var fundingAsset []models.FundingAsset
+	if len(resp) > 10 {
+		fundingAsset = resp[0:10]
+	} else {
+		fundingAsset = resp[0:]
+	}
+
+	//获取盈利情况
+	logs := service.LineUserProfitLogs{Service: s.Service}
+	totalProfit, todayProfit := logs.GetProfitInfoByUserId(userinfo.Id)
+	user := map[string]interface{}{
+		"avatar":      userinfo.Avatar,
+		"invite_num":  userinfo.RecommendNum,
+		"open_status": apiUserinfo.OpenStatus,
+		"is_auth":     isAuth,
+		"invite_url":  fmt.Sprintf("%s/invice_url?invite_code=%s", ext.ExtConfig.Domain, userinfo.InviteCode),
+		"invite_code": userinfo.InviteCode,
+		"api_name":    apiUserinfo.ApiName,
+		"api_key":     inttostring.EncryptString(apiUserinfo.ApiKey, 4, 4),
+		"api_secret":  inttostring.EncryptString(apiUserinfo.ApiSecret, 4, 4),
+	}
+	returnMap := map[string]interface{}{
+		"u_balance":     usdtBalance.Truncate(2),
+		"margin":        userinfo.Money,
+		"userinfo":      user,
+		"funding_asset": fundingAsset,
+		"total_profit":  totalProfit.Float64,
+		"today_profit":  todayProfit.Float64,
+	}
+	e.OK(returnMap, "success")
+
+}
+
+// OpenStatus 开启或者关闭
+func (e LineUserApi) OpenStatus(c *gin.Context) {
+	s := service.LineUser{}
+	req := dto.OpenStatusReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	userId := common.GetUserId(c)
+	var apiUser models.LineApiUser
+	err = e.Orm.Model(&models.LineApiUser{}).Where("user_id = ?", userId).Find(&apiUser).Error
+
+	if apiUser.ApiSecret == "" || apiUser.ApiKey == "" {
+		e.Error(statuscode.UserApiKeyRequired, nil, sysstatuscode.GetStatusCodeDescription(c, statuscode.UserApiKeyRequired))
+		return
+	}
+	err = e.Orm.Model(&models.LineApiUser{}).Where("user_id = ?", userId).Update("open_status", req.Status).Error
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(nil, "success")
+}
+
+// RechargeNetworkList 充值 通过充值币种选择主网络
+func (e LineUserApi) RechargeNetworkList(c *gin.Context) {
+	s := service.LineUser{}
+	req := dto.RechargeListReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	data, code := s.RechargeNetworkList(&req)
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	e.OK(data, "success")
+}
+
+// RechargeNetworkAddress 充值 通过主网ID和用户ID获取交易地址
+func (e LineUserApi) RechargeNetworkAddress(c *gin.Context) {
+	s := service.LineUser{}
+	req := dto.RechargeAddressListReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.UserId = common.GetUserId(c)
+	data, code := s.RechargeNetworkAddress(&req)
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	e.OK(data, "success")
+}
+
+// Notify uDun回调
+func (e LineUserApi) Notify(c *gin.Context) {
+	timestamp := c.PostForm("timestamp")
+	nonce := c.PostForm("nonce")
+	body := c.PostForm("body")
+	sign := c.PostForm("sign")
+	callback := udunservice.TradeCallback(e.Orm, timestamp, nonce, body, sign)
+	c.String(200, callback)
+	//c.Writer.WriteString(callback)
+	return
+}
+
+// FundingTrend 资金走势
+func (e LineUserApi) FundingTrend(c *gin.Context) {
+	s := service.LineUser{}
+	req := dto.RechargeAddressListReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	userId := common.GetUserId(c)
+	data, code := s.FundingTrend(userId)
+	if code != statuscode.OK {
+		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code))
+		return
+	}
+	e.OK(data, "success")
+}
+
+// PreOrder 预下单
+func (e LineUserApi) PreOrder(c *gin.Context) {
+	s := service.LineUser{}
+	req := dto.VtsRechargePreOrderReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	userId := common.GetUserId(c)
+	resp := dto.VtsRechargePreOrderResp{}
+	err = s.PreOrder(userId, &req, &resp)
+	if err != nil {
+		e.Error(500, err, fmt.Sprintf("发起充值失败,\r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(resp, "success")
+}
+
+func (e LineUserApi) CallBack(c *gin.Context) {
+	req := coingatedto.OrderCallBackResponse{}
+	s := service.LineUser{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	err = s.CallBack(&req)
+
+	if err != nil {
+		val, _ := sonic.Marshal(req)
+		e.Logger.Error("回调失败:", err.Error(), " \r\n回调内容:", string(val))
+		e.Error(500, err, fmt.Sprintf("支付回调失败, \r\n失败信息 %s", err.Error()))
+		return
+	}
+
+	e.OK(nil, "")
+}
diff --git a/app/admin/models/binance_account.go b/app/admin/models/binance_account.go
new file mode 100644
index 0000000..c4fc0cf
--- /dev/null
+++ b/app/admin/models/binance_account.go
@@ -0,0 +1,11 @@
+package models
+
+type FundingAsset struct {
+	Asset         string `json:"asset"`
+	Free          string `json:"free"`
+	Locked        string `json:"locked"`
+	Freeze        string `json:"freeze"`
+	Withdrawing   string `json:"withdrawing"`
+	BtcValuation  string `json:"btcValuation"`
+	UsdtValuation string `json:"usdt_valuation"`
+}
diff --git a/app/admin/models/casbin_rule.go b/app/admin/models/casbin_rule.go
new file mode 100644
index 0000000..d9013ee
--- /dev/null
+++ b/app/admin/models/casbin_rule.go
@@ -0,0 +1,16 @@
+package models
+
+type CasbinRule struct {
+	ID    uint   `gorm:"primaryKey;autoIncrement"`
+	Ptype string `gorm:"size:512;uniqueIndex:unique_index"`
+	V0    string `gorm:"size:512;uniqueIndex:unique_index"`
+	V1    string `gorm:"size:512;uniqueIndex:unique_index"`
+	V2    string `gorm:"size:512;uniqueIndex:unique_index"`
+	V3    string `gorm:"size:512;uniqueIndex:unique_index"`
+	V4    string `gorm:"size:512;uniqueIndex:unique_index"`
+	V5    string `gorm:"size:512;uniqueIndex:unique_index"`
+}
+
+func (CasbinRule) TableName() string {
+	return "sys_casbin_rule"
+}
diff --git a/app/admin/models/datascope.go b/app/admin/models/datascope.go
new file mode 100644
index 0000000..8ccd047
--- /dev/null
+++ b/app/admin/models/datascope.go
@@ -0,0 +1,81 @@
+package models
+
+import (
+	"errors"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"gorm.io/gorm"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+)
+
+type DataPermission struct {
+	DataScope string
+	UserId    int
+	DeptId    int
+	RoleId    int
+}
+
+func (e *DataPermission) GetDataScope(tableName string, db *gorm.DB) (*gorm.DB, error) {
+
+	if !config.ApplicationConfig.EnableDP {
+		usageStr := `数据权限已经为您` + pkg.Green(`关闭`) + `,如需开启请参考配置文件字段说明`
+		log.Debug("%s\n", usageStr)
+		return db, nil
+	}
+	user := new(SysUser)
+	role := new(SysRole)
+	err := db.Find(user, e.UserId).Error
+	if err != nil {
+		return nil, errors.New("获取用户数据出错 msg:" + err.Error())
+	}
+	err = db.Find(role, user.RoleId).Error
+	if err != nil {
+		return nil, errors.New("获取用户数据出错 msg:" + err.Error())
+	}
+	if role.DataScope == "2" {
+		db = db.Where(tableName+".create_by in (select sys_user.user_id from sys_role_dept left join sys_user on sys_user.dept_id=sys_role_dept.dept_id where sys_role_dept.role_id = ?)", user.RoleId)
+	}
+	if role.DataScope == "3" {
+		db = db.Where(tableName+".create_by in (SELECT user_id from sys_user where dept_id = ? )", user.DeptId)
+	}
+	if role.DataScope == "4" {
+		db = db.Where(tableName+".create_by in (SELECT user_id from sys_user where sys_user.dept_id in(select dept_id from sys_dept where dept_path like ? ))", "%"+pkg.IntToString(user.DeptId)+"%")
+	}
+	if role.DataScope == "5" || role.DataScope == "" {
+		db = db.Where(tableName+".create_by = ?", e.UserId)
+	}
+
+	return db, nil
+}
+
+//func DataScopes(tableName string, userId int) func(db *gorm.DB) *gorm.DB {
+//	return func(db *gorm.DB) *gorm.DB {
+//		user := new(SysUser)
+//		role := new(SysRole)
+//		user.UserId = userId
+//		err := db.Find(user, userId).Error
+//		if err != nil {
+//			db.Error = errors.New("获取用户数据出错 msg:" + err.Error())
+//			return db
+//		}
+//		err = db.Find(role, user.RoleId).Error
+//		if err != nil {
+//			db.Error = errors.New("获取用户数据出错 msg:" + err.Error())
+//			return db
+//		}
+//		if role.DataScope == "2" {
+//			return db.Where(tableName+".create_by in (select sys_user.user_id from sys_role_dept left join sys_user on sys_user.dept_id=sys_role_dept.dept_id where sys_role_dept.role_id = ?)", user.RoleId)
+//		}
+//		if role.DataScope == "3" {
+//			return db.Where(tableName+".create_by in (SELECT user_id from sys_user where dept_id = ? )", user.DeptId)
+//		}
+//		if role.DataScope == "4" {
+//			return db.Where(tableName+".create_by in (SELECT user_id from sys_user where sys_user.dept_id in(select dept_id from sys_dept where dept_path like ? ))", "%"+pkg.IntToString(user.DeptId)+"%")
+//		}
+//		if role.DataScope == "5" || role.DataScope == "" {
+//			return db.Where(tableName+".create_by = ?", userId)
+//		}
+//		return db
+//	}
+//}
diff --git a/app/admin/models/initdb.go b/app/admin/models/initdb.go
new file mode 100644
index 0000000..cdec260
--- /dev/null
+++ b/app/admin/models/initdb.go
@@ -0,0 +1,55 @@
+package models
+
+import (
+	"fmt"
+	"go-admin/common/global"
+	"gorm.io/gorm"
+	"io/ioutil"
+	"log"
+	"strings"
+)
+
+func InitDb(db *gorm.DB) (err error) {
+	filePath := "config/db.sql"
+	err = ExecSql(db, filePath)
+	if global.Driver == "postgres" {
+		filePath = "config/pg.sql"
+		err = ExecSql(db, filePath)
+	}
+	return err
+}
+
+func ExecSql(db *gorm.DB, filePath string) error {
+	sql, err := Ioutil(filePath)
+	if err != nil {
+		fmt.Println("数据库基础数据初始化脚本读取失败!原因:", err.Error())
+		return err
+	}
+	sqlList := strings.Split(sql, ";")
+	for i := 0; i < len(sqlList)-1; i++ {
+		if strings.Contains(sqlList[i], "--") {
+			fmt.Println(sqlList[i])
+			continue
+		}
+		sql := strings.Replace(sqlList[i]+";", "\n", "", -1)
+		sql = strings.TrimSpace(sql)
+		if err = db.Exec(sql).Error; err != nil {
+			log.Printf("error sql: %s", sql)
+			if !strings.Contains(err.Error(), "Query was empty") {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func Ioutil(filePath string) (string, error) {
+	if contents, err := ioutil.ReadFile(filePath); err == nil {
+		//因为contents是[]byte类型,直接转换成string类型后会多一行空格,需要使用strings.Replace替换换行符
+		result := strings.Replace(string(contents), "\n", "", 1)
+		fmt.Println("Use ioutil.ReadFile to read a file:", result)
+		return result, nil
+	} else {
+		return "", err
+	}
+}
diff --git a/app/admin/models/line_account_setting.go b/app/admin/models/line_account_setting.go
new file mode 100644
index 0000000..0de4b37
--- /dev/null
+++ b/app/admin/models/line_account_setting.go
@@ -0,0 +1,29 @@
+package models
+
+import (
+
+	"go-admin/common/models"
+
+)
+
+type LineAccountSetting struct {
+    models.Model
+    
+    UserName string `json:"userName" gorm:"type:varchar(255);comment:用户"` 
+    Password string `json:"password" gorm:"type:varchar(255);comment:密码"` 
+    models.ModelTime
+    models.ControlBy
+}
+
+func (LineAccountSetting) TableName() string {
+    return "line_account_setting"
+}
+
+func (e *LineAccountSetting) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineAccountSetting) GetId() interface{} {
+	return e.Id
+}
\ No newline at end of file
diff --git a/app/admin/models/line_api_group.go b/app/admin/models/line_api_group.go
new file mode 100644
index 0000000..8c105a2
--- /dev/null
+++ b/app/admin/models/line_api_group.go
@@ -0,0 +1,29 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type LineApiGroup struct {
+	models.Model
+
+	GroupName string `json:"groupName" gorm:"type:varchar(255);comment:用户组名称"`
+	ApiUserId string `json:"apiUserId" gorm:"type:varchar(255);comment:绑定的api账户id"`
+	AApiName  string `json:"a_api_name" gorm:"-"`
+	BApiName  string `json:"b_api_name" gorm:"-"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LineApiGroup) TableName() string {
+	return "line_api_group"
+}
+
+func (e *LineApiGroup) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineApiGroup) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/models/line_api_user.go b/app/admin/models/line_api_user.go
new file mode 100644
index 0000000..e8010d7
--- /dev/null
+++ b/app/admin/models/line_api_user.go
@@ -0,0 +1,42 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type LineApiUser struct {
+	models.Model
+
+	UserId      int64  `json:"userId" gorm:"type:int unsigned;comment:用户id"`
+	JysId       int64  `json:"jysId" gorm:"type:int;comment:关联交易所账号id"`
+	ApiName     string `json:"apiName" gorm:"type:varchar(255);comment:api用户名"`
+	ApiKey      string `json:"apiKey" gorm:"type:varchar(255);comment:apiKey"`
+	ApiSecret   string `json:"apiSecret" gorm:"type:varchar(255);comment:apiSecret"`
+	IpAddress   string `json:"ipAddress" gorm:"type:varchar(255);comment:代理地址"`
+	UserPass    string `json:"userPass" gorm:"type:varchar(255);comment:代码账号密码"`
+	AdminId     int64  `json:"adminId" gorm:"type:int unsigned;comment:管理员id"`
+	Affiliation int64  `json:"affiliation" gorm:"type:int;comment:归属:1=现货,2=合约,3=现货合约"`
+	AdminShow   int64  `json:"adminShow" gorm:"type:int;comment:是否超管可见:1=是,0=否"`
+	Site        string `json:"site" gorm:"type:enum('1','2','3');comment:允许下单的方向:1=多;2=空;3=多空"`
+	Subordinate string `json:"subordinate" gorm:"type:enum('0','1','2');comment:从属关系:0=未绑定关系;1=主账号;2=副帐号"`
+	GroupId     int64  `json:"groupId" gorm:"type:int unsigned;comment:所属组id"`
+	OpenStatus  int64  `json:"openStatus" gorm:"type:int unsigned;comment:开启状态 0=关闭 1=开启"`
+
+	SpotLastTime    string `json:"spotLastTime" gorm:"-"`    //现货websocket最后通信时间
+	FuturesLastTime string `json:"futuresLastTime" gorm:"-"` //合约websocket最后通信时间
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LineApiUser) TableName() string {
+	return "line_api_user"
+}
+
+func (e *LineApiUser) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineApiUser) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/models/line_coinnetwork.go b/app/admin/models/line_coinnetwork.go
new file mode 100644
index 0000000..041425c
--- /dev/null
+++ b/app/admin/models/line_coinnetwork.go
@@ -0,0 +1,41 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type LineCoinnetwork struct {
+	models.Model
+
+	NetworkName string `json:"networkName" gorm:"type:varchar(255);comment:网络名称"`
+	TokenName   string `json:"tokenName" gorm:"type:varchar(255);comment:网络token名称"`
+	ArrivalNum  int64  `json:"arrivalNum" gorm:"type:int;comment:充值区块确认数"`
+	UnlockNum   int64  `json:"unlockNum" gorm:"type:int;comment:提现解锁确认数"`
+	UnlockTime  int64  `json:"unlockTime" gorm:"type:int;comment:提现确认平均时间,单位分钟"`
+	Fee         string `json:"fee" gorm:"type:decimal(32,6);comment:网络手续费,该字段是动态的,后面会有服务定时更新该字段"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LineCoinnetwork) TableName() string {
+	return "line_coinnetwork"
+}
+
+func (e *LineCoinnetwork) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineCoinnetwork) GetId() interface{} {
+	return e.Id
+}
+
+type VtsCoinNetWorkDB struct {
+	Id          int     `json:"id"`
+	NetworkName string  `json:"network_name"`
+	TokenName   string  `json:"token_name"`
+	ArrivalNum  int     `json:"arrival_num"`
+	UnlockNum   int     `json:"unlock_num"`
+	UnlockTime  int     `json:"unlock_time"`
+	Fee         float64 `json:"fee"`
+}
diff --git a/app/admin/models/line_cointonetwork.go b/app/admin/models/line_cointonetwork.go
new file mode 100644
index 0000000..85e0f60
--- /dev/null
+++ b/app/admin/models/line_cointonetwork.go
@@ -0,0 +1,79 @@
+package models
+
+import (
+	"time"
+
+	"go-admin/common/models"
+)
+
+type LineCointonetwork struct {
+	models.Model
+
+	CoinId                   int64     `json:"coinId" gorm:"type:int unsigned;comment:币种id"`
+	NetworkId                int64     `json:"networkId" gorm:"type:int unsigned;comment:公链网络id"`
+	IsMain                   int64     `json:"isMain" gorm:"type:int unsigned;comment:是否主网--1否,3是.比如BTC在BTC网络中就属于主网"`
+	IsDeposit                int64     `json:"isDeposit" gorm:"type:int;comment:是否开启充值:1==否,3==是"`
+	IsWithdraw               int64     `json:"isWithdraw" gorm:"type:int unsigned;comment:是否开启提现:1==否,3==是"`
+	CoinCode                 string    `json:"coinCode" gorm:"type:varchar(255);comment:币种代号"`
+	Token                    string    `json:"token" gorm:"type:varchar(255);comment:代币token"`
+	MinChargeNum             string    `json:"minChargeNum" gorm:"type:decimal(32,8);comment:最小充值数量"`
+	MinOutNum                string    `json:"minOutNum" gorm:"type:decimal(32,8);comment:单笔最小提币数量"`
+	MaxOutNum                string    `json:"maxOutNum" gorm:"type:decimal(32,8);comment:单笔最大提币数量"`
+	TransferFee              string    `json:"transferFee" gorm:"type:decimal(32,8);comment:提币手续费"`
+	DetailCode               string    `json:"detailCode" gorm:"type:varchar(255);comment:币种全称"`
+	NetworkName              string    `json:"networkName" gorm:"type:varchar(255);comment:公链网络简称"`
+	TokenName                string    `json:"tokenName" gorm:"type:varchar(255);comment:公链网络全称"`
+	ChargeType               int64     `json:"chargeType" gorm:"type:int;comment:手续费类型 1==固定 3==百分比"`
+	RechargeSwitchTime       time.Time `json:"rechargeSwitchTime" gorm:"type:timestamp(6);comment:充值开关时间"`
+	WithdrawSwitchTime       time.Time `json:"withdrawSwitchTime" gorm:"type:timestamp(6);comment:提币开关时间"`
+	IsoutsideWithdrawVerify  int64     `json:"isoutsideWithdrawVerify" gorm:"type:int;comment:是否开启外部提币免审1==否3==是"`
+	OutsideWithdrawVerifyNum string    `json:"outsideWithdrawVerifyNum" gorm:"type:decimal(32,8);comment:外部提币免审阈值"`
+	IsinsideTransferVerify   int64     `json:"isinsideTransferVerify" gorm:"type:int;comment:是否开启内部转账免审1==否3==是"`
+	InsidetransferVerifyNum  string    `json:"insidetransferVerifyNum" gorm:"type:decimal(32,8);comment:内部转账免审阈值"`
+	EverydaymaxWithdrawNum   string    `json:"everydaymaxWithdrawNum" gorm:"type:decimal(32,8);comment:每日最大累计提币数量"`
+	EverydaymaxVerifyNum     string    `json:"everydaymaxVerifyNum" gorm:"type:decimal(32,8);comment:每日最大免审累计数量"`
+	Isinsidetransferfee      int64     `json:"isinsidetransferfee" gorm:"type:int;comment:是否开启内部转账免手续费1==否3==是"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LineCointonetwork) TableName() string {
+	return "line_cointonetwork"
+}
+
+func (e *LineCointonetwork) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineCointonetwork) GetId() interface{} {
+	return e.Id
+}
+
+type VtsCoinToNetWorkDB struct {
+	CoinId      int     `json:"coin_id"`
+	CoinCode    string  `json:"coin_code"`
+	DetailCode  string  `json:"detail_code"`
+	NetworkId   int     `json:"network_id"`
+	NetWorkName string  `json:"network_name"`
+	TokenName   string  `json:"token_name"`
+	TransferFee float64 `json:"transfer_fee"`
+}
+
+type VtsCoinToNetWorkResp struct {
+	CoinId          int    `json:"coin_id"`
+	CoinCode        string `json:"coin_code"`
+	DetailCode      string `json:"detail_code"`
+	NetWorkId       int    `json:"network_id"`
+	NetWorkName     string `json:"network_name"`
+	TokenName       string `json:"token_name"`
+	TransferFee     string `json:"transfer_fee"`
+	TransferFeeUsdt string `json:"transfer_fee_usdt"`
+}
+
+type RechargeAddressListResp struct {
+	Address    string `json:"address"`     //地址
+	MinNum     string `json:"min_num"`     //最小充值数量
+	ArrivalNum int    `json:"arrival_num"` //充值区块确认数
+	UnlockNum  int    `json:"unlock_num"`  //提现解锁确认数
+}
diff --git a/app/admin/models/line_direction.go b/app/admin/models/line_direction.go
new file mode 100644
index 0000000..87496f4
--- /dev/null
+++ b/app/admin/models/line_direction.go
@@ -0,0 +1,37 @@
+package models
+
+import (
+
+	"go-admin/common/models"
+
+)
+
+type LineDirection struct {
+    models.Model
+    
+    Symbol string `json:"symbol" gorm:"type:varchar(255);comment:交易对"` 
+    Type int64 `json:"type" gorm:"type:int unsigned;comment:交易对类型:1=现货,2=合约"` 
+    BuyPoint1 string `json:"buyPoint1" gorm:"type:varchar(255);comment:买入点一"` 
+    BuyPoint2 string `json:"buyPoint2" gorm:"type:varchar(255);comment:买入点二"` 
+    BuyPoint3 string `json:"buyPoint3" gorm:"type:varchar(255);comment:买入点三"` 
+    SellPoint1 string `json:"sellPoint1" gorm:"type:varchar(255);comment:卖出点一"` 
+    SellPoint2 string `json:"sellPoint2" gorm:"type:varchar(255);comment:卖出点二"` 
+    SellPoint3 string `json:"sellPoint3" gorm:"type:varchar(255);comment:卖出点三"` 
+    Direction string `json:"direction" gorm:"type:varchar(255);comment:预估方向"` 
+    AiAnswer string `json:"aiAnswer" gorm:"type:text;comment:AI智能分析"` 
+    models.ModelTime
+    models.ControlBy
+}
+
+func (LineDirection) TableName() string {
+    return "line_direction"
+}
+
+func (e *LineDirection) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineDirection) GetId() interface{} {
+	return e.Id
+}
\ No newline at end of file
diff --git a/app/admin/models/line_order_template_logs.go b/app/admin/models/line_order_template_logs.go
new file mode 100644
index 0000000..23bbc11
--- /dev/null
+++ b/app/admin/models/line_order_template_logs.go
@@ -0,0 +1,32 @@
+package models
+
+import (
+
+	"go-admin/common/models"
+
+)
+
+type LineOrderTemplateLogs struct {
+    models.Model
+    
+    Name string `json:"name" gorm:"type:varchar(255);comment:模板名称"` 
+    UserId int64 `json:"userId" gorm:"type:int;comment:用户id"` 
+    Params string `json:"params" gorm:"type:text;comment:参数"` 
+    Type int64 `json:"type" gorm:"type:int unsigned;comment:模板类型:1=单独添加;2=批量添加"` 
+    Switch string `json:"switch" gorm:"type:enum('0','1');comment:开关:0=关,1=开"` 
+    models.ModelTime
+    models.ControlBy
+}
+
+func (LineOrderTemplateLogs) TableName() string {
+    return "line_order_template_logs"
+}
+
+func (e *LineOrderTemplateLogs) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineOrderTemplateLogs) GetId() interface{} {
+	return e.Id
+}
\ No newline at end of file
diff --git a/app/admin/models/line_pre_order.go b/app/admin/models/line_pre_order.go
new file mode 100644
index 0000000..f6bd75a
--- /dev/null
+++ b/app/admin/models/line_pre_order.go
@@ -0,0 +1,60 @@
+package models
+
+import (
+	"go-admin/common/models"
+	"time"
+
+	"github.com/shopspring/decimal"
+)
+
+type LinePreOrder struct {
+	models.Model
+	ExchangeType   string          `json:"exchangeType" gorm:"type:varchar(20);comment:交易所类型 (字典 exchange_type)"`
+	Pid            int             `json:"pid" gorm:"type:int unsigned;omitempty;comment:pid"`
+	ApiId          int             `json:"apiId" gorm:"type:varchar(255);omitempty;comment:api用户"`
+	GroupId        string          `json:"groupId" gorm:"type:int unsigned;omitempty;comment:交易对组id"`
+	Symbol         string          `json:"symbol" gorm:"type:varchar(255);omitempty;comment:交易对"`
+	QuoteSymbol    string          `json:"quoteSymbol" gorm:"type:varchar(255);omitempty;comment:计较货币"`
+	SignPrice      string          `json:"signPrice" gorm:"type:decimal(18,8);omitempty;comment:对标价"`
+	SignPriceU     decimal.Decimal `json:"signPriceU" gorm:"type:decimal(18,8);omitempty;comment:交易对对标U的行情价"`
+	SignPriceType  string          `json:"signPriceType" gorm:"type:enum('new','tall','low','mixture','entrust','add');omitempty;comment:对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"`
+	Rate           string          `json:"rate" gorm:"type:decimal(18,2);omitempty;comment:下单百分比"`
+	Price          string          `json:"price" gorm:"type:decimal(18,8);omitempty;comment:触发价格"`
+	Num            string          `json:"num" gorm:"type:decimal(18,8);omitempty;comment:购买数量"`
+	BuyPrice       string          `json:"buyPrice" gorm:"type:decimal(18,8);omitempty;comment:购买金额"`
+	SymbolType     int             `json:"symbolType" gorm:"type:int;comment:交易对类型:1=现货;2=合约"`
+	Site           string          `json:"site" gorm:"type:enum('BUY','SELL');omitempty;comment:购买方向:BUY=买;SELL=卖"`
+	OrderSn        string          `json:"orderSn" gorm:"type:varchar(255);omitempty;comment:订单号"`
+	OrderType      int             `json:"orderType" gorm:"type:int;omitempty;comment:订单类型:0=主单 1=止盈 2=止损 3=平仓"`
+	Desc           string          `json:"desc" gorm:"type:text;omitempty;comment:订单描述"`
+	Status         int             `json:"status" gorm:"type:int;omitempty;comment:是否被触发:0=待触发;1=已触发;2=下单失败;4=已取消;5=委托中;6=已成交;9=已平仓"`
+	AdminId        string          `json:"adminId" gorm:"type:int unsigned;omitempty;comment:操作管理员id"`
+	CloseType      int             `json:"closeType" gorm:"type:int unsigned;omitempty;comment:平仓类型 是否为盈利平仓 1= 是 0 =否"`
+	CoverType      int             `json:"coverType" gorm:"type:int unsigned;omitempty;comment:对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货"`
+	ExpireTime     time.Time       `json:"expireTime" gorm:"comment:过期时间"`
+	MainOrderType  string          `json:"mainOrderType" gorm:"type:enum;comment:第一笔(主单类型) 限价(LIMIT)市价(MARKET)"`
+	HedgeOrderType string          `json:"hedgeOrderType" gorm:"type:enum;comment:第二笔类型 限价(LIMIT)市价(MARKET)"`
+	Child          []LinePreOrder  `json:"child" gorm:"-"`
+	ApiName        string          `json:"api_name" gorm:"->"`
+	ChildNum       int64           `json:"child_num" gorm:"->"`
+	// LinePreOrder 线上预埋单\
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LinePreOrder) TableName() string {
+	return "line_pre_order"
+}
+
+func (e *LinePreOrder) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LinePreOrder) GetId() interface{} {
+	return e.Id
+}
+
+type PositionSymbol struct {
+	Symbol string
+}
diff --git a/app/admin/models/line_pre_order_status.go b/app/admin/models/line_pre_order_status.go
new file mode 100644
index 0000000..8f47e64
--- /dev/null
+++ b/app/admin/models/line_pre_order_status.go
@@ -0,0 +1,29 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type LinePreOrderStatus struct {
+	models.Model
+
+	OrderId           int    `json:"orderId" gorm:"type:bigint;comment:主订单id"`
+	OrderSn           string `json:"orderSn" gorm:"type:varchar(255);comment:主订单号"`
+	AddPositionStatus int    `json:"addPositionStatus" gorm:"type:int;comment:加仓状态 0-无 1-已加仓"`
+	HedgeStatus       int    `json:"hedgeStatus" gorm:"type:int;comment:对冲状态 0-无 1-已对冲"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LinePreOrderStatus) TableName() string {
+	return "line_pre_order_status"
+}
+
+func (e *LinePreOrderStatus) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LinePreOrderStatus) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/models/line_pre_script.go b/app/admin/models/line_pre_script.go
new file mode 100644
index 0000000..125eef8
--- /dev/null
+++ b/app/admin/models/line_pre_script.go
@@ -0,0 +1,33 @@
+package models
+
+import (
+
+	"go-admin/common/models"
+
+)
+
+type LinePreScript struct {
+    models.Model
+    
+    ApiId int64 `json:"apiId" gorm:"type:int unsigned;comment:api用户"` 
+    ScriptNum int64 `json:"scriptNum" gorm:"type:int unsigned;comment:脚本批次"` 
+    ScriptParams string `json:"scriptParams" gorm:"type:text;comment:脚本参数"` 
+    Status string `json:"status" gorm:"type:enum('0','1','2');comment:执行状态:0=等待执行,1=执行中,2=执行结束"` 
+    Desc string `json:"desc" gorm:"type:longtext;comment:运行备注"` 
+    AdminId int64 `json:"adminId" gorm:"type:int unsigned;comment:管理员id"` 
+    models.ModelTime
+    models.ControlBy
+}
+
+func (LinePreScript) TableName() string {
+    return "line_pre_script"
+}
+
+func (e *LinePreScript) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LinePreScript) GetId() interface{} {
+	return e.Id
+}
\ No newline at end of file
diff --git a/app/admin/models/line_price_limit.go b/app/admin/models/line_price_limit.go
new file mode 100644
index 0000000..61a210f
--- /dev/null
+++ b/app/admin/models/line_price_limit.go
@@ -0,0 +1,30 @@
+package models
+
+import (
+	"github.com/shopspring/decimal"
+	"go-admin/common/models"
+)
+
+type LinePriceLimit struct {
+	models.Model
+
+	Symbol          string          `json:"symbol" gorm:"type:varchar(255);comment:交易对"`
+	Type            string          `json:"type" gorm:"type:enum('1','2');comment:类型:1=现货,2=合约"`
+	DirectionStatus string          `json:"directionStatus" gorm:"type:enum('1','2');comment:方向:1=涨,2=跌"`
+	Range           decimal.Decimal `json:"range" gorm:"type:decimal(10,5);comment:幅度"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LinePriceLimit) TableName() string {
+	return "line_price_limit"
+}
+
+func (e *LinePriceLimit) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LinePriceLimit) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/models/line_recharge.go b/app/admin/models/line_recharge.go
new file mode 100644
index 0000000..57cde30
--- /dev/null
+++ b/app/admin/models/line_recharge.go
@@ -0,0 +1,45 @@
+package models
+
+import (
+    "time"
+
+	"go-admin/common/models"
+
+)
+
+type LineRecharge struct {
+    models.Model
+    
+    CoinId int64 `json:"coinId" gorm:"type:int;comment:币种id"` 
+    UserId int64 `json:"userId" gorm:"type:int;comment:用户Id"` 
+    Confirms string `json:"confirms" gorm:"type:int;comment:区块确认数"` 
+    TranType string `json:"tranType" gorm:"type:int;comment:类型:1线上,2内部"` 
+    BlockIndex string `json:"blockIndex" gorm:"type:int;comment:区块高度"` 
+    Amount string `json:"amount" gorm:"type:decimal(32,8);comment:数量"` 
+    Account string `json:"account" gorm:"type:varchar(255);comment:账户"` 
+    Address string `json:"address" gorm:"type:varchar(255);comment:地址"` 
+    Txid string `json:"txid" gorm:"type:varchar(255);comment:交易id"` 
+    BlockTime time.Time `json:"blockTime" gorm:"type:timestamp;comment:同步时间"` 
+    TimeReceived time.Time `json:"timeReceived" gorm:"type:timestamp;comment:确认时间"` 
+    MainCoin string `json:"mainCoin" gorm:"type:varchar(255);comment:充值网络"` 
+    OrderNo string `json:"orderNo" gorm:"type:varchar(50);comment:订单号"` 
+    Status string `json:"status" gorm:"type:int;comment:状态1==进行中暂时保留,2==成功,3==失败"` 
+    State string `json:"state" gorm:"type:int;comment:来源状态 0 待審核 1 審核成功 2 審核駁回 3交易成功 4交易失敗"` 
+    Fee string `json:"fee" gorm:"type:decimal(32,8);comment:手续费"` 
+    AddressFrom string `json:"addressFrom" gorm:"type:varchar(255);comment:来源地址"` 
+    models.ModelTime
+    models.ControlBy
+}
+
+func (LineRecharge) TableName() string {
+    return "line_recharge"
+}
+
+func (e *LineRecharge) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineRecharge) GetId() interface{} {
+	return e.Id
+}
\ No newline at end of file
diff --git a/app/admin/models/line_symbol.go b/app/admin/models/line_symbol.go
new file mode 100644
index 0000000..724e391
--- /dev/null
+++ b/app/admin/models/line_symbol.go
@@ -0,0 +1,32 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type LineSymbol struct {
+	models.Model
+
+	ApiId      string `json:"apiId" gorm:"type:int;comment:api账户id"`
+	Symbol     string `json:"symbol" gorm:"type:varchar(32);comment:交易对"`
+	BaseAsset  string `json:"baseAsset" gorm:"type:varchar(255);comment:基础货币"`
+	QuoteAsset string `json:"quoteAsset" gorm:"type:varchar(255);comment:计价货币"`
+	Switch     string `json:"switch" gorm:"type:enum('0','1');comment:状态"`
+	Type       string `json:"type" gorm:"type:enum('1','2');comment:交易对类型"`
+	Number     int    `json:"number" gorm:"->"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LineSymbol) TableName() string {
+	return "line_symbol"
+}
+
+func (e *LineSymbol) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineSymbol) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/models/line_symbol_black.go b/app/admin/models/line_symbol_black.go
new file mode 100644
index 0000000..ccc3639
--- /dev/null
+++ b/app/admin/models/line_symbol_black.go
@@ -0,0 +1,29 @@
+package models
+
+import (
+
+	"go-admin/common/models"
+
+)
+
+type LineSymbolBlack struct {
+    models.Model
+    
+    Symbol string `json:"symbol" gorm:"type:varchar(255);comment:交易对"` 
+    Type string `json:"type" gorm:"type:enum('1','2');comment:类型:1=现货,2=合约"` 
+    models.ModelTime
+    models.ControlBy
+}
+
+func (LineSymbolBlack) TableName() string {
+    return "line_symbol_black"
+}
+
+func (e *LineSymbolBlack) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineSymbolBlack) GetId() interface{} {
+	return e.Id
+}
\ No newline at end of file
diff --git a/app/admin/models/line_symbol_group.go b/app/admin/models/line_symbol_group.go
new file mode 100644
index 0000000..cd795a9
--- /dev/null
+++ b/app/admin/models/line_symbol_group.go
@@ -0,0 +1,30 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type LineSymbolGroup struct {
+	models.Model
+
+	GroupName string `json:"groupName" gorm:"type:varchar(255);comment:交易对组名称"`
+	Symbol    string `json:"symbol" gorm:"type:text;comment:交易对"`
+	GroupType string `json:"groupType" gorm:"type:enum('1','2');comment:分组类型:1=普通类型"`
+	Type      string `json:"type" gorm:"type:enum('1','2');comment:类型:1=现货,2=合约"`
+	Count     int    `json:"count" gorm:"->"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LineSymbolGroup) TableName() string {
+	return "line_symbol_group"
+}
+
+func (e *LineSymbolGroup) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineSymbolGroup) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/models/line_system_setting.go b/app/admin/models/line_system_setting.go
new file mode 100644
index 0000000..71133e2
--- /dev/null
+++ b/app/admin/models/line_system_setting.go
@@ -0,0 +1,41 @@
+package models
+
+import (
+	"go-admin/common/models"
+
+	"github.com/shopspring/decimal"
+)
+
+type LineSystemSetting struct {
+	models.Model
+
+	Time                      int64           `json:"time" gorm:"type:int;comment:导入:挂单时长达到时间后失效"`
+	BatchTime                 int64           `json:"batchTime" gorm:"type:int;comment:批量:挂单时长达到时间后失效"`
+	ProfitRate                string          `json:"profitRate" gorm:"type:decimal(10,2);comment:平仓盈利比例"`
+	CoverOrderTypeBRate       string          `json:"coverOrderTypeBRate" gorm:"type:decimal(10,2);comment:b账户限价补单的买入百分比"`
+	ScaleOrderTypeARate       string          `json:"scaleOrderTypeARate" gorm:"type:decimal(10,2);comment:a账户限价加仓买入百分比"`
+	ScaleOrderTypeBRate       string          `json:"scaleOrderTypeBRate" gorm:"type:decimal(10,2);comment:b账户限价加仓买入百分比"`
+	ScaleUnrealizedProfitRate string          `json:"scaleUnrealizedProfitRate" gorm:"type:decimal(10,5) unsigned;comment:亏损百分比加仓"`
+	ScaleType                 int             `json:"scaleType" gorm:"type:int;comment:加仓类型 1-百分比 2-数值"`
+	ScaleNum                  string          `json:"scaleNum" gorm:"type:decimal(18,2) unsigned;comment:加仓数值"`
+	ScaleSubordinate          int64           `json:"scaleSubordinate" gorm:"type:int unsigned;comment:加仓账户:1=A账户;2=副账户;3=都加"`
+	AutoScaleTimes            int64           `json:"autoScaleTimes" gorm:"type:int unsigned;comment:自动加仓次数"`
+	HedgePerformance          decimal.Decimal `json:"hedgePerformance" gorm:"type:decimal(5,2);comment:对冲平仓涨跌幅"`
+	ProtectHedgeRate          decimal.Decimal `json:"protectHedgeRate" gorm:"type:decimal(5,2);comment:保护对冲触发百分比"`
+	ProtectHedgeEnable        int             `json:"protectHedgeEnable" gorm:"type:int;comment:是否只开启保护对冲 1-开启 0-关闭"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LineSystemSetting) TableName() string {
+	return "line_system_setting"
+}
+
+func (e *LineSystemSetting) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineSystemSetting) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/models/line_uduncoin.go b/app/admin/models/line_uduncoin.go
new file mode 100644
index 0000000..8b1d951
--- /dev/null
+++ b/app/admin/models/line_uduncoin.go
@@ -0,0 +1,36 @@
+package models
+
+import (
+
+	"go-admin/common/models"
+
+)
+
+type LineUduncoin struct {
+    models.Model
+    
+    TokenStatus int64 `json:"tokenStatus" gorm:"type:int;comment:0: 主幣 1:代幣"` 
+    Decimals int64 `json:"decimals" gorm:"type:int;comment:幣種精度,8"` 
+    MainCoinType string `json:"mainCoinType" gorm:"type:varchar(255);comment:主幣種類型"` 
+    CoinType string `json:"coinType" gorm:"type:varchar(255);comment:幣種類型"` 
+    Symbol string `json:"symbol" gorm:"type:varchar(255);comment:幣種symbol"` 
+    Name string `json:"name" gorm:"type:varchar(255);comment:幣種別名,BTC"` 
+    Logo string `json:"logo" gorm:"type:varchar(255);comment:幣種logo地址"` 
+    CoinName string `json:"coinName" gorm:"type:varchar(255);comment:幣種全稱,Bitcoin"` 
+    MainSymbol string `json:"mainSymbol" gorm:"type:varchar(255);comment:主幣種symbol"` 
+    models.ModelTime
+    models.ControlBy
+}
+
+func (LineUduncoin) TableName() string {
+    return "line_uduncoin"
+}
+
+func (e *LineUduncoin) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineUduncoin) GetId() interface{} {
+	return e.Id
+}
\ No newline at end of file
diff --git a/app/admin/models/line_user.go b/app/admin/models/line_user.go
new file mode 100644
index 0000000..426b3eb
--- /dev/null
+++ b/app/admin/models/line_user.go
@@ -0,0 +1,56 @@
+package models
+
+import (
+	"github.com/shopspring/decimal"
+	"time"
+
+	"go-admin/common/models"
+)
+
+type LineUser struct {
+	models.Model
+
+	GroupId        int             `json:"groupId" gorm:"type:int unsigned;comment:组别ID"`
+	Pid            int             `json:"pid" gorm:"type:int unsigned;comment:推荐人ID"`
+	Username       string          `json:"username" gorm:"type:varchar(32);comment:用户名"`
+	Nickname       string          `json:"nickname" gorm:"type:varchar(50);comment:昵称"`
+	Password       string          `json:"password" gorm:"type:varchar(32);comment:密码"`
+	Salt           string          `json:"salt" gorm:"type:varchar(30);comment:密码盐"`
+	Email          string          `json:"email" gorm:"type:varchar(100);comment:电子邮箱"`
+	Mobile         string          `json:"mobile" gorm:"type:varchar(11);comment:手机号"`
+	Area           string          `json:"area" gorm:"type:varchar(255);comment:手机号归属地"`
+	Avatar         string          `json:"avatar" gorm:"type:varchar(255);comment:头像"`
+	Level          int             `json:"level" gorm:"type:tinyint unsigned;comment:等级"`
+	Gender         int             `json:"gender" gorm:"type:tinyint unsigned;comment:性别"`
+	Bio            string          `json:"bio" gorm:"type:varchar(100);comment:格言"`
+	Money          decimal.Decimal `json:"money" gorm:"type:decimal(10,2) unsigned;comment:保证金"`
+	Score          int             `json:"score" gorm:"type:int unsigned;comment:积分"`
+	InviteCode     string          `json:"invite_code" gorm:"type:varchar(255);comment:邀请码"`
+	Successions    int             `json:"successions" gorm:"type:int unsigned;comment:连续登录天数"`
+	MaxSuccessions int             `json:"maxSuccessions" gorm:"type:int unsigned;comment:最大连续登录天数"`
+	Loginip        string          `json:"loginip" gorm:"type:varchar(50);comment:登录IP"`
+	Loginfailure   int             `json:"loginfailure" gorm:"type:tinyint unsigned;comment:失败次数"`
+	Joinip         string          `json:"joinip" gorm:"type:varchar(50);comment:加入IP"`
+	Jointime       int             `json:"jointime" gorm:"type:int;comment:加入时间"`
+	RecommendNum   int             `json:"recommend_num" gorm:"type:int;comment:推荐人数"`
+	Token          string          `json:"token" gorm:"type:varchar(50);comment:Token"`
+	Status         string          `json:"status" gorm:"type:varchar(30);comment:状态"`
+	Verification   string          `json:"verification" gorm:"type:varchar(255);comment:验证"`
+	LoginTime      time.Time       `json:"loginTime" gorm:"type:timestamp;comment:登录时间"`
+	OpenStatus     int             `json:"open_status" gorm:"-"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LineUser) TableName() string {
+	return "line_user"
+}
+
+func (e *LineUser) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineUser) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/models/line_user_funding_trend.go b/app/admin/models/line_user_funding_trend.go
new file mode 100644
index 0000000..e14f61f
--- /dev/null
+++ b/app/admin/models/line_user_funding_trend.go
@@ -0,0 +1,33 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type LineUserFundingTrend struct {
+	models.Model
+
+	UserId  int64  `json:"userId" gorm:"type:int unsigned;comment:用户id"`
+	Funding string `json:"funding" gorm:"type:decimal(32,8) unsigned;comment:资金账户总额 换算U"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LineUserFundingTrend) TableName() string {
+	return "line_user_funding_trend"
+}
+
+func (e *LineUserFundingTrend) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineUserFundingTrend) GetId() interface{} {
+	return e.Id
+}
+
+type LineUserFundingTrendResp struct {
+	UserId    int64  `json:"user_id" gorm:"type:int unsigned;comment:用户id"`
+	Funding   string `json:"funding" gorm:"type:decimal(32,8) unsigned;comment:资金账户总额"`
+	CreatedAt string `json:"created_at"`
+}
diff --git a/app/admin/models/line_user_profit_logs.go b/app/admin/models/line_user_profit_logs.go
new file mode 100644
index 0000000..b1e8d4b
--- /dev/null
+++ b/app/admin/models/line_user_profit_logs.go
@@ -0,0 +1,32 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type LineUserProfitLogs struct {
+	models.Model
+
+	UserId     int64  `json:"userId" gorm:"type:int unsigned;comment:line_user 表的id"`
+	ApiId      int64  `json:"apiId" gorm:"type:int unsigned;comment:line_apiuser 表的id"`
+	PreOrderId int64  `json:"preOrderId" gorm:"type:int unsigned;comment:line_pre_order 止盈单id"`
+	Num        string `json:"num" gorm:"type:decimal(18,8);comment:成交数量"`
+	Symbol     string `json:"symbol" gorm:"type:varchar(255);comment:交易对"`
+	Rate       string `json:"rate" gorm:"type:decimal(10,5);comment:盈利比例"`
+	Amount     string `json:"amount" gorm:"type:decimal(18,5);comment:盈利金额(换算成U的价值)"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LineUserProfitLogs) TableName() string {
+	return "line_user_profit_logs"
+}
+
+func (e *LineUserProfitLogs) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineUserProfitLogs) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/models/line_wallet.go b/app/admin/models/line_wallet.go
new file mode 100644
index 0000000..3245d61
--- /dev/null
+++ b/app/admin/models/line_wallet.go
@@ -0,0 +1,31 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type LineWallet struct {
+	models.Model
+
+	UserId        int64  `json:"userId" gorm:"type:int;comment:用户Id"`
+	CoinId        int64  `json:"coinId" gorm:"type:int;comment:币种id"`
+	CoinCode      string `json:"coinCode" gorm:"type:varchar(255);comment:标签"`
+	Tag           string `json:"tag" gorm:"type:varchar(255);comment:标签"`
+	Address       string `json:"address" gorm:"type:varchar(255);comment:地址"`
+	CoinNetworkId int    `json:"coinNetworkId" gorm:"type:int;comment:币种主网id,useri+主网id做唯一"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (LineWallet) TableName() string {
+	return "line_wallet"
+}
+
+func (e *LineWallet) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *LineWallet) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/models/sys_api.go b/app/admin/models/sys_api.go
new file mode 100644
index 0000000..0b78e49
--- /dev/null
+++ b/app/admin/models/sys_api.go
@@ -0,0 +1,91 @@
+package models
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"regexp"
+	"strings"
+
+	"github.com/bitly/go-simplejson"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"github.com/go-admin-team/go-admin-core/sdk/runtime"
+	"github.com/go-admin-team/go-admin-core/storage"
+
+	"go-admin/common/models"
+)
+
+type SysApi struct {
+	Id     int    `json:"id" gorm:"primaryKey;autoIncrement;comment:主键编码"`
+	Handle string `json:"handle" gorm:"size:128;comment:handle"`
+	Title  string `json:"title" gorm:"size:128;comment:标题"`
+	Path   string `json:"path" gorm:"size:128;comment:地址"`
+	Action string `json:"action" gorm:"size:16;comment:请求类型"`
+	Type   string `json:"type" gorm:"size:16;comment:接口类型"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (*SysApi) TableName() string {
+	return "sys_api"
+}
+
+func (e *SysApi) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysApi) GetId() interface{} {
+	return e.Id
+}
+
+func SaveSysApi(message storage.Messager) (err error) {
+	var rb []byte
+	rb, err = json.Marshal(message.GetValues())
+	if err != nil {
+		err = fmt.Errorf("json Marshal error, %v", err.Error())
+		return err
+	}
+
+	var l runtime.Routers
+	err = json.Unmarshal(rb, &l)
+	if err != nil {
+		err = fmt.Errorf("json Unmarshal error, %s", err.Error())
+		return err
+	}
+	dbList := sdk.Runtime.GetDb()
+	for _, d := range dbList {
+		for _, v := range l.List {
+			if v.HttpMethod != "HEAD" ||
+				strings.Contains(v.RelativePath, "/swagger/") ||
+				strings.Contains(v.RelativePath, "/static/") ||
+				strings.Contains(v.RelativePath, "/form-generator/") ||
+				strings.Contains(v.RelativePath, "/sys/tables") {
+
+				// 根据接口方法注释里的@Summary填充接口名称,适用于代码生成器
+				// 可在此处增加配置路径前缀的if判断,只对代码生成的自建应用进行定向的接口名称填充
+				jsonFile, _ := ioutil.ReadFile("docs/swagger.json")
+				jsonData, _ := simplejson.NewFromReader(bytes.NewReader(jsonFile))
+				urlPath := v.RelativePath
+				idPatten := "(.*)/:(\\w+)" // 正则替换,把:id换成{id}
+				reg, _ := regexp.Compile(idPatten)
+				if reg.MatchString(urlPath) {
+					urlPath = reg.ReplaceAllString(v.RelativePath, "${1}/{${2}}") // 把:id换成{id}
+				}
+				apiTitle, _ := jsonData.Get("paths").Get(urlPath).Get(strings.ToLower(v.HttpMethod)).Get("summary").String()
+
+				err := d.Debug().Where(SysApi{Path: v.RelativePath, Action: v.HttpMethod}).
+					Attrs(SysApi{Handle: v.Handler, Title: apiTitle}).
+					FirstOrCreate(&SysApi{}).
+					//Update("handle", v.Handler).
+					Error
+				if err != nil {
+					err := fmt.Errorf("Models SaveSysApi error: %s \r\n ", err.Error())
+					return err
+				}
+			}
+		}
+	}
+	return nil
+}
diff --git a/app/admin/models/sys_config.go b/app/admin/models/sys_config.go
new file mode 100644
index 0000000..2024bbb
--- /dev/null
+++ b/app/admin/models/sys_config.go
@@ -0,0 +1,30 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type SysConfig struct {
+	models.Model
+	ConfigName  string `json:"configName" gorm:"size:128;comment:ConfigName"`   //
+	ConfigKey   string `json:"configKey" gorm:"size:128;comment:ConfigKey"`     //
+	ConfigValue string `json:"configValue" gorm:"size:255;comment:ConfigValue"` //
+	ConfigType  string `json:"configType" gorm:"size:64;comment:ConfigType"`
+	IsFrontend  string `json:"isFrontend" gorm:"size:64;comment:是否前台"` //
+	Remark      string `json:"remark" gorm:"size:128;comment:Remark"`  //
+	models.ControlBy
+	models.ModelTime
+}
+
+func (*SysConfig) TableName() string {
+	return "sys_config"
+}
+
+func (e *SysConfig) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysConfig) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/models/sys_dept.go b/app/admin/models/sys_dept.go
new file mode 100644
index 0000000..e4400de
--- /dev/null
+++ b/app/admin/models/sys_dept.go
@@ -0,0 +1,33 @@
+package models
+
+import "go-admin/common/models"
+
+type SysDept struct {
+	DeptId   int    `json:"deptId" gorm:"primaryKey;autoIncrement;"` //部门编码
+	ParentId int    `json:"parentId" gorm:""`                        //上级部门
+	DeptPath string `json:"deptPath" gorm:"size:255;"`               //
+	DeptName string `json:"deptName"  gorm:"size:128;"`              //部门名称
+	Sort     int    `json:"sort" gorm:"size:4;"`                     //排序
+	Leader   string `json:"leader" gorm:"size:128;"`                 //负责人
+	Phone    string `json:"phone" gorm:"size:11;"`                   //手机
+	Email    string `json:"email" gorm:"size:64;"`                   //邮箱
+	Status   int    `json:"status" gorm:"size:4;"`                   //状态
+	models.ControlBy
+	models.ModelTime
+	DataScope string    `json:"dataScope" gorm:"-"`
+	Params    string    `json:"params" gorm:"-"`
+	Children  []SysDept `json:"children" gorm:"-"`
+}
+
+func (*SysDept) TableName() string {
+	return "sys_dept"
+}
+
+func (e *SysDept) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysDept) GetId() interface{} {
+	return e.DeptId
+}
diff --git a/app/admin/models/sys_dict_data.go b/app/admin/models/sys_dict_data.go
new file mode 100644
index 0000000..15abf89
--- /dev/null
+++ b/app/admin/models/sys_dict_data.go
@@ -0,0 +1,34 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type SysDictData struct {
+	DictCode  int    `json:"dictCode" gorm:"primaryKey;column:dict_code;autoIncrement;comment:主键编码"`
+	DictSort  int    `json:"dictSort" gorm:"size:20;comment:DictSort"`
+	DictLabel string `json:"dictLabel" gorm:"size:128;comment:DictLabel"`
+	DictValue string `json:"dictValue" gorm:"size:255;comment:DictValue"`
+	DictType  string `json:"dictType" gorm:"size:64;comment:DictType"`
+	CssClass  string `json:"cssClass" gorm:"size:128;comment:CssClass"`
+	ListClass string `json:"listClass" gorm:"size:128;comment:ListClass"`
+	IsDefault string `json:"isDefault" gorm:"size:8;comment:IsDefault"`
+	Status    int    `json:"status" gorm:"size:4;comment:Status"`
+	Default   string `json:"default" gorm:"size:8;comment:Default"`
+	Remark    string `json:"remark" gorm:"size:255;comment:Remark"`
+	models.ControlBy
+	models.ModelTime
+}
+
+func (*SysDictData) TableName() string {
+	return "sys_dict_data"
+}
+
+func (e *SysDictData) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysDictData) GetId() interface{} {
+	return e.DictCode
+}
diff --git a/app/admin/models/sys_dict_type.go b/app/admin/models/sys_dict_type.go
new file mode 100644
index 0000000..49f7ebe
--- /dev/null
+++ b/app/admin/models/sys_dict_type.go
@@ -0,0 +1,28 @@
+package models
+
+import (
+	"go-admin/common/models"
+)
+
+type SysDictType struct {
+	ID       int    `json:"id" gorm:"primaryKey;column:dict_id;autoIncrement;comment:主键编码"`
+	DictName string `json:"dictName" gorm:"size:128;comment:DictName"`
+	DictType string `json:"dictType" gorm:"size:128;comment:DictType"`
+	Status   int    `json:"status" gorm:"size:4;comment:Status"`
+	Remark   string `json:"remark" gorm:"size:255;comment:Remark"`
+	models.ControlBy
+	models.ModelTime
+}
+
+func (*SysDictType) TableName() string {
+	return "sys_dict_type"
+}
+
+func (e *SysDictType) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysDictType) GetId() interface{} {
+	return e.ID
+}
diff --git a/app/admin/models/sys_login_log.go b/app/admin/models/sys_login_log.go
new file mode 100644
index 0000000..98873e8
--- /dev/null
+++ b/app/admin/models/sys_login_log.go
@@ -0,0 +1,72 @@
+package models
+
+import (
+	"encoding/json"
+	"errors"
+	"time"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"github.com/go-admin-team/go-admin-core/storage"
+
+	"go-admin/common/models"
+)
+
+type SysLoginLog struct {
+	models.Model
+	Username      string    `json:"username" gorm:"size:128;comment:用户名"`
+	Status        string    `json:"status" gorm:"size:4;comment:状态"`
+	Ipaddr        string    `json:"ipaddr" gorm:"size:255;comment:ip地址"`
+	LoginLocation string    `json:"loginLocation" gorm:"size:255;comment:归属地"`
+	Browser       string    `json:"browser" gorm:"size:255;comment:浏览器"`
+	Os            string    `json:"os" gorm:"size:255;comment:系统"`
+	Platform      string    `json:"platform" gorm:"size:255;comment:固件"`
+	LoginTime     time.Time `json:"loginTime" gorm:"comment:登录时间"`
+	Remark        string    `json:"remark" gorm:"size:255;comment:备注"`
+	Msg           string    `json:"msg" gorm:"size:255;comment:信息"`
+	CreatedAt     time.Time `json:"createdAt" gorm:"comment:创建时间"`
+	UpdatedAt     time.Time `json:"updatedAt" gorm:"comment:最后更新时间"`
+	models.ControlBy
+}
+
+func (*SysLoginLog) TableName() string {
+	return "sys_login_log"
+}
+
+func (e *SysLoginLog) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysLoginLog) GetId() interface{} {
+	return e.Id
+}
+
+// SaveLoginLog 从队列中获取登录日志
+func SaveLoginLog(message storage.Messager) (err error) {
+	//准备db
+	db := sdk.Runtime.GetDbByKey(message.GetPrefix())
+	if db == nil {
+		err = errors.New("db not exist")
+		log.Errorf("host[%s]'s %s", message.GetPrefix(), err.Error())
+		return err
+	}
+	var rb []byte
+	rb, err = json.Marshal(message.GetValues())
+	if err != nil {
+		log.Errorf("json Marshal error, %s", err.Error())
+		return err
+	}
+	var l SysLoginLog
+	err = json.Unmarshal(rb, &l)
+	if err != nil {
+		log.Errorf("json Unmarshal error, %s", err.Error())
+		return err
+	}
+	err = db.Create(&l).Error
+	if err != nil {
+		log.Errorf("db create error, %s", err.Error())
+		return err
+	}
+	return nil
+}
diff --git a/app/admin/models/sys_menu.go b/app/admin/models/sys_menu.go
new file mode 100644
index 0000000..ea7e669
--- /dev/null
+++ b/app/admin/models/sys_menu.go
@@ -0,0 +1,50 @@
+package models
+
+import "go-admin/common/models"
+
+type SysMenu struct {
+	MenuId     int       `json:"menuId" gorm:"primaryKey;autoIncrement"`
+	MenuName   string    `json:"menuName" gorm:"size:128;"`
+	Title      string    `json:"title" gorm:"size:128;"`
+	Icon       string    `json:"icon" gorm:"size:128;"`
+	Path       string    `json:"path" gorm:"size:128;"`
+	Paths      string    `json:"paths" gorm:"size:128;"`
+	MenuType   string    `json:"menuType" gorm:"size:1;"`
+	Action     string    `json:"action" gorm:"size:16;"`
+	Permission string    `json:"permission" gorm:"size:255;"`
+	ParentId   int       `json:"parentId" gorm:"size:11;"`
+	NoCache    bool      `json:"noCache" gorm:"size:8;"`
+	Breadcrumb string    `json:"breadcrumb" gorm:"size:255;"`
+	Component  string    `json:"component" gorm:"size:255;"`
+	Sort       int       `json:"sort" gorm:"size:4;"`
+	Visible    string    `json:"visible" gorm:"size:1;"`
+	IsFrame    string    `json:"isFrame" gorm:"size:1;DEFAULT:0;"`
+	SysApi     []SysApi  `json:"sysApi" gorm:"many2many:sys_menu_api_rule"`
+	Apis       []int     `json:"apis" gorm:"-"`
+	DataScope  string    `json:"dataScope" gorm:"-"`
+	Params     string    `json:"params" gorm:"-"`
+	RoleId     int       `gorm:"-"`
+	Children   []SysMenu `json:"children,omitempty" gorm:"-"`
+	IsSelect   bool      `json:"is_select" gorm:"-"`
+	models.ControlBy
+	models.ModelTime
+}
+
+type SysMenuSlice []SysMenu
+
+func (x SysMenuSlice) Len() int           { return len(x) }
+func (x SysMenuSlice) Less(i, j int) bool { return x[i].Sort < x[j].Sort }
+func (x SysMenuSlice) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+
+func (*SysMenu) TableName() string {
+	return "sys_menu"
+}
+
+func (e *SysMenu) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysMenu) GetId() interface{} {
+	return e.MenuId
+}
diff --git a/app/admin/models/sys_opera_log.go b/app/admin/models/sys_opera_log.go
new file mode 100644
index 0000000..e29a54d
--- /dev/null
+++ b/app/admin/models/sys_opera_log.go
@@ -0,0 +1,88 @@
+package models
+
+import (
+	"encoding/json"
+	"errors"
+	"time"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"github.com/go-admin-team/go-admin-core/storage"
+
+	"go-admin/common/models"
+)
+
+type SysOperaLog struct {
+	models.Model
+	Title         string    `json:"title" gorm:"size:255;comment:操作模块"`
+	BusinessType  string    `json:"businessType" gorm:"size:128;comment:操作类型"`
+	BusinessTypes string    `json:"businessTypes" gorm:"size:128;comment:BusinessTypes"`
+	Method        string    `json:"method" gorm:"size:128;comment:函数"`
+	RequestMethod string    `json:"requestMethod" gorm:"size:128;comment:请求方式 GET POST PUT DELETE"`
+	OperatorType  string    `json:"operatorType" gorm:"size:128;comment:操作类型"`
+	OperName      string    `json:"operName" gorm:"size:128;comment:操作者"`
+	DeptName      string    `json:"deptName" gorm:"size:128;comment:部门名称"`
+	OperUrl       string    `json:"operUrl" gorm:"size:255;comment:访问地址"`
+	OperIp        string    `json:"operIp" gorm:"size:128;comment:客户端ip"`
+	OperLocation  string    `json:"operLocation" gorm:"size:128;comment:访问位置"`
+	OperParam     string    `json:"operParam" gorm:"text;comment:请求参数"`
+	Status        string    `json:"status" gorm:"size:4;comment:操作状态 1:正常 2:关闭"`
+	OperTime      time.Time `json:"operTime" gorm:"comment:操作时间"`
+	JsonResult    string    `json:"jsonResult" gorm:"size:255;comment:返回数据"`
+	Remark        string    `json:"remark" gorm:"size:255;comment:备注"`
+	LatencyTime   string    `json:"latencyTime" gorm:"size:128;comment:耗时"`
+	UserAgent     string    `json:"userAgent" gorm:"size:255;comment:ua"`
+	CreatedAt     time.Time `json:"createdAt" gorm:"comment:创建时间"`
+	UpdatedAt     time.Time `json:"updatedAt" gorm:"comment:最后更新时间"`
+	models.ControlBy
+}
+
+func (*SysOperaLog) TableName() string {
+	return "sys_opera_log"
+}
+
+func (e *SysOperaLog) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysOperaLog) GetId() interface{} {
+	return e.Id
+}
+
+// SaveOperaLog 从队列中获取操作日志
+func SaveOperaLog(message storage.Messager) (err error) {
+	//准备db
+	db := sdk.Runtime.GetDbByKey(message.GetPrefix())
+	if db == nil {
+		err = errors.New("db not exist")
+		log.Errorf("host[%s]'s %s", message.GetPrefix(), err.Error())
+		// Log writing to the database ignores error
+		return nil
+	}
+	var rb []byte
+	rb, err = json.Marshal(message.GetValues())
+	if err != nil {
+		log.Errorf("json Marshal error, %s", err.Error())
+		// Log writing to the database ignores error
+		return nil
+	}
+	var l SysOperaLog
+	err = json.Unmarshal(rb, &l)
+	if err != nil {
+		log.Errorf("json Unmarshal error, %s", err.Error())
+		// Log writing to the database ignores error
+		return nil
+	}
+	// 超出100个字符返回值截断
+	if len(l.JsonResult) > 100 {
+		l.JsonResult = l.JsonResult[:100]
+	}
+	err = db.Create(&l).Error
+	if err != nil {
+		log.Errorf("db create error, %s", err.Error())
+		// Log writing to the database ignores error
+		return nil
+	}
+	return nil
+}
diff --git a/app/admin/models/sys_post.go b/app/admin/models/sys_post.go
new file mode 100644
index 0000000..705318a
--- /dev/null
+++ b/app/admin/models/sys_post.go
@@ -0,0 +1,30 @@
+package models
+
+import "go-admin/common/models"
+
+type SysPost struct {
+	PostId   int    `gorm:"primaryKey;autoIncrement" json:"postId"` //岗位编号
+	PostName string `gorm:"size:128;" json:"postName"`              //岗位名称
+	PostCode string `gorm:"size:128;" json:"postCode"`              //岗位代码
+	Sort     int    `gorm:"size:4;" json:"sort"`                    //岗位排序
+	Status   int    `gorm:"size:4;" json:"status"`                  //状态
+	Remark   string `gorm:"size:255;" json:"remark"`                //描述
+	models.ControlBy
+	models.ModelTime
+
+	DataScope string `gorm:"-" json:"dataScope"`
+	Params    string `gorm:"-" json:"params"`
+}
+
+func (*SysPost) TableName() string {
+	return "sys_post"
+}
+
+func (e *SysPost) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysPost) GetId() interface{} {
+	return e.PostId
+}
diff --git a/app/admin/models/sys_role.go b/app/admin/models/sys_role.go
new file mode 100644
index 0000000..d23fb17
--- /dev/null
+++ b/app/admin/models/sys_role.go
@@ -0,0 +1,35 @@
+package models
+
+import "go-admin/common/models"
+
+type SysRole struct {
+	RoleId    int        `json:"roleId" gorm:"primaryKey;autoIncrement"` // 角色编码
+	RoleName  string     `json:"roleName" gorm:"size:128;"`              // 角色名称
+	Status    string     `json:"status" gorm:"size:4;"`                  // 状态 1禁用 2正常
+	RoleKey   string     `json:"roleKey" gorm:"size:128;"`               //角色代码
+	RoleSort  int        `json:"roleSort" gorm:""`                       //角色排序
+	Flag      string     `json:"flag" gorm:"size:128;"`                  //
+	Remark    string     `json:"remark" gorm:"size:255;"`                //备注
+	Admin     bool       `json:"admin" gorm:"size:4;"`
+	DataScope string     `json:"dataScope" gorm:"size:128;"`
+	Params    string     `json:"params" gorm:"-"`
+	MenuIds   []int      `json:"menuIds" gorm:"-"`
+	DeptIds   []int      `json:"deptIds" gorm:"-"`
+	SysDept   []SysDept  `json:"sysDept" gorm:"many2many:sys_role_dept;foreignKey:RoleId;joinForeignKey:role_id;references:DeptId;joinReferences:dept_id;"`
+	SysMenu   *[]SysMenu `json:"sysMenu" gorm:"many2many:sys_role_menu;foreignKey:RoleId;joinForeignKey:role_id;references:MenuId;joinReferences:menu_id;"`
+	models.ControlBy
+	models.ModelTime
+}
+
+func (*SysRole) TableName() string {
+	return "sys_role"
+}
+
+func (e *SysRole) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysRole) GetId() interface{} {
+	return e.RoleId
+}
diff --git a/app/admin/models/sys_user.go b/app/admin/models/sys_user.go
new file mode 100644
index 0000000..eab2cad
--- /dev/null
+++ b/app/admin/models/sys_user.go
@@ -0,0 +1,77 @@
+package models
+
+import (
+	"go-admin/common/models"
+	"golang.org/x/crypto/bcrypt"
+	"gorm.io/gorm"
+)
+
+type SysUser struct {
+	UserId   int      `gorm:"primaryKey;autoIncrement;comment:编码"  json:"userId"`
+	Username string   `json:"username" gorm:"size:64;comment:用户名"`
+	Password string   `json:"-" gorm:"size:128;comment:密码"`
+	NickName string   `json:"nickName" gorm:"size:128;comment:昵称"`
+	Phone    string   `json:"phone" gorm:"size:11;comment:手机号"`
+	RoleId   int      `json:"roleId" gorm:"size:20;comment:角色ID"`
+	Salt     string   `json:"-" gorm:"size:255;comment:加盐"`
+	Avatar   string   `json:"avatar" gorm:"size:255;comment:头像"`
+	Sex      string   `json:"sex" gorm:"size:255;comment:性别"`
+	Email    string   `json:"email" gorm:"size:128;comment:邮箱"`
+	DeptId   int      `json:"deptId" gorm:"size:20;comment:部门"`
+	PostId   int      `json:"postId" gorm:"size:20;comment:岗位"`
+	Remark   string   `json:"remark" gorm:"size:255;comment:备注"`
+	Status   string   `json:"status" gorm:"size:4;comment:状态"`
+	DeptIds  []int    `json:"deptIds" gorm:"-"`
+	PostIds  []int    `json:"postIds" gorm:"-"`
+	RoleIds  []int    `json:"roleIds" gorm:"-"`
+	Dept     *SysDept `json:"dept"`
+	models.ControlBy
+	models.ModelTime
+}
+
+func (*SysUser) TableName() string {
+	return "sys_user"
+}
+
+func (e *SysUser) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysUser) GetId() interface{} {
+	return e.UserId
+}
+
+// Encrypt 加密
+func (e *SysUser) Encrypt() (err error) {
+	if e.Password == "" {
+		return
+	}
+
+	var hash []byte
+	if hash, err = bcrypt.GenerateFromPassword([]byte(e.Password), bcrypt.DefaultCost); err != nil {
+		return
+	} else {
+		e.Password = string(hash)
+		return
+	}
+}
+
+func (e *SysUser) BeforeCreate(_ *gorm.DB) error {
+	return e.Encrypt()
+}
+
+func (e *SysUser) BeforeUpdate(_ *gorm.DB) error {
+	var err error
+	if e.Password != "" {
+		err = e.Encrypt()
+	}
+	return err
+}
+
+func (e *SysUser) AfterFind(_ *gorm.DB) error {
+	e.DeptIds = []int{e.DeptId}
+	e.PostIds = []int{e.PostId}
+	e.RoleIds = []int{e.RoleId}
+	return nil
+}
diff --git a/app/admin/models/sysmodel/article.go b/app/admin/models/sysmodel/article.go
new file mode 100644
index 0000000..7913f8b
--- /dev/null
+++ b/app/admin/models/sysmodel/article.go
@@ -0,0 +1,72 @@
+package sysmodel
+
+import "time"
+
+// 文章中心
+type GetArticleListReq struct {
+	TypeID   int    `json:"category_id" query:"category_id"` // 类别 ID
+	Language string `json:"-"`                               //
+}
+
+type ArticleCenterList struct {
+	Type      int    `json:"type"` // 类型:1 文章类别,2 文章
+	ID        int    `json:"id"`
+	ParentID  int    `json:"parent_id"`
+	Icon      string `json:"icon"`
+	Title     string `json:"title"`
+	JumpRoute string `json:"jump_route"` // 自助服务的跳转路由
+}
+
+type GetArticleCenterResp struct {
+	Type      int                    `json:"type"` // 类型:1 文章类别,2 文章
+	ID        int                    `json:"id"`
+	Icon      string                 `json:"icon"`
+	Title     string                 `json:"title"`
+	JumpRoute string                 `json:"jump_route"`
+	Child     []GetArticleCenterResp `json:"child"`
+}
+
+// 文章类别
+type GetArticleCategoryResp struct {
+	ID       int                      `json:"id"`
+	ParentID int                      `json:"parent_id"`
+	Title    string                   `json:"title"`
+	Child    []GetArticleCategoryResp `json:"child"`
+}
+
+// 文章列表
+type GetArticleListResp struct {
+	ID         int    `json:"id"`
+	CategoryID int    `json:"category_id"`
+	Title      string `json:"title"`
+	Content    string `json:"content"`
+	CreateTime int64  `json:"create_time"`
+}
+
+// 文章详情
+type GetArticleDetailResp struct {
+	ID             int       `json:"id"`
+	Title          string    `json:"title"`
+	Content        string    `json:"content"`
+	CreateTime     time.Time `json:"-"` //
+	UpdateTime     time.Time `json:"-"` //
+	CreateTimeResp int64     `json:"create_time"`
+}
+
+// 文章搜索
+type GetArticleSearchList struct {
+	ID             int            `json:"id"`
+	TypeID         int            `json:"category_id"`
+	Path           string         `json:"path"`
+	Title          string         `json:"title"`
+	Content        string         `json:"content"`
+	CreateTime     time.Time      `json:"-"`
+	CreateTimeResp int64          `json:"create_time"`
+	AllParent      []CategoryList `json:"all_parent"`
+}
+
+type CategoryList struct {
+	ID       int    `json:"id"`
+	ParentID int    `json:"parent_id"`
+	Title    string `json:"title"`
+}
diff --git a/app/admin/models/sysmodel/authentication.go b/app/admin/models/sysmodel/authentication.go
new file mode 100644
index 0000000..f5cde8c
--- /dev/null
+++ b/app/admin/models/sysmodel/authentication.go
@@ -0,0 +1,384 @@
+package sysmodel
+
+import (
+	statuscode "go-admin/common/status_code"
+	"go-admin/pkg/cryptohelper/md5helper"
+	"go-admin/pkg/emailhelper"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+
+	"go-admin/pkg/utility"
+)
+
+type FrontedUserRegisterReq struct {
+	Account       string `json:"account"`         // 账号
+	RegisterType  int    `json:"register_type"`   // 注册类型 1: 手机 2: 邮箱
+	PhoneAreaCode string `json:"phone_area_code"` // 区域电话代码
+	Phone         string `json:"phone"`           // 手机号码
+	Captcha       string `json:"captcha"`         // 验证码:携带验证码注册
+	Email         string `json:"email"`           // 邮箱地址
+	Password      string `json:"password"`        // 密码
+	CheckPassword string `json:"check_password"`  // 确认密码
+	InviteCode    string `json:"invite_code"`     // 邀请码
+	IP            string `json:"-"`               // IP
+	Pid           int    `json:"-"`               // 推荐人ID
+
+}
+
+// CheckParams 校验邮箱参数
+func (i *FrontedUserRegisterReq) CheckParams() int {
+	if i.RegisterType == TSmsCode {
+		if i.Phone == "" {
+			return statuscode.PhoneRequired
+		}
+		if i.PhoneAreaCode == "+86" {
+			if !utility.IsMobileChina(i.Phone) {
+				return statuscode.PhoneFormatInvalid
+			}
+		}
+		i.Account = i.Phone
+
+	} else if i.RegisterType == TEmailCode {
+		// 邮箱校验
+		if i.Email == "" {
+			return statuscode.EmailRequired
+		}
+		if !emailhelper.CheckIsEmail(i.Email) {
+			return statuscode.EmailFormatInvalid
+		}
+		i.Account = i.Email
+	} else {
+		log.Error("only support email and phone register")
+		return statuscode.ParameterInvalid
+	}
+	return statuscode.OK
+}
+
+/**
+ * 身份认证模型
+ */
+
+// UserRegisterReq 用户注册
+type UserRegisterReq struct {
+	Account        string `json:"account"`         // 账号
+	RegisterType   int    `json:"register_type"`   // 注册类型 1: 手机 2: 邮箱
+	PhoneAreaCode  string `json:"phone_area_code"` // 区域电话代码
+	Phone          string `json:"phone"`           // 手机号码
+	Email          string `json:"email"`           // 邮箱地址
+	Password       string `json:"password"`        // 密码
+	Captcha        string `json:"captcha"`         // 验证码:1-不带验证码注册,仅验证注册信息是否合法;2-携带验证码注册,成功后返回 token
+	InviteCode     string `json:"invite_code"`     // 邀请码
+	UserAddress    string `json:"user_address"`    // 地址
+	Receive        string `json:"-"`               // 验证码接收方
+	PhoneBindState int    `json:"-"`               // 手机绑定状态
+	EmailBindState int    `json:"-"`               // 邮箱绑定状态
+	IP             string `json:"-"`               // IP
+	Source         int    `json:"-"`               // 来源:0-未知,1-Android,2-iOS,3-PC
+	AgentCode      string `json:"agent_code"`      // 代理邀请码
+	AreaId         int    `json:"areaid"`          // 地区序号
+}
+
+func (i *UserRegisterReq) Valid() int {
+	// 注册类型
+	if i.RegisterType == TSmsCode {
+		// 手机校验
+		if i.PhoneAreaCode == "" {
+			return statuscode.PleaseSelectThePhoneAreaCode
+		}
+		if i.Phone == "" {
+			return statuscode.PhoneRequired
+		}
+		if i.PhoneAreaCode == "86" {
+			if !utility.IsMobileChina(i.Phone) {
+				return statuscode.PhoneFormatInvalid
+			}
+		} /*else {
+			if !utility.ValidatePhoneNumber(i.Phone) {
+				return statuscode.Differentarea
+			}
+		}*/
+
+		i.Account = i.Phone
+		i.Receive = i.Phone
+		i.PhoneBindState = AuthBoundOpen
+
+	} else if i.RegisterType == TEmailCode {
+		// 邮箱校验
+		if i.Email == "" {
+			return statuscode.EmailRequired
+		}
+		if !emailhelper.CheckIsEmail(i.Email) {
+			return statuscode.EmailFormatInvalid
+		}
+
+		i.Account = i.Email
+		i.Receive = i.Email
+		i.EmailBindState = AuthBoundOpen
+
+	} else {
+		log.Error("only support email and phone register")
+		return statuscode.ParameterInvalid
+	}
+
+	// 密码校验
+	if i.Password == "" {
+		return statuscode.PasswordRequired
+	}
+	if !utility.CheckPasswordOk(8, 32, i.Password) {
+		return statuscode.PasswordRules
+	}
+	// 加密密码
+	i.Password = md5helper.MD52(i.Password)
+
+	return statuscode.OK
+}
+
+// TokenResp 注册成功,返回 token
+type TokenResp struct {
+	JwtToken  string `json:"jwt_token"`
+	JwtExpire string `json:"jwt_expire"`
+}
+
+// UserAccountPwdLoginReq 用户账号密码登录
+type UserAccountPwdLoginReq struct {
+	LoginType       int    `json:"login_type"`      // 1 手机,2 邮箱
+	PhoneAreaCode   string `json:"phone_area_code"` // 区域电话代码
+	Phone           string `json:"phone"`           // 手机号码
+	Email           string `json:"email"`           // 邮箱
+	Password        string `json:"password"`        // 密码
+	CaptchaEmbedded        // 嵌入验证码
+	LoginIP         string `json:"-"`         // IP
+	Source          int    `json:"-"`         // 来源:0-未知,1-Android,2-iOS,3-PC
+	DeviceID        string `json:"-"`         // 设备ID
+	TimeStamp       string `json:"sessionId"` //时间戳
+}
+type UserRefreshTokenReq struct {
+	RefreshKey  string `json:"refresh_key"`  // 刷新token的key
+	RefreshTime string `json:"refresh_time"` // 刷新时间戳
+}
+
+func (l *UserAccountPwdLoginReq) Valid() int {
+	// 登录类型
+	if l.LoginType == TSmsCode {
+		// 手机校验
+		if l.PhoneAreaCode == "86" {
+			if !utility.IsMobileChina(l.Phone) {
+				return statuscode.PhoneFormatInvalid
+			}
+		} /*else {
+			if !utility.ValidatePhoneNumber(l.Phone) {
+				return statuscode.Differentarea
+			}
+		}*/
+	} else if l.LoginType == TEmailCode {
+		// 邮箱校验
+		if !emailhelper.CheckIsEmail(l.Email) {
+			return statuscode.EmailFormatInvalid
+		}
+	} else {
+		return statuscode.ParameterInvalid
+	}
+
+	// 密码校验
+	if len(l.Password) == 0 {
+		return statuscode.PasswordRequired
+	}
+	l.Password = md5helper.MD52(l.Password)
+
+	return statuscode.OK
+}
+
+// UserLoginResp 用户登录响应
+type UserLoginResp struct {
+	UserAccount   string `json:"user_account"`    // 账号
+	AreaPhoneCode string `json:"area_phone_code"` // 区域电话代码
+	PhoneNumber   string `json:"phone_number"`    // 手机
+	EmailAddr     string `json:"email_addr"`      // 邮箱
+	PhonePass     string `json:"phone_pass"`      // 手机加密显示
+	EmailPass     string `json:"email_pass"`      // 邮箱加密显示
+	IsPhoneAuth   int    `json:"is_phone_auth"`   // 是否开启手机验证 0否,1是
+	IsEmailAuth   int    `json:"is_email_auth"`   // 是否开启手机验证 0否,1是
+	IsGoogleAuth  int    `json:"is_google_auth"`  // 是否开启谷歌验证 0否,1是
+	LoginType     int    `json:"login_type"`      // 登录类型 1 手机 2 邮箱
+	IdCardState   int    `json:"id_card_state"`   // 实名认证审核状态:1未审核,2审核通过,3审核不通过4审核中
+	JwtToken      string `json:"jwt_token"`       // 登录成功返回 token
+	JwtExpire     string `json:"jwt_expire"`      // token过期时间
+}
+
+// 扫码登录 - 秘钥
+type ScanLoginSecret struct {
+	Secret   string `json:"secret"`    // 秘钥
+	Status   int    `json:"status"`    // 状态:0 初始化,1 登录中,2 登录成功,-1 已过期
+	Token    string `json:"token"`     // 登录成功返回
+	IP       string `json:"ip"`        // 登录IP(PC)
+	Position string `json:"position"`  // IP归属地
+	DeviceID string `json:"device_id"` // 登录设备(PC)
+	Time     int64  `json:"time"`      // 秘钥生成时间
+}
+
+// 扫码登录 - APP扫描请求参数
+type ScanLoginScanReq struct {
+	Secret  string `json:"secret"`  // 二维码秘钥
+	Confirm int    `json:"confirm"` // 确认登录:0-查询登录状态,1-确认登录
+}
+
+// UserChangePwdReq 修改密码
+type UserChangePwdReq struct {
+	NewPassword     string `json:"new_password"` // 密码
+	OldPassword     string `json:"old_password"` // 旧密码
+	CaptchaEmbedded        // 嵌入验证码
+	UserId          int    `json:"-"`
+}
+
+func (p *UserChangePwdReq) Valid() int {
+	if p.OldPassword == "" {
+		return statuscode.OriginalPasswordRequired
+	}
+
+	if p.NewPassword == "" {
+		return statuscode.NewPasswordRequired
+	}
+
+	if !utility.CheckPasswordOk(8, 32, p.NewPassword) {
+		return statuscode.PasswordRules
+	}
+
+	p.OldPassword = md5helper.MD52(p.OldPassword)
+	p.NewPassword = md5helper.MD52(p.NewPassword)
+
+	return statuscode.OK
+}
+
+// ResetPwdReq 重置密码
+type ResetPwdReq struct {
+	RetrieveType  int    `json:"retrieve_type"`   // 找回密码类型:1 手机,2 邮箱
+	PhoneAreaCode string `json:"phone_area_code"` // 区域电话代码
+	Phone         string `json:"phone"`           // 手机号码
+	Email         string `json:"email"`           // 邮箱地址
+	Password      string `json:"password"`        // 密码
+	Credentials   string `json:"credentials"`     // 凭证
+	UserID        int    `json:"-"`
+}
+
+func (self *ResetPwdReq) Valid() int {
+	// 发送手机验证码
+	if self.RetrieveType == TSmsCode {
+		// 区域电话代码不能为空
+		if self.PhoneAreaCode == "" {
+			return statuscode.PleaseSelectThePhoneAreaCode
+		}
+
+		// 电话号码不能为空
+		if self.Phone == "" {
+			return statuscode.PhoneRequired
+		}
+
+		// 校验手机号码是否合法
+		if self.PhoneAreaCode == "86" {
+			if !utility.IsMobileChina(self.Phone) {
+				return statuscode.PhoneFormatInvalid
+			}
+		} /*else {
+			if !utility.ValidatePhoneNumber(self.Phone) {
+				return statuscode.Differentarea
+			}
+		}*/
+
+	} else if self.RetrieveType == TEmailCode { // 发送邮箱验证码
+		// 邮箱不能为空
+		if self.Email == "" {
+			return statuscode.EmailRequired
+		}
+
+		// 校验邮箱是否合法
+		if !emailhelper.CheckIsEmail(self.Email) {
+			return statuscode.EmailFormatInvalid
+		}
+
+	} else {
+
+		log.Error("only support phone and email auth")
+		return statuscode.ParameterInvalid
+	}
+
+	// 传凭证时,才校验密码
+	if len(self.Credentials) > 0 {
+		if self.Password == "" {
+			return statuscode.NewPasswordRequired
+		}
+		if !utility.CheckPasswordOk(8, 32, self.Password) {
+			return statuscode.PasswordRules
+		}
+
+		self.Password = md5helper.MD52(self.Password)
+	}
+
+	return statuscode.OK
+}
+
+// ResetPwdResp 重置密码响应
+type ResetPwdResp struct {
+	RetrieveType  int    `json:"retrieve_type"`   // 找回密码类型:1 手机,2 邮箱
+	Account       string `json:"account"`         // 账号
+	AreaPhoneCode string `json:"area_phone_code"` // 区域电话代码
+	PhoneNumber   string `json:"phone_number"`    // 手机号码
+	EmailAddr     string `json:"email_addr"`      // 邮箱地址
+	PhonePass     string `json:"phone_pass"`      // 手机加密显示
+	EmailPass     string `json:"email_pass"`      // 邮箱加密显示
+	IsPhoneAuth   int    `json:"is_phone_auth"`   // 是否绑定手机 0否,1是
+	IsEmailAuth   int    `json:"is_email_auth"`   // 是否绑定邮箱 0否,1是
+	IsGoogleAuth  int    `json:"is_google_auth"`  // 是否绑定谷歌验证器
+}
+
+// 重置密码安全校验
+type ResetPwdCheck struct {
+	RetrieveType    int    `json:"retrieve_type"`   // 找回密码类型:1 手机,2 邮箱
+	PhoneAreaCode   string `json:"phone_area_code"` // 区域电话代码
+	Phone           string `json:"phone"`           // 手机号码
+	Email           string `json:"email"`           // 邮箱地址
+	CaptchaEmbedded        // 嵌入验证码
+}
+
+func (self *ResetPwdCheck) Valid() int {
+	// 发送手机验证码
+	if self.RetrieveType == TSmsCode {
+		// 区域电话代码不能为空
+		if self.PhoneAreaCode == "" {
+			return statuscode.PleaseSelectThePhoneAreaCode
+		}
+
+		// 电话号码不能为空
+		if self.Phone == "" {
+			return statuscode.PhoneRequired
+		}
+
+		// 校验手机号码是否合法
+		if self.PhoneAreaCode == "86" {
+			if !utility.IsMobileChina(self.Phone) {
+				return statuscode.PhoneFormatInvalid
+			}
+		} /*else {
+			if !utility.ValidatePhoneNumber(self.Phone) {
+				return statuscode.Differentarea
+			}
+		}*/
+
+	} else if self.RetrieveType == TEmailCode { // 发送邮箱验证码
+		// 邮箱不能为空
+		if self.Email == "" {
+			return statuscode.EmailRequired
+		}
+
+		// 校验邮箱是否合法
+		if !emailhelper.CheckIsEmail(self.Email) {
+			return statuscode.EmailFormatInvalid
+		}
+
+	} else {
+
+		log.Error("only support phone and email auth")
+		return statuscode.ParameterInvalid
+	}
+
+	return statuscode.OK
+}
diff --git a/app/admin/models/sysmodel/authenticator.go b/app/admin/models/sysmodel/authenticator.go
new file mode 100644
index 0000000..61b216c
--- /dev/null
+++ b/app/admin/models/sysmodel/authenticator.go
@@ -0,0 +1,124 @@
+package sysmodel
+
+import (
+	"go-admin/common/const/enum/businesstype"
+	statuscode "go-admin/common/status_code"
+	"go-admin/pkg/emailhelper"
+	"go-admin/pkg/utility"
+)
+
+/**
+ * 验证器模型
+ */
+
+// 验证器状态
+var AuthNotBound = 0   // 未绑定
+var AuthBoundOpen = 1  // 绑定开启
+var AuthBoundClose = 2 // 绑定未开启
+
+// GetGoogleSecretResp 获取 Google 验证器秘钥
+type GetGoogleSecretResp struct {
+	Secret     string `json:"secret"`
+	GoogleAuth string `json:"google_auth"`
+}
+
+// UserAuthSwitchStatus 用户身份验证器开关状态
+type UserAuthSwitchStatus struct {
+	PhoneAuth    int    `db:"phoneauthisopen"`    // 手机验证器:0 关,1 开
+	EmailAuth    int    `db:"emailauthisopen"`    // 邮箱验证器:0 关,1 开
+	GoogleAuth   int    `db:"googleidcardisopen"` // 谷歌验证器:0 关,1 开
+	GoogleSecret string `db:"googlesecret"`       // 谷歌秘钥
+}
+
+// Authenticator 验证器-验证结构
+type Authenticator struct {
+	UserID        int
+	PhoneAuth     int                       // 手机验证器:0 关,1 开
+	EmailAuth     int                       // 邮箱验证器:0 关,1 开
+	GoogleAuth    int                       // 谷歌验证器:0 关,1 开
+	Phone         string                    // 手机号
+	Email         string                    // 邮箱
+	GoogleSecret  string                    // 谷歌秘钥
+	SmsCaptcha    string                    // 手机验证码
+	EmailCaptcha  string                    // 邮箱验证码
+	GoogleCaptcha string                    // 谷歌验证码
+	BusinessType  businesstype.BusinessType // 业务类型
+}
+
+// AuthenticatorSwitch 身份验证开关【请求】结构
+type AuthenticatorSwitch struct {
+	OperationType    int                       `json:"operation_type"`     // 操作类型:1-开启,2-更改,3-关闭
+	ValidatorType    int                       `json:"validator_type"`     // 验证器类型:1-手机,2-邮箱,3-Google
+	SmsCaptcha       string                    `json:"sms_captcha"`        // 手机验证码
+	EmailCaptcha     string                    `json:"email_captcha"`      // 邮箱验证码
+	GoogleCaptcha    string                    `json:"google_captcha"`     // 谷歌验证码
+	NewPhoneArea     string                    `json:"new_phone_area"`     // 新区号:开启、更改手机验证器时必传
+	NewPhone         string                    `json:"new_phone"`          // 新手机号:开启、更改手机验证器时必传
+	NewPhoneCaptcha  string                    `json:"new_phone_captcha"`  // 新手机验证码
+	NewEmail         string                    `json:"new_email"`          // 新邮箱:开启、更改邮箱验证器时必传
+	NewEmailCaptcha  string                    `json:"new_email_captcha"`  // 新邮箱验证码:开启、更改邮箱验证器时必传
+	NewGoogleCaptcha string                    `json:"new_google_captcha"` // 新邮箱验证码:开启、更改邮箱验证器时必传
+	UserID           int                       `json:"-"`                  //
+	BusinessType     businesstype.BusinessType `json:"-"`                  // 业务类型:11-开启手机验证,21-更改手机验证,31-关闭手机验证,12-开启邮箱验证,22-更改邮箱验证,32-关闭邮箱验证,13-开启Google验证,23-更改Google验证,33-关闭Google验证
+}
+
+func (self *AuthenticatorSwitch) Valid() int {
+	// 计算业务类型
+	self.BusinessType = businesstype.BusinessType(self.OperationType*10 + self.ValidatorType)
+
+	switch self.BusinessType {
+
+	case businesstype.OpenPhoneAuth, businesstype.ChangePhoneAuth: // 开启手机 & 更改手机
+		if self.NewPhoneArea == "" {
+			return statuscode.PleaseSelectThePhoneAreaCode
+		}
+		if self.NewPhone == "" {
+			return statuscode.PhoneRequired
+		}
+		if self.NewPhoneCaptcha == "" {
+			return statuscode.PhoneCaptchaRequired
+		}
+
+		if self.NewPhoneArea == "86" {
+			if !utility.IsMobileChina(self.NewPhone) {
+				return statuscode.PhoneFormatInvalid
+			}
+		} /*else {
+			if !utility.ValidatePhoneNumber(self.NewPhone) {
+				return enum.Differentarea
+			}
+		}*/
+
+		return statuscode.OK
+
+	case businesstype.ClosePhoneAuth: // 关闭手机
+
+	case businesstype.OpenEmailAuth, businesstype.ChangeEmailAuth: // 开启邮箱 & 更改邮箱
+		if self.NewEmail == "" {
+			return statuscode.EmailRequired
+		}
+		if self.NewEmailCaptcha == "" {
+			return statuscode.EmailCaptchaRequired
+		}
+
+		if !emailhelper.CheckIsEmail(self.NewEmail) {
+			return statuscode.EmailFormatInvalid
+		}
+
+		return statuscode.OK
+
+	case businesstype.CloseEmailAuth: // 关闭邮箱
+
+	case businesstype.OpenGoogleAuth: // 开启 Google
+		if self.NewGoogleCaptcha == "" {
+			return statuscode.GoogleCaptchaRequired
+		}
+	case businesstype.ChangeGoogleAuth: // 更改 Google 实质就是关闭,但业务类型要区分开
+	case businesstype.CloseGoogleAuth: // 关闭 Google
+
+	default:
+		return statuscode.UnsupportedBusinessType
+	}
+
+	return statuscode.OK
+}
diff --git a/app/admin/models/sysmodel/captcha.go b/app/admin/models/sysmodel/captcha.go
new file mode 100644
index 0000000..3f4aaaa
--- /dev/null
+++ b/app/admin/models/sysmodel/captcha.go
@@ -0,0 +1,116 @@
+package sysmodel
+
+import (
+	statuscode "go-admin/common/status_code"
+	"go-admin/pkg/emailhelper"
+	"go-admin/pkg/utility"
+	"time"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+)
+
+/**
+ * 验证码模型
+ */
+
+var TSmsCode = 1                         // 手机验证码
+var TEmailCode = 2                       // 邮箱验证码
+var CodeValidTime = 5 * 60 * time.Second // 验证码有效期 5min
+
+// SendCaptchaReq 发送验证码
+type SendCaptchaReq struct {
+	BusinessType  int    `json:"business_type"`   // 业务类型:1-注册,2-登录,3-找回密码,4-修改密码,11-开启手机验证,21-更改手机验证,31-关闭手机验证,12-开启邮箱验证,22-更改邮箱验证,32-关闭邮箱验证,13-开启Google验证,23-更改Google验证,33-关闭Google验证  100-手机验证码 101
+	SendType      int    `json:"send_type"`       // 发送验证码类型 1 手机 2 邮箱
+	IsNew         int    `json:"is_new"`          // 更改手机、邮箱验证时,新号码获取验证码需传 is_new: 1
+	PhoneAreaCode string `json:"phone_area_code"` // 区域电话代码
+	Phone         string `json:"phone"`           // 手机号码
+	Email         string `json:"email"`           // 邮箱地址
+	Uid           int    `json:"-"`               // 存用户ID用于判断是否登录,从token中解析得到,而非传入
+	IP            string `json:"-"`               // IP
+	Receive       string `json:"-"`               // 验证码接收方
+}
+
+func (self *SendCaptchaReq) Valid() int {
+	// 业务类型不能为空
+	if self.BusinessType <= 0 {
+		log.Error("send verify code business info unknown")
+		return statuscode.ParameterInvalid
+	}
+	// 业务类型 1 注册 2 登录 3 找回密码 无须登录,其余业务须登录
+	if self.BusinessType > 3 && self.Uid == 0 {
+		return statuscode.NotLoggedIn
+	}
+
+	// 发送手机验证码
+	if self.SendType == TSmsCode {
+		// 区域电话代码不能为空
+		if self.PhoneAreaCode == "" {
+			return statuscode.PleaseSelectThePhoneAreaCode
+		}
+
+		// 电话号码不能为空
+		if self.Phone == "" {
+			return statuscode.PhoneRequired
+		}
+
+		// 校验手机号码是否合法
+		if self.PhoneAreaCode == "86" {
+			if !utility.IsMobileChina(self.Phone) {
+				return statuscode.PhoneFormatInvalid
+			}
+		} /*else {
+			if !utility.ValidatePhoneNumber(self.Phone) {
+				return enum.Differentarea
+			}
+		}*/
+
+		// 接收方
+		self.Receive = self.Phone
+
+	} else if self.SendType == TEmailCode { // 发送邮箱验证码
+		// 邮箱不能为空
+		if self.Email == "" {
+			return statuscode.EmailRequired
+		}
+
+		// 校验邮箱是否合法
+		if !emailhelper.CheckIsEmail(self.Email) {
+			return statuscode.EmailFormatInvalid
+		}
+
+		// 接收方
+		self.Receive = self.Email
+
+	} else {
+		log.Error("only support phone and email auth")
+		return statuscode.ParameterInvalid
+	}
+
+	return statuscode.OK
+}
+
+// CaptchaEmbedded 校验验证码的嵌入结构
+type CaptchaEmbedded struct {
+	SmsCaptcha    string `json:"sms_captcha"`    // 手机验证码
+	EmailCaptcha  string `json:"email_captcha"`  // 邮箱验证码
+	GoogleCaptcha string `json:"google_captcha"` // 谷歌验证码
+}
+
+// CheckCaptcha 校验验证码
+type CheckCaptcha struct {
+	BusinessType int       `db:"businesstype"` // 业务类型
+	Receive      string    `db:"phone"`        // 接收方, 手机或邮箱
+	Captcha      string    `db:"code"`         // 验证码
+	Flag         int       `db:"verifyflag"`   // 标志:0-未验证,1-已验证
+	Now          time.Time `db:"now"`
+}
+
+// Credential 验证码校验通过生成凭证
+type Credential struct {
+	BusinessType int    // 业务类型
+	UserID       int    // 用户ID
+	Phone        string // 手机
+	Email        string // 邮箱
+	Time         int64  // 凭证生成时间戳
+	Rand         int64  // 随机种子
+}
diff --git a/app/admin/models/sysmodel/sysstatuscode.go b/app/admin/models/sysmodel/sysstatuscode.go
new file mode 100644
index 0000000..4af6a60
--- /dev/null
+++ b/app/admin/models/sysmodel/sysstatuscode.go
@@ -0,0 +1,13 @@
+package sysmodel
+
+type StatusCode struct {
+	Code    int    `db:"code" gorm:"code"`       // 状态码
+	Explain string `db:"explain" gorm:"explain"` // 描述
+	ZhCN    string `db:"zh_cn" gorm:"zh_cn"`     // 简体中文
+	ZhHK    string `db:"zh_hk" gorm:"zh_hk"`     // 繁体中文
+	En      string `db:"en" gorm:"en"`           // 英文
+}
+
+func (StatusCode) TableName() string {
+	return "sys_status_code"
+}
diff --git a/app/admin/models/vts_recharge.go b/app/admin/models/vts_recharge.go
new file mode 100644
index 0000000..97cc665
--- /dev/null
+++ b/app/admin/models/vts_recharge.go
@@ -0,0 +1,47 @@
+package models
+
+import (
+	"github.com/shopspring/decimal"
+	"time"
+
+	"go-admin/common/models"
+)
+
+type VtsRecharge struct {
+	models.Model
+
+	CoinCode        string          `json:"coinCode" gorm:"type:varchar(20);comment:币种"`
+	TranType        int             `json:"tranType" gorm:"type:int;comment:类型:1-线上 2-内部"`
+	OrderNo         string          `json:"orderNo" gorm:"type:varchar(255);comment:订单号"`
+	AdUserId        int             `json:"adUserId" gorm:"type:bigint;comment:用户id"`
+	Amount          decimal.Decimal `json:"amount" gorm:"type:decimal(32,8);comment:订单价格"`
+	PriceCurrency   string          `json:"priceCurrency" gorm:"type:varchar(20);comment:CoinGate结算货币代码"`
+	ReceiveAmount   decimal.Decimal `json:"receiveAmount" gorm:"type:decimal(32,8);comment:实收数量"`
+	PayAmount       decimal.Decimal `json:"payAmount" gorm:"type:decimal(32,8);comment:实际支付数量"`
+	PayCurrency     string          `json:"payCurrency" gorm:"type:varchar(255);comment:实际支付的加密货币"`
+	UnderpaidAmount decimal.Decimal `json:"underpaidAmount" gorm:"type:decimal(32,8);comment:买家少付数量"`
+	OverpaidAmount  decimal.Decimal `json:"overpaidAmount" gorm:"type:decimal(32,8);comment:买家多付数量"`
+	IsRefundable    int             `json:"isRefundable" gorm:"type:tinyint;comment:指示购物者是否可以请求发票退款"`
+	WalletCreateAt  time.Time       `json:"walletCreateAt" gorm:"type:datetime;comment:第三方创建时间"`
+	WalletId        int             `json:"walletId" gorm:"type:int;comment:第三方钱包订单"`
+	Fee             decimal.Decimal `json:"fee" gorm:"type:decimal(32,8);comment:手续费"`
+	CallbackAt      time.Time       `json:"callbackAt" gorm:"type:datetime;comment:回调时间"`
+	Status          string          `json:"status" gorm:"type:varchar(20);comment:状态(字典 vts_recharge_status)"`
+	ConfirmStatus   string          `json:"confirmStatus" gorm:"type:varchar(20);comment:确认状态(字典 vts_confirm_status)"`
+	Remark          string          `json:"remark" gorm:"type:varchar(500);comment:备注"`
+	models.ModelTime
+	models.ControlBy
+}
+
+func (VtsRecharge) TableName() string {
+	return "vts_recharge"
+}
+
+func (e *VtsRecharge) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *VtsRecharge) GetId() interface{} {
+	return e.Id
+}
diff --git a/app/admin/router/init_router.go b/app/admin/router/init_router.go
new file mode 100644
index 0000000..61fb978
--- /dev/null
+++ b/app/admin/router/init_router.go
@@ -0,0 +1,40 @@
+package router
+
+import (
+	"os"
+
+	"github.com/gin-gonic/gin"
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	common "go-admin/common/middleware"
+)
+
+// InitRouter 路由初始化,不要怀疑,这里用到了
+func InitRouter() {
+	var r *gin.Engine
+	h := sdk.Runtime.GetEngine()
+	if h == nil {
+		log.Fatal("not found engine...")
+		os.Exit(-1)
+	}
+	switch h.(type) {
+	case *gin.Engine:
+		r = h.(*gin.Engine)
+	default:
+		log.Fatal("not support other engine")
+		os.Exit(-1)
+	}
+
+	// the jwt middleware
+	authMiddleware, err := common.AuthInit()
+	if err != nil {
+		log.Fatalf("JWT Init Error, %s", err.Error())
+	}
+
+	// 注册系统路由
+	InitSysRouter(r, authMiddleware)
+
+	// 注册业务路由
+	// TODO: 这里可存放业务路由,里边并无实际路由只有演示代码
+	InitExamplesRouter(r, authMiddleware)
+}
diff --git a/app/admin/router/line_account_setting.go b/app/admin/router/line_account_setting.go
new file mode 100644
index 0000000..6597462
--- /dev/null
+++ b/app/admin/router/line_account_setting.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineAccountSettingRouter)
+}
+
+// registerLineAccountSettingRouter
+func registerLineAccountSettingRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineAccountSetting{}
+	r := v1.Group("/line-account-setting").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_api_group.go b/app/admin/router/line_api_group.go
new file mode 100644
index 0000000..04da850
--- /dev/null
+++ b/app/admin/router/line_api_group.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineApiGroupRouter)
+}
+
+// registerLineApiGroupRouter
+func registerLineApiGroupRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineApiGroup{}
+	r := v1.Group("/line-api-group").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_api_user.go b/app/admin/router/line_api_user.go
new file mode 100644
index 0000000..ae2c66e
--- /dev/null
+++ b/app/admin/router/line_api_user.go
@@ -0,0 +1,31 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/actions"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineApiUserRouter)
+}
+
+// registerLineApiUserRouter
+func registerLineApiUserRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineApiUser{}
+	r := v1.Group("/line-api-user").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+
+		r.POST("bind", api.Bind)               //绑定从属关系
+		r.POST("getUser", api.GetUser)         //获取未绑定的用户
+		r.POST("getMainUser", api.GetMainUser) //获取获取主账号的用户
+	}
+}
diff --git a/app/admin/router/line_coinnetwork.go b/app/admin/router/line_coinnetwork.go
new file mode 100644
index 0000000..391f428
--- /dev/null
+++ b/app/admin/router/line_coinnetwork.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineCoinnetworkRouter)
+}
+
+// registerLineCoinnetworkRouter
+func registerLineCoinnetworkRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineCoinnetwork{}
+	r := v1.Group("/line-coinnetwork").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_cointonetwork.go b/app/admin/router/line_cointonetwork.go
new file mode 100644
index 0000000..806176c
--- /dev/null
+++ b/app/admin/router/line_cointonetwork.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineCointonetworkRouter)
+}
+
+// registerLineCointonetworkRouter
+func registerLineCointonetworkRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineCointonetwork{}
+	r := v1.Group("/line-cointonetwork").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_direction.go b/app/admin/router/line_direction.go
new file mode 100644
index 0000000..ce84a42
--- /dev/null
+++ b/app/admin/router/line_direction.go
@@ -0,0 +1,39 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/actions"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineDirectionRouter)
+	routerNoVersion = append(routerNoVersion, registerLineDirectionNoVersionRouter)
+}
+
+func registerLineDirectionNoVersionRouter(v1 *gin.RouterGroup) {
+	api := apis.LineDirection{}
+
+	group := v1.Group("/Direction")
+	{
+		group.POST("addDirection", api.AddDirection) // 新增预估方向
+	}
+}
+
+// registerLineDirectionRouter
+func registerLineDirectionRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineDirection{}
+	r := v1.Group("/line-direction").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+
+		r.PUT("/reload-group", api.ReloadGroupData)
+	}
+}
diff --git a/app/admin/router/line_order_template_logs.go b/app/admin/router/line_order_template_logs.go
new file mode 100644
index 0000000..3bd90c6
--- /dev/null
+++ b/app/admin/router/line_order_template_logs.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineOrderTemplateLogsRouter)
+}
+
+// registerLineOrderTemplateLogsRouter
+func registerLineOrderTemplateLogsRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineOrderTemplateLogs{}
+	r := v1.Group("/line-order-template-logs").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_pre_order.go b/app/admin/router/line_pre_order.go
new file mode 100644
index 0000000..5753dcb
--- /dev/null
+++ b/app/admin/router/line_pre_order.go
@@ -0,0 +1,49 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/actions"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLinePreOrderRouter)
+	routerNoCheckRole = append(routerNoCheckRole, unRegisterLinePreOrderRouter)
+}
+
+// registerLinePreOrderRouter
+func registerLinePreOrderRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LinePreOrder{}
+	r := v1.Group("/line-pre-order").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+
+		r.POST("addOrder", actions.PermissionAction(), api.AddPreOrder)              //添加订单
+		r.POST("batchAddOrder", actions.PermissionAction(), api.BatchAddOrder)       //批量添加订单
+		r.POST("quickAddPreOrder", actions.PermissionAction(), api.QuickAddPreOrder) //快捷下单
+		r.POST("lever", actions.PermissionAction(), api.Lever)                       //设置杠杆
+		r.POST("marginType", actions.PermissionAction(), api.MarginType)             //设置仓位模式
+		r.POST("cancelOpenOrder", actions.PermissionAction(), api.CancelOpenOrder)   //取消委托
+		r.POST("clearAll", actions.PermissionAction(), api.ClearAll)                 // 一键清除数据
+		r.POST("getChildOrder", actions.PermissionAction(), api.GetChildOrderList)   // 获取子订单
+		r.POST("manuallyCover", actions.PermissionAction(), api.ManuallyCover)       // 手动加仓
+		r.POST("closePosition", actions.PermissionAction(), api.ClosePosition)       // 平仓
+		r.GET("getOrderPage", actions.PermissionAction(), api.GetOrderPage)          //订单列表
+		r.POST("clearUnTriggered", actions.PermissionAction(), api.ClearUnTriggered) // 清除待触发的交易对
+	}
+}
+
+func unRegisterLinePreOrderRouter(v1 *gin.RouterGroup) {
+	api := apis.LinePreOrder{}
+	r := v1.Group("/line-pre-order")
+	{
+		r.POST("queryOrder", api.QueryOrder) //查询订单
+	}
+}
diff --git a/app/admin/router/line_pre_order_status.go b/app/admin/router/line_pre_order_status.go
new file mode 100644
index 0000000..7510db4
--- /dev/null
+++ b/app/admin/router/line_pre_order_status.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLinePreOrderStatusRouter)
+}
+
+// registerLinePreOrderStatusRouter
+func registerLinePreOrderStatusRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LinePreOrderStatus{}
+	r := v1.Group("/line-pre-order-status").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_pre_script.go b/app/admin/router/line_pre_script.go
new file mode 100644
index 0000000..7438572
--- /dev/null
+++ b/app/admin/router/line_pre_script.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLinePreScriptRouter)
+}
+
+// registerLinePreScriptRouter
+func registerLinePreScriptRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LinePreScript{}
+	r := v1.Group("/line-pre-script").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_price_limit.go b/app/admin/router/line_price_limit.go
new file mode 100644
index 0000000..d51233f
--- /dev/null
+++ b/app/admin/router/line_price_limit.go
@@ -0,0 +1,28 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/actions"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLinePriceLimitRouter)
+}
+
+// registerLinePriceLimitRouter
+func registerLinePriceLimitRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LinePriceLimit{}
+	r := v1.Group("/line-price-limit").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+		r.POST("upRange", api.UpRange) //更新涨跌幅
+	}
+}
diff --git a/app/admin/router/line_recharge.go b/app/admin/router/line_recharge.go
new file mode 100644
index 0000000..af7560b
--- /dev/null
+++ b/app/admin/router/line_recharge.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineRechargeRouter)
+}
+
+// registerLineRechargeRouter
+func registerLineRechargeRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineRecharge{}
+	r := v1.Group("/line-recharge").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_symbol.go b/app/admin/router/line_symbol.go
new file mode 100644
index 0000000..fef0e5c
--- /dev/null
+++ b/app/admin/router/line_symbol.go
@@ -0,0 +1,32 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/actions"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineSymbolRouter)
+}
+
+// registerLineSymbolRouter
+func registerLineSymbolRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineSymbol{}
+	r := v1.Group("/line-symbol").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("getSameSymbol", actions.PermissionAction(), api.GetSameSymbol) //获取现货和合约都有的交易对
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+
+		r.POST("syncSpotSymbol", api.SyncSpotSymbol) //同步现货交易对
+		r.POST("syncFutSymbol", api.SyncFutSymbol)   //同步合约交易对
+		r.POST("getSymbol", api.GetSymbol)           //获取现货和合约都有的交易对
+	}
+}
diff --git a/app/admin/router/line_symbol_black.go b/app/admin/router/line_symbol_black.go
new file mode 100644
index 0000000..681a0b7
--- /dev/null
+++ b/app/admin/router/line_symbol_black.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineSymbolBlackRouter)
+}
+
+// registerLineSymbolBlackRouter
+func registerLineSymbolBlackRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineSymbolBlack{}
+	r := v1.Group("/line-symbol-black").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_symbol_group.go b/app/admin/router/line_symbol_group.go
new file mode 100644
index 0000000..46c47cc
--- /dev/null
+++ b/app/admin/router/line_symbol_group.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineSymbolGroupRouter)
+}
+
+// registerLineSymbolGroupRouter
+func registerLineSymbolGroupRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineSymbolGroup{}
+	r := v1.Group("/line-symbol-group").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_system_setting.go b/app/admin/router/line_system_setting.go
new file mode 100644
index 0000000..dc89b47
--- /dev/null
+++ b/app/admin/router/line_system_setting.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineSystemSettingRouter)
+}
+
+// registerLineSystemSettingRouter
+func registerLineSystemSettingRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineSystemSetting{}
+	r := v1.Group("/line-system-setting").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_uduncoin.go b/app/admin/router/line_uduncoin.go
new file mode 100644
index 0000000..d8beb63
--- /dev/null
+++ b/app/admin/router/line_uduncoin.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineUduncoinRouter)
+}
+
+// registerLineUduncoinRouter
+func registerLineUduncoinRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineUduncoin{}
+	r := v1.Group("/line-uduncoin").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_user.go b/app/admin/router/line_user.go
new file mode 100644
index 0000000..35cafa0
--- /dev/null
+++ b/app/admin/router/line_user.go
@@ -0,0 +1,64 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/admin/fronted"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/actions"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerFrontedCheckRole = append(routerFrontedCheckRole, frontedRegisterLinUserRouter)
+	routerCheckRole = append(routerCheckRole, registerLineUserRouter)
+}
+
+// registerLineUserRouter
+func registerLineUserRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineUser{}
+	r := v1.Group("/line-user").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
+
+func frontedRegisterLinUserRouter(v1 *gin.RouterGroup) {
+	api := fronted.LineUserApi{}
+	r := v1.Group("/line")
+	{
+		r.POST("/register", api.Register)               //用户注册
+		r.POST("/verifyEmail", api.VerifyEmail)         //验证邮箱
+		r.POST("/sendVerifyEmail", api.SendVerifyEmail) //发送验证邮箱
+		r.POST("/sendRegisterSms", api.SendRegisterSms) //发送注册短信
+		r.POST("/login", api.Login)                     //登录
+	}
+
+	//需要token鉴权
+	r.POST("/center", middleware.FrontedAuth, api.Info)                //用户中心
+	r.POST("/getIp", middleware.FrontedAuth, api.GetWhiteIp)           //用户手动获取ApiKey白名单ip
+	r.POST("/addApiAuth", middleware.FrontedAuth, api.AddApiKey)       //用户手动添加Apikey
+	r.POST("/updateApiAuth", middleware.FrontedAuth, api.UpdateApiKey) //用户手动修改Apikey
+	r.POST("/opStatus", middleware.FrontedAuth, api.OpenStatus)        //开启或者关闭状态
+
+	//充值
+	r.POST("/notify", api.Notify)                                                         //uDun回调
+	r.POST("/rechargeNetworkList", middleware.FrontedAuth, api.RechargeNetworkList)       //充值 通过充值币种选择主网络
+	r.POST("/rechargeNetworkAddress", middleware.FrontedAuth, api.RechargeNetworkAddress) //充值 通过主网ID和用户ID获取交易地址
+	r.POST("/fundingTrend", middleware.FrontedAuth, api.FundingTrend)                     //资金走势
+
+	//coinGate 充值
+	r.POST("/callback", api.CallBack)                         //coinGate 回调地址
+	r.POST("/preorder", middleware.FrontedAuth, api.PreOrder) //coinGate 充值
+
+}
+
+func frontedUserCenterRouter(v1 *gin.RouterGroup) {
+	//api := fronted.LineUserApi{}
+
+}
diff --git a/app/admin/router/line_user_funding_trend.go b/app/admin/router/line_user_funding_trend.go
new file mode 100644
index 0000000..c8df210
--- /dev/null
+++ b/app/admin/router/line_user_funding_trend.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineUserFundingTrendRouter)
+}
+
+// registerLineUserFundingTrendRouter
+func registerLineUserFundingTrendRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineUserFundingTrend{}
+	r := v1.Group("/line-user-funding-trend").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_user_profit_logs.go b/app/admin/router/line_user_profit_logs.go
new file mode 100644
index 0000000..03ccccd
--- /dev/null
+++ b/app/admin/router/line_user_profit_logs.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineUserProfitLogsRouter)
+}
+
+// registerLineUserProfitLogsRouter
+func registerLineUserProfitLogsRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineUserProfitLogs{}
+	r := v1.Group("/line-user-profit-logs").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/line_wallet.go b/app/admin/router/line_wallet.go
new file mode 100644
index 0000000..164b606
--- /dev/null
+++ b/app/admin/router/line_wallet.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerLineWalletRouter)
+}
+
+// registerLineWalletRouter
+func registerLineWalletRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.LineWallet{}
+	r := v1.Group("/line-wallet").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/router.go b/app/admin/router/router.go
new file mode 100644
index 0000000..45269e5
--- /dev/null
+++ b/app/admin/router/router.go
@@ -0,0 +1,65 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	_ "github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+)
+
+var (
+	routerFrontedCheckRole = make([]func(*gin.RouterGroup), 0)
+	routerNoCheckRole      = make([]func(*gin.RouterGroup), 0)
+	routerNoVersion        = make([]func(*gin.RouterGroup), 0)
+	routerCheckRole        = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0)
+)
+
+func InitExamplesRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine {
+
+	// 无需认证的路由
+	examplesNoCheckRoleRouter(r)
+
+	examplesNoCheckAppRoleRouter(r)
+
+	examplesNoVersionRouter(r)
+
+	// 需要认证的路由
+	examplesCheckRoleRouter(r, authMiddleware)
+
+	return r
+}
+
+func examplesNoVersionRouter(r *gin.Engine) {
+	// 可根据业务需求来设置接口版本
+	v1 := r.Group("/api")
+	for _, f := range routerNoVersion {
+		f(v1)
+	}
+}
+
+// 无需认证的路由示例
+func examplesNoCheckRoleRouter(r *gin.Engine) {
+	// 可根据业务需求来设置接口版本
+	v1 := r.Group("/api/v1")
+	for _, f := range routerNoCheckRole {
+		f(v1)
+	}
+}
+
+// 无需认证app的路由示例
+func examplesNoCheckAppRoleRouter(r *gin.Engine) {
+	// 可根据业务需求来设置接口版本
+	v1 := r.Group("/api/v1")
+	for _, f := range routerFrontedCheckRole {
+		f(v1)
+	}
+}
+
+// 需要认证的路由示例
+func examplesCheckRoleRouter(r *gin.Engine, authMiddleware *jwtauth.GinJWTMiddleware) {
+	// 可根据业务需求来设置接口版本
+	v1 := r.Group("/api/v1")
+	for _, f := range routerCheckRole {
+		f(v1, authMiddleware)
+	}
+}
diff --git a/app/admin/router/sys_api.go b/app/admin/router/sys_api.go
new file mode 100644
index 0000000..8272df3
--- /dev/null
+++ b/app/admin/router/sys_api.go
@@ -0,0 +1,24 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerSysApiRouter)
+}
+
+// registerSysApiRouter
+func registerSysApiRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.SysApi{}
+	r := v1.Group("/sys-api").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", api.GetPage)
+		r.GET("/:id", api.Get)
+		r.PUT("/:id", api.Update)
+	}
+}
diff --git a/app/admin/router/sys_config.go b/app/admin/router/sys_config.go
new file mode 100644
index 0000000..2dabd08
--- /dev/null
+++ b/app/admin/router/sys_config.go
@@ -0,0 +1,43 @@
+package router
+
+import (
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerSysConfigRouter)
+}
+
+// 需认证的路由代码
+func registerSysConfigRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.SysConfig{}
+	r := v1.Group("/config").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", api.GetPage)
+		r.GET("/:id", api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", api.Update)
+		r.DELETE("", api.Delete)
+	}
+
+	r1 := v1.Group("/configKey").Use(authMiddleware.MiddlewareFunc())
+	{
+		r1.GET("/:configKey", api.GetSysConfigByKEYForService)
+	}
+
+	r2 := v1.Group("/app-config")
+	{
+		r2.GET("", api.Get2SysApp)
+	}
+
+	r3 := v1.Group("/set-config").Use(authMiddleware.MiddlewareFunc())
+	{
+		r3.PUT("", api.Update2Set)
+		r3.GET("", api.Get2Set)
+	}
+
+}
diff --git a/app/admin/router/sys_dept.go b/app/admin/router/sys_dept.go
new file mode 100644
index 0000000..f939374
--- /dev/null
+++ b/app/admin/router/sys_dept.go
@@ -0,0 +1,32 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerSysDeptRouter)
+}
+
+// 需认证的路由代码
+func registerSysDeptRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.SysDept{}
+
+	r := v1.Group("/dept").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", api.GetPage)
+		r.GET("/:id", api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", api.Update)
+		r.DELETE("", api.Delete)
+	}
+
+	r1 := v1.Group("").Use(authMiddleware.MiddlewareFunc())
+	{
+		r1.GET("/deptTree", api.Get2Tree)
+	}
+
+}
\ No newline at end of file
diff --git a/app/admin/router/sys_dict.go b/app/admin/router/sys_dict.go
new file mode 100644
index 0000000..ae9e0c4
--- /dev/null
+++ b/app/admin/router/sys_dict.go
@@ -0,0 +1,37 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerDictRouter)
+}
+
+func registerDictRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	dictApi := apis.SysDictType{}
+	dataApi := apis.SysDictData{}
+	dicts := v1.Group("/dict").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+
+		dicts.GET("/data", dataApi.GetPage)
+		dicts.GET("/data/:dictCode", dataApi.Get)
+		dicts.POST("/data", dataApi.Insert)
+		dicts.PUT("/data/:dictCode", dataApi.Update)
+		dicts.DELETE("/data", dataApi.Delete)
+
+		dicts.GET("/type-option-select", dictApi.GetAll)
+		dicts.GET("/type", dictApi.GetPage)
+		dicts.GET("/type/:id", dictApi.Get)
+		dicts.POST("/type", dictApi.Insert)
+		dicts.PUT("/type/:id", dictApi.Update)
+		dicts.DELETE("/type", dictApi.Delete)
+	}
+	opSelect := v1.Group("/dict-data").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		opSelect.GET("/option-select", dataApi.GetAll)
+	}
+}
diff --git a/app/admin/router/sys_login_log.go b/app/admin/router/sys_login_log.go
new file mode 100644
index 0000000..61b4e83
--- /dev/null
+++ b/app/admin/router/sys_login_log.go
@@ -0,0 +1,24 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerSysLoginLogRouter)
+}
+
+// 需认证的路由代码
+func registerSysLoginLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.SysLoginLog{}
+
+	r := v1.Group("/sys-login-log").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", api.GetPage)
+		r.GET("/:id", api.Get)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/sys_menu.go b/app/admin/router/sys_menu.go
new file mode 100644
index 0000000..b5cad5a
--- /dev/null
+++ b/app/admin/router/sys_menu.go
@@ -0,0 +1,33 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerSysMenuRouter)
+}
+
+// 需认证的路由代码
+func registerSysMenuRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.SysMenu{}
+
+	r := v1.Group("/menu").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", api.GetPage)
+		r.GET("/:id", api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", api.Update)
+		r.DELETE("", api.Delete)
+	}
+
+	r1 := v1.Group("").Use(authMiddleware.MiddlewareFunc())
+	{
+		r1.GET("/menurole", api.GetMenuRole)
+		//r1.GET("/menuids", api.GetMenuIDS)
+	}
+
+}
\ No newline at end of file
diff --git a/app/admin/router/sys_opera_log.go b/app/admin/router/sys_opera_log.go
new file mode 100644
index 0000000..d24d54f
--- /dev/null
+++ b/app/admin/router/sys_opera_log.go
@@ -0,0 +1,23 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerSysOperaLogRouter)
+}
+
+// 需认证的路由代码
+func registerSysOperaLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.SysOperaLog{}
+	r := v1.Group("/sys-opera-log").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", api.GetPage)
+		r.GET("/:id", api.Get)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/sys_post.go b/app/admin/router/sys_post.go
new file mode 100644
index 0000000..e299a5d
--- /dev/null
+++ b/app/admin/router/sys_post.go
@@ -0,0 +1,25 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerSyPostRouter)
+}
+
+// 需认证的路由代码
+func registerSyPostRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.SysPost{}
+	r := v1.Group("/post").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", api.GetPage)
+		r.GET("/:id", api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/sys_role.go b/app/admin/router/sys_role.go
new file mode 100644
index 0000000..5bfdd2a
--- /dev/null
+++ b/app/admin/router/sys_role.go
@@ -0,0 +1,31 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerSysRoleRouter)
+}
+
+// 需认证的路由代码
+func registerSysRoleRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.SysRole{}
+	r := v1.Group("/role").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", api.GetPage)
+		r.GET("/:id", api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", api.Update)
+		r.DELETE("", api.Delete)
+	}
+	r1 := v1.Group("").Use(authMiddleware.MiddlewareFunc())
+	{
+		r1.PUT("/role-status", api.Update2Status)
+		r1.PUT("/roledatascope", api.Update2DataScope)
+	}
+}
diff --git a/app/admin/router/sys_router.go b/app/admin/router/sys_router.go
new file mode 100644
index 0000000..b713e4b
--- /dev/null
+++ b/app/admin/router/sys_router.go
@@ -0,0 +1,88 @@
+package router
+
+import (
+	"go-admin/app/admin/apis"
+	"mime"
+
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/ws"
+	ginSwagger "github.com/swaggo/gin-swagger"
+
+	swaggerfiles "github.com/swaggo/files"
+
+	"go-admin/common/middleware"
+	"go-admin/common/middleware/handler"
+	_ "go-admin/docs/admin"
+)
+
+func InitSysRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.RouterGroup {
+	g := r.Group("")
+	sysBaseRouter(g)
+	// 静态文件
+	sysStaticFileRouter(g)
+	// swagger;注意:生产环境可以注释掉
+	if config.ApplicationConfig.Mode != "prod" {
+		sysSwaggerRouter(g)
+	}
+	// 需要认证
+	sysCheckRoleRouterInit(g, authMiddleware)
+	return g
+}
+
+func sysBaseRouter(r *gin.RouterGroup) {
+
+	go ws.WebsocketManager.Start()
+	go ws.WebsocketManager.SendService()
+	go ws.WebsocketManager.SendAllService()
+
+	if config.ApplicationConfig.Mode != "prod" {
+		r.GET("/", apis.GoAdmin)
+	}
+	r.GET("/info", handler.Ping)
+}
+
+func sysStaticFileRouter(r *gin.RouterGroup) {
+	err := mime.AddExtensionType(".js", "application/javascript")
+	if err != nil {
+		return
+	}
+	r.Static("/static", "./static")
+	if config.ApplicationConfig.Mode != "prod" {
+		r.Static("/form-generator", "./static/form-generator")
+	}
+}
+
+func sysSwaggerRouter(r *gin.RouterGroup) {
+	r.GET("/swagger/admin/*any", ginSwagger.WrapHandler(swaggerfiles.NewHandler(), ginSwagger.InstanceName("admin")))
+}
+
+func sysCheckRoleRouterInit(r *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	wss := r.Group("").Use(authMiddleware.MiddlewareFunc())
+	{
+		wss.GET("/ws/:id/:channel", ws.WebsocketManager.WsClient)
+		wss.GET("/wslogout/:id/:channel", ws.WebsocketManager.UnWsClient)
+	}
+
+	v1 := r.Group("/api/v1")
+	{
+		v1.POST("/login", authMiddleware.LoginHandler)
+		// Refresh time can be longer than token timeout
+		v1.GET("/refresh_token", authMiddleware.RefreshHandler)
+	}
+	registerBaseRouter(v1, authMiddleware)
+}
+
+func registerBaseRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.SysMenu{}
+	api2 := apis.SysDept{}
+	v1auth := v1.Group("").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		v1auth.GET("/roleMenuTreeselect/:roleId", api.GetMenuTreeSelect)
+		//v1.GET("/menuTreeselect", api.GetMenuTreeSelect)
+		v1auth.GET("/roleDeptTreeselect/:roleId", api2.GetDeptTreeRoleSelect)
+		v1auth.POST("/logout", handler.LogOut)
+	}
+}
diff --git a/app/admin/router/sys_user.go b/app/admin/router/sys_user.go
new file mode 100644
index 0000000..4a545a6
--- /dev/null
+++ b/app/admin/router/sys_user.go
@@ -0,0 +1,39 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/admin/apis"
+	"go-admin/common/actions"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerSysUserRouter)
+}
+
+// 需认证的路由代码
+func registerSysUserRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.SysUser{}
+	r := v1.Group("/sys-user").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()).Use(actions.PermissionAction())
+	{
+		r.GET("", api.GetPage)
+		r.GET("/:id", api.Get)
+		r.POST("", api.Insert)
+		r.PUT("", api.Update)
+		r.DELETE("", api.Delete)
+	}
+
+	user := v1.Group("/user").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()).Use(actions.PermissionAction())
+	{
+		user.GET("/profile", api.GetProfile)
+		user.POST("/avatar", api.InsetAvatar)
+		user.PUT("/pwd/set", api.UpdatePwd)
+		user.PUT("/pwd/reset", api.ResetPwd)
+		user.PUT("/status", api.UpdateStatus)
+	}
+	v1auth := v1.Group("").Use(authMiddleware.MiddlewareFunc())
+	{
+		v1auth.GET("/getinfo", api.GetInfo)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/router/vts_recharge.go b/app/admin/router/vts_recharge.go
new file mode 100644
index 0000000..5ad89c3
--- /dev/null
+++ b/app/admin/router/vts_recharge.go
@@ -0,0 +1,27 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+
+	"go-admin/app/admin/apis"
+	"go-admin/common/middleware"
+	"go-admin/common/actions"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerVtsRechargeRouter)
+}
+
+// registerVtsRechargeRouter
+func registerVtsRechargeRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.VtsRecharge{}
+	r := v1.Group("/vts-recharge").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", actions.PermissionAction(), api.GetPage)
+		r.GET("/:id", actions.PermissionAction(), api.Get)
+		r.POST("", api.Insert)
+		r.PUT("/:id", actions.PermissionAction(), api.Update)
+		r.DELETE("", api.Delete)
+	}
+}
\ No newline at end of file
diff --git a/app/admin/service/aduserdb/ad_identification.go b/app/admin/service/aduserdb/ad_identification.go
new file mode 100644
index 0000000..349b2fc
--- /dev/null
+++ b/app/admin/service/aduserdb/ad_identification.go
@@ -0,0 +1,198 @@
+package aduserdb
+
+//
+//import (
+//	"errors"
+//	"go-admin/app/admin/models"
+//	"go-admin/app/admin/service/dto"
+//
+//	"go.uber.org/zap"
+//	"gorm.io/gorm"
+//
+//	log "github.com/go-admin-team/go-admin-core/logger"
+//)
+//
+//// AddJunior 初级认证
+//func AddJunior(orm *gorm.DB, ident models.AdIdentification) error {
+//	err := orm.Model(ident).Create(ident).Error
+//	// err := dbhelper.MasterPgdb.InsertTx("ad_identification", &ident, tx)
+//	if err != nil {
+//		log.Error("register Junior", zap.Error(err))
+//		return err
+//	}
+//	return nil
+//}
+//
+//// ValidIdCard 验证证件信息是否已存在
+//func ValidIdCard(orm *gorm.DB, idcardtype int, idcard string) (resp models.AdIdentification) {
+//	// sql := `SELECT
+//	// 			id, userid, name, surname, middlename, birthdate, countryid, city, address, zipcode, idcardtype, idcard,
+//	// 			idcardimage1, idcardimage2, idcardvideo, verifyfile, idcardlevel, idcardstate, verifytype,
+//	// 			createtime, verifytime, reason, videocode, faceimage1, faceimage2, accountid, workid,
+//	// 			idcreditails, selfiecredential, facemapcredential
+//	// 		FROM ad_identification WHERE  idcardtype = $1 AND idcard = $2 `
+//	// err := dbhelper.MasterPgdb.Get(&resp, sql, idcardtype, idcard)
+//	err := orm.Model(resp).Where("idcard_type =? AND idcard=?", idcardtype, idcard).Error
+//
+//	if err != nil {
+//		log.Error("ValidIdCard : ", zap.Error(err))
+//		return
+//	}
+//	return resp
+//}
+//
+//// UpdateJunior 更新初级认证
+//func UpdateJunior(orm *gorm.DB, ident dto.IdentificationJuniorReq) error {
+//	// updateSql := `UPDATE
+//	//                    ad_identification
+//	//               SET
+//	//                    name = :name,surname = :surname,middlename = :middlename,
+//	//                    idcardlevel = 1,idcardstate = 1,birthdate = :birthdate,
+//	//                    countryid = :countryid,idcardtype = :idcardtype,idcard = :idcard
+//	//               WHERE userid = :userid`
+//
+//	//dbhelper.MasterPgdb.NamedExecTx(updateSql, &ident, tx);
+//	if err := orm.Model(models.AdIdentification{}).Where("user_id =?", ident.UserId).Updates(map[string]interface{}{
+//		"name": ident.Name, "surname": ident.Surname, "middle_name": ident.MiddleName,
+//		"idcard_level": 1, "idcard_state": 1, "birth_date": ident.BirthDate, "country_id": ident.CountryId,
+//		"idcard_type": ident.IdCardType, "idcard": ident.IdCard,
+//	}).Error; err != nil {
+//		log.Error("UpdateJunior", zap.Error(err))
+//		return err
+//	}
+//	return nil
+//}
+//
+//// UpdateMiddle 中级认证
+//func UpdateMiddle(orm *gorm.DB, ident dto.IdentificationMiddleReq) error {
+//	// updateSql := `UPDATE
+//	//                   ad_identification
+//	//               SET
+//	//                   idcardimage1 = :idcardimage1,idcardimage2 = :idcardimage2,idcardvideo = :idcardvideo,
+//	//                   idcardlevel = 2,idcardstate = :idcardstate,verifytype = :verifytype,videocode= :videocode,
+//	//                   reason = :reason,verifytime = :verifytime,faceimage1 = :faceimage1,faceimage2 = :faceimage2,
+//	//                   accountid = :accountid,workid = :workid,idcreditails = :idcreditails,
+//	//                   selfiecredential = :selfiecredential,facemapcredential = :facemapcredential
+//	//               WHERE userid = :userid`
+//	// dbhelper.MasterPgdb.NamedExecTx(updateSql, &ident, tx)
+//
+//	if err := orm.Model(models.AdIdentification{}).Where("user_id=?", ident.UserId).Updates(map[string]interface{}{
+//		"idcard_image1": ident.IdCardImage1, "idcard_image2": ident.IdCardImage2,
+//		"idcard_video": ident.IdCardVideo, "idcard_level": 2, "idcard_state": ident.IdCardState,
+//		"verify_type": ident.VerifyType, "video_code": ident.VideoCode, "reason": ident.Reason,
+//		"verify_time": ident.VerifyTime, "face_image1": ident.FaceImage1, "face_image2": ident.FaceImage2,
+//		"account_id": ident.AccountId, "work_id": ident.WorkFlowExecutionId, "id_creditails": ident.IdCreditails,
+//		"selfile_credential": ident.SelfieCredential, "facemap_credential": ident.FacemapCredential,
+//	}).Error; err != nil {
+//		log.Error("UpdateMiddle", zap.Error(err))
+//		return err
+//	}
+//	return nil
+//}
+//
+//// UpdateMiddleByThird d
+//func UpdateMiddleByThird(orm *gorm.DB, ident dto.IdentificationMiddleReq) error {
+//	// updateSql := `UPDATE
+//	//                   ad_identification
+//	//               SET
+//	//                   idcardimage1 = :idcardimage1,idcardimage2 = :idcardimage2,idcardstate = :idcardstate,
+//	//                   reason = :reason,verifytime = :verifytime,faceimage1 = :faceimage1,faceimage2 = :faceimage2
+//
+//	//               WHERE userid = :userid`
+//
+//	// dbhelper.MasterPgdb.NamedExecTx(updateSql, &ident, tx)
+//
+//	if err := orm.Model(models.AdIdentification{}).Where("user_id=?", ident.UserId).Updates(map[string]interface{}{
+//		"idcard_image1": ident.IdCardImage1, "idcard_image2": ident.IdCardImage2, "idcard_state": ident.IdCardState,
+//		"reason": ident.Reason, "verify_time": ident.VerifyTime, "face_image1": ident.FaceImage1, "face_image2": ident.FaceImage2,
+//	}).Error; err != nil {
+//		log.Error("UpdateMiddleByThird", zap.Error(err))
+//		return err
+//	}
+//	return nil
+//}
+//
+//// UpdateSenior 用户高级认证
+//func UpdateSenior(orm *gorm.DB, userId int) error {
+//	// updateSql := `UPDATE ad_identification SET idcardlevel = 3,idcardstate = 1 WHERE userid = $1`
+//	// dbhelper.MasterPgdb.ExecTx(updateSql, tx, userId)
+//
+//	if err := orm.Model(models.AdIdentification{}).Where("user_id=?", userId).Updates(map[string]interface{}{
+//		"idcard_level": 3, "idcard_state": 1,
+//	}).Error; err != nil {
+//		log.Error("UpdateSenior", zap.Error(err))
+//		return err
+//	}
+//	return nil
+//}
+//
+//// GetIdentification 获取认证信息
+//func GetIdentification(orm *gorm.DB, userId int) (models.AdIdentification, error) {
+//	// sqlInfo := `SELECT id, userid, name, surname, middlename, birthdate, countryid, city,
+//	// 	address, zipcode, idcardtype, idcard, idcardimage1, idcardimage2, idcardvideo,
+//	// 	 verifyfile, idcardlevel, idcardstate, verifytype,createtime,verifytime,reason,
+//	// 	 accountid, workid ,
+//	// 	 idcreditails ,
+//	// 	 selfiecredential ,
+//	// 	 facemapcredential
+//	//     FROM ad_identification WHERE userid = $1`
+//
+//	//dbhelper.MasterPgdb.Get(&ident, sqlInfo, userId)
+//	var ident models.AdIdentification
+//	err := orm.Model(ident).Where("user_id =?", userId).First(&ident).Error
+//
+//	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+//		log.Error("get Identification", zap.Error(err))
+//		return ident, err
+//	}
+//	return ident, nil
+//}
+//
+//// UpdateJuniorMidAuth 标准(中级)认证审核
+//// func UpdateJuniorMidAuth(req dto.IdentJuniorMiddleAuthReq, tx *sqlx.Tx) error {
+//// 	updateSql := `UPDATE
+////                      ad_identification
+////                   SET
+////                      idcardstate = :idcardstate,reason = :reason,verifytime = :verifytime
+////                   WHERE userid = :userid`
+//// 	if _, err := dbhelper.MasterPgdb.NamedExecTx(updateSql, &req, tx); err != nil {
+//// 		log.Error("UpdateJuniorMidAuth", zap.Error(err))
+//// 		return err
+//// 	}
+//// 	return nil
+//// }
+//
+//// UpdateSeniorAuth 高级认证审核
+//// func UpdateSeniorAuth(req dto.IdentificationSeniorReq, tx *sqlx.Tx) error {
+//// 	updateSql := `UPDATE
+////                      ad_identification
+////                   SET
+////                      city = :city,address = :address,zipcode = :zipcode,
+////                      idcardlevel = 3,idcardstate = :idcardstate,verifytype = 2,
+////                      verifyfile = :verifyfile,reason = :reason,verifytime = :verifytime
+////                   WHERE userid = :userid`
+//// 	if _, err := dbhelper.MasterPgdb.NamedExecTx(updateSql, &req, tx); err != nil {
+//// 		log.Error("UpdateSeniorAuth", zap.Error(err))
+//// 		return err
+//// 	}
+//// 	return nil
+//// }
+//
+//// IdentDetail 认证详情
+//// func IdentDetail(userid int) (detail dto.IdentDetailResp, err error) {
+//// 	sql := `SELECT
+////                 userid,name,surname,middlename,idcardtype,idcard,idcardimage1,
+////                 idcardimage2,birthdate,idcardvideo,address,city,zipcode,
+////                 verifyfile,reason,videocode,faceimage1,faceimage2,ad_user.phone,
+////                 ad_user.useraccount, to_char(ad_user.createtime,'yyyy-MM-dd hh24:MI:ss') as createtime,ad_user.useremail, ad_user.area,ad_country.namezh
+////             FROM
+////                 ad_identification
+////                 JOIN ad_user ON ad_user.id = ad_identification.userid
+////                 JOIN ad_country ON ad_country.id = ad_identification.countryid
+////             WHERE ad_identification.userid = $1`
+//// 	err = dbhelper.MasterPgdb.Get(&detail, sql, userid)
+//// 	if err != nil {
+//// 		log.Error("IdentDetail", zap.Error(err))
+//// 	}
+//// 	return
+//// }
diff --git a/app/admin/service/aduserdb/ad_user_db.go b/app/admin/service/aduserdb/ad_user_db.go
new file mode 100644
index 0000000..ad799e1
--- /dev/null
+++ b/app/admin/service/aduserdb/ad_user_db.go
@@ -0,0 +1,552 @@
+package aduserdb
+
+import (
+	"errors"
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"go-admin/app/admin/models"
+	statuscode "go-admin/common/status_code"
+
+	"go.uber.org/zap"
+	"gorm.io/gorm"
+)
+
+//func SetUserStatus(orm *gorm.DB, req adminmodel.UserForbidReq) error {
+//	// sql := `UPDATE ad_user SET
+//	// 		status = :status,
+//	// 		c2cadvertstatus = :c2cadvertstatus,
+//	// 		vtsstatus = :vtsstatus,
+//	// 		chargestatus = :chargestatus,
+//	// 		withdrawalstatus = :withdrawalstatus,
+//	// 		futstatus = :futstatus,
+//	// 		transferstatus = :transferstatus,
+//	// 		c2ctradestatus = :c2ctradestatus
+//	// 		WHERE id = :id`
+//	err := orm.Model(&models.AdUser{}).Where("id =?", req.ID).Updates(map[string]interface{}{"status": req.Status, "c2c_advert_status": req.C2cAdvertStatus,
+//		"vts_status": req.VtsStatus, "charge_status": req.ChargeStatus, "with_drawal_status": req.WithdrawalStatus,
+//		"fut_status": req.FutStatus, "transfer_status": req.TransferStatus, "c2c_trade_status": req.C2cTradeStatus}).Error
+//
+//	if err != nil {
+//		log.Error("SetUserStatus", err)
+//	}
+//	return err
+//}
+//func SetUserInfoStopRate(orm *gorm.DB, userId int, stopRate int, openratetime time.Time) error {
+//	// sql := `UPDATE ad_userinfo SET
+//	// 		stoprate = $1,
+//	// 		openratetime = $2
+//	// 		WHERE userid = $3`
+//	err := orm.Model(&models.AdUserInfo{}).Where("user_id=?", userId).Updates(map[string]interface{}{"stoprate": stopRate, "open_rate_time": openratetime}).Error
+//
+//	if err != nil {
+//		log.Error("SetUserInfoStopRate", zap.Error(err))
+//	}
+//	return err
+//}
+//func GetUserStatusByID(orm *gorm.DB, id int) (data adminmodel.UserForbidUserResp, err error) {
+//	// sql := `SELECT id,nickname,status,c2cadvertstatus,vtsstatus,chargestatus,withdrawalstatus,futstatus,transferstatus,c2ctradestatus FROM ad_user WHERE id=$1`
+//
+//	err = orm.Model(&models.AdUser{}).Where("id=?", id).First(&data).Error
+//	if err != nil {
+//		log.Error("GetUserStatusByID", zap.Error(err))
+//	}
+//	return
+//}
+
+// GetUserById 通过id获取用户信息
+func GetUserById(orm *gorm.DB, id int) (data models.LineUser, err error) {
+	// sql := "SELECT " + userFile + " FROM ad_user WHERE id= $1" //`SELECT "" FROM ad_user where id= $1`
+	err = orm.Model(&data).Where("id =?", id).First(&data).Error
+	if err != nil {
+		log.Error("GetUserById", zap.Error(err))
+	}
+	return
+}
+
+// GetUserByInviteCode 根据邀请码获取用户信息
+func GetUserByInviteCode(orm *gorm.DB, inviteCode string) (user models.LineUser, err error) {
+	if err = orm.Model(&user).Where("invite_code = ?", inviteCode).First(&user).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+		log.Error("GetUserByInviteCode ", zap.Error(err))
+		return
+	}
+	err = nil
+	return
+}
+
+// GetUserStatusById 通过id获取用户基础状态
+func GetUserStatusById(orm *gorm.DB, id int) (data models.LineUser) {
+	// sql := "SELECT id,futstatus,transferstatus,withdrawalstatus,vtsstatus,chargestatus FROM ad_user WHERE id=$1" //`SELECT "" FROM ad_user where id= $1`
+	err := orm.Model(&data).Where("id =?", id).First(&data).Error
+	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+		log.Error("GetUserStatusById", zap.Error(err))
+	}
+	err = nil
+	return
+}
+
+func GetUserByEmail(orm *gorm.DB, userEmail string) (user models.LineUser, err error) {
+	// sql := sqlUser + ` AND useremail = $1`
+	if err = orm.Model(&user).Where("email = ?", userEmail).First(&user).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+		log.Error("GetUserByEmail ", zap.Error(err))
+		return
+	}
+	err = nil
+	return
+}
+
+func GetUserByPhone(orm *gorm.DB, area, phone string) (user models.LineUser, err error) {
+	// sql := sqlUser + ` AND area = $1 AND phone = $2`
+	if err = orm.Model(&user).Where("area =? AND mobile =?", area, phone).First(&user).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+		log.Error("GetUserByPhone ", zap.Error(err))
+		return
+	}
+	err = nil
+	return
+}
+
+// AddUser 添加用户
+func AddUser(orm *gorm.DB, user *models.LineUser) (int, error) {
+	err := orm.Model(user).Create(user).Error
+	// userId, err := dbhelper.MasterPgdb.InsertReIdTx("ad_user", &user, tx)
+	if err != nil {
+		log.Error("AddUser err", zap.Error(err))
+		return user.Id, err
+	}
+	return user.Id, nil
+}
+
+func UpdateUserStatus(orm *gorm.DB, phone string) (int, error) {
+	err := orm.Model(&models.LineUser{}).Update("status", "normal").Error
+	// userId, err := dbhelper.MasterPgdb.InsertReIdTx("ad_user", &user, tx)
+	if err != nil {
+		log.Error("UpdateUserStatus err", zap.Error(err))
+		return statuscode.ServerError, err
+	}
+	return 0, nil
+}
+
+// AddUserInfo 添加用户信息
+//func AddUserInfo(orm *gorm.DB, userInfo models.AdUserInfo) error {
+//	layout := "2006-01-02 15:04:05" // Go 的日期格式化布局
+//	parsedTime, _ := time.Parse(layout, "1970-01-01 00:00:01")
+//	userInfo.SecurityUpdateTime = parsedTime
+//	userInfo.OpenRateTime = parsedTime
+//
+//	if err := orm.Model(&userInfo).Create(&userInfo).Error; err != nil {
+//		log.Error("AddUserInfo error ", zap.Error(err))
+//		return err
+//	}
+//	return nil
+//}
+
+// UpdateUserRecommend 更新用户推荐人数
+func UpdateUserRecommend(orm *gorm.DB, userId int) error {
+	updateSql := `UPDATE ad_user_info SET total_num = total_num + 1 WHERE user_id = ?`
+	if err := orm.Exec(updateSql, userId).Error; err != nil {
+		log.Error("update user recommend total failed", zap.Error(err))
+		return err
+	}
+	return nil
+}
+
+//
+//// UpdateUserPushCid 第三方离线推送clientid,绑定该cid-用户
+//func UpdateUserPushCid(orm *gorm.DB, userId int, pushCId string) error {
+//	//先清除之前绑定该cid的用户,
+//	// updateCidSql := `UPDATE ad_userinfo SET pushcid='' WHERE pushcid=$1`
+//	err := orm.Model(&models.AdUserInfo{}).Where("push_cid =?", pushCId).Update("push_cid", pushCId).Error
+//	if err != nil {
+//		log.Error("update user UpdateUserPushCid pushcid failed", zap.Error(err))
+//		return err
+//	}
+//	//再绑定新用户给cid
+//	// updateSql := `UPDATE ad_userinfo SET pushcid = $1 WHERE userid = $2 `
+//	if err = orm.Model(&models.AdUserInfo{}).Where("user_id =?", userId).Update("push_cid", pushCId).Error; err != nil {
+//		log.Error("update user UpdateUserPushCid  failed", zap.Error(err))
+//		return err
+//	}
+//
+//	return nil
+//}
+//
+//// UpdateUserAuth 更新认证状态
+//func UpdateUserAuth(orm *gorm.DB, userId, idcardstate, authlevel int) error {
+//	// updateSql := `UPDATE ad_user SET idcardstate = $1,authlevel = $2 WHERE id = $3`
+//	if err := orm.Model(&models.AdUser{}).Where("id=?", userId).Updates(map[string]interface{}{"id_card_state": idcardstate,
+//		"auth_level": authlevel}).Error; err != nil {
+//		log.Error("UpdateUserAuth", zap.Error(err))
+//		return err
+//	}
+//	return nil
+//}
+//
+//// GetUserInfo 获取用户信息
+//func GetUserInfo(orm *gorm.DB, userId int) (models.AdUserInfo, error) {
+//	var user models.AdUserInfo
+//
+//	if err := orm.Model(&user).Where("user_id =?", userId).First(&user).Error; err != nil {
+//		log.Error("get userinfo", zap.Error(err))
+//		return user, err
+//	}
+//	return user, nil
+//}
+//
+//// GetUserCId 获取用户信息cid
+//func GetUserCId(orm *gorm.DB, userId int) models.AdUserInfo {
+//	var user models.AdUserInfo
+//	if err := orm.Model(&user).Where("user_id =?", userId).First(&user).Error; err != nil {
+//		log.Error("GetUserCId", zap.Error(err))
+//		return user
+//	}
+//	return user
+//}
+//
+//// UpdateUserPwd 更新密码
+//func UpdateUserPwd(orm *gorm.DB, userId int, password string) error {
+//	// var updateSql = `UPDATE ad_user SET userpassword = $1 WHERE id = $2`
+//
+//	if err := orm.Model(&models.AdUser{}).Where("id =?", userId).Update("user_password", password).Error; err != nil {
+//		log.Error("update user password failed", zap.Error(err))
+//		return err
+//	}
+//	return nil
+//}
+//
+//// UpdateUserInfo 更新
+//func UpdateUserInfo(orm *gorm.DB, userinfo dto.UpdateUserInfo) error {
+//	// sql := `UPDATE ad_user SET `
+//	// set := make([]string, 0, 2)
+//	set := make(map[string]interface{}, 0)
+//	if len(userinfo.NickName) > 0 {
+//		// set = append(set, " nickname = :nickname ")
+//		set["nick_name"] = userinfo.NickName
+//	}
+//	if len(userinfo.HeadImage) > 0 {
+//		// set = append(set, " image = :headimage ")
+//		set["image"] = userinfo.HeadImage
+//	}
+//
+//	if len(set) == 0 {
+//		return errors.New("No changes")
+//	}
+//
+//	if err := orm.Model(models.AdUser{}).Where("id =?", userinfo.UserID).Updates(set).Error; err != nil {
+//		log.Error("UpdateUserInfo", zap.Error(err))
+//		return err
+//	}
+//
+//	return nil
+//}
+//
+//// SetRateCountry 设置目前用户使用的汇率(基础货币)
+//func SetRateCountry(orm *gorm.DB, userId int, RateCountry string) error {
+//	// sql := `UPDATE ad_userinfo SET ratecountry = $1 WHERE userid = $2`
+//	data := models.AdUserInfo{}
+//
+//	if err := orm.Model(data).Where("user_id =?", userId).Update("rate_country", RateCountry).Error; err != nil {
+//		log.Error("update ad_userinfo ratecountry failed", zap.Error(err))
+//		return err
+//	}
+//	return nil
+//}
+//
+//// GetUserAuthSwitch 获取用户验证器开启状态
+//func GetUserAuthSwitch(orm *gorm.DB, userID int) (auth sysmodel.UserAuthSwitchStatus, err error) {
+//	// sql := `SELECT phoneauthisopen, emailauthisopen, googleidcardisopen, googlesecret FROM ad_userinfo WHERE userid = $1 LIMIT 1`
+//	data := models.AdUserInfo{}
+//
+//	err = orm.Model(data).Where("user_id =?", userID).First(&data).Error
+//
+//	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+//		log.Error("GetUserAuthSwitch", zap.Error(err))
+//		return
+//	}
+//
+//	err = nil
+//	auth.EmailAuth = data.EmailAuthIsOpen
+//	auth.GoogleAuth = data.GoogleIdcardIsOpen
+//	auth.GoogleSecret = data.GoogleSecret
+//	auth.PhoneAuth = data.PhoneAuthIsOpen
+//
+//	return
+//}
+//
+//// BindPhoneAuth 绑定手机验证
+//func BindPhoneAuth(orm *gorm.DB, userId int, area string, phone string) error {
+//	// updateUser := `UPDATE ad_user SET area = $1, phone = $2 WHERE id = $3`
+//	// updateUserinfo := `UPDATE ad_userinfo SET phoneauthisopen = $1 WHERE userid = $2`
+//	user := models.AdUser{}
+//	userInfo := models.AdUserInfo{}
+//	user.Id = userId
+//	user.Area = area
+//	user.Phone = phone
+//
+//	//事务
+//	err := orm.Transaction(func(tx *gorm.DB) error {
+//		err := tx.Model(user).Updates(map[string]interface{}{"area": area, "phone": phone}).Error
+//
+//		if err != nil {
+//			return err
+//		}
+//
+//		err = tx.Model(userInfo).Where("user_id =?", userId).Update("phone_auth_is_open", sysmodel.AuthBoundOpen).Error
+//
+//		if err != nil {
+//			return err
+//		}
+//
+//		return nil
+//	})
+//
+//	if err != nil {
+//		log.Error("BindPhoneAuth Commit Error:", zap.Error(err))
+//		return err
+//	}
+//
+//	return nil
+//}
+//
+//// ChangePhoneAuth 更改手机验证
+//func ChangePhoneAuth(orm *gorm.DB, userId int, area string, phone string) error {
+//	// updateUser := `UPDATE ad_user SET area = $1, phone = $2 WHERE id = $3`
+//	// updateUserinfo := `UPDATE ad_userinfo SET securityupdatetime = $1 WHERE userid = $2`
+//	user := models.AdUser{}
+//	user.Id = userId
+//
+//	err := orm.Transaction(func(tx *gorm.DB) error {
+//		err := orm.Model(user).Updates(map[string]interface{}{"area": area, "phone": phone}).Error
+//
+//		if err != nil {
+//			return err
+//		}
+//
+//		err = orm.Model(models.AdUserInfo{}).Where("user_id =?", userId).Update("security_update_time", time.Now()).Error
+//
+//		if err != nil {
+//			return err
+//		}
+//
+//		return nil
+//	})
+//
+//	if err != nil {
+//		log.Error("Commit Error:", zap.Error(err))
+//		return err
+//	}
+//
+//	return nil
+//}
+//
+//// ClosePhoneAuth 关闭手机验证
+//func ClosePhoneAuth(orm *gorm.DB, userId int) error {
+//
+//	// updateSql := `UPDATE ad_userinfo SET phoneauthisopen = $1, securityupdatetime = $2 WHERE userid = $3`
+//	user := models.AdUser{}
+//	user.Id = userId
+//
+//	if err := orm.Model(user).Updates(map[string]interface{}{"phone_auth_is_open": sysmodel.AuthBoundClose, "security_update_time": time.Now()}).Error; err != nil {
+//		log.Error("ClosePhoneAuth failed", zap.Error(err))
+//		return err
+//	}
+//
+//	return nil
+//}
+//
+//// BindEmailAuth 绑定邮箱验证
+//func BindEmailAuth(orm *gorm.DB, userId int, email string) error {
+//	// updateUser := `UPDATE ad_user SET useremail = $1 WHERE id = $2`
+//	// updateUserinfo := `UPDATE ad_userinfo SET emailauthisopen = $1 WHERE userid = $2`
+//	user := models.LineUser{}
+//	user.Id = userId
+//
+//	err := orm.Transaction(func(tx *gorm.DB) error {
+//		err := orm.Model(user).Updates(map[string]interface{}{"user_email": email}).Error
+//
+//		if err != nil {
+//			return err
+//		}
+//
+//		err = orm.Model(models.AdUserInfo{}).Where("user_id =?", userId).Update("email_auth_is_open", sysmodel.AuthBoundOpen).Error
+//
+//		if err != nil {
+//			return err
+//		}
+//
+//		return nil
+//	})
+//
+//	if err != nil {
+//		log.Error("BindEmailAuth Commit Error:", zap.Error(err))
+//		return err
+//	}
+//
+//	return nil
+//}
+//
+//// ChangeEmailAuth 更改邮箱验证
+//func ChangeEmailAuth(orm *gorm.DB, userId int, email string) error {
+//	// updateUser := `UPDATE ad_user SET useremail = $1 WHERE id = $2`
+//	// updateUserinfo := `UPDATE ad_userinfo SET securityupdatetime = $1 WHERE userid = $2`
+//	user := models.AdUser{}
+//	user.Id = userId
+//
+//	err := orm.Transaction(func(tx *gorm.DB) error {
+//		err := orm.Model(user).Update("user_email", email).Error
+//
+//		if err != nil {
+//			return err
+//		}
+//
+//		err = orm.Model(models.AdUserInfo{}).Where("user_id =?", userId).Update("security_update_time", time.Now()).Error
+//
+//		if err != nil {
+//			return err
+//		}
+//
+//		return nil
+//	})
+//
+//	if err != nil {
+//		log.Error("ChangeEmailAuth Commit Error:", zap.Error(err))
+//		return err
+//	}
+//
+//	return nil
+//}
+//
+//// CloseEmailAuth 关闭邮箱验证
+//func CloseEmailAuth(orm *gorm.DB, userId int) error {
+//	userInfo := models.AdUserInfo{}
+//
+//	// updateSql := `UPDATE ad_userinfo SET emailauthisopen = $1, securityupdatetime = $2 WHERE userid = $3`
+//	if err := orm.Model(userInfo).Where("user_id =?", userId).Updates(map[string]interface{}{
+//		"email_auth_is_open": sysmodel.AuthBoundClose, "security_update_time": time.Now()}).Error; err != nil {
+//		log.Error("CloseEmailAuth failed", zap.Error(err))
+//		return err
+//	}
+//
+//	return nil
+//}
+//
+//// OpenGoogleAuth 开启 Google 验证
+//func OpenGoogleAuth(orm *gorm.DB, userId int) error {
+//	updateSql := `UPDATE ad_user_info SET google_idcard_is_open = ?, google_secret = googlesecret1 WHERE user_id = ?`
+//	if err := orm.Exec(updateSql, sysmodel.AuthBoundOpen, userId).Error; err != nil {
+//		log.Error("OpenGoogleAuth failed", zap.Error(err))
+//		return err
+//	}
+//
+//	return nil
+//}
+//
+////// ChangeGoogleAuth 更改 Google 验证
+////func ChangeGoogleAuth(userId int) (err error) {
+////
+////	updateSql := `UPDATE ad_userinfo SET googlesecret = googlesecret1 WHERE userid = $1`
+////	if _, err = dbhelper.MasterPgdb.Exec(updateSql, userId); err != nil {
+////		log.Error("ChangeGoogleAuth failed", zap.Error(err))
+////	}
+////
+////	return err
+////}
+//
+//// CloseGoogleAuth 关闭 Google 验证
+//func CloseGoogleAuth(orm *gorm.DB, userId int) error {
+//
+//	// updateSql := `UPDATE ad_userinfo SET googleidcardisopen = $1, securityupdatetime = $2 WHERE userid = $3`
+//	if err := orm.Model(models.AdUserInfo{}).Where("user_id=?", userId).Updates(map[string]interface{}{
+//		"google_idcard_is_open": sysmodel.AuthBoundClose, "security_update_time": time.Now()}).Error; err != nil {
+//		log.Error("CloseGoogleAuth failed", zap.Error(err))
+//		return err
+//	}
+//
+//	return nil
+//}
+//
+//// GetNewGoogleSecret 获取新谷歌秘钥
+//func GetNewGoogleSecret(orm *gorm.DB, userID int) (string, error) {
+//	secret := struct {
+//		NewSecret string `gorm:"googlesecret1"`
+//	}{}
+//
+//	err := orm.Model(models.AdUserInfo{}).Where("user_id=?", userID).First(secret).Error
+//
+//	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+//		log.Error("CloseGoogleAuth failed", zap.Error(err))
+//		return "", err
+//	}
+//
+//	return secret.NewSecret, nil
+//}
+//
+//// TemporaryStorageSecret 临时存储更改的 Secret
+//func TemporaryStorageSecret(orm *gorm.DB, userId int, secret string) error {
+//
+//	// sql := `UPDATE ad_userinfo SET googlesecret1 = $1 WHERE userid = $2`
+//	if err := orm.Model(models.AdUserInfo{}).Where("user_id=?", userId).Update("googlesecret1", secret).Error; err != nil {
+//		log.Error("TemporaryStorageSecret failed", zap.Error(err))
+//		return err
+//	}
+//
+//	return nil
+//}
+//
+//// ALLInvite 累计邀请人数
+//func ALLInvite(orm *gorm.DB, userId int) (count int) {
+//	// sql := `SELECT totalnum FROM ad_userinfo WHERE userid = $1`
+//	if err := orm.Model(models.AdUserInfo{}).Where("user_id=?", userId).Select("total_num").First(&count).Error; err != nil {
+//		log.Error("get userinfo", zap.Error(err))
+//		return count
+//	}
+//	return
+//}
+//
+//// ThisMonthInvite 本月邀请
+//func ThisMonthInvite(orm *gorm.DB, userId int) (count int) {
+//	// sql := `SELECT count(*) FROM ad_userinfo WHERE recommenid = $1 AND  createtime BETWEEN (now() - INTERVAL '30 days') AND now()`
+//	var total int64
+//
+//	if err := orm.Model(models.AdUserInfo{}).Where("recommen_id=? AND created_at BETWEEN (now() - INTERVAL '30 days') AND now()").Count(&total).Error; err != nil {
+//		log.Error("get userinfo", zap.Error(err))
+//		return count
+//	}
+//
+//	count = int(total)
+//	return
+//}
+//
+//// InviteNum 总邀请人数
+//func InviteNum(orm *gorm.DB, userId int) (count int) {
+//	// sql := `SELECT count(*) FROM ad_userinfo WHERE recommenid = $1`
+//	var total int64
+//
+//	if err := orm.Model(models.AdUserInfo{}).Where("recommen_id=?", userId).Count(&total).Error; err != nil {
+//		log.Error("get userinfo", zap.Error(err))
+//		return count
+//	}
+//
+//	count = int(total)
+//	return
+//}
+//
+//// UpdateUserTransferOpen 更新内部转账开关
+//func UpdateUserTransferOpen(orm *gorm.DB, userId, transferOpen int) error {
+//	// updateSql := `UPDATE ad_userinfo SET transferopen = $1 WHERE userid = $2`
+//	if err := orm.Model(models.AdUserInfo{}).Where("user_id=?", userId).Update("transfer_open", transferOpen).Error; err != nil {
+//		log.Error("UpdateUserTransferOpen  failed", zap.Error(err))
+//		return err
+//	}
+//	return nil
+//}
+//
+//// UpdateUserTransferStatus 更新内部划转开关
+//func UpdateUserTransferStatus(orm *gorm.DB, userid, transferStatus int) error {
+//	// sql := `UPDATE ad_user SET transferstatus = $1 WHERE id = $2`
+//	user := models.AdUser{}
+//	user.Id = userid
+//
+//	if err := orm.Model(user).Update("transfer_status", transferStatus).Error; err != nil {
+//		log.Error("UpdateUserTransferStatus  failed", zap.Error(err))
+//		return err
+//	}
+//	return nil
+//}
diff --git a/app/admin/service/aduserdb/ad_verifycode.go b/app/admin/service/aduserdb/ad_verifycode.go
new file mode 100644
index 0000000..424dedd
--- /dev/null
+++ b/app/admin/service/aduserdb/ad_verifycode.go
@@ -0,0 +1,138 @@
+package aduserdb
+
+//
+//import (
+//	"errors"
+//	"go-admin/app/admin/models"
+//	"go-admin/app/admin/models/sysmodel"
+//	"time"
+//
+//	"go.uber.org/zap"
+//	"gorm.io/gorm"
+//
+//	log "github.com/go-admin-team/go-admin-core/logger"
+//)
+//
+//// 是否重复发送
+//// ∵ now - send < 60 时,不能重复发送
+//// ∴ send > now - 60 时,不能重复发送
+//func IsRepeatSend(orm *gorm.DB, receive string, businessType int) (verifyCode models.AdVerifyCode, err error) {
+//	// sqlSe := `
+//	// 	SELECT id, sendtime, verifytime
+//	// 	FROM ad_verifycode
+//	// 	WHERE businesstype = $1 AND phone = $2 AND sendtime > $3 AND verifyflag = $4
+//	// 	LIMIT 1
+//	// `
+//	// Now - 60
+//	nowSub60 := time.Now().Add(-time.Minute)
+//	err = orm.Model(verifyCode).Where("business_type =? AND phone =? AND send_time >? AND verify_flag =?", businessType, receive, nowSub60, 0).
+//		First(&verifyCode).
+//		Error
+//
+//	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+//		log.Error("IsRepeatSend", zap.Error(err))
+//		return
+//	}
+//
+//	return
+//}
+//
+//// GetVerifyCode 获取验证码
+//func GetVerifyCode(orm *gorm.DB, req sysmodel.CheckCaptcha) (verifyCode models.AdVerifyCode) {
+//	req.Now = time.Now()
+//	req.Flag = 0
+//
+//	//sql := `
+//	//	SELECT id FROM ad_verifycode
+//	//	WHERE phone = :phone AND code = :code AND sendtime < :now
+//	//	AND verifytime > :now AND businesstype = :businesstype AND verifyflag = :verifyflag
+//	//`
+//	// 查询符合业务的未被验证的验证码
+//	//if err = dbhelper.MasterPgdb.GetNameQuery(&verifyCode, sql, req); err != nil {
+//	//	log.Error("GetVerifyCode", zap.Error(err))
+//	//	return
+//	//}
+//
+//	// sqlSe := `SELECT id,phone,code FROM ad_verifycode WHERE phone=$1 AND code=$2 AND businesstype=$3 AND verifyflag=0 AND sendtime<$4 AND verifytime>$4 ORDER BY id DESC LIMIT 1`
+//	// err := dbhelper.MasterPgdb.Get(&verifyCode, sqlSe, req.Receive, req.Captcha, req.BusinessType, req.Now)
+//	err := orm.Model(verifyCode).Where("phone =? AND code=? AND business_type=? AND verify_flag=0 AND send_time  AND verify_time >?",
+//		req.Receive, req.Captcha, req.BusinessType, req.Now, req.Now).
+//		Order("id desc").
+//		First(&verifyCode).
+//		Error
+//	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+//		log.Error("GetVerifyCode", zap.Error(err))
+//	}
+//	return
+//}
+//
+//// // UpdateVerifyCode 更新验证码状态
+//// func UpdateVerifyCode(cc sysmodel.CheckCaptcha, tx *sqlx.Tx) error {
+//// 	cc.Flag = 1
+//// 	cc.Now = time.Now()
+//
+//// 	sqlUp := `
+//// 		UPDATE ad_verifycode
+//// 		SET validtime = :now, verifyflag = :verifyflag
+//// 		WHERE phone = :phone AND code = :code AND sendtime < :now AND verifytime > :now AND businesstype = :businesstype AND verifyflag = 0
+//// 	`
+//// 	var re sql.Result
+//// 	var err error
+//// 	if tx == nil {
+//// 		re, err = dbhelper.MasterPgdb.NamedExec(sqlUp, cc)
+//// 	} else {
+//// 		// 更新该验证码为已验证
+//// 		re, err = dbhelper.MasterPgdb.NamedExecTx(sqlUp, cc, tx)
+//// 	}
+//// 	if err != nil {
+//// 		log.Error("UpdateVerifyCode", zap.Error(err))
+//// 		return err
+//// 	}
+//// 	if row, _ := re.RowsAffected(); row == 0 {
+//// 		return errors.New("验证码无效")
+//// 	}
+//
+//// 	return nil
+//// }
+//
+//// UpdateVerifyFlag 更新验证码状态,改为已经使用过该验证码
+//func UpdateVerifyFlag(orm *gorm.DB, id int) error {
+//	// sqlUp := `UPDATE ad_verifycode	SET validtime =$1, verifyflag =1 WHERE id=$2`
+//	verifyCode := models.AdVerifyCode{}
+//	verifyCode.Id = id
+//
+//	res := orm.Model(verifyCode).Updates(map[string]interface{}{"valid_time": time.Now(), "verify_flag": 1})
+//	// re, err := dbhelper.MasterPgdb.ExecTx(sqlUp, tx, time.Now(), id)
+//	if res.Error != nil {
+//		log.Error("UpdateVerifyFlag", zap.Error(res.Error))
+//		return res.Error
+//	}
+//	if res.RowsAffected == 0 {
+//		return errors.New("验证码无效")
+//	}
+//	return nil
+//
+//	//cc.Flag = 1
+//	//cc.Now = time.Now()
+//	//sqlUp := `
+//	//	UPDATE ad_verifycode
+//	//	SET validtime = :now, verifyflag = :verifyflag
+//	//	WHERE phone = :phone AND code = :code AND sendtime < :now AND verifytime > :now AND businesstype = :businesstype AND verifyflag = 0
+//	//`
+//	//var re sql.Result
+//	//var err error
+//	//if tx == nil {
+//	//	re, err = dbhelper.MasterPgdb.NamedExec(sqlUp, cc)
+//	//} else {
+//	//	// 更新该验证码为已验证
+//	//	re, err = dbhelper.MasterPgdb.NamedExecTx(sqlUp, cc, tx)
+//	//}
+//	//if err != nil {
+//	//	log.Error("UpdateVerifyCode", zap.Error(err))
+//	//	return err
+//	//}
+//	//if row, _ := re.RowsAffected(); row == 0 {
+//	//	return errors.New("验证码无效")
+//	//}
+//	//return nil
+//}
diff --git a/app/admin/service/binance_account.go b/app/admin/service/binance_account.go
new file mode 100644
index 0000000..dfc0b58
--- /dev/null
+++ b/app/admin/service/binance_account.go
@@ -0,0 +1,64 @@
+package service
+
+import (
+	"errors"
+	"fmt"
+	"github.com/bytedance/sonic"
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"go-admin/app/admin/models"
+	"go-admin/common/helper"
+	ext "go-admin/config"
+	"net/http"
+)
+
+const ProxyType = "socks5"
+
+type BinanceAccount struct {
+	service.Service
+}
+
+// GetFundingAsset 查询资金账户
+func (e *BinanceAccount) GetFundingAsset(userId int) (resp []models.FundingAsset, err error) {
+	var apiUser models.LineApiUser
+	err = e.Orm.Where(&models.LineApiUser{}).Where("user_id = ?", userId).Find(&apiUser).Error
+	if err != nil {
+		e.Log.Errorf("Service LineApiUser error:%s \r\n", err)
+		return []models.FundingAsset{}, err
+	}
+	if apiUser.Id <= 0 {
+		e.Log.Errorf("Service LineApiUser error:%s \r\n", "用户未找到")
+		return []models.FundingAsset{}, err
+	}
+	var proxyUrl, proxyType string
+	if ext.ExtConfig.ProxyUrl != "" {
+		proxyUrl = "127.0.0.1:7890"
+		proxyType = "http"
+	}
+
+	if apiUser.IpAddress != "" && apiUser.UserPass != "" {
+		proxyUrl = fmt.Sprintf("%s:%s", apiUser.IpAddress, apiUser.UserPass)
+		proxyType = ProxyType
+	}
+	clinet, err := helper.NewBinanceClient(apiUser.ApiKey, apiUser.ApiSecret, proxyType, proxyUrl)
+	if err != nil {
+		e.Log.Errorf("Service NewBinanceClient error:%s \r\n", err)
+		return []models.FundingAsset{}, err
+	}
+	req := map[string]int64{
+		"recvWindow": 10000,
+	}
+
+	httpResp, statusCode, err := clinet.SendSpotAuth("/sapi/v1/asset/get-funding-asset", "POST", req)
+	if err != nil {
+		e.Log.Errorf("Service SendSpotAuth error:%s \r\n", err)
+		return []models.FundingAsset{}, err
+	}
+
+	if statusCode != http.StatusOK {
+		e.Log.Errorf("Service 请求失败 error:%s \r\n", err)
+		return []models.FundingAsset{}, errors.New("请求失败")
+	}
+	sonic.Unmarshal(httpResp, &resp)
+
+	return resp, nil
+}
diff --git a/app/admin/service/common/base.go b/app/admin/service/common/base.go
new file mode 100644
index 0000000..c1825ec
--- /dev/null
+++ b/app/admin/service/common/base.go
@@ -0,0 +1,103 @@
+package common
+
+import (
+	"errors"
+	"go-admin/pkg/cryptohelper/jwthelper"
+	"net"
+	"strconv"
+
+	"github.com/gin-gonic/gin"
+)
+
+// 通过原生 token 获取登录用户 ID,判断是否登录。
+// 注:该方法未经过登录中间件,从原始 token 中解析出登录信息,而非从已解析的 token 串中获取登录信息。
+func GetUserIdByToken(ctx *gin.Context) int {
+	token := ctx.GetHeader("token")
+	if len(token) == 0 {
+		return 0
+	}
+	// 解析token
+	flag, rew := jwthelper.MidValidToken(token, 3)
+	if flag < 0 || len(rew) == 0 {
+		return 0
+	}
+
+	loginUser := jwthelper.GetLoginUserJwt(rew)
+
+	return loginUser.UserID
+}
+
+// 获取操作系统:1-Android,2-IOS,3-PC
+func GetOS(ctx *gin.Context) int {
+	osStr := ctx.GetHeader("os")      // 获取请求头中的"os"字段
+	osInt, err := strconv.Atoi(osStr) // 转换为整数
+	if err != nil {
+		return 0 // 如果转换失败,返回0
+	}
+	return osInt
+}
+
+// 获取 设备ID
+func GetDeviceID(ctx *gin.Context) string {
+	device := ctx.GetHeader("device_id") // 获取请求头中的"os"字段
+
+	return device
+}
+
+// 获取 language,默认语言:zh-CN
+// 英语 en
+// 日本语 jp
+// 韩语 kr
+// 马来西亚语 my
+// 泰国语 th
+// 越南语 vn
+// 简体中文 zh-CN
+// 繁体中文 zh-HK
+func GetLanguage(ctx *gin.Context) string {
+	lang := ""
+
+	language := ctx.GetHeader("Accept-Language")
+	if language == "" {
+
+		val, exits := ctx.Get("language")
+
+		if !exits {
+			lang = "zh-CN"
+		} else {
+			lang = val.(string)
+		}
+
+	} else {
+		lang = language
+	}
+	return lang
+}
+
+// 根据token获取当前userid
+func GetUserId(ctx *gin.Context) int {
+	token := ctx.GetHeader("ParseToken") // .Request.Header.Peek("token")
+	// loghelper.Debug("token:  " + token)
+	if len(token) == 0 {
+		return 0
+	}
+	tokenItem := jwthelper.GetLoginUserJwt(token)
+	return tokenItem.UserID
+}
+
+// GetClientIp 获取本机ip
+func GetClientIp() (string, error) {
+	adders, err := net.InterfaceAddrs()
+	if err != nil {
+		return "", err
+	}
+	for _, address := range adders {
+		// 检查ip地址判断是否回环地址
+		if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
+			if ipnet.IP.To4() != nil {
+				return ipnet.IP.String(), nil
+			}
+
+		}
+	}
+	return "", errors.New("Can not find the client ip address!")
+}
diff --git a/app/admin/service/dto/line_account_setting.go b/app/admin/service/dto/line_account_setting.go
new file mode 100644
index 0000000..f928226
--- /dev/null
+++ b/app/admin/service/dto/line_account_setting.go
@@ -0,0 +1,86 @@
+package dto
+
+import (
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineAccountSettingGetPageReq struct {
+	dto.Pagination     `search:"-"`
+    LineAccountSettingOrder
+}
+
+type LineAccountSettingOrder struct {
+    Id string `form:"idOrder"  search:"type:order;column:id;table:line_account_setting"`
+    UserName string `form:"userNameOrder"  search:"type:order;column:user_name;table:line_account_setting"`
+    Password string `form:"passwordOrder"  search:"type:order;column:password;table:line_account_setting"`
+    CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_account_setting"`
+    UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_account_setting"`
+    DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_account_setting"`
+    CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:line_account_setting"`
+    UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_account_setting"`
+    
+}
+
+func (m *LineAccountSettingGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineAccountSettingInsertReq struct {
+    Id int `json:"-" comment:"id"` // id
+    UserName string `json:"userName" comment:"用户"`
+    Password string `json:"password" comment:"密码"`
+    common.ControlBy
+}
+
+func (s *LineAccountSettingInsertReq) Generate(model *models.LineAccountSetting)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.UserName = s.UserName
+    model.Password = s.Password
+    model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LineAccountSettingInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineAccountSettingUpdateReq struct {
+    Id int `uri:"id" comment:"id"` // id
+    UserName string `json:"userName" comment:"用户"`
+    Password string `json:"password" comment:"密码"`
+    common.ControlBy
+}
+
+func (s *LineAccountSettingUpdateReq) Generate(model *models.LineAccountSetting)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.UserName = s.UserName
+    model.Password = s.Password
+    model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LineAccountSettingUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineAccountSettingGetReq 功能获取请求参数
+type LineAccountSettingGetReq struct {
+     Id int `uri:"id"`
+}
+func (s *LineAccountSettingGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineAccountSettingDeleteReq 功能删除请求参数
+type LineAccountSettingDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineAccountSettingDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_api_group.go b/app/admin/service/dto/line_api_group.go
new file mode 100644
index 0000000..f47eaf3
--- /dev/null
+++ b/app/admin/service/dto/line_api_group.go
@@ -0,0 +1,87 @@
+package dto
+
+import (
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineApiGroupGetPageReq struct {
+	dto.Pagination     `search:"-"`
+    GroupName string `form:"groupName"  search:"type:exact;column:group_name;table:line_api_group" comment:"用户组名称"`
+    LineApiGroupOrder
+}
+
+type LineApiGroupOrder struct {
+    Id string `form:"idOrder"  search:"type:order;column:id;table:line_api_group"`
+    GroupName string `form:"groupNameOrder"  search:"type:order;column:group_name;table:line_api_group"`
+    ApiUserId string `form:"apiUserIdOrder"  search:"type:order;column:api_user_id;table:line_api_group"`
+    CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_api_group"`
+    UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_api_group"`
+    DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_api_group"`
+    CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:line_api_group"`
+    UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_api_group"`
+    
+}
+
+func (m *LineApiGroupGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineApiGroupInsertReq struct {
+    Id int `json:"-" comment:""` // 
+    GroupName string `json:"groupName" comment:"用户组名称"`
+    ApiUserId string `json:"apiUserId" comment:"绑定的api账户id"`
+    common.ControlBy
+}
+
+func (s *LineApiGroupInsertReq) Generate(model *models.LineApiGroup)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.GroupName = s.GroupName
+    model.ApiUserId = s.ApiUserId
+    model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LineApiGroupInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineApiGroupUpdateReq struct {
+    Id int `uri:"id" comment:""` // 
+    GroupName string `json:"groupName" comment:"用户组名称"`
+    ApiUserId string `json:"apiUserId" comment:"绑定的api账户id"`
+    common.ControlBy
+}
+
+func (s *LineApiGroupUpdateReq) Generate(model *models.LineApiGroup)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.GroupName = s.GroupName
+    model.ApiUserId = s.ApiUserId
+    model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LineApiGroupUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineApiGroupGetReq 功能获取请求参数
+type LineApiGroupGetReq struct {
+     Id int `uri:"id"`
+}
+func (s *LineApiGroupGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineApiGroupDeleteReq 功能删除请求参数
+type LineApiGroupDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineApiGroupDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_api_user.go b/app/admin/service/dto/line_api_user.go
new file mode 100644
index 0000000..a9a1b62
--- /dev/null
+++ b/app/admin/service/dto/line_api_user.go
@@ -0,0 +1,150 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineApiUserGetPageReq struct {
+	dto.Pagination `search:"-"`
+	LineApiUserOrder
+}
+
+type LineApiUserOrder struct {
+	Id          string `form:"idOrder"  search:"type:order;column:id;table:line_api_user"`
+	UserId      string `form:"userIdOrder"  search:"type:order;column:user_id;table:line_api_user"`
+	JysId       string `form:"jysIdOrder"  search:"type:order;column:jys_id;table:line_api_user"`
+	ApiName     string `form:"apiNameOrder"  search:"type:order;column:api_name;table:line_api_user"`
+	ApiKey      string `form:"apiKeyOrder"  search:"type:order;column:api_key;table:line_api_user"`
+	ApiSecret   string `form:"apiSecretOrder"  search:"type:order;column:api_secret;table:line_api_user"`
+	IpAddress   string `form:"ipAddressOrder"  search:"type:order;column:ip_address;table:line_api_user"`
+	UserPass    string `form:"userPassOrder"  search:"type:order;column:user_pass;table:line_api_user"`
+	AdminId     string `form:"adminIdOrder"  search:"type:order;column:admin_id;table:line_api_user"`
+	Affiliation string `form:"affiliationOrder"  search:"type:order;column:affiliation;table:line_api_user"`
+	AdminShow   string `form:"adminShowOrder"  search:"type:order;column:admin_show;table:line_api_user"`
+	Site        string `form:"siteOrder"  search:"type:order;column:site;table:line_api_user"`
+	Subordinate string `form:"subordinateOrder"  search:"type:order;column:subordinate;table:line_api_user"`
+	GroupId     string `form:"groupIdOrder"  search:"type:order;column:group_id;table:line_api_user"`
+	OpenStatus  string `form:"openStatusOrder"  search:"type:order;column:open_status;table:line_api_user"`
+	CreatedAt   string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_api_user"`
+	UpdatedAt   string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_api_user"`
+	DeletedAt   string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_api_user"`
+	CreateBy    string `form:"createByOrder"  search:"type:order;column:create_by;table:line_api_user"`
+	UpdateBy    string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_api_user"`
+}
+
+func (m *LineApiUserGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineApiUserInsertReq struct {
+	Id          int    `json:"-" comment:"id"` // id
+	UserId      int64  `json:"userId" comment:"用户id"`
+	JysId       int64  `json:"jysId" comment:"关联交易所账号id"`
+	ApiName     string `json:"apiName" comment:"api用户名"`
+	ApiKey      string `json:"apiKey" comment:"apiKey"`
+	ApiSecret   string `json:"apiSecret" comment:"apiSecret"`
+	IpAddress   string `json:"ipAddress" comment:"代理地址"`
+	UserPass    string `json:"userPass" comment:"代码账号密码"`
+	AdminId     int64  `json:"adminId" comment:"管理员id"`
+	Affiliation int64  `json:"affiliation" comment:"归属:1=现货,2=合约,3=现货合约"`
+	AdminShow   int64  `json:"adminShow" comment:"是否超管可见:1=是,0=否"`
+	Site        string `json:"site" comment:"允许下单的方向:1=多;2=空;3=多空"`
+	Subordinate string `json:"subordinate" comment:"从属关系:0=未绑定关系;1=主账号;2=副帐号"`
+	GroupId     int64  `json:"groupId" comment:"所属组id"`
+	OpenStatus  int64  `json:"openStatus" comment:"开启状态 0=关闭 1=开启"`
+	common.ControlBy
+}
+
+func (s *LineApiUserInsertReq) Generate(model *models.LineApiUser) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.UserId = s.UserId
+	model.JysId = s.JysId
+	model.ApiName = s.ApiName
+	model.ApiKey = s.ApiKey
+	model.ApiSecret = s.ApiSecret
+	model.IpAddress = s.IpAddress
+	model.UserPass = s.UserPass
+	model.AdminId = s.AdminId
+	model.Affiliation = s.Affiliation
+	model.AdminShow = s.AdminShow
+	model.Site = s.Site
+	model.Subordinate = s.Subordinate
+	model.GroupId = s.GroupId
+	model.OpenStatus = s.OpenStatus
+	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LineApiUserInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineApiUserUpdateReq struct {
+	Id          int    `uri:"id" comment:"id"` // id
+	UserId      int64  `json:"userId" comment:"用户id"`
+	JysId       int64  `json:"jysId" comment:"关联交易所账号id"`
+	ApiName     string `json:"apiName" comment:"api用户名"`
+	ApiKey      string `json:"apiKey" comment:"apiKey"`
+	ApiSecret   string `json:"apiSecret" comment:"apiSecret"`
+	IpAddress   string `json:"ipAddress" comment:"代理地址"`
+	UserPass    string `json:"userPass" comment:"代码账号密码"`
+	AdminId     int64  `json:"adminId" comment:"管理员id"`
+	Affiliation int64  `json:"affiliation" comment:"归属:1=现货,2=合约,3=现货合约"`
+	AdminShow   int64  `json:"adminShow" comment:"是否超管可见:1=是,0=否"`
+	Site        string `json:"site" comment:"允许下单的方向:1=多;2=空;3=多空"`
+	Subordinate string `json:"subordinate" comment:"从属关系:0=未绑定关系;1=主账号;2=副帐号"`
+	GroupId     int64  `json:"groupId" comment:"所属组id"`
+	OpenStatus  int64  `json:"openStatus" comment:"开启状态 0=关闭 1=开启"`
+	common.ControlBy
+}
+
+func (s *LineApiUserUpdateReq) Generate(model *models.LineApiUser) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.UserId = s.UserId
+	model.JysId = s.JysId
+	model.ApiName = s.ApiName
+	model.ApiKey = s.ApiKey
+	model.ApiSecret = s.ApiSecret
+	model.IpAddress = s.IpAddress
+	model.UserPass = s.UserPass
+	model.AdminId = s.AdminId
+	model.Affiliation = s.Affiliation
+	model.AdminShow = s.AdminShow
+	model.Site = s.Site
+	model.Subordinate = s.Subordinate
+	model.GroupId = s.GroupId
+	model.OpenStatus = s.OpenStatus
+	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LineApiUserUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineApiUserGetReq 功能获取请求参数
+type LineApiUserGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *LineApiUserGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineApiUserDeleteReq 功能删除请求参数
+type LineApiUserDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineApiUserDeleteReq) GetId() interface{} {
+	return s.Ids
+}
+
+type LineApiUserBindSubordinateReq struct {
+	UserIdStr string `json:"user_id_str"`
+	GroupName string `json:"group_name"`
+}
diff --git a/app/admin/service/dto/line_coinnetwork.go b/app/admin/service/dto/line_coinnetwork.go
new file mode 100644
index 0000000..4d7b8ef
--- /dev/null
+++ b/app/admin/service/dto/line_coinnetwork.go
@@ -0,0 +1,106 @@
+package dto
+
+import (
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineCoinnetworkGetPageReq struct {
+	dto.Pagination     `search:"-"`
+    LineCoinnetworkOrder
+}
+
+type LineCoinnetworkOrder struct {
+    Id string `form:"idOrder"  search:"type:order;column:id;table:line_coinnetwork"`
+    NetworkName string `form:"networkNameOrder"  search:"type:order;column:network_name;table:line_coinnetwork"`
+    TokenName string `form:"tokenNameOrder"  search:"type:order;column:token_name;table:line_coinnetwork"`
+    ArrivalNum string `form:"arrivalNumOrder"  search:"type:order;column:arrival_num;table:line_coinnetwork"`
+    UnlockNum string `form:"unlockNumOrder"  search:"type:order;column:unlock_num;table:line_coinnetwork"`
+    UnlockTime string `form:"unlockTimeOrder"  search:"type:order;column:unlock_time;table:line_coinnetwork"`
+    Fee string `form:"feeOrder"  search:"type:order;column:fee;table:line_coinnetwork"`
+    CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:line_coinnetwork"`
+    UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_coinnetwork"`
+    CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_coinnetwork"`
+    UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_coinnetwork"`
+    DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_coinnetwork"`
+    
+}
+
+func (m *LineCoinnetworkGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineCoinnetworkInsertReq struct {
+    Id int `json:"-" comment:"主键ID"` // 主键ID
+    NetworkName string `json:"networkName" comment:"网络名称"`
+    TokenName string `json:"tokenName" comment:"网络token名称"`
+    ArrivalNum int64 `json:"arrivalNum" comment:"充值区块确认数"`
+    UnlockNum int64 `json:"unlockNum" comment:"提现解锁确认数"`
+    UnlockTime int64 `json:"unlockTime" comment:"提现确认平均时间,单位分钟"`
+    Fee string `json:"fee" comment:"网络手续费,该字段是动态的,后面会有服务定时更新该字段"`
+    common.ControlBy
+}
+
+func (s *LineCoinnetworkInsertReq) Generate(model *models.LineCoinnetwork)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.NetworkName = s.NetworkName
+    model.TokenName = s.TokenName
+    model.ArrivalNum = s.ArrivalNum
+    model.UnlockNum = s.UnlockNum
+    model.UnlockTime = s.UnlockTime
+    model.Fee = s.Fee
+    model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LineCoinnetworkInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineCoinnetworkUpdateReq struct {
+    Id int `uri:"id" comment:"主键ID"` // 主键ID
+    NetworkName string `json:"networkName" comment:"网络名称"`
+    TokenName string `json:"tokenName" comment:"网络token名称"`
+    ArrivalNum int64 `json:"arrivalNum" comment:"充值区块确认数"`
+    UnlockNum int64 `json:"unlockNum" comment:"提现解锁确认数"`
+    UnlockTime int64 `json:"unlockTime" comment:"提现确认平均时间,单位分钟"`
+    Fee string `json:"fee" comment:"网络手续费,该字段是动态的,后面会有服务定时更新该字段"`
+    common.ControlBy
+}
+
+func (s *LineCoinnetworkUpdateReq) Generate(model *models.LineCoinnetwork)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.NetworkName = s.NetworkName
+    model.TokenName = s.TokenName
+    model.ArrivalNum = s.ArrivalNum
+    model.UnlockNum = s.UnlockNum
+    model.UnlockTime = s.UnlockTime
+    model.Fee = s.Fee
+    model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LineCoinnetworkUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineCoinnetworkGetReq 功能获取请求参数
+type LineCoinnetworkGetReq struct {
+     Id int `uri:"id"`
+}
+func (s *LineCoinnetworkGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineCoinnetworkDeleteReq 功能删除请求参数
+type LineCoinnetworkDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineCoinnetworkDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_cointonetwork.go b/app/admin/service/dto/line_cointonetwork.go
new file mode 100644
index 0000000..f2b5ec4
--- /dev/null
+++ b/app/admin/service/dto/line_cointonetwork.go
@@ -0,0 +1,197 @@
+package dto
+
+import (
+    "time"
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineCointonetworkGetPageReq struct {
+	dto.Pagination     `search:"-"`
+    LineCointonetworkOrder
+}
+
+type LineCointonetworkOrder struct {
+    Id string `form:"idOrder"  search:"type:order;column:id;table:line_cointonetwork"`
+    CoinId string `form:"coinIdOrder"  search:"type:order;column:coin_id;table:line_cointonetwork"`
+    NetworkId string `form:"networkIdOrder"  search:"type:order;column:network_id;table:line_cointonetwork"`
+    IsMain string `form:"isMainOrder"  search:"type:order;column:is_main;table:line_cointonetwork"`
+    IsDeposit string `form:"isDepositOrder"  search:"type:order;column:is_deposit;table:line_cointonetwork"`
+    IsWithdraw string `form:"isWithdrawOrder"  search:"type:order;column:is_withdraw;table:line_cointonetwork"`
+    CoinCode string `form:"coinCodeOrder"  search:"type:order;column:coin_code;table:line_cointonetwork"`
+    Token string `form:"tokenOrder"  search:"type:order;column:token;table:line_cointonetwork"`
+    MinChargeNum string `form:"minChargeNumOrder"  search:"type:order;column:min_charge_num;table:line_cointonetwork"`
+    MinOutNum string `form:"minOutNumOrder"  search:"type:order;column:min_out_num;table:line_cointonetwork"`
+    MaxOutNum string `form:"maxOutNumOrder"  search:"type:order;column:max_out_num;table:line_cointonetwork"`
+    TransferFee string `form:"transferFeeOrder"  search:"type:order;column:transfer_fee;table:line_cointonetwork"`
+    CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:line_cointonetwork"`
+    UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_cointonetwork"`
+    CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_cointonetwork"`
+    UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_cointonetwork"`
+    DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_cointonetwork"`
+    DetailCode string `form:"detailCodeOrder"  search:"type:order;column:detail_code;table:line_cointonetwork"`
+    NetworkName string `form:"networkNameOrder"  search:"type:order;column:network_name;table:line_cointonetwork"`
+    TokenName string `form:"tokenNameOrder"  search:"type:order;column:token_name;table:line_cointonetwork"`
+    ChargeType string `form:"chargeTypeOrder"  search:"type:order;column:charge_type;table:line_cointonetwork"`
+    RechargeSwitchTime string `form:"rechargeSwitchTimeOrder"  search:"type:order;column:recharge_switch_time;table:line_cointonetwork"`
+    WithdrawSwitchTime string `form:"withdrawSwitchTimeOrder"  search:"type:order;column:withdraw_switch_time;table:line_cointonetwork"`
+    IsoutsideWithdrawVerify string `form:"isoutsideWithdrawVerifyOrder"  search:"type:order;column:isoutside_withdraw_verify;table:line_cointonetwork"`
+    OutsideWithdrawVerifyNum string `form:"outsideWithdrawVerifyNumOrder"  search:"type:order;column:outside_withdraw_verify_num;table:line_cointonetwork"`
+    IsinsideTransferVerify string `form:"isinsideTransferVerifyOrder"  search:"type:order;column:isinside_transfer_verify;table:line_cointonetwork"`
+    InsidetransferVerifyNum string `form:"insidetransferVerifyNumOrder"  search:"type:order;column:insidetransfer_verify_num;table:line_cointonetwork"`
+    EverydaymaxWithdrawNum string `form:"everydaymaxWithdrawNumOrder"  search:"type:order;column:everydaymax_withdraw_num;table:line_cointonetwork"`
+    EverydaymaxVerifyNum string `form:"everydaymaxVerifyNumOrder"  search:"type:order;column:everydaymax_verify_num;table:line_cointonetwork"`
+    Isinsidetransferfee string `form:"isinsidetransferfeeOrder"  search:"type:order;column:isinsidetransferfee;table:line_cointonetwork"`
+    
+}
+
+func (m *LineCointonetworkGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineCointonetworkInsertReq struct {
+    Id int `json:"-" comment:""` // 
+    CoinId int64 `json:"coinId" comment:"币种id"`
+    NetworkId int64 `json:"networkId" comment:"公链网络id"`
+    IsMain int64 `json:"isMain" comment:"是否主网--1否,3是.比如BTC在BTC网络中就属于主网"`
+    IsDeposit int64 `json:"isDeposit" comment:"是否开启充值:1==否,3==是"`
+    IsWithdraw int64 `json:"isWithdraw" comment:"是否开启提现:1==否,3==是"`
+    CoinCode string `json:"coinCode" comment:"币种代号"`
+    Token string `json:"token" comment:"代币token"`
+    MinChargeNum string `json:"minChargeNum" comment:"最小充值数量"`
+    MinOutNum string `json:"minOutNum" comment:"单笔最小提币数量"`
+    MaxOutNum string `json:"maxOutNum" comment:"单笔最大提币数量"`
+    TransferFee string `json:"transferFee" comment:"提币手续费"`
+    DetailCode string `json:"detailCode" comment:"币种全称"`
+    NetworkName string `json:"networkName" comment:"公链网络简称"`
+    TokenName string `json:"tokenName" comment:"公链网络全称"`
+    ChargeType int64 `json:"chargeType" comment:"手续费类型 1==固定 3==百分比"`
+    RechargeSwitchTime time.Time `json:"rechargeSwitchTime" comment:"充值开关时间"`
+    WithdrawSwitchTime time.Time `json:"withdrawSwitchTime" comment:"提币开关时间"`
+    IsoutsideWithdrawVerify int64 `json:"isoutsideWithdrawVerify" comment:"是否开启外部提币免审1==否3==是"`
+    OutsideWithdrawVerifyNum string `json:"outsideWithdrawVerifyNum" comment:"外部提币免审阈值"`
+    IsinsideTransferVerify int64 `json:"isinsideTransferVerify" comment:"是否开启内部转账免审1==否3==是"`
+    InsidetransferVerifyNum string `json:"insidetransferVerifyNum" comment:"内部转账免审阈值"`
+    EverydaymaxWithdrawNum string `json:"everydaymaxWithdrawNum" comment:"每日最大累计提币数量"`
+    EverydaymaxVerifyNum string `json:"everydaymaxVerifyNum" comment:"每日最大免审累计数量"`
+    Isinsidetransferfee int64 `json:"isinsidetransferfee" comment:"是否开启内部转账免手续费1==否3==是"`
+    common.ControlBy
+}
+
+func (s *LineCointonetworkInsertReq) Generate(model *models.LineCointonetwork)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.CoinId = s.CoinId
+    model.NetworkId = s.NetworkId
+    model.IsMain = s.IsMain
+    model.IsDeposit = s.IsDeposit
+    model.IsWithdraw = s.IsWithdraw
+    model.CoinCode = s.CoinCode
+    model.Token = s.Token
+    model.MinChargeNum = s.MinChargeNum
+    model.MinOutNum = s.MinOutNum
+    model.MaxOutNum = s.MaxOutNum
+    model.TransferFee = s.TransferFee
+    model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+    model.DetailCode = s.DetailCode
+    model.NetworkName = s.NetworkName
+    model.TokenName = s.TokenName
+    model.ChargeType = s.ChargeType
+    model.RechargeSwitchTime = s.RechargeSwitchTime
+    model.WithdrawSwitchTime = s.WithdrawSwitchTime
+    model.IsoutsideWithdrawVerify = s.IsoutsideWithdrawVerify
+    model.OutsideWithdrawVerifyNum = s.OutsideWithdrawVerifyNum
+    model.IsinsideTransferVerify = s.IsinsideTransferVerify
+    model.InsidetransferVerifyNum = s.InsidetransferVerifyNum
+    model.EverydaymaxWithdrawNum = s.EverydaymaxWithdrawNum
+    model.EverydaymaxVerifyNum = s.EverydaymaxVerifyNum
+    model.Isinsidetransferfee = s.Isinsidetransferfee
+}
+
+func (s *LineCointonetworkInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineCointonetworkUpdateReq struct {
+    Id int `uri:"id" comment:""` // 
+    CoinId int64 `json:"coinId" comment:"币种id"`
+    NetworkId int64 `json:"networkId" comment:"公链网络id"`
+    IsMain int64 `json:"isMain" comment:"是否主网--1否,3是.比如BTC在BTC网络中就属于主网"`
+    IsDeposit int64 `json:"isDeposit" comment:"是否开启充值:1==否,3==是"`
+    IsWithdraw int64 `json:"isWithdraw" comment:"是否开启提现:1==否,3==是"`
+    CoinCode string `json:"coinCode" comment:"币种代号"`
+    Token string `json:"token" comment:"代币token"`
+    MinChargeNum string `json:"minChargeNum" comment:"最小充值数量"`
+    MinOutNum string `json:"minOutNum" comment:"单笔最小提币数量"`
+    MaxOutNum string `json:"maxOutNum" comment:"单笔最大提币数量"`
+    TransferFee string `json:"transferFee" comment:"提币手续费"`
+    DetailCode string `json:"detailCode" comment:"币种全称"`
+    NetworkName string `json:"networkName" comment:"公链网络简称"`
+    TokenName string `json:"tokenName" comment:"公链网络全称"`
+    ChargeType int64 `json:"chargeType" comment:"手续费类型 1==固定 3==百分比"`
+    RechargeSwitchTime time.Time `json:"rechargeSwitchTime" comment:"充值开关时间"`
+    WithdrawSwitchTime time.Time `json:"withdrawSwitchTime" comment:"提币开关时间"`
+    IsoutsideWithdrawVerify int64 `json:"isoutsideWithdrawVerify" comment:"是否开启外部提币免审1==否3==是"`
+    OutsideWithdrawVerifyNum string `json:"outsideWithdrawVerifyNum" comment:"外部提币免审阈值"`
+    IsinsideTransferVerify int64 `json:"isinsideTransferVerify" comment:"是否开启内部转账免审1==否3==是"`
+    InsidetransferVerifyNum string `json:"insidetransferVerifyNum" comment:"内部转账免审阈值"`
+    EverydaymaxWithdrawNum string `json:"everydaymaxWithdrawNum" comment:"每日最大累计提币数量"`
+    EverydaymaxVerifyNum string `json:"everydaymaxVerifyNum" comment:"每日最大免审累计数量"`
+    Isinsidetransferfee int64 `json:"isinsidetransferfee" comment:"是否开启内部转账免手续费1==否3==是"`
+    common.ControlBy
+}
+
+func (s *LineCointonetworkUpdateReq) Generate(model *models.LineCointonetwork)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.CoinId = s.CoinId
+    model.NetworkId = s.NetworkId
+    model.IsMain = s.IsMain
+    model.IsDeposit = s.IsDeposit
+    model.IsWithdraw = s.IsWithdraw
+    model.CoinCode = s.CoinCode
+    model.Token = s.Token
+    model.MinChargeNum = s.MinChargeNum
+    model.MinOutNum = s.MinOutNum
+    model.MaxOutNum = s.MaxOutNum
+    model.TransferFee = s.TransferFee
+    model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+    model.DetailCode = s.DetailCode
+    model.NetworkName = s.NetworkName
+    model.TokenName = s.TokenName
+    model.ChargeType = s.ChargeType
+    model.RechargeSwitchTime = s.RechargeSwitchTime
+    model.WithdrawSwitchTime = s.WithdrawSwitchTime
+    model.IsoutsideWithdrawVerify = s.IsoutsideWithdrawVerify
+    model.OutsideWithdrawVerifyNum = s.OutsideWithdrawVerifyNum
+    model.IsinsideTransferVerify = s.IsinsideTransferVerify
+    model.InsidetransferVerifyNum = s.InsidetransferVerifyNum
+    model.EverydaymaxWithdrawNum = s.EverydaymaxWithdrawNum
+    model.EverydaymaxVerifyNum = s.EverydaymaxVerifyNum
+    model.Isinsidetransferfee = s.Isinsidetransferfee
+}
+
+func (s *LineCointonetworkUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineCointonetworkGetReq 功能获取请求参数
+type LineCointonetworkGetReq struct {
+     Id int `uri:"id"`
+}
+func (s *LineCointonetworkGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineCointonetworkDeleteReq 功能删除请求参数
+type LineCointonetworkDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineCointonetworkDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_direction.go b/app/admin/service/dto/line_direction.go
new file mode 100644
index 0000000..310446b
--- /dev/null
+++ b/app/admin/service/dto/line_direction.go
@@ -0,0 +1,170 @@
+package dto
+
+import (
+	"errors"
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+	"go-admin/pkg/utility"
+	"strings"
+)
+
+type LineDirectionGetPageReq struct {
+	dto.Pagination `search:"-"`
+	Symbol         string `form:"symbol"  search:"type:contains;column:symbol;table:line_direction" comment:"交易对"`
+	Type           int64  `form:"type"  search:"type:exact;column:type;table:line_direction" comment:"交易对类型:1=现货,2=合约"`
+	Direction      string `form:"direction"  search:"type:contains;column:direction;table:line_direction" comment:"预估方向"`
+	LineDirectionOrder
+}
+
+type LineDirectionOrder struct {
+	Id         string `form:"idOrder"  search:"type:order;column:id;table:line_direction"`
+	Symbol     string `form:"symbolOrder"  search:"type:order;column:symbol;table:line_direction"`
+	Type       string `form:"typeOrder"  search:"type:order;column:type;table:line_direction"`
+	BuyPoint1  string `form:"buyPoint1Order"  search:"type:order;column:buy_point1;table:line_direction"`
+	BuyPoint2  string `form:"buyPoint2Order"  search:"type:order;column:buy_point2;table:line_direction"`
+	BuyPoint3  string `form:"buyPoint3Order"  search:"type:order;column:buy_point3;table:line_direction"`
+	SellPoint1 string `form:"sellPoint1Order"  search:"type:order;column:sell_point1;table:line_direction"`
+	SellPoint2 string `form:"sellPoint2Order"  search:"type:order;column:sell_point2;table:line_direction"`
+	SellPoint3 string `form:"sellPoint3Order"  search:"type:order;column:sell_point3;table:line_direction"`
+	Direction  string `form:"directionOrder"  search:"type:order;column:direction;table:line_direction"`
+	AiAnswer   string `form:"aiAnswerOrder"  search:"type:order;column:ai_answer;table:line_direction"`
+	CreatedAt  string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_direction"`
+	UpdatedAt  string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_direction"`
+	DeletedAt  string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_direction"`
+	CreateBy   string `form:"createByOrder"  search:"type:order;column:create_by;table:line_direction"`
+	UpdateBy   string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_direction"`
+}
+
+func (m *LineDirectionGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineDirectionInsertReq struct {
+	Id         int    `json:"-" comment:""` //
+	Symbol     string `json:"symbol" comment:"交易对"`
+	Type       int64  `json:"type" comment:"交易对类型:1=现货,2=合约"`
+	BuyPoint1  string `json:"buyPoint1" comment:"买入点一"`
+	BuyPoint2  string `json:"buyPoint2" comment:"买入点二"`
+	BuyPoint3  string `json:"buyPoint3" comment:"买入点三"`
+	SellPoint1 string `json:"sellPoint1" comment:"卖出点一"`
+	SellPoint2 string `json:"sellPoint2" comment:"卖出点二"`
+	SellPoint3 string `json:"sellPoint3" comment:"卖出点三"`
+	Direction  string `json:"direction" comment:"预估方向"`
+	AiAnswer   string `json:"aiAnswer" comment:"AI智能分析"`
+	common.ControlBy
+}
+
+func (s *LineDirectionInsertReq) Generate(model *models.LineDirection) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.Symbol = s.Symbol
+	model.Type = s.Type
+	model.BuyPoint1 = s.BuyPoint1
+	model.BuyPoint2 = s.BuyPoint2
+	model.BuyPoint3 = s.BuyPoint3
+	model.SellPoint1 = s.SellPoint1
+	model.SellPoint2 = s.SellPoint2
+	model.SellPoint3 = s.SellPoint3
+	model.Direction = s.Direction
+	model.AiAnswer = s.AiAnswer
+	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LineDirectionInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineDirectionUpdateReq struct {
+	Id         int    `uri:"id" comment:""` //
+	Symbol     string `json:"symbol" comment:"交易对"`
+	Type       int64  `json:"type" comment:"交易对类型:1=现货,2=合约"`
+	BuyPoint1  string `json:"buyPoint1" comment:"买入点一"`
+	BuyPoint2  string `json:"buyPoint2" comment:"买入点二"`
+	BuyPoint3  string `json:"buyPoint3" comment:"买入点三"`
+	SellPoint1 string `json:"sellPoint1" comment:"卖出点一"`
+	SellPoint2 string `json:"sellPoint2" comment:"卖出点二"`
+	SellPoint3 string `json:"sellPoint3" comment:"卖出点三"`
+	Direction  string `json:"direction" comment:"预估方向"`
+	AiAnswer   string `json:"aiAnswer" comment:"AI智能分析"`
+	common.ControlBy
+}
+
+func (s *LineDirectionUpdateReq) Generate(model *models.LineDirection) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.Symbol = s.Symbol
+	model.Type = s.Type
+	model.BuyPoint1 = s.BuyPoint1
+	model.BuyPoint2 = s.BuyPoint2
+	model.BuyPoint3 = s.BuyPoint3
+	model.SellPoint1 = s.SellPoint1
+	model.SellPoint2 = s.SellPoint2
+	model.SellPoint3 = s.SellPoint3
+	model.Direction = s.Direction
+	model.AiAnswer = s.AiAnswer
+	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LineDirectionUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineDirectionGetReq 功能获取请求参数
+type LineDirectionGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *LineDirectionGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineDirectionDeleteReq 功能删除请求参数
+type LineDirectionDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineDirectionDeleteReq) GetId() interface{} {
+	return s.Ids
+}
+
+type AddDirectionReq struct {
+	AccountName string `json:"accountName" form:"accountName"`
+	Password    string `json:"password" form:"password"`
+	Symbol      string `json:"symbol" form:"symbol"`
+	Type        string `json:"type" form:"type"`
+	BuyPoint1   string `json:"buy_point1" form:"buy_point1"`
+	BuyPoint2   string `json:"buy_point2" form:"buy_point2"`
+	BuyPoint3   string `json:"buy_point3" form:"buy_point3"`
+	SellPoint1  string `json:"sell_point1" form:"sell_point1"`
+	SellPoint2  string `json:"sell_point2" form:"sell_point2"`
+	SellPoint3  string `json:"sell_point3" form:"sell_point3"`
+	Direction   string `json:"direction" form:"direction"`
+	AiAnswer    string `json:"ai_answer" form:"ai_answer"`
+}
+
+func (a *AddDirectionReq) CheckParams() error {
+	if a.AccountName == "" || a.Password == "" || a.Symbol == "" || a.Type == "" || a.BuyPoint1 == "" ||
+		a.BuyPoint2 == "" || a.BuyPoint3 == "" || a.SellPoint1 == "" ||
+		a.SellPoint2 == "" || a.SellPoint3 == "" || a.AiAnswer == "" {
+		return errors.New("参数校验失败 传了空值")
+	}
+
+	a.BuyPoint1 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(a.BuyPoint1, ",", "."), "。", "."), " ", "")
+	a.BuyPoint2 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(a.BuyPoint2, ",", "."), "。", "."), " ", "")
+	a.BuyPoint3 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(a.BuyPoint3, ",", "."), "。", "."), " ", "")
+	a.SellPoint1 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(a.SellPoint1, ",", "."), "。", "."), " ", "")
+	a.SellPoint2 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(a.SellPoint2, ",", "."), "。", "."), " ", "")
+	a.SellPoint3 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(a.SellPoint3, ",", "."), "。", "."), " ", "")
+
+	a.Symbol = utility.ReplaceSuffix(strings.ReplaceAll(a.Symbol, " ", ""), "4小时", "USDT")
+	a.Symbol = strings.ReplaceAll(a.Symbol, "1小时", "USDT")
+	a.Symbol = strings.ReplaceAll(a.Symbol, "1日", "USDT")
+	a.Symbol = strings.ReplaceAll(a.Symbol, "四小时", "USDT")
+	a.Symbol = strings.ReplaceAll(a.Symbol, "一小时", "USDT")
+	a.Symbol = strings.ReplaceAll(a.Symbol, "一日", "USDT")
+
+	return nil
+}
diff --git a/app/admin/service/dto/line_order_template_logs.go b/app/admin/service/dto/line_order_template_logs.go
new file mode 100644
index 0000000..9946d9f
--- /dev/null
+++ b/app/admin/service/dto/line_order_template_logs.go
@@ -0,0 +1,104 @@
+package dto
+
+import (
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineOrderTemplateLogsGetPageReq struct {
+	dto.Pagination     `search:"-"`
+    Name string `form:"name"  search:"type:exact;column:name;table:line_order_template_logs" comment:"模板名称"`
+    UserId int64 `form:"userId"  search:"type:exact;column:user_id;table:line_order_template_logs" comment:"用户id"`
+    Type int64 `form:"type"  search:"type:exact;column:type;table:line_order_template_logs" comment:"模板类型:1=单独添加;2=批量添加"`
+    LineOrderTemplateLogsOrder
+}
+
+type LineOrderTemplateLogsOrder struct {
+    Id string `form:"idOrder"  search:"type:order;column:id;table:line_order_template_logs"`
+    Name string `form:"nameOrder"  search:"type:order;column:name;table:line_order_template_logs"`
+    UserId string `form:"userIdOrder"  search:"type:order;column:user_id;table:line_order_template_logs"`
+    Params string `form:"paramsOrder"  search:"type:order;column:params;table:line_order_template_logs"`
+    Type string `form:"typeOrder"  search:"type:order;column:type;table:line_order_template_logs"`
+    CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_order_template_logs"`
+    UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_order_template_logs"`
+    DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_order_template_logs"`
+    Switch string `form:"switchOrder"  search:"type:order;column:switch;table:line_order_template_logs"`
+    CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:line_order_template_logs"`
+    UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_order_template_logs"`
+    
+}
+
+func (m *LineOrderTemplateLogsGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineOrderTemplateLogsInsertReq struct {
+    Id int `json:"-" comment:"id"` // id
+    Name string `json:"name" comment:"模板名称"`
+    UserId int64 `json:"userId" comment:"用户id"`
+    Params string `json:"params" comment:"参数"`
+    Type int64 `json:"type" comment:"模板类型:1=单独添加;2=批量添加"`
+    Switch string `json:"switch" comment:"开关:0=关,1=开"`
+    common.ControlBy
+}
+
+func (s *LineOrderTemplateLogsInsertReq) Generate(model *models.LineOrderTemplateLogs)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.Name = s.Name
+    model.UserId = s.UserId
+    model.Params = s.Params
+    model.Type = s.Type
+    model.Switch = s.Switch
+    model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LineOrderTemplateLogsInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineOrderTemplateLogsUpdateReq struct {
+    Id int `uri:"id" comment:"id"` // id
+    Name string `json:"name" comment:"模板名称"`
+    UserId int64 `json:"userId" comment:"用户id"`
+    Params string `json:"params" comment:"参数"`
+    Type int64 `json:"type" comment:"模板类型:1=单独添加;2=批量添加"`
+    Switch string `json:"switch" comment:"开关:0=关,1=开"`
+    common.ControlBy
+}
+
+func (s *LineOrderTemplateLogsUpdateReq) Generate(model *models.LineOrderTemplateLogs)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.Name = s.Name
+    model.UserId = s.UserId
+    model.Params = s.Params
+    model.Type = s.Type
+    model.Switch = s.Switch
+    model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LineOrderTemplateLogsUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineOrderTemplateLogsGetReq 功能获取请求参数
+type LineOrderTemplateLogsGetReq struct {
+     Id int `uri:"id"`
+}
+func (s *LineOrderTemplateLogsGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineOrderTemplateLogsDeleteReq 功能删除请求参数
+type LineOrderTemplateLogsDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineOrderTemplateLogsDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_pre_order.go b/app/admin/service/dto/line_pre_order.go
new file mode 100644
index 0000000..f022b4d
--- /dev/null
+++ b/app/admin/service/dto/line_pre_order.go
@@ -0,0 +1,486 @@
+package dto
+
+import (
+	"errors"
+	"strconv"
+	"time"
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+
+	"github.com/shopspring/decimal"
+)
+
+type LinePreOrderGetPageReq struct {
+	dto.Pagination    `search:"-"`
+	ExchangeType      string `json:"exchangeType" search:"type:exact;column:exchange_type;table:line_pre_order" comment:"交易所类型 字典exchange_type"`
+	ApiId             string `form:"apiId"  search:"type:exact;column:api_id;table:line_pre_order" comment:"api用户"`
+	Symbol            string `form:"symbol"  search:"type:exact;column:symbol;table:line_pre_order" comment:"交易对"`
+	QuoteSymbol       string `form:"quoteSymbol"  search:"type:exact;column:quote_symbol;table:line_pre_order" comment:"计较货币"`
+	SignPriceType     string `form:"signPriceType"  search:"type:exact;column:sign_price_type;table:line_pre_order" comment:"对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"`
+	Rate              string `form:"rate"  search:"type:exact;column:rate;table:line_pre_order" comment:"下单百分比"`
+	Site              string `form:"site"  search:"type:exact;column:site;table:line_pre_order" comment:"购买方向:BUY=买;SELL=卖"`
+	OrderSn           string `form:"orderSn"  search:"type:exact;column:order_sn;table:line_pre_order" comment:"订单号"`
+	Status            string `form:"status"  search:"type:exact;column:status;table:line_pre_order" comment:"是否被触发:0=待触发;1=已触发;2=下单失败;3=已记录;4=已取消;5=委托中;6=已平仓;7=已补单;8=补单失败;9=现货已成交;10=合约已补单;11=合约补单失败;12=合约已成交;13=已开仓"`
+	OrderType         string `form:"orderType"  search:"type:exact;column:order_type;table:line_pre_order" comment:"订单类型:1=现货;2=合约;3=合约止盈;4=合约止损;5=现货止盈;6=现货止损;7=止损补仓;8=现货加仓;9=现货平仓;10 = 合约止损补仓,11=合约加仓;12=合约平仓"`
+	AddPositionStatus int    `form:"addPositionStatus" search:"-"`
+	HedgeStatus       int    `form:"hedgeStatus" search:"-"`
+	LinePreOrderOrder
+}
+
+type LinePreOrderOrder struct {
+	Id            string `form:"idOrder"  search:"type:order;column:id;table:line_pre_order"`
+	Pid           string `form:"pidOrder"  search:"type:order;column:pid;table:line_pre_order"`
+	ApiId         string `form:"apiIdOrder"  search:"type:order;column:api_id;table:line_pre_order"`
+	GroupId       string `form:"groupIdOrder"  search:"type:order;column:group_id;table:line_pre_order"`
+	Symbol        string `form:"symbolOrder"  search:"type:order;column:symbol;table:line_pre_order"`
+	QuoteSymbol   string `form:"quoteSymbolOrder"  search:"type:order;column:quote_symbol;table:line_pre_order"`
+	SignPrice     string `form:"signPriceOrder"  search:"type:order;column:sign_price;table:line_pre_order"`
+	SignPriceType string `form:"signPriceTypeOrder"  search:"type:order;column:sign_price_type;table:line_pre_order"`
+	Rate          string `form:"rateOrder"  search:"type:order;column:rate;table:line_pre_order"`
+	Price         string `form:"priceOrder"  search:"type:order;column:price;table:line_pre_order"`
+	Num           string `form:"numOrder"  search:"type:order;column:num;table:line_pre_order"`
+	BuyPrice      string `form:"buyPriceOrder"  search:"type:order;column:buy_price;table:line_pre_order"`
+	Site          string `form:"siteOrder"  search:"type:order;column:site;table:line_pre_order"`
+	OrderSn       string `form:"orderSnOrder"  search:"type:order;column:order_sn;table:line_pre_order"`
+	OrderType     string `form:"orderTypeOrder"  search:"type:order;column:order_type;table:line_pre_order"`
+	CoverRate     string `form:"coverRateOrder"  search:"type:order;column:cover_rate;table:line_pre_order"`
+	Desc          string `form:"descOrder"  search:"type:order;column:desc;table:line_pre_order"`
+	Status        string `form:"statusOrder"  search:"type:order;column:status;table:line_pre_order"`
+	AdminId       string `form:"adminIdOrder"  search:"type:order;column:admin_id;table:line_pre_order"`
+	IsAutoScale   string `form:"isAutoScaleOrder"  search:"type:order;column:is_auto_scale;table:line_pre_order"`
+	ScaleType     string `form:"scaleTypeOrder"  search:"type:order;column:scale_type;table:line_pre_order"`
+	CloseType     string `form:"closeTypeOrder"  search:"type:order;column:close_type;table:line_pre_order"`
+	CreatedAt     string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_pre_order"`
+	UpdatedAt     string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_pre_order"`
+	DeletedAt     string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_pre_order"`
+	CreateBy      string `form:"createByOrder"  search:"type:order;column:create_by;table:line_pre_order"`
+	UpdateBy      string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_pre_order"`
+	Direction     string `form:"directionOrder"  search:"type:order;column:direction;table:line_pre_order"`
+	UpdateTime    string `form:"updateTimeOrder"  search:"type:order;column:update_time;table:line_pre_order"`
+}
+
+func (m *LinePreOrderGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LinePreOrderInsertReq struct {
+	Id            int    `json:"-" comment:"id"` // id
+	ExchangeType  string `json:"exchangeType" comment:"交易所类型 字典exchange_type"`
+	Pid           string `json:"pid" comment:"pid"`
+	ApiId         string `json:"apiId" comment:"api用户"`
+	GroupId       string `json:"groupId" comment:"交易对组id"`
+	Symbol        string `json:"symbol" comment:"交易对"`
+	QuoteSymbol   string `json:"quoteSymbol" comment:"计较货币"`
+	SignPrice     string `json:"signPrice" comment:"对标价"`
+	SignPriceType string `json:"signPriceType" comment:"对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"`
+	Rate          string `json:"rate" comment:"下单百分比"`
+	Price         string `json:"price" comment:"触发价格"`
+	Num           string `json:"num" comment:"购买数量"`
+	BuyPrice      string `json:"buyPrice" comment:"购买金额"`
+	Site          string `json:"site" comment:"购买方向:BUY=买;SELL=卖"`
+	OrderSn       string `json:"orderSn" comment:"订单号"`
+	OrderType     int    `json:"orderType" comment:"订单类型:0=主单;1=止盈;2=止损;3=平仓"`
+	Desc          string `json:"desc" comment:"订单描述"`
+	Status        int    `json:"status" comment:"是否被触发:0=待触发;1=已触发;2=下单失败;4=已取消;5=委托中;6=已成交;9=已平仓"`
+	AdminId       string `json:"adminId" comment:"操作管理员id"`
+	IsAutoScale   int    `json:"isAutoScale" comment:"订单类型:是否为自动加仓 1 = 是 2=手动"`
+	ScaleType     int    `json:"scaleType" comment:"是否为普通对冲 1 = 是 2 = 半自动补仓(会自动平B仓)"`
+	CloseType     int    `json:"closeType" comment:"平仓类型 是否为盈利平仓 1= 是 0 =否"`
+	Direction     string `json:"direction" comment:"预估方向"`
+	common.ControlBy
+}
+
+func (s *LinePreOrderInsertReq) Generate(model *models.LinePreOrder) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	pid, _ := strconv.Atoi(s.Pid)
+	model.Pid = pid
+	model.ApiId, _ = strconv.Atoi(s.ApiId)
+	model.GroupId = s.GroupId
+	model.Symbol = s.Symbol
+	model.QuoteSymbol = s.QuoteSymbol
+	model.SignPrice = s.SignPrice
+	model.SignPriceType = s.SignPriceType
+	model.Rate = s.Rate
+	model.Price = s.Price
+	model.Num = s.Num
+	model.BuyPrice = s.BuyPrice
+	model.Site = s.Site
+	model.OrderSn = s.OrderSn
+	model.OrderType = s.OrderType
+	model.Desc = s.Desc
+	model.Status = s.Status
+	model.AdminId = s.AdminId
+	model.CloseType = s.CloseType
+	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LinePreOrderInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LinePreOrderUpdateReq struct {
+	Id            int       `uri:"id" comment:"id"` // id
+	ExchangeType  string    `json:"exchangeType" comment:"交易所类型 字典exchange_type"`
+	Pid           string    `json:"pid" comment:"pid"`
+	ApiId         string    `json:"apiId" comment:"api用户"`
+	GroupId       string    `json:"groupId" comment:"交易对组id"`
+	Symbol        string    `json:"symbol" comment:"交易对"`
+	QuoteSymbol   string    `json:"quoteSymbol" comment:"计较货币"`
+	SignPrice     string    `json:"signPrice" comment:"对标价"`
+	SignPriceType string    `json:"signPriceType" comment:"对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"`
+	Rate          string    `json:"rate" comment:"下单百分比"`
+	Price         string    `json:"price" comment:"触发价格"`
+	Num           string    `json:"num" comment:"购买数量"`
+	BuyPrice      string    `json:"buyPrice" comment:"购买金额"`
+	Site          string    `json:"site" comment:"购买方向:BUY=买;SELL=卖"`
+	OrderSn       string    `json:"orderSn" comment:"订单号"`
+	OrderType     int       `json:"orderType" comment:"订单类型:0=主单;1=止盈;2=止损;3=平仓"`
+	Desc          string    `json:"desc" comment:"订单描述"`
+	Status        int       `json:"status" comment:"是否被触发:0=待触发;1=已触发;2=下单失败;4=已取消;5=委托中;6=已成交;9=已平仓"`
+	AdminId       string    `json:"adminId" comment:"操作管理员id"`
+	CloseType     int       `json:"closeType" comment:"平仓类型 是否为盈利平仓 1= 是 0 =否"`
+	UpdateTime    time.Time `json:"updateTime" comment:"修改时间"`
+	common.ControlBy
+}
+
+func (s *LinePreOrderUpdateReq) Generate(model *models.LinePreOrder) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	pid, _ := strconv.Atoi(s.Pid)
+	model.Pid = pid
+	model.ExchangeType = s.ExchangeType
+	model.ApiId, _ = strconv.Atoi(s.ApiId)
+	model.GroupId = s.GroupId
+	model.Symbol = s.Symbol
+	model.QuoteSymbol = s.QuoteSymbol
+	model.SignPrice = s.SignPrice
+	model.SignPriceType = s.SignPriceType
+	model.Rate = s.Rate
+	model.Price = s.Price
+	model.Num = s.Num
+	model.BuyPrice = s.BuyPrice
+	model.Site = s.Site
+	model.OrderSn = s.OrderSn
+	model.OrderType = s.OrderType
+	model.Desc = s.Desc
+	model.Status = s.Status
+	model.AdminId = s.AdminId
+	model.CloseType = s.CloseType
+	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LinePreOrderUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LinePreOrderGetReq 功能获取请求参数
+type LinePreOrderGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *LinePreOrderGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LinePreOrderDeleteReq 功能删除请求参数
+type LinePreOrderDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LinePreOrderDeleteReq) GetId() interface{} {
+	return s.Ids
+}
+
+type LineAddPreOrderReq struct {
+	ExchangeType   string `json:"exchange_type"`    //交易所类型
+	OrderType      int    `json:"order_type"`       //订单类型
+	Symbol         string `json:"symbol"`           //交易对
+	ApiUserId      string `json:"api_id"`           //下单用户
+	Site           string `json:"site"`             //购买方向
+	BuyPrice       string `json:"buy_price"`        //购买金额 U
+	PricePattern   string `json:"price_pattern"`    //价格模式
+	Price          string `json:"price"`            //下单价百分比
+	Profit         string `json:"profit"`           //止盈价
+	StopPrice      string `json:"stop_price"`       //止损价
+	PriceType      string `json:"price_type"`       //价格类型
+	SaveTemplate   string `json:"save_template"`    //是否保存模板
+	TemplateName   string `json:"template_name"`    //模板名字
+	SymbolType     int    `json:"symbol_type"`      //交易对类型 1-现货 2-合约
+	CoverType      int    `json:"cover_type"`       //对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货
+	ExpireHour     int    `json:"expire_hour"`      // 过期时间 单位小时
+	MainOrderType  string `json:"main_order_type"`  //主单类型:限价(LIMIT)或市价(MARKET)
+	HedgeOrderType string `json:"hedge_order_type"` //第二笔(对冲单)类型:限价(LIMIT)或市价(MARKET)
+}
+
+func (req LineAddPreOrderReq) CheckParams() error {
+	if req.ExchangeType == "" {
+		return errors.New("请选择交易所")
+	}
+
+	if req.ApiUserId == "" {
+		return errors.New("选择下单用户")
+	}
+	if req.Symbol == "" {
+		return errors.New("请选择交易对")
+	}
+
+	if req.Price == "" {
+		return errors.New("输出下单价")
+	}
+
+	if req.PricePattern == "" {
+		return errors.New("请选择价格类型")
+	}
+
+	return nil
+}
+
+// LineBatchAddPreOrderReq 批量添加订单请求参数
+type LineBatchAddPreOrderReq struct {
+	ExchangeType   string `json:"exchange_type"`    //交易所类型 字典exchange_type
+	SymbolType     int    `json:"symbolType"`       //主单交易对类型 0-现货 1-合约
+	OrderType      int    `json:"order_type"`       //订单类型
+	SymbolGroupId  string `json:"symbol_group_id"`  //交易对组id
+	Symbol         string `json:"symbol"`           //交易对
+	ApiUserId      string `json:"api_id"`           //下单用户
+	Site           string `json:"site"`             //购买方向
+	BuyPrice       string `json:"buy_price"`        //购买金额 U
+	PricePattern   string `json:"price_pattern"`    //价格模式
+	Price          string `json:"price"`            //下单价百分比
+	Profit         string `json:"profit"`           //止盈价
+	StopPrice      string `json:"stop_price"`       //止损价
+	PriceType      string `json:"price_type"`       //价格类型
+	SaveTemplate   string `json:"save_template"`    //是否保存模板
+	TemplateName   string `json:"template_name"`    //模板名字
+	OrderNum       int    `json:"order_num"`        //脚本运行次数
+	Script         string `json:"script"`           //是否是脚本运行 1 = 是 0= 否
+	CoverType      int    `json:"cover_type"`       //对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货
+	ExpireHour     int    `json:"expire_hour"`      // 过期时间 单位小时
+	MainOrderType  string `json:"main_order_type"`  //主单类型:限价(LIMIT)或市价(MARKET)
+	HedgeOrderType string `json:"hedge_order_type"` //第二笔(对冲单)类型:限价(LIMIT)或市价(MARKET)
+}
+
+func (req LineBatchAddPreOrderReq) CheckParams() error {
+	if req.ExchangeType == "" {
+		return errors.New("请选择交易所")
+	}
+
+	if req.ApiUserId == "" {
+		return errors.New("选择下单用户")
+	}
+	if req.SymbolGroupId == "" {
+		return errors.New("请选择交易对组")
+	}
+
+	if req.Price == "" {
+		return errors.New("输出下单价")
+	}
+
+	if req.PricePattern == "" {
+		return errors.New("请选择价格类型")
+	}
+
+	return nil
+}
+
+type Ticker struct {
+	Symbol string `json:"symbol"`
+	Price  string `json:"price"`
+}
+type QuickAddPreOrderReq struct {
+	Ids string `json:"ids"`
+}
+
+// LeverReq 设置杠杆请求
+type LeverReq struct {
+	ApiUserIds string `json:"api_user_ids"`
+	Symbol     string `json:"symbol"`
+	Leverage   int    `json:"leverage"`
+	GroupId    int    `json:"group_id"`
+	IsAll      int    `json:"is_all"` // 1= 全部 0=不是全部
+}
+
+func (c LeverReq) CheckParams() error {
+	if c.Leverage > 125 || c.Leverage < 1 {
+		return errors.New("请输入1-125的杠杆倍数")
+	}
+	if c.ApiUserIds == "" {
+		return errors.New("请选择api用户")
+	}
+	return nil
+}
+
+type MarginTypeReq struct {
+	ApiUserIds string `json:"api_user_ids"`
+	Symbol     string `json:"symbol"`      // 交易对
+	MarginType string `json:"margin_type"` //全仓  CROSSED    逐仓 ISOLATED
+	GroupId    int    `json:"group_id"`    // 交易对组id
+	IsAll      int    `json:"is_all"`      // 1= 全部 0=不是全部
+}
+
+type CancelOpenOrderReq struct {
+	ApiId     int    `json:"api_id"`
+	Symbol    string `json:"symbol"`
+	OrderSn   string `json:"order_sn"`
+	OrderType int    `json:"order_type"`
+}
+
+type GetChildOrderReq struct {
+	Id int `json:"id"` //id
+}
+
+func (c MarginTypeReq) CheckParams() error {
+	if c.Symbol == "" && c.GroupId == 0 {
+		return errors.New("请选择交易对或交易对组")
+	}
+	if c.MarginType == "" {
+		return errors.New("请选择仓位模式")
+	}
+	if c.ApiUserIds == "" {
+		return errors.New("请选择api用户")
+	}
+	return nil
+}
+
+type PreOrderRedisList struct {
+	Id          int    `json:"id"`
+	Symbol      string `json:"symbol"`
+	Price       string `json:"price"`
+	Site        string `json:"site"`
+	ApiId       int    `json:"api_id"`
+	OrderSn     string `json:"order_sn"`
+	QuoteSymbol string `json:"quote_symbol"`
+}
+
+type StopLossRedisList struct {
+	// Id       int             `json:"id"`
+	PId      int    `json:"pid"`
+	OrderTye string `json:"orderType"`
+	// Num      decimal.Decimal `json:"num"`
+
+	Symbol   string          `json:"symbol"`
+	Price    decimal.Decimal `json:"price"` //触发价(根据主单价格触发)
+	Site     string          `json:"site"`
+	ApiId    int             `json:"api_id"`
+	Stoploss decimal.Decimal `json:"stoploss"` //亏损百分比对冲
+}
+
+// ManuallyCover 手动加仓请求体
+type ManuallyCover struct {
+	ApiId             int    `json:"api_id"`               //主账号id
+	CoverAccount      int    `json:"cover_account"`        // 1=加主账号 2=加付帐号 3=都加
+	SymbolType        int    `json:"symbol_type"`          //加仓交易对类型 1=现货 2=合约
+	Symbols           string `json:"symbols"`              //加仓交易对 -> ETHUSDT,BTCUSDT
+	CoverAccountAType string `json:"cover_account_a_type"` //加仓A账号订单类型 MARKET=市价  LIMIT=限价
+	CoverAccountARate string `json:"cover_account_a_rate"` //加仓A账号限价比例 限价才有比例
+	CoverAccountBType string `json:"cover_account_b_type"` //加仓b账号订单类型 MARKET=市价  LIMIT=限价
+	CoverAccountBRate string `json:"cover_account_b_rate"` //加仓b账号限价比例 限价才有比例
+	CoverType         int    `json:"cover_type"`           //1 = 百分比 2=金额
+	Value             string `json:"value"`                //加仓数值
+}
+
+func (m *ManuallyCover) CheckParams() error {
+	if m.ApiId <= 0 {
+		return errors.New("请选择主账号")
+	}
+
+	if m.CoverAccount <= 0 {
+		return errors.New("请选择加仓账号")
+	}
+
+	if len(m.Symbols) == 0 {
+		return errors.New("请选择加仓交易对")
+	}
+
+	if m.CoverType <= 0 {
+		return errors.New("请填写加仓类型")
+	}
+	if len(m.Value) == 0 {
+		return errors.New("请填写加仓数值")
+	}
+	return nil
+}
+
+// ClosePosition 平仓请求
+type ClosePosition struct {
+	ApiId     int    `json:"api_id"`     //api-user 用户id
+	Symbol    string `json:"symbol"`     // 交易对
+	Rate      string `json:"rate"`       //限价平仓百分比
+	CloseType int    `json:"close_type"` //现货平仓=1 合约平仓=2
+}
+
+func (m *ClosePosition) CheckParams() error {
+	if m.ApiId <= 0 {
+		return errors.New("请选择账号")
+	}
+
+	if m.CloseType <= 0 && m.CloseType != 1 && m.CloseType != 2 {
+		return errors.New("请选择平仓类型")
+	}
+
+	return nil
+}
+
+type QueryOrderReq struct {
+	OrderType int    `json:"order_type"` // 订单类型
+	ApiId     int    `json:"api_id"`     //用户api_id
+	OrderSn   string `json:"order_sn"`   //订单号
+	Symbol    string `json:"symbol"`     //交易对
+}
+
+type SpotQueryOrderResp struct {
+	Symbol                  string `json:"symbol"`
+	OrderId                 int    `json:"orderId"`
+	OrderListId             int    `json:"orderListId"`
+	ClientOrderId           string `json:"clientOrderId"`
+	Price                   string `json:"price"`
+	OrigQty                 string `json:"origQty"`
+	ExecutedQty             string `json:"executedQty"`
+	OrigQuoteOrderQty       string `json:"origQuoteOrderQty"`
+	CummulativeQuoteQty     string `json:"cummulativeQuoteQty"`
+	Status                  string `json:"status"`
+	TimeInForce             string `json:"timeInForce"`
+	Type                    string `json:"type"`
+	Side                    string `json:"side"`
+	StopPrice               string `json:"stopPrice"`
+	IcebergQty              string `json:"icebergQty"`
+	Time                    int64  `json:"time"`
+	UpdateTime              int64  `json:"updateTime"`
+	IsWorking               bool   `json:"isWorking"`
+	WorkingTime             int64  `json:"workingTime"`
+	SelfTradePreventionMode string `json:"selfTradePreventionMode"`
+}
+
+type FutQueryOrderResp struct {
+	AvgPrice                string `json:"avgPrice"`
+	ClientOrderId           string `json:"clientOrderId"`
+	CumQuote                string `json:"cumQuote"`
+	ExecutedQty             string `json:"executedQty"`
+	OrderId                 int    `json:"orderId"`
+	OrigQty                 string `json:"origQty"`
+	OrigType                string `json:"origType"`
+	Price                   string `json:"price"`
+	ReduceOnly              bool   `json:"reduceOnly"`
+	Side                    string `json:"side"`
+	PositionSide            string `json:"positionSide"`
+	Status                  string `json:"status"`
+	StopPrice               string `json:"stopPrice"`
+	ClosePosition           bool   `json:"closePosition"`
+	Symbol                  string `json:"symbol"`
+	Time                    int64  `json:"time"`
+	TimeInForce             string `json:"timeInForce"`
+	Type                    string `json:"type"`
+	ActivatePrice           string `json:"activatePrice"`
+	PriceRate               string `json:"priceRate"`
+	UpdateTime              int64  `json:"updateTime"`
+	WorkingType             string `json:"workingType"`
+	PriceProtect            bool   `json:"priceProtect"`
+	PriceMatch              string `json:"priceMatch"`
+	SelfTradePreventionMode string `json:"selfTradePreventionMode"`
+	GoodTillDate            int    `json:"goodTillDate"`
+}
diff --git a/app/admin/service/dto/line_pre_order_status.go b/app/admin/service/dto/line_pre_order_status.go
new file mode 100644
index 0000000..e45bcf9
--- /dev/null
+++ b/app/admin/service/dto/line_pre_order_status.go
@@ -0,0 +1,95 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LinePreOrderStatusGetPageReq struct {
+	dto.Pagination `search:"-"`
+	LinePreOrderStatusOrder
+}
+
+type LinePreOrderStatusOrder struct {
+	Id                string `form:"idOrder"  search:"type:order;column:id;table:line_pre_order_status"`
+	OrderId           string `form:"orderIdOrder"  search:"type:order;column:order_id;table:line_pre_order_status"`
+	OrderSn           string `form:"orderSnOrder"  search:"type:order;column:order_sn;table:line_pre_order_status"`
+	AddPositionStatus string `form:"addPositionStatusOrder"  search:"type:order;column:add_position_status;table:line_pre_order_status"`
+	HedgeStatus       string `form:"hedgeStatusOrder"  search:"type:order;column:hedge_status;table:line_pre_order_status"`
+	CreatedAt         string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_pre_order_status"`
+	UpdatedAt         string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_pre_order_status"`
+	DeletedAt         string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_pre_order_status"`
+	CreateBy          string `form:"createByOrder"  search:"type:order;column:create_by;table:line_pre_order_status"`
+	UpdateBy          string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_pre_order_status"`
+}
+
+func (m *LinePreOrderStatusGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LinePreOrderStatusInsertReq struct {
+	Id                int    `json:"-" comment:"主键"` // 主键
+	OrderId           int    `json:"orderId" comment:"主订单id"`
+	OrderSn           string `json:"orderSn" comment:"主订单号"`
+	AddPositionStatus int    `json:"addPositionStatus" comment:"加仓状态 0-无 1-已加仓"`
+	HedgeStatus       int    `json:"hedgeStatus" comment:"对冲状态 0-无 1-已对冲"`
+	common.ControlBy
+}
+
+func (s *LinePreOrderStatusInsertReq) Generate(model *models.LinePreOrderStatus) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.OrderId = s.OrderId
+	model.OrderSn = s.OrderSn
+	model.AddPositionStatus = s.AddPositionStatus
+	model.HedgeStatus = s.HedgeStatus
+	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LinePreOrderStatusInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LinePreOrderStatusUpdateReq struct {
+	Id                int    `uri:"id" comment:"主键"` // 主键
+	OrderId           int    `json:"orderId" comment:"主订单id"`
+	OrderSn           string `json:"orderSn" comment:"主订单号"`
+	AddPositionStatus int    `json:"addPositionStatus" comment:"加仓状态 0-无 1-已加仓"`
+	HedgeStatus       int    `json:"hedgeStatus" comment:"对冲状态 0-无 1-已对冲"`
+	common.ControlBy
+}
+
+func (s *LinePreOrderStatusUpdateReq) Generate(model *models.LinePreOrderStatus) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.OrderId = s.OrderId
+	model.OrderSn = s.OrderSn
+	model.AddPositionStatus = s.AddPositionStatus
+	model.HedgeStatus = s.HedgeStatus
+	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LinePreOrderStatusUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LinePreOrderStatusGetReq 功能获取请求参数
+type LinePreOrderStatusGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *LinePreOrderStatusGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LinePreOrderStatusDeleteReq 功能删除请求参数
+type LinePreOrderStatusDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LinePreOrderStatusDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_pre_script.go b/app/admin/service/dto/line_pre_script.go
new file mode 100644
index 0000000..d30697a
--- /dev/null
+++ b/app/admin/service/dto/line_pre_script.go
@@ -0,0 +1,108 @@
+package dto
+
+import (
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LinePreScriptGetPageReq struct {
+	dto.Pagination     `search:"-"`
+    ApiId int64 `form:"apiId"  search:"type:exact;column:api_id;table:line_pre_script" comment:"api用户"`
+    Status string `form:"status"  search:"type:exact;column:status;table:line_pre_script" comment:"执行状态:0=等待执行,1=执行中,2=执行结束"`
+    LinePreScriptOrder
+}
+
+type LinePreScriptOrder struct {
+    Id string `form:"idOrder"  search:"type:order;column:id;table:line_pre_script"`
+    ApiId string `form:"apiIdOrder"  search:"type:order;column:api_id;table:line_pre_script"`
+    ScriptNum string `form:"scriptNumOrder"  search:"type:order;column:script_num;table:line_pre_script"`
+    ScriptParams string `form:"scriptParamsOrder"  search:"type:order;column:script_params;table:line_pre_script"`
+    Status string `form:"statusOrder"  search:"type:order;column:status;table:line_pre_script"`
+    Desc string `form:"descOrder"  search:"type:order;column:desc;table:line_pre_script"`
+    AdminId string `form:"adminIdOrder"  search:"type:order;column:admin_id;table:line_pre_script"`
+    CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_pre_script"`
+    UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_pre_script"`
+    DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_pre_script"`
+    CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:line_pre_script"`
+    UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_pre_script"`
+    
+}
+
+func (m *LinePreScriptGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LinePreScriptInsertReq struct {
+    Id int `json:"-" comment:""` // 
+    ApiId int64 `json:"apiId" comment:"api用户"`
+    ScriptNum int64 `json:"scriptNum" comment:"脚本批次"`
+    ScriptParams string `json:"scriptParams" comment:"脚本参数"`
+    Status string `json:"status" comment:"执行状态:0=等待执行,1=执行中,2=执行结束"`
+    Desc string `json:"desc" comment:"运行备注"`
+    AdminId int64 `json:"adminId" comment:"管理员id"`
+    common.ControlBy
+}
+
+func (s *LinePreScriptInsertReq) Generate(model *models.LinePreScript)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.ApiId = s.ApiId
+    model.ScriptNum = s.ScriptNum
+    model.ScriptParams = s.ScriptParams
+    model.Status = s.Status
+    model.Desc = s.Desc
+    model.AdminId = s.AdminId
+    model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LinePreScriptInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LinePreScriptUpdateReq struct {
+    Id int `uri:"id" comment:""` // 
+    ApiId int64 `json:"apiId" comment:"api用户"`
+    ScriptNum int64 `json:"scriptNum" comment:"脚本批次"`
+    ScriptParams string `json:"scriptParams" comment:"脚本参数"`
+    Status string `json:"status" comment:"执行状态:0=等待执行,1=执行中,2=执行结束"`
+    Desc string `json:"desc" comment:"运行备注"`
+    AdminId int64 `json:"adminId" comment:"管理员id"`
+    common.ControlBy
+}
+
+func (s *LinePreScriptUpdateReq) Generate(model *models.LinePreScript)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.ApiId = s.ApiId
+    model.ScriptNum = s.ScriptNum
+    model.ScriptParams = s.ScriptParams
+    model.Status = s.Status
+    model.Desc = s.Desc
+    model.AdminId = s.AdminId
+    model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LinePreScriptUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LinePreScriptGetReq 功能获取请求参数
+type LinePreScriptGetReq struct {
+     Id int `uri:"id"`
+}
+func (s *LinePreScriptGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LinePreScriptDeleteReq 功能删除请求参数
+type LinePreScriptDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LinePreScriptDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_price_limit.go b/app/admin/service/dto/line_price_limit.go
new file mode 100644
index 0000000..a7a78fd
--- /dev/null
+++ b/app/admin/service/dto/line_price_limit.go
@@ -0,0 +1,144 @@
+package dto
+
+import (
+	"github.com/shopspring/decimal"
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LinePriceLimitGetPageReq struct {
+	dto.Pagination  `search:"-"`
+	Symbol          string `form:"symbol"  search:"type:exact;column:symbol;table:line_price_limit" comment:"交易对"`
+	Type            string `form:"type"  search:"type:exact;column:type;table:line_price_limit" comment:"类型:1=现货,2=合约"`
+	DirectionStatus string `form:"directionStatus"  search:"type:exact;column:direction_status;table:line_price_limit" comment:"方向:1=涨,2=跌"`
+	Range           string `form:"range"  search:"type:exact;column:range;table:line_price_limit" comment:"幅度"`
+	StartRange      string `form:"startRange" search:"-" comment:"幅度"`
+	EndRange        string `form:"endRange" search:"-" comment:"幅度"`
+	LinePriceLimitOrder
+}
+
+type LinePriceLimitOrder struct {
+	Id              string `form:"idOrder"  search:"type:order;column:id;table:line_price_limit"`
+	Symbol          string `form:"symbolOrder"  search:"type:order;column:symbol;table:line_price_limit"`
+	Type            string `form:"typeOrder"  search:"type:order;column:type;table:line_price_limit"`
+	DirectionStatus string `form:"directionStatusOrder"  search:"type:order;column:direction_status;table:line_price_limit"`
+	Range           string `form:"rangeOrder"  search:"type:order;column:range;table:line_price_limit"`
+	CreatedAt       string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_price_limit"`
+	UpdatedAt       string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_price_limit"`
+	DeletedAt       string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_price_limit"`
+	CreateBy        string `form:"createByOrder"  search:"type:order;column:create_by;table:line_price_limit"`
+	UpdateBy        string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_price_limit"`
+}
+
+func (m *LinePriceLimitGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LinePriceLimitInsertReq struct {
+	Id              int             `json:"-" comment:"id"` // id
+	Symbol          string          `json:"symbol" comment:"交易对"`
+	Type            string          `json:"type" comment:"类型:1=现货,2=合约"`
+	DirectionStatus string          `json:"directionStatus" comment:"方向:1=涨,2=跌"`
+	Range           decimal.Decimal `json:"range" comment:"幅度"`
+	common.ControlBy
+}
+
+func (s *LinePriceLimitInsertReq) Generate(model *models.LinePriceLimit) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.Symbol = s.Symbol
+	model.Type = s.Type
+	model.DirectionStatus = s.DirectionStatus
+	model.Range = s.Range
+	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LinePriceLimitInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LinePriceLimitUpdateReq struct {
+	Id              int             `uri:"id" comment:"id"` // id
+	Symbol          string          `json:"symbol" comment:"交易对"`
+	Type            string          `json:"type" comment:"类型:1=现货,2=合约"`
+	DirectionStatus string          `json:"directionStatus" comment:"方向:1=涨,2=跌"`
+	Range           decimal.Decimal `json:"range" comment:"幅度"`
+	common.ControlBy
+}
+
+func (s *LinePriceLimitUpdateReq) Generate(model *models.LinePriceLimit) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.Symbol = s.Symbol
+	model.Type = s.Type
+	model.DirectionStatus = s.DirectionStatus
+	model.Range = s.Range
+	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LinePriceLimitUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LinePriceLimitGetReq 功能获取请求参数
+type LinePriceLimitGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *LinePriceLimitGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LinePriceLimitDeleteReq 功能删除请求参数
+type LinePriceLimitDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LinePriceLimitDeleteReq) GetId() interface{} {
+	return s.Ids
+}
+
+type Ticker24Hr struct {
+	Symbol             string `json:"symbol"`
+	PriceChange        string `json:"priceChange"`
+	PriceChangePercent string `json:"priceChangePercent"`
+	WeightedAvgPrice   string `json:"weightedAvgPrice"`
+	PrevClosePrice     string `json:"prevClosePrice"`
+	LastPrice          string `json:"lastPrice"`
+	LastQty            string `json:"lastQty"`
+	BidPrice           string `json:"bidPrice"`
+	BidQty             string `json:"bidQty"`
+	AskPrice           string `json:"askPrice"`
+	AskQty             string `json:"askQty"`
+	OpenPrice          string `json:"openPrice"`
+	HighPrice          string `json:"highPrice"`
+	LowPrice           string `json:"lowPrice"`
+	Volume             string `json:"volume"`
+	QuoteVolume        string `json:"quoteVolume"`
+	OpenTime           int64  `json:"openTime"`
+	CloseTime          int64  `json:"closeTime"`
+	FirstId            int    `json:"firstId"`
+	LastId             int    `json:"lastId"`
+	Count              int    `json:"count"`
+}
+type FutTicker24Hr struct {
+	Symbol             string `json:"symbol"`
+	PriceChange        string `json:"priceChange"`
+	PriceChangePercent string `json:"priceChangePercent"`
+	WeightedAvgPrice   string `json:"weightedAvgPrice"`
+	LastPrice          string `json:"lastPrice"`
+	LastQty            string `json:"lastQty"`
+	OpenPrice          string `json:"openPrice"`
+	HighPrice          string `json:"highPrice"`
+	LowPrice           string `json:"lowPrice"`
+	Volume             string `json:"volume"`
+	QuoteVolume        string `json:"quoteVolume"`
+	OpenTime           int64  `json:"openTime"`
+	CloseTime          int64  `json:"closeTime"`
+	FirstId            int    `json:"firstId"`
+	LastId             int    `json:"lastId"`
+	Count              int    `json:"count"`
+}
diff --git a/app/admin/service/dto/line_recharge.go b/app/admin/service/dto/line_recharge.go
new file mode 100644
index 0000000..e245ab3
--- /dev/null
+++ b/app/admin/service/dto/line_recharge.go
@@ -0,0 +1,162 @@
+package dto
+
+import (
+    "time"
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineRechargeGetPageReq struct {
+	dto.Pagination     `search:"-"`
+    LineRechargeOrder
+}
+
+type LineRechargeOrder struct {
+    Id string `form:"idOrder"  search:"type:order;column:id;table:line_recharge"`
+    CoinId string `form:"coinIdOrder"  search:"type:order;column:coin_id;table:line_recharge"`
+    UserId string `form:"userIdOrder"  search:"type:order;column:user_id;table:line_recharge"`
+    Confirms string `form:"confirmsOrder"  search:"type:order;column:confirms;table:line_recharge"`
+    TranType string `form:"tranTypeOrder"  search:"type:order;column:tran_type;table:line_recharge"`
+    BlockIndex string `form:"blockIndexOrder"  search:"type:order;column:block_index;table:line_recharge"`
+    Amount string `form:"amountOrder"  search:"type:order;column:amount;table:line_recharge"`
+    Account string `form:"accountOrder"  search:"type:order;column:account;table:line_recharge"`
+    Address string `form:"addressOrder"  search:"type:order;column:address;table:line_recharge"`
+    Txid string `form:"txidOrder"  search:"type:order;column:txid;table:line_recharge"`
+    BlockTime string `form:"blockTimeOrder"  search:"type:order;column:block_time;table:line_recharge"`
+    TimeReceived string `form:"timeReceivedOrder"  search:"type:order;column:time_received;table:line_recharge"`
+    CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:line_recharge"`
+    UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_recharge"`
+    CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_recharge"`
+    UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_recharge"`
+    DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_recharge"`
+    MainCoin string `form:"mainCoinOrder"  search:"type:order;column:main_coin;table:line_recharge"`
+    OrderNo string `form:"orderNoOrder"  search:"type:order;column:order_no;table:line_recharge"`
+    Status string `form:"statusOrder"  search:"type:order;column:status;table:line_recharge"`
+    State string `form:"stateOrder"  search:"type:order;column:state;table:line_recharge"`
+    Fee string `form:"feeOrder"  search:"type:order;column:fee;table:line_recharge"`
+    AddressFrom string `form:"addressFromOrder"  search:"type:order;column:address_from;table:line_recharge"`
+    
+}
+
+func (m *LineRechargeGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineRechargeInsertReq struct {
+    Id int `json:"-" comment:"主键"` // 主键
+    CoinId int64 `json:"coinId" comment:"币种id"`
+    UserId int64 `json:"userId" comment:"用户Id"`
+    Confirms string `json:"confirms" comment:"区块确认数"`
+    TranType string `json:"tranType" comment:"类型:1线上,2内部"`
+    BlockIndex string `json:"blockIndex" comment:"区块高度"`
+    Amount string `json:"amount" comment:"数量"`
+    Account string `json:"account" comment:"账户"`
+    Address string `json:"address" comment:"地址"`
+    Txid string `json:"txid" comment:"交易id"`
+    BlockTime time.Time `json:"blockTime" comment:"同步时间"`
+    TimeReceived time.Time `json:"timeReceived" comment:"确认时间"`
+    MainCoin string `json:"mainCoin" comment:"充值网络"`
+    OrderNo string `json:"orderNo" comment:"订单号"`
+    Status string `json:"status" comment:"状态1==进行中暂时保留,2==成功,3==失败"`
+    State string `json:"state" comment:"来源状态 0 待審核 1 審核成功 2 審核駁回 3交易成功 4交易失敗"`
+    Fee string `json:"fee" comment:"手续费"`
+    AddressFrom string `json:"addressFrom" comment:"来源地址"`
+    common.ControlBy
+}
+
+func (s *LineRechargeInsertReq) Generate(model *models.LineRecharge)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.CoinId = s.CoinId
+    model.UserId = s.UserId
+    model.Confirms = s.Confirms
+    model.TranType = s.TranType
+    model.BlockIndex = s.BlockIndex
+    model.Amount = s.Amount
+    model.Account = s.Account
+    model.Address = s.Address
+    model.Txid = s.Txid
+    model.BlockTime = s.BlockTime
+    model.TimeReceived = s.TimeReceived
+    model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+    model.MainCoin = s.MainCoin
+    model.OrderNo = s.OrderNo
+    model.Status = s.Status
+    model.State = s.State
+    model.Fee = s.Fee
+    model.AddressFrom = s.AddressFrom
+}
+
+func (s *LineRechargeInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineRechargeUpdateReq struct {
+    Id int `uri:"id" comment:"主键"` // 主键
+    CoinId int64 `json:"coinId" comment:"币种id"`
+    UserId int64 `json:"userId" comment:"用户Id"`
+    Confirms string `json:"confirms" comment:"区块确认数"`
+    TranType string `json:"tranType" comment:"类型:1线上,2内部"`
+    BlockIndex string `json:"blockIndex" comment:"区块高度"`
+    Amount string `json:"amount" comment:"数量"`
+    Account string `json:"account" comment:"账户"`
+    Address string `json:"address" comment:"地址"`
+    Txid string `json:"txid" comment:"交易id"`
+    BlockTime time.Time `json:"blockTime" comment:"同步时间"`
+    TimeReceived time.Time `json:"timeReceived" comment:"确认时间"`
+    MainCoin string `json:"mainCoin" comment:"充值网络"`
+    OrderNo string `json:"orderNo" comment:"订单号"`
+    Status string `json:"status" comment:"状态1==进行中暂时保留,2==成功,3==失败"`
+    State string `json:"state" comment:"来源状态 0 待審核 1 審核成功 2 審核駁回 3交易成功 4交易失敗"`
+    Fee string `json:"fee" comment:"手续费"`
+    AddressFrom string `json:"addressFrom" comment:"来源地址"`
+    common.ControlBy
+}
+
+func (s *LineRechargeUpdateReq) Generate(model *models.LineRecharge)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.CoinId = s.CoinId
+    model.UserId = s.UserId
+    model.Confirms = s.Confirms
+    model.TranType = s.TranType
+    model.BlockIndex = s.BlockIndex
+    model.Amount = s.Amount
+    model.Account = s.Account
+    model.Address = s.Address
+    model.Txid = s.Txid
+    model.BlockTime = s.BlockTime
+    model.TimeReceived = s.TimeReceived
+    model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+    model.MainCoin = s.MainCoin
+    model.OrderNo = s.OrderNo
+    model.Status = s.Status
+    model.State = s.State
+    model.Fee = s.Fee
+    model.AddressFrom = s.AddressFrom
+}
+
+func (s *LineRechargeUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineRechargeGetReq 功能获取请求参数
+type LineRechargeGetReq struct {
+     Id int `uri:"id"`
+}
+func (s *LineRechargeGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineRechargeDeleteReq 功能删除请求参数
+type LineRechargeDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineRechargeDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_symbol.go b/app/admin/service/dto/line_symbol.go
new file mode 100644
index 0000000..757a16e
--- /dev/null
+++ b/app/admin/service/dto/line_symbol.go
@@ -0,0 +1,109 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineSymbolGetPageReq struct {
+	dto.Pagination `search:"-"`
+	Symbol         string `form:"symbol"  search:"type:contains;column:symbol;table:line_symbol" comment:"交易对"`
+	BaseAsset      string `form:"baseAsset"  search:"type:contains;column:base_asset;table:line_symbol" comment:"基础货币"`
+	QuoteAsset     string `form:"quoteAsset"  search:"type:exact;column:quote_asset;table:line_symbol" comment:"计价货币"`
+	Type           string `form:"type"  search:"type:exact;column:type;table:line_symbol" comment:"交易对类型"`
+	LineSymbolOrder
+}
+
+type LineSymbolOrder struct {
+	Id         string `form:"idOrder"  search:"type:order;column:id;table:line_symbol"`
+	ApiId      string `form:"apiIdOrder"  search:"type:order;column:api_id;table:line_symbol"`
+	Symbol     string `form:"symbolOrder"  search:"type:order;column:symbol;table:line_symbol"`
+	BaseAsset  string `form:"baseAssetOrder"  search:"type:order;column:base_asset;table:line_symbol"`
+	QuoteAsset string `form:"quoteAssetOrder"  search:"type:order;column:quote_asset;table:line_symbol"`
+	CreatedAt  string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_symbol"`
+	UpdatedAt  string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_symbol"`
+	DeletedAt  string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_symbol"`
+	CreateBy   string `form:"createByOrder"  search:"type:order;column:create_by;table:line_symbol"`
+	UpdateBy   string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_symbol"`
+	Switch     string `form:"switchOrder"  search:"type:order;column:switch;table:line_symbol"`
+	Type       string `form:"typeOrder"  search:"type:order;column:type;table:line_symbol"`
+}
+
+func (m *LineSymbolGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineSymbolInsertReq struct {
+	Id         int    `json:"-" comment:"id"` // id
+	ApiId      string `json:"apiId" comment:"api账户id"`
+	Symbol     string `json:"symbol" comment:"交易对"`
+	BaseAsset  string `json:"baseAsset" comment:"基础货币"`
+	QuoteAsset string `json:"quoteAsset" comment:"计价货币"`
+	Switch     string `json:"switch" comment:"状态"`
+	Type       string `json:"type" comment:"交易对类型"`
+	common.ControlBy
+}
+
+func (s *LineSymbolInsertReq) Generate(model *models.LineSymbol) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.ApiId = s.ApiId
+	model.Symbol = s.Symbol
+	model.BaseAsset = s.BaseAsset
+	model.QuoteAsset = s.QuoteAsset
+	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+	model.Switch = s.Switch
+	model.Type = s.Type
+}
+
+func (s *LineSymbolInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineSymbolUpdateReq struct {
+	Id         int    `uri:"id" comment:"id"` // id
+	ApiId      string `json:"apiId" comment:"api账户id"`
+	Symbol     string `json:"symbol" comment:"交易对"`
+	BaseAsset  string `json:"baseAsset" comment:"基础货币"`
+	QuoteAsset string `json:"quoteAsset" comment:"计价货币"`
+	Switch     string `json:"switch" comment:"状态"`
+	Type       string `json:"type" comment:"交易对类型"`
+	common.ControlBy
+}
+
+func (s *LineSymbolUpdateReq) Generate(model *models.LineSymbol) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.ApiId = s.ApiId
+	model.Symbol = s.Symbol
+	model.BaseAsset = s.BaseAsset
+	model.QuoteAsset = s.QuoteAsset
+	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+	model.Switch = s.Switch
+	model.Type = s.Type
+}
+
+func (s *LineSymbolUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineSymbolGetReq 功能获取请求参数
+type LineSymbolGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *LineSymbolGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineSymbolDeleteReq 功能删除请求参数
+type LineSymbolDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineSymbolDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_symbol_black.go b/app/admin/service/dto/line_symbol_black.go
new file mode 100644
index 0000000..04ce1b9
--- /dev/null
+++ b/app/admin/service/dto/line_symbol_black.go
@@ -0,0 +1,88 @@
+package dto
+
+import (
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineSymbolBlackGetPageReq struct {
+	dto.Pagination     `search:"-"`
+    Symbol string `form:"symbol"  search:"type:exact;column:symbol;table:line_symbol_black" comment:"交易对"`
+    Type string `form:"type"  search:"type:exact;column:type;table:line_symbol_black" comment:"类型:1=现货,2=合约"`
+    LineSymbolBlackOrder
+}
+
+type LineSymbolBlackOrder struct {
+    Id string `form:"idOrder"  search:"type:order;column:id;table:line_symbol_black"`
+    Symbol string `form:"symbolOrder"  search:"type:order;column:symbol;table:line_symbol_black"`
+    Type string `form:"typeOrder"  search:"type:order;column:type;table:line_symbol_black"`
+    CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_symbol_black"`
+    UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_symbol_black"`
+    DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_symbol_black"`
+    CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:line_symbol_black"`
+    UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_symbol_black"`
+    
+}
+
+func (m *LineSymbolBlackGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineSymbolBlackInsertReq struct {
+    Id int `json:"-" comment:"id"` // id
+    Symbol string `json:"symbol" comment:"交易对"`
+    Type string `json:"type" comment:"类型:1=现货,2=合约"`
+    common.ControlBy
+}
+
+func (s *LineSymbolBlackInsertReq) Generate(model *models.LineSymbolBlack)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.Symbol = s.Symbol
+    model.Type = s.Type
+    model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LineSymbolBlackInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineSymbolBlackUpdateReq struct {
+    Id int `uri:"id" comment:"id"` // id
+    Symbol string `json:"symbol" comment:"交易对"`
+    Type string `json:"type" comment:"类型:1=现货,2=合约"`
+    common.ControlBy
+}
+
+func (s *LineSymbolBlackUpdateReq) Generate(model *models.LineSymbolBlack)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.Symbol = s.Symbol
+    model.Type = s.Type
+    model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LineSymbolBlackUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineSymbolBlackGetReq 功能获取请求参数
+type LineSymbolBlackGetReq struct {
+     Id int `uri:"id"`
+}
+func (s *LineSymbolBlackGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineSymbolBlackDeleteReq 功能删除请求参数
+type LineSymbolBlackDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineSymbolBlackDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_symbol_group.go b/app/admin/service/dto/line_symbol_group.go
new file mode 100644
index 0000000..f707915
--- /dev/null
+++ b/app/admin/service/dto/line_symbol_group.go
@@ -0,0 +1,97 @@
+package dto
+
+import (
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineSymbolGroupGetPageReq struct {
+	dto.Pagination     `search:"-"`
+    Type string `form:"type"  search:"type:exact;column:type;table:line_symbol_group" comment:"类型:1=现货,2=合约"`
+    LineSymbolGroupOrder
+}
+
+type LineSymbolGroupOrder struct {
+    Id string `form:"idOrder"  search:"type:order;column:id;table:line_symbol_group"`
+    GroupName string `form:"groupNameOrder"  search:"type:order;column:group_name;table:line_symbol_group"`
+    Symbol string `form:"symbolOrder"  search:"type:order;column:symbol;table:line_symbol_group"`
+    GroupType string `form:"groupTypeOrder"  search:"type:order;column:groupType;table:line_symbol_group"`
+    Type string `form:"typeOrder"  search:"type:order;column:type;table:line_symbol_group"`
+    CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_symbol_group"`
+    UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_symbol_group"`
+    DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_symbol_group"`
+    CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:line_symbol_group"`
+    UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_symbol_group"`
+    
+}
+
+func (m *LineSymbolGroupGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineSymbolGroupInsertReq struct {
+    Id int `json:"-" comment:""` // 
+    GroupName string `json:"groupName" comment:"交易对组名称"`
+    Symbol string `json:"symbol" comment:"交易对"`
+    GroupType string `json:"groupType" comment:"分组类型:1=普通类型"`
+    Type string `json:"type" comment:"类型:1=现货,2=合约"`
+    common.ControlBy
+}
+
+func (s *LineSymbolGroupInsertReq) Generate(model *models.LineSymbolGroup)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.GroupName = s.GroupName
+    model.Symbol = s.Symbol
+    model.GroupType = s.GroupType
+    model.Type = s.Type
+    model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LineSymbolGroupInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineSymbolGroupUpdateReq struct {
+    Id int `uri:"id" comment:""` // 
+    GroupName string `json:"groupName" comment:"交易对组名称"`
+    Symbol string `json:"symbol" comment:"交易对"`
+    GroupType string `json:"groupType" comment:"分组类型:1=普通类型"`
+    Type string `json:"type" comment:"类型:1=现货,2=合约"`
+    common.ControlBy
+}
+
+func (s *LineSymbolGroupUpdateReq) Generate(model *models.LineSymbolGroup)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.GroupName = s.GroupName
+    model.Symbol = s.Symbol
+    model.GroupType = s.GroupType
+    model.Type = s.Type
+    model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LineSymbolGroupUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineSymbolGroupGetReq 功能获取请求参数
+type LineSymbolGroupGetReq struct {
+     Id int `uri:"id"`
+}
+func (s *LineSymbolGroupGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineSymbolGroupDeleteReq 功能删除请求参数
+type LineSymbolGroupDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineSymbolGroupDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_system_setting.go b/app/admin/service/dto/line_system_setting.go
new file mode 100644
index 0000000..1f2811e
--- /dev/null
+++ b/app/admin/service/dto/line_system_setting.go
@@ -0,0 +1,134 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+
+	"github.com/shopspring/decimal"
+)
+
+type LineSystemSettingGetPageReq struct {
+	dto.Pagination `search:"-"`
+	LineSystemSettingOrder
+}
+
+type LineSystemSettingOrder struct {
+	Id                        string `form:"idOrder"  search:"type:order;column:id;table:line_system_setting"`
+	CreatedAt                 string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_system_setting"`
+	UpdatedAt                 string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_system_setting"`
+	DeletedAt                 string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_system_setting"`
+	Time                      string `form:"timeOrder"  search:"type:order;column:time;table:line_system_setting"`
+	BatchTime                 string `form:"batchTimeOrder"  search:"type:order;column:batch_time;table:line_system_setting"`
+	ProfitRate                string `form:"profitRateOrder"  search:"type:order;column:profit_rate;table:line_system_setting"`
+	CoverOrderTypeBRate       string `form:"coverOrderTypeBRateOrder"  search:"type:order;column:cover_order_type_b_rate;table:line_system_setting"`
+	ScaleOrderTypeARate       string `form:"scaleOrderTypeARateOrder"  search:"type:order;column:scale_order_type_a_rate;table:line_system_setting"`
+	ScaleOrderTypeBRate       string `form:"scaleOrderTypeBRateOrder"  search:"type:order;column:scale_order_type_b_rate;table:line_system_setting"`
+	ScaleUnRealizedProfitRate string `form:"scaleUnRealizedProfitRateOrder"  search:"type:order;column:scale_unRealizedProfitRate;table:line_system_setting"`
+	ScaleNum                  string `form:"scaleNumOrder"  search:"type:order;column:scale_num;table:line_system_setting"`
+	ScaleSubordinate          string `form:"scaleSubordinateOrder"  search:"type:order;column:scale_subordinate;table:line_system_setting"`
+	AutoScaleTimes            string `form:"autoScaleTimesOrder"  search:"type:order;column:auto_scale_times;table:line_system_setting"`
+	CreateBy                  string `form:"createByOrder"  search:"type:order;column:create_by;table:line_system_setting"`
+	UpdateBy                  string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_system_setting"`
+}
+
+func (m *LineSystemSettingGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineSystemSettingInsertReq struct {
+	Id                        int    `json:"-" comment:"id"` // id
+	Time                      int64  `json:"time" comment:"导入:挂单时长达到时间后失效"`
+	BatchTime                 int64  `json:"batchTime" comment:"批量:挂单时长达到时间后失效"`
+	ProfitRate                string `json:"profitRate" comment:"平仓盈利比例"`
+	CoverOrderTypeBRate       string `json:"coverOrderTypeBRate" comment:"b账户限价补单的买入百分比"`
+	ScaleOrderTypeARate       string `json:"scaleOrderTypeARate" comment:"a账户限价加仓买入百分比"`
+	ScaleOrderTypeBRate       string `json:"scaleOrderTypeBRate" comment:"b账户限价加仓买入百分比"`
+	ScaleUnRealizedProfitRate string `json:"scaleUnRealizedProfitRate" comment:"亏损百分比加仓"`
+	ScaleNum                  string `json:"scaleNum" comment:"加仓数值"`
+	ScaleSubordinate          int64  `json:"scaleSubordinate" comment:"加仓账户:1=A账户;2=副账户;3=都加"`
+	AutoScaleTimes            int64  `json:"autoScaleTimes" comment:"自动加仓次数"`
+	ProtectHedgeEnable        int    `json:"protectHedgeEnable" comment:"是否只开启保险对冲 0-否 1-是"`
+	common.ControlBy
+}
+
+func (s *LineSystemSettingInsertReq) Generate(model *models.LineSystemSetting) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.Time = s.Time
+	model.BatchTime = s.BatchTime
+	model.ProfitRate = s.ProfitRate
+	model.CoverOrderTypeBRate = s.CoverOrderTypeBRate
+	model.ScaleOrderTypeARate = s.ScaleOrderTypeARate
+	model.ScaleOrderTypeBRate = s.ScaleOrderTypeBRate
+	model.ScaleUnrealizedProfitRate = s.ScaleUnRealizedProfitRate
+	model.ScaleNum = s.ScaleNum
+	model.ScaleSubordinate = s.ScaleSubordinate
+	model.AutoScaleTimes = s.AutoScaleTimes
+	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LineSystemSettingInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineSystemSettingUpdateReq struct {
+	Id                        int             `uri:"id" comment:"id"` // id
+	Time                      int64           `json:"time" comment:"导入:挂单时长达到时间后失效"`
+	BatchTime                 int64           `json:"batchTime" comment:"批量:挂单时长达到时间后失效"`
+	ProfitRate                string          `json:"profitRate" comment:"平仓盈利比例"`
+	CoverOrderTypeBRate       string          `json:"coverOrderTypeBRate" comment:"b账户限价补单的买入百分比"`
+	ScaleOrderTypeARate       string          `json:"scaleOrderTypeARate" comment:"a账户限价加仓买入百分比"`
+	ScaleOrderTypeBRate       string          `json:"scaleOrderTypeBRate" comment:"b账户限价加仓买入百分比"`
+	ScaleUnrealizedProfitRate string          `json:"scaleUnRealizedProfitRate" comment:"亏损百分比加仓"`
+	ScaleNum                  string          `json:"scaleNum" comment:"加仓数值"`
+	ScaleSubordinate          int64           `json:"scaleSubordinate" comment:"加仓账户:1=A账户;2=副账户;3=都加"`
+	AutoScaleTimes            int64           `json:"autoScaleTimes" comment:"自动加仓次数"`
+	HedgePerformance          decimal.Decimal `json:"hedgePerformance" comment:"对冲平仓涨跌幅"`
+	ProtectHedgeRate          decimal.Decimal `json:"protectHedgeRate" comment:"对冲市价亏损百分比"`
+	ProtectHedgeEnable        int             `json:"protectHedgeEnable" comment:"是否只开启保险对冲 0-否 1-是"`
+	common.ControlBy
+}
+
+func (s *LineSystemSettingUpdateReq) Generate(model *models.LineSystemSetting) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.Time = s.Time
+	model.BatchTime = s.BatchTime
+	model.ProfitRate = s.ProfitRate
+	model.CoverOrderTypeBRate = s.CoverOrderTypeBRate
+	model.ScaleOrderTypeARate = s.ScaleOrderTypeARate
+	model.ScaleOrderTypeBRate = s.ScaleOrderTypeBRate
+	model.ScaleUnrealizedProfitRate = s.ScaleUnrealizedProfitRate
+	model.ScaleNum = s.ScaleNum
+	model.ScaleSubordinate = s.ScaleSubordinate
+	model.AutoScaleTimes = s.AutoScaleTimes
+	model.HedgePerformance = s.HedgePerformance
+	model.ProtectHedgeRate = s.ProtectHedgeRate
+	model.ProtectHedgeEnable = s.ProtectHedgeEnable
+	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LineSystemSettingUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineSystemSettingGetReq 功能获取请求参数
+type LineSystemSettingGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *LineSystemSettingGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineSystemSettingDeleteReq 功能删除请求参数
+type LineSystemSettingDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineSystemSettingDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_uduncoin.go b/app/admin/service/dto/line_uduncoin.go
new file mode 100644
index 0000000..69bf100
--- /dev/null
+++ b/app/admin/service/dto/line_uduncoin.go
@@ -0,0 +1,120 @@
+package dto
+
+import (
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineUduncoinGetPageReq struct {
+	dto.Pagination     `search:"-"`
+    LineUduncoinOrder
+}
+
+type LineUduncoinOrder struct {
+    Id string `form:"idOrder"  search:"type:order;column:id;table:line_uduncoin"`
+    TokenStatus string `form:"tokenStatusOrder"  search:"type:order;column:token_status;table:line_uduncoin"`
+    Decimals string `form:"decimalsOrder"  search:"type:order;column:decimals;table:line_uduncoin"`
+    MainCoinType string `form:"mainCoinTypeOrder"  search:"type:order;column:main_coin_type;table:line_uduncoin"`
+    CoinType string `form:"coinTypeOrder"  search:"type:order;column:coin_type;table:line_uduncoin"`
+    Symbol string `form:"symbolOrder"  search:"type:order;column:symbol;table:line_uduncoin"`
+    Name string `form:"nameOrder"  search:"type:order;column:name;table:line_uduncoin"`
+    Logo string `form:"logoOrder"  search:"type:order;column:logo;table:line_uduncoin"`
+    CoinName string `form:"coinNameOrder"  search:"type:order;column:coin_name;table:line_uduncoin"`
+    MainSymbol string `form:"mainSymbolOrder"  search:"type:order;column:main_symbol;table:line_uduncoin"`
+    CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:line_uduncoin"`
+    UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_uduncoin"`
+    CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_uduncoin"`
+    UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_uduncoin"`
+    
+}
+
+func (m *LineUduncoinGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineUduncoinInsertReq struct {
+    Id int `json:"-" comment:"主键ID"` // 主键ID
+    TokenStatus int64 `json:"tokenStatus" comment:"0: 主幣 1:代幣"`
+    Decimals int64 `json:"decimals" comment:"幣種精度,8"`
+    MainCoinType string `json:"mainCoinType" comment:"主幣種類型"`
+    CoinType string `json:"coinType" comment:"幣種類型"`
+    Symbol string `json:"symbol" comment:"幣種symbol"`
+    Name string `json:"name" comment:"幣種別名,BTC"`
+    Logo string `json:"logo" comment:"幣種logo地址"`
+    CoinName string `json:"coinName" comment:"幣種全稱,Bitcoin"`
+    MainSymbol string `json:"mainSymbol" comment:"主幣種symbol"`
+    common.ControlBy
+}
+
+func (s *LineUduncoinInsertReq) Generate(model *models.LineUduncoin)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.TokenStatus = s.TokenStatus
+    model.Decimals = s.Decimals
+    model.MainCoinType = s.MainCoinType
+    model.CoinType = s.CoinType
+    model.Symbol = s.Symbol
+    model.Name = s.Name
+    model.Logo = s.Logo
+    model.CoinName = s.CoinName
+    model.MainSymbol = s.MainSymbol
+    model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LineUduncoinInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineUduncoinUpdateReq struct {
+    Id int `uri:"id" comment:"主键ID"` // 主键ID
+    TokenStatus int64 `json:"tokenStatus" comment:"0: 主幣 1:代幣"`
+    Decimals int64 `json:"decimals" comment:"幣種精度,8"`
+    MainCoinType string `json:"mainCoinType" comment:"主幣種類型"`
+    CoinType string `json:"coinType" comment:"幣種類型"`
+    Symbol string `json:"symbol" comment:"幣種symbol"`
+    Name string `json:"name" comment:"幣種別名,BTC"`
+    Logo string `json:"logo" comment:"幣種logo地址"`
+    CoinName string `json:"coinName" comment:"幣種全稱,Bitcoin"`
+    MainSymbol string `json:"mainSymbol" comment:"主幣種symbol"`
+    common.ControlBy
+}
+
+func (s *LineUduncoinUpdateReq) Generate(model *models.LineUduncoin)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.TokenStatus = s.TokenStatus
+    model.Decimals = s.Decimals
+    model.MainCoinType = s.MainCoinType
+    model.CoinType = s.CoinType
+    model.Symbol = s.Symbol
+    model.Name = s.Name
+    model.Logo = s.Logo
+    model.CoinName = s.CoinName
+    model.MainSymbol = s.MainSymbol
+    model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LineUduncoinUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineUduncoinGetReq 功能获取请求参数
+type LineUduncoinGetReq struct {
+     Id int `uri:"id"`
+}
+func (s *LineUduncoinGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineUduncoinDeleteReq 功能删除请求参数
+type LineUduncoinDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineUduncoinDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_user.go b/app/admin/service/dto/line_user.go
new file mode 100644
index 0000000..24f0c9b
--- /dev/null
+++ b/app/admin/service/dto/line_user.go
@@ -0,0 +1,332 @@
+package dto
+
+import (
+	"github.com/shopspring/decimal"
+	statuscode "go-admin/common/status_code"
+	"go-admin/pkg/emailhelper"
+	"go-admin/pkg/utility"
+	"time"
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineUserGetPageReq struct {
+	dto.Pagination `search:"-"`
+	LineUserOrder
+}
+
+type LineUserOrder struct {
+	Id             string `form:"idOrder"  search:"type:order;column:id;table:line_user"`
+	GroupId        int    `form:"groupIdOrder"  search:"type:order;column:group_id;table:line_user"`
+	Username       string `form:"usernameOrder"  search:"type:order;column:username;table:line_user"`
+	Nickname       string `form:"nicknameOrder"  search:"type:order;column:nickname;table:line_user"`
+	Password       string `form:"passwordOrder"  search:"type:order;column:password;table:line_user"`
+	Salt           string `form:"saltOrder"  search:"type:order;column:salt;table:line_user"`
+	Email          string `form:"emailOrder"  search:"type:order;column:email;table:line_user"`
+	Mobile         string `form:"mobileOrder"  search:"type:order;column:mobile;table:line_user"`
+	Avatar         string `form:"avatarOrder"  search:"type:order;column:avatar;table:line_user"`
+	Level          int    `form:"levelOrder"  search:"type:order;column:level;table:line_user"`
+	Gender         int    `form:"genderOrder"  search:"type:order;column:gender;table:line_user"`
+	Bio            string `form:"bioOrder"  search:"type:order;column:bio;table:line_user"`
+	Money          string `form:"moneyOrder"  search:"type:order;column:money;table:line_user"`
+	Score          int    `form:"scoreOrder"  search:"type:order;column:score;table:line_user"`
+	Successions    int    `form:"successionsOrder"  search:"type:order;column:successions;table:line_user"`
+	MaxSuccessions int    `form:"maxSuccessionsOrder"  search:"type:order;column:max_successions;table:line_user"`
+	Loginip        string `form:"loginipOrder"  search:"type:order;column:loginip;table:line_user"`
+	Loginfailure   int    `form:"loginfailureOrder"  search:"type:order;column:loginfailure;table:line_user"`
+	Joinip         string `form:"joinipOrder"  search:"type:order;column:joinip;table:line_user"`
+	Jointime       int    `form:"jointimeOrder"  search:"type:order;column:jointime;table:line_user"`
+	Token          string `form:"tokenOrder"  search:"type:order;column:token;table:line_user"`
+	Status         string `form:"statusOrder"  search:"type:order;column:status;table:line_user"`
+	Verification   string `form:"verificationOrder"  search:"type:order;column:verification;table:line_user"`
+	LoginTime      string `form:"loginTimeOrder"  search:"type:order;column:login_time;table:line_user"`
+	CreatedAt      string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_user"`
+	UpdatedAt      string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_user"`
+}
+
+func (m *LineUserGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineUserInsertReq struct {
+	Id             int             `json:"-" comment:"ID"` // ID
+	GroupId        int             `json:"groupId" comment:"组别ID"`
+	Username       string          `json:"username" comment:"用户名"`
+	Nickname       string          `json:"nickname" comment:"昵称"`
+	Password       string          `json:"password" comment:"密码"`
+	Salt           string          `json:"salt" comment:"密码盐"`
+	Email          string          `json:"email" comment:"电子邮箱"`
+	Mobile         string          `json:"mobile" comment:"手机号"`
+	Area           string          `json:"area" comment:"手机号归属地"`
+	Avatar         string          `json:"avatar" comment:"头像"`
+	Level          int             `json:"level" comment:"等级"`
+	Gender         int             `json:"gender" comment:"性别"`
+	Bio            string          `json:"bio" comment:"格言"`
+	Money          decimal.Decimal `json:"money" comment:"保证金"`
+	Score          int             `json:"score" comment:"积分"`
+	Successions    int             `json:"successions" comment:"连续登录天数"`
+	MaxSuccessions int             `json:"maxSuccessions" comment:"最大连续登录天数"`
+	Loginip        string          `json:"loginip" comment:"登录IP"`
+	Loginfailure   int             `json:"loginfailure" comment:"失败次数"`
+	Joinip         string          `json:"joinip" comment:"加入IP"`
+	Jointime       int             `json:"jointime" comment:"加入时间"`
+	RecommendNum   int             `json:"recommend_num" comment:"推荐人数"`
+	Token          string          `json:"token" comment:"Token"`
+	Status         string          `json:"status" comment:"状态"`
+	Verification   string          `json:"verification" comment:"验证"`
+	LoginTime      time.Time       `json:"loginTime" comment:"登录时间"`
+	common.ControlBy
+}
+
+func (s *LineUserInsertReq) Generate(model *models.LineUser) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.GroupId = s.GroupId
+	model.Username = s.Username
+	model.Nickname = s.Nickname
+	model.Password = s.Password
+	model.Salt = s.Salt
+	model.Email = s.Email
+	model.Mobile = s.Mobile
+	model.Area = s.Area
+	model.Avatar = s.Avatar
+	model.Level = s.Level
+	model.Gender = s.Gender
+	model.Bio = s.Bio
+	model.Money = s.Money
+	model.Score = s.Score
+	model.Successions = s.Successions
+	model.MaxSuccessions = s.MaxSuccessions
+	model.Loginip = s.Loginip
+	model.Loginfailure = s.Loginfailure
+	model.Joinip = s.Joinip
+	model.Jointime = s.Jointime
+	model.RecommendNum = s.RecommendNum
+	model.Token = s.Token
+	model.Status = s.Status
+	model.Verification = s.Verification
+	model.LoginTime = s.LoginTime
+}
+
+func (s *LineUserInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineUserUpdateReq struct {
+	Id             int             `uri:"id" comment:"ID"` // ID
+	GroupId        int             `json:"groupId" comment:"组别ID"`
+	Pid            int             `json:"pid" comment:"推荐人ID"`
+	Username       string          `json:"username" comment:"用户名"`
+	Nickname       string          `json:"nickname" comment:"昵称"`
+	Password       string          `json:"password" comment:"密码"`
+	Salt           string          `json:"salt" comment:"密码盐"`
+	Email          string          `json:"email" comment:"电子邮箱"`
+	Mobile         string          `json:"mobile" comment:"手机号"`
+	Area           string          `json:"area" comment:"手机号归属地"`
+	Avatar         string          `json:"avatar" comment:"头像"`
+	Level          int             `json:"level" comment:"等级"`
+	Gender         int             `json:"gender" comment:"性别"`
+	Bio            string          `json:"bio" comment:"格言"`
+	Money          decimal.Decimal `json:"money" comment:"余额"`
+	Score          int             `json:"score" comment:"积分"`
+	InviteCode     string          `json:"invite_code" comment:"邀请码"`
+	Successions    int             `json:"successions" comment:"连续登录天数"`
+	MaxSuccessions int             `json:"maxSuccessions" comment:"最大连续登录天数"`
+	Loginip        string          `json:"loginip" comment:"登录IP"`
+	Loginfailure   int             `json:"loginfailure" comment:"失败次数"`
+	Joinip         string          `json:"joinip" comment:"加入IP"`
+	Jointime       int             `json:"jointime" comment:"加入时间"`
+	RecommendNum   int             `json:"recommend_num" comment:"推荐人数"`
+	Token          string          `json:"token" comment:"Token"`
+	Status         string          `json:"status" comment:"状态"`
+	Verification   string          `json:"verification" comment:"验证"`
+	LoginTime      time.Time       `json:"loginTime" comment:"登录时间"`
+	OpenStatus     int             `json:"open_status"`
+	common.ControlBy
+}
+
+func (s *LineUserUpdateReq) Generate(model *models.LineUser) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.GroupId = s.GroupId
+	model.Pid = s.Pid
+	model.Username = s.Username
+	model.Nickname = s.Nickname
+	model.Password = s.Password
+	model.Salt = s.Salt
+	model.Email = s.Email
+	model.Mobile = s.Mobile
+	model.Area = s.Area
+	model.Avatar = s.Avatar
+	model.Level = s.Level
+	model.Gender = s.Gender
+	model.Bio = s.Bio
+	model.Money = s.Money
+	model.Score = s.Score
+	model.InviteCode = s.InviteCode
+	model.Successions = s.Successions
+	model.MaxSuccessions = s.MaxSuccessions
+	model.Loginip = s.Loginip
+	model.Loginfailure = s.Loginfailure
+	model.Joinip = s.Joinip
+	model.Jointime = s.Jointime
+	model.Token = s.Token
+	model.Status = s.Status
+	model.Verification = s.Verification
+	model.LoginTime = s.LoginTime
+}
+
+func (s *LineUserUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineUserGetReq 功能获取请求参数
+type LineUserGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *LineUserGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineUserDeleteReq 功能删除请求参数
+type LineUserDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineUserDeleteReq) GetId() interface{} {
+	return s.Ids
+}
+
+// FrontedUserVerifyEmailReq 验证邮箱验证码参数
+type FrontedUserVerifyEmailReq struct {
+	Email      string `json:"email"`
+	VerifyCode string `json:"verify_code"`
+}
+
+type FrontedSendVerifyEmailReq struct {
+	Email string `json:"email"`
+}
+
+type FrontedSendVerifySmsReq struct {
+	PhoneAreaCode string `json:"phone_area_code"` // 区域电话代码
+	Phone         string `json:"phone"`           // 手机号码
+}
+
+func (receiver *FrontedSendVerifyEmailReq) CheckParams() int {
+	// 邮箱校验
+	if receiver.Email == "" {
+		return statuscode.EmailRequired
+	}
+	if !emailhelper.CheckIsEmail(receiver.Email) {
+		return statuscode.EmailFormatInvalid
+	}
+	return statuscode.OK
+}
+
+func (receiver FrontedSendVerifySmsReq) CheckParams() int {
+	// 短信校验
+	if receiver.PhoneAreaCode == "" || receiver.Phone == "" {
+		return statuscode.ParameterInvalid
+	}
+	if receiver.PhoneAreaCode == "+86" {
+		if !utility.IsMobileChina(receiver.Phone) {
+			return statuscode.PhoneFormatInvalid
+		}
+	}
+	return statuscode.OK
+}
+
+// FrontedLoginReq 登录请求
+type FrontedLoginReq struct {
+	Email         string `json:"email"`
+	Phone         string `json:"phone"`
+	PhoneAreaCode string `json:"phone_area_code"`
+	Password      string `json:"password"`   // 密码
+	LoginType     int    `json:"login_type"` // 1 手机,2 邮箱
+}
+
+func (receiver FrontedLoginReq) CheckParams() int {
+	if receiver.Password == "" {
+		return statuscode.PasswordRequired
+	}
+	if receiver.LoginType == 2 {
+
+		if receiver.Email == "" {
+			return statuscode.EmailRequired
+		}
+		if !emailhelper.CheckIsEmail(receiver.Email) {
+			return statuscode.EmailFormatInvalid
+		}
+		return statuscode.OK
+	}
+
+	if receiver.LoginType == 1 { //手机号登录
+		if receiver.Phone == "" {
+			return statuscode.PhoneRequired
+		}
+		return statuscode.OK
+	}
+	return statuscode.ParamErr
+}
+
+type AddApiKeyReq struct {
+	ApiName   string `json:"api_name"`
+	ApiKey    string `json:"api_key"`
+	ApiSecret string `json:"api_secret"`
+	ApiIp     string `json:"api_ip"`
+}
+
+func (a AddApiKeyReq) CheckParams() int {
+	if a.ApiKey == "" || a.ApiSecret == "" {
+		return statuscode.ParamErr
+	}
+	return statuscode.OK
+}
+
+// OpenStatusReq 开启或者闭关状态
+type OpenStatusReq struct {
+	Status int `json:"status"`
+}
+
+type RechargeListReq struct {
+	Coin string `json:"coin"`
+}
+
+// ApiRestrictions 检查api 是否可用
+type ApiRestrictions struct {
+	IpRestrict                   bool  `json:"ipRestrict"`
+	CreateTime                   int64 `json:"createTime"`
+	EnableReading                bool  `json:"enableReading"`
+	EnableWithdrawals            bool  `json:"enableWithdrawals"`
+	EnableInternalTransfer       bool  `json:"enableInternalTransfer"`
+	EnableMargin                 bool  `json:"enableMargin"`
+	EnableFutures                bool  `json:"enableFutures"`
+	PermitsUniversalTransfer     bool  `json:"permitsUniversalTransfer"`
+	EnableVanillaOptions         bool  `json:"enableVanillaOptions"`
+	EnableFixApiTrade            bool  `json:"enableFixApiTrade"`
+	EnableFixReadOnly            bool  `json:"enableFixReadOnly"`
+	EnableSpotAndMarginTrading   bool  `json:"enableSpotAndMarginTrading"`
+	EnablePortfolioMarginTrading bool  `json:"enablePortfolioMarginTrading"`
+}
+
+type RechargeAddressListReq struct {
+	UserId    int    `json:"user_id"`
+	NetWorkId int    `json:"network_id"`
+	CoinCode  string `json:"coin"`
+}
+
+type VtsRechargePreOrderReq struct {
+	CoinCode string          `json:"coin_code" form:"coin_code"`
+	Amount   decimal.Decimal `json:"amount" form:"amount"`
+}
+
+type VtsRechargePreOrderResp struct {
+	PaymentUrl    string `json:"paymentUrl"`
+	PriceAmount   string `json:"priceAmount"`
+	PriceCurrency string `json:"priceCurrency"`
+}
diff --git a/app/admin/service/dto/line_user_funding_trend.go b/app/admin/service/dto/line_user_funding_trend.go
new file mode 100644
index 0000000..ed3b5da
--- /dev/null
+++ b/app/admin/service/dto/line_user_funding_trend.go
@@ -0,0 +1,82 @@
+package dto
+
+import (
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineUserFundingTrendGetPageReq struct {
+	dto.Pagination     `search:"-"`
+    LineUserFundingTrendOrder
+}
+
+type LineUserFundingTrendOrder struct {
+    Id string `form:"idOrder"  search:"type:order;column:id;table:line_user_funding_trend"`
+    UserId string `form:"userIdOrder"  search:"type:order;column:user_id;table:line_user_funding_trend"`
+    Funding string `form:"fundingOrder"  search:"type:order;column:funding;table:line_user_funding_trend"`
+    CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_user_funding_trend"`
+    UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_user_funding_trend"`
+    DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_user_funding_trend"`
+    
+}
+
+func (m *LineUserFundingTrendGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineUserFundingTrendInsertReq struct {
+    Id int `json:"-" comment:""` // 
+    UserId int64 `json:"userId" comment:"用户id"`
+    Funding string `json:"funding" comment:"资金账户总额 换算U"`
+    common.ControlBy
+}
+
+func (s *LineUserFundingTrendInsertReq) Generate(model *models.LineUserFundingTrend)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.UserId = s.UserId
+    model.Funding = s.Funding
+}
+
+func (s *LineUserFundingTrendInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineUserFundingTrendUpdateReq struct {
+    Id int `uri:"id" comment:""` // 
+    UserId int64 `json:"userId" comment:"用户id"`
+    Funding string `json:"funding" comment:"资金账户总额 换算U"`
+    common.ControlBy
+}
+
+func (s *LineUserFundingTrendUpdateReq) Generate(model *models.LineUserFundingTrend)  {
+    if s.Id == 0 {
+        model.Model = common.Model{ Id: s.Id }
+    }
+    model.UserId = s.UserId
+    model.Funding = s.Funding
+}
+
+func (s *LineUserFundingTrendUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineUserFundingTrendGetReq 功能获取请求参数
+type LineUserFundingTrendGetReq struct {
+     Id int `uri:"id"`
+}
+func (s *LineUserFundingTrendGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineUserFundingTrendDeleteReq 功能删除请求参数
+type LineUserFundingTrendDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineUserFundingTrendDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_user_profit_logs.go b/app/admin/service/dto/line_user_profit_logs.go
new file mode 100644
index 0000000..e662138
--- /dev/null
+++ b/app/admin/service/dto/line_user_profit_logs.go
@@ -0,0 +1,113 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineUserProfitLogsGetPageReq struct {
+	dto.Pagination `search:"-"`
+	UserId         int64  `form:"userId"  search:"type:exact;column:user_id;table:line_user_profit_logs" comment:"line_user 表的id"`
+	ApiId          int64  `form:"apiId"  search:"type:exact;column:api_id;table:line_user_profit_logs" comment:"line_apiuser 表的id"`
+	PreOrderId     int64  `form:"preOrderId"  search:"type:exact;column:pre_order_id;table:line_user_profit_logs" comment:"line_pre_order 主订单id"`
+	Num            string `form:"num"  search:"type:exact;column:num;table:line_user_profit_logs" comment:"成交数量"`
+	Symbol         string `form:"symbol"  search:"type:exact;column:symbol;table:line_user_profit_logs" comment:"交易对"`
+	LineUserProfitLogsOrder
+}
+
+type LineUserProfitLogsOrder struct {
+	Id         string `form:"idOrder"  search:"type:order;column:id;table:line_user_profit_logs"`
+	UserId     string `form:"userIdOrder"  search:"type:order;column:user_id;table:line_user_profit_logs"`
+	ApiId      string `form:"apiIdOrder"  search:"type:order;column:api_id;table:line_user_profit_logs"`
+	PreOrderId string `form:"preOrderIdOrder"  search:"type:order;column:pre_order_id;table:line_user_profit_logs"`
+	Num        string `form:"numOrder"  search:"type:order;column:num;table:line_user_profit_logs"`
+	Symbol     string `form:"symbolOrder"  search:"type:order;column:symbol;table:line_user_profit_logs"`
+	Rate       string `form:"rateOrder"  search:"type:order;column:rate;table:line_user_profit_logs"`
+	CreatedAt  string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_user_profit_logs"`
+	UpdatedAt  string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_user_profit_logs"`
+	DeletedAt  string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_user_profit_logs"`
+	CreateBy   string `form:"createByOrder"  search:"type:order;column:create_by;table:line_user_profit_logs"`
+	UpdateBy   string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_user_profit_logs"`
+}
+
+func (m *LineUserProfitLogsGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineUserProfitLogsInsertReq struct {
+	Id         int    `json:"-" comment:""` //
+	UserId     int64  `json:"userId" comment:"line_user 表的id"`
+	ApiId      int64  `json:"apiId" comment:"line_apiuser 表的id"`
+	PreOrderId int64  `json:"preOrderId" comment:"line_pre_order 主订单id"`
+	Num        string `json:"num" comment:"成交数量"`
+	Symbol     string `json:"symbol" comment:"交易对"`
+	Rate       string `json:"rate" comment:"盈利比例"`
+	Amount     string `json:"amount" comment:"盈利金额(换算成U的价值)"`
+	common.ControlBy
+}
+
+func (s *LineUserProfitLogsInsertReq) Generate(model *models.LineUserProfitLogs) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.UserId = s.UserId
+	model.ApiId = s.ApiId
+	model.PreOrderId = s.PreOrderId
+	model.Num = s.Num
+	model.Symbol = s.Symbol
+	model.Rate = s.Rate
+	model.Amount = s.Amount
+	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *LineUserProfitLogsInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineUserProfitLogsUpdateReq struct {
+	Id         int    `uri:"id" comment:""` //
+	UserId     int64  `json:"userId" comment:"line_user 表的id"`
+	ApiId      int64  `json:"apiId" comment:"line_apiuser 表的id"`
+	PreOrderId int64  `json:"preOrderId" comment:"line_pre_order 主订单id"`
+	Num        string `json:"num" comment:"成交数量"`
+	Symbol     string `json:"symbol" comment:"交易对"`
+	Rate       string `json:"rate" comment:"盈利比例"`
+	Amoubt     string `json:"" comment:"盈利比例"`
+	common.ControlBy
+}
+
+func (s *LineUserProfitLogsUpdateReq) Generate(model *models.LineUserProfitLogs) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.UserId = s.UserId
+	model.ApiId = s.ApiId
+	model.PreOrderId = s.PreOrderId
+	model.Num = s.Num
+	model.Symbol = s.Symbol
+	model.Rate = s.Rate
+	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *LineUserProfitLogsUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineUserProfitLogsGetReq 功能获取请求参数
+type LineUserProfitLogsGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *LineUserProfitLogsGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineUserProfitLogsDeleteReq 功能删除请求参数
+type LineUserProfitLogsDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineUserProfitLogsDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/line_wallet.go b/app/admin/service/dto/line_wallet.go
new file mode 100644
index 0000000..6db95b6
--- /dev/null
+++ b/app/admin/service/dto/line_wallet.go
@@ -0,0 +1,104 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type LineWalletGetPageReq struct {
+	dto.Pagination `search:"-"`
+	LineWalletOrder
+}
+
+type LineWalletOrder struct {
+	Id            string `form:"idOrder"  search:"type:order;column:id;table:line_wallet"`
+	UserId        string `form:"userIdOrder"  search:"type:order;column:user_id;table:line_wallet"`
+	CoinId        string `form:"coinIdOrder"  search:"type:order;column:coin_id;table:line_wallet"`
+	CoinCode      string `form:"coinCode"  search:"type:order;column:coin_code;table:line_wallet"`
+	Tag           string `form:"tagOrder"  search:"type:order;column:tag;table:line_wallet"`
+	Address       string `form:"addressOrder"  search:"type:order;column:address;table:line_wallet"`
+	CreateBy      string `form:"createByOrder"  search:"type:order;column:create_by;table:line_wallet"`
+	UpdateBy      string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_wallet"`
+	CreatedAt     string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_wallet"`
+	UpdatedAt     string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_wallet"`
+	CoinNetworkId int    `form:"coinNetworkIdOrder"  search:"type:order;column:coin_network_id;table:line_wallet"`
+}
+
+func (m *LineWalletGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type LineWalletInsertReq struct {
+	Id            int    `json:"-" comment:"主键ID"` // 主键ID
+	UserId        int64  `json:"userId" comment:"用户Id"`
+	CoinId        int64  `json:"coinId" comment:"币种id"`
+	CoinCode      string `json:"coinCode" comment:"币种名称"`
+	Tag           string `json:"tag" comment:"标签"`
+	Address       string `json:"address" comment:"地址"`
+	CoinNetworkId int    `json:"coinNetworkId" comment:"币种主网id,useri+主网id做唯一"`
+	common.ControlBy
+}
+
+func (s *LineWalletInsertReq) Generate(model *models.LineWallet) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.UserId = s.UserId
+	model.CoinId = s.CoinId
+	model.Tag = s.Tag
+	model.CoinCode = s.CoinCode
+	model.Address = s.Address
+	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+	model.CoinNetworkId = s.CoinNetworkId
+}
+
+func (s *LineWalletInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type LineWalletUpdateReq struct {
+	Id            int    `uri:"id" comment:"主键ID"` // 主键ID
+	UserId        int64  `json:"userId" comment:"用户Id"`
+	CoinId        int64  `json:"coinId" comment:"币种id"`
+	CoinCode      string `json:"coinCode" comment:"币种名称"`
+	Tag           string `json:"tag" comment:"标签"`
+	Address       string `json:"address" comment:"地址"`
+	CoinNetworkId int    `json:"coinNetworkId" comment:"币种主网id,useri+主网id做唯一"`
+	common.ControlBy
+}
+
+func (s *LineWalletUpdateReq) Generate(model *models.LineWallet) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.UserId = s.UserId
+	model.CoinId = s.CoinId
+	model.Tag = s.Tag
+	model.CoinCode = s.CoinCode
+	model.Address = s.Address
+	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+	model.CoinNetworkId = s.CoinNetworkId
+}
+
+func (s *LineWalletUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineWalletGetReq 功能获取请求参数
+type LineWalletGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *LineWalletGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// LineWalletDeleteReq 功能删除请求参数
+type LineWalletDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *LineWalletDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/sys_api.go b/app/admin/service/dto/sys_api.go
new file mode 100644
index 0000000..d26034e
--- /dev/null
+++ b/app/admin/service/dto/sys_api.go
@@ -0,0 +1,95 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+// SysApiGetPageReq 功能列表请求参数
+type SysApiGetPageReq struct {
+	dto.Pagination `search:"-"`
+	Title          string `form:"title"  search:"type:contains;column:title;table:sys_api" comment:"标题"`
+	Path           string `form:"path"  search:"type:contains;column:path;table:sys_api" comment:"地址"`
+	Action         string `form:"action"  search:"type:exact;column:action;table:sys_api" comment:"请求方式"`
+	ParentId       string `form:"parentId"  search:"type:exact;column:parent_id;table:sys_api" comment:"按钮id"`
+	Type           string `form:"type" search:"-" comment:"类型"`
+	SysApiOrder
+}
+
+type SysApiOrder struct {
+	TitleOrder     string `search:"type:order;column:title;table:sys_api" form:"titleOrder"`
+	PathOrder      string `search:"type:order;column:path;table:sys_api" form:"pathOrder"`
+	CreatedAtOrder string `search:"type:order;column:created_at;table:sys_api" form:"createdAtOrder"`
+}
+
+func (m *SysApiGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+// SysApiInsertReq 功能创建请求参数
+type SysApiInsertReq struct {
+	Id     int    `json:"-" comment:"编码"` // 编码
+	Handle string `json:"handle" comment:"handle"`
+	Title  string `json:"title" comment:"标题"`
+	Path   string `json:"path" comment:"地址"`
+	Type   string `json:"type" comment:""`
+	Action string `json:"action" comment:"类型"`
+	common.ControlBy
+}
+
+func (s *SysApiInsertReq) Generate(model *models.SysApi) {
+	model.Handle = s.Handle
+	model.Title = s.Title
+	model.Path = s.Path
+	model.Type = s.Type
+	model.Action = s.Action
+}
+
+func (s *SysApiInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+// SysApiUpdateReq 功能更新请求参数
+type SysApiUpdateReq struct {
+	Id     int    `uri:"id" comment:"编码"` // 编码
+	Handle string `json:"handle" comment:"handle"`
+	Title  string `json:"title" comment:"标题"`
+	Path   string `json:"path" comment:"地址"`
+	Type   string `json:"type" comment:""`
+	Action string `json:"action" comment:"类型"`
+	common.ControlBy
+}
+
+func (s *SysApiUpdateReq) Generate(model *models.SysApi) {
+	if s.Id != 0 {
+		model.Id = s.Id
+	}
+	model.Handle = s.Handle
+	model.Title = s.Title
+	model.Path = s.Path
+	model.Type = s.Type
+	model.Action = s.Action
+}
+
+func (s *SysApiUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// SysApiGetReq 功能获取请求参数
+type SysApiGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *SysApiGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// SysApiDeleteReq 功能删除请求参数
+type SysApiDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *SysApiDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/sys_config.go b/app/admin/service/dto/sys_config.go
new file mode 100644
index 0000000..0e97bc1
--- /dev/null
+++ b/app/admin/service/dto/sys_config.go
@@ -0,0 +1,117 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+// SysConfigGetPageReq 列表或者搜索使用结构体
+type SysConfigGetPageReq struct {
+	dto.Pagination `search:"-"`
+	ConfigName     string `form:"configName" search:"type:contains;column:config_name;table:sys_config"`
+	ConfigKey      string `form:"configKey" search:"type:contains;column:config_key;table:sys_config"`
+	ConfigType     string `form:"configType" search:"type:exact;column:config_type;table:sys_config"`
+	IsFrontend     string `form:"isFrontend" search:"type:exact;column:is_frontend;table:sys_config"`
+	SysConfigOrder
+}
+
+type SysConfigOrder struct {
+	IdOrder         string `search:"type:order;column:id;table:sys_config" form:"idOrder"`
+	ConfigNameOrder string `search:"type:order;column:config_name;table:sys_config" form:"configNameOrder"`
+	ConfigKeyOrder  string `search:"type:order;column:config_key;table:sys_config" form:"configKeyOrder"`
+	ConfigTypeOrder string `search:"type:order;column:config_type;table:sys_config" form:"configTypeOrder"`
+	CreatedAtOrder  string `search:"type:order;column:created_at;table:sys_config" form:"createdAtOrder"`
+}
+
+func (m *SysConfigGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type SysConfigGetToSysAppReq struct {
+	IsFrontend string `form:"isFrontend" search:"type:exact;column:is_frontend;table:sys_config"`
+}
+
+func (m *SysConfigGetToSysAppReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+// SysConfigControl 增、改使用的结构体
+type SysConfigControl struct {
+	Id          int    `uri:"Id" comment:"编码"` // 编码
+	ConfigName  string `json:"configName" comment:""`
+	ConfigKey   string `uri:"configKey" json:"configKey" comment:""`
+	ConfigValue string `json:"configValue" comment:""`
+	ConfigType  string `json:"configType" comment:""`
+	IsFrontend  string `json:"isFrontend"`
+	Remark      string `json:"remark" comment:""`
+	common.ControlBy
+}
+
+// Generate 结构体数据转化 从 SysConfigControl 至 system.SysConfig 对应的模型
+func (s *SysConfigControl) Generate(model *models.SysConfig) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.ConfigName = s.ConfigName
+	model.ConfigKey = s.ConfigKey
+	model.ConfigValue = s.ConfigValue
+	model.ConfigType = s.ConfigType
+	model.IsFrontend = s.IsFrontend
+	model.Remark = s.Remark
+
+}
+
+// GetId 获取数据对应的ID
+func (s *SysConfigControl) GetId() interface{} {
+	return s.Id
+}
+
+// GetSetSysConfigReq 增、改使用的结构体
+type GetSetSysConfigReq struct {
+	ConfigKey   string `json:"configKey" comment:""`
+	ConfigValue string `json:"configValue" comment:""`
+}
+
+// Generate 结构体数据转化 从 SysConfigControl 至 system.SysConfig 对应的模型
+func (s *GetSetSysConfigReq) Generate(model *models.SysConfig) {
+	model.ConfigValue = s.ConfigValue
+}
+
+type UpdateSetSysConfigReq map[string]string
+
+// SysConfigByKeyReq 根据Key获取配置
+type SysConfigByKeyReq struct {
+	ConfigKey string `uri:"configKey" search:"type:contains;column:config_key;table:sys_config"`
+}
+
+func (m *SysConfigByKeyReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type GetSysConfigByKEYForServiceResp struct {
+	ConfigKey   string `json:"configKey" comment:""`
+	ConfigValue string `json:"configValue" comment:""`
+}
+
+type SysConfigGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *SysConfigGetReq) GetId() interface{} {
+	return s.Id
+}
+
+type SysConfigDeleteReq struct {
+	Ids []int `json:"ids"`
+	common.ControlBy
+}
+
+func (s *SysConfigDeleteReq) GetId() interface{} {
+	return s.Ids
+}
+
+type SameSymbol struct {
+	Symbol string `json:"symbol"`
+	Number int    `json:"number"`
+}
diff --git a/app/admin/service/dto/sys_dept.go b/app/admin/service/dto/sys_dept.go
new file mode 100644
index 0000000..345a550
--- /dev/null
+++ b/app/admin/service/dto/sys_dept.go
@@ -0,0 +1,110 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	common "go-admin/common/models"
+)
+
+// SysDeptGetPageReq 列表或者搜索使用结构体
+type SysDeptGetPageReq struct {
+	DeptId         int    `form:"deptId" search:"type:exact;column:dept_id;table:sys_dept" comment:"id"`       //id
+	ParentId       int    `form:"parentId" search:"type:exact;column:parent_id;table:sys_dept" comment:"上级部门"` //上级部门
+	DeptPath       string `form:"deptPath" search:"type:exact;column:dept_path;table:sys_dept" comment:""`     //路径
+	DeptName       string `form:"deptName" search:"type:exact;column:dept_name;table:sys_dept" comment:"部门名称"` //部门名称
+	Sort           int    `form:"sort" search:"type:exact;column:sort;table:sys_dept" comment:"排序"`            //排序
+	Leader         string `form:"leader" search:"type:exact;column:leader;table:sys_dept" comment:"负责人"`       //负责人
+	Phone          string `form:"phone" search:"type:exact;column:phone;table:sys_dept" comment:"手机"`          //手机
+	Email          string `form:"email" search:"type:exact;column:email;table:sys_dept" comment:"邮箱"`          //邮箱
+	Status         string `form:"status" search:"type:exact;column:status;table:sys_dept" comment:"状态"`        //状态
+}
+
+func (m *SysDeptGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type SysDeptInsertReq struct {
+	DeptId   int    `uri:"id" comment:"编码"`                                         // 编码
+	ParentId int    `json:"parentId" comment:"上级部门" vd:"?"`                         //上级部门
+	DeptPath string `json:"deptPath" comment:""`                                    //路径
+	DeptName string `json:"deptName" comment:"部门名称" vd:"len($)>0"`                  //部门名称
+	Sort     int    `json:"sort" comment:"排序" vd:"?"`                               //排序
+	Leader   string `json:"leader" comment:"负责人" vd:"@:len($)>0; msg:'leader不能为空'"` //负责人
+	Phone    string `json:"phone" comment:"手机" vd:"?"`                              //手机
+	Email    string `json:"email" comment:"邮箱" vd:"?"`                              //邮箱
+	Status   int    `json:"status" comment:"状态" vd:"$>0"`                           //状态
+	common.ControlBy
+}
+
+func (s *SysDeptInsertReq) Generate(model *models.SysDept) {
+	if s.DeptId != 0 {
+		model.DeptId = s.DeptId
+	}
+	model.DeptName = s.DeptName
+	model.ParentId = s.ParentId
+	model.DeptPath = s.DeptPath
+	model.Sort = s.Sort
+	model.Leader = s.Leader
+	model.Phone = s.Phone
+	model.Email = s.Email
+	model.Status = s.Status
+}
+
+// GetId 获取数据对应的ID
+func (s *SysDeptInsertReq) GetId() interface{} {
+	return s.DeptId
+}
+
+type SysDeptUpdateReq struct {
+	DeptId   int    `uri:"id" comment:"编码"`                                         // 编码
+	ParentId int    `json:"parentId" comment:"上级部门" vd:"?"`                         //上级部门
+	DeptPath string `json:"deptPath" comment:""`                                    //路径
+	DeptName string `json:"deptName" comment:"部门名称" vd:"len($)>0"`                  //部门名称
+	Sort     int    `json:"sort" comment:"排序" vd:"?"`                               //排序
+	Leader   string `json:"leader" comment:"负责人" vd:"@:len($)>0; msg:'leader不能为空'"` //负责人
+	Phone    string `json:"phone" comment:"手机" vd:"?"`                              //手机
+	Email    string `json:"email" comment:"邮箱" vd:"?"`                              //邮箱
+	Status   int    `json:"status" comment:"状态" vd:"$>0"`                           //状态
+	common.ControlBy
+}
+
+// Generate 结构体数据转化 从 SysDeptControl 至 SysDept 对应的模型
+func (s *SysDeptUpdateReq) Generate(model *models.SysDept) {
+	if s.DeptId != 0 {
+		model.DeptId = s.DeptId
+	}
+	model.DeptName = s.DeptName
+	model.ParentId = s.ParentId
+	model.DeptPath = s.DeptPath
+	model.Sort = s.Sort
+	model.Leader = s.Leader
+	model.Phone = s.Phone
+	model.Email = s.Email
+	model.Status = s.Status
+}
+
+// GetId 获取数据对应的ID
+func (s *SysDeptUpdateReq) GetId() interface{} {
+	return s.DeptId
+}
+
+type SysDeptGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *SysDeptGetReq) GetId() interface{} {
+	return s.Id
+}
+
+type SysDeptDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *SysDeptDeleteReq) GetId() interface{} {
+	return s.Ids
+}
+
+type DeptLabel struct {
+	Id       int         `gorm:"-" json:"id"`
+	Label    string      `gorm:"-" json:"label"`
+	Children []DeptLabel `gorm:"-" json:"children"`
+}
diff --git a/app/admin/service/dto/sys_dict_data.go b/app/admin/service/dto/sys_dict_data.go
new file mode 100644
index 0000000..842f418
--- /dev/null
+++ b/app/admin/service/dto/sys_dict_data.go
@@ -0,0 +1,108 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type SysDictDataGetPageReq struct {
+	dto.Pagination `search:"-"`
+	Id             int    `form:"id" search:"type:exact;column:dict_code;table:sys_dict_data" comment:""`
+	DictLabel      string `form:"dictLabel" search:"type:contains;column:dict_label;table:sys_dict_data" comment:""`
+	DictValue      string `form:"dictValue" search:"type:contains;column:dict_value;table:sys_dict_data" comment:""`
+	DictType       string `form:"dictType" search:"type:contains;column:dict_type;table:sys_dict_data" comment:""`
+	Status         string `form:"status" search:"type:exact;column:status;table:sys_dict_data" comment:""`
+}
+
+func (m *SysDictDataGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type SysDictDataGetAllResp struct {
+	DictLabel string `json:"label"`
+	DictValue string `json:"value"`
+}
+
+type SysDictDataInsertReq struct {
+	Id        int    `json:"-" comment:""`
+	DictSort  int    `json:"dictSort" comment:""`
+	DictLabel string `json:"dictLabel" comment:""`
+	DictValue string `json:"dictValue" comment:""`
+	DictType  string `json:"dictType" comment:""`
+	CssClass  string `json:"cssClass" comment:""`
+	ListClass string `json:"listClass" comment:""`
+	IsDefault string `json:"isDefault" comment:""`
+	Status    int    `json:"status" comment:""`
+	Default   string `json:"default" comment:""`
+	Remark    string `json:"remark" comment:""`
+	common.ControlBy
+}
+
+func (s *SysDictDataInsertReq) Generate(model *models.SysDictData) {
+	model.DictCode = s.Id
+	model.DictSort = s.DictSort
+	model.DictLabel = s.DictLabel
+	model.DictValue = s.DictValue
+	model.DictType = s.DictType
+	model.CssClass = s.CssClass
+	model.ListClass = s.ListClass
+	model.IsDefault = s.IsDefault
+	model.Status = s.Status
+	model.Default = s.Default
+	model.Remark = s.Remark
+}
+
+func (s *SysDictDataInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type SysDictDataUpdateReq struct {
+	Id        int    `uri:"dictCode" comment:""`
+	DictSort  int    `json:"dictSort" comment:""`
+	DictLabel string `json:"dictLabel" comment:""`
+	DictValue string `json:"dictValue" comment:""`
+	DictType  string `json:"dictType" comment:""`
+	CssClass  string `json:"cssClass" comment:""`
+	ListClass string `json:"listClass" comment:""`
+	IsDefault string `json:"isDefault" comment:""`
+	Status    int    `json:"status" comment:""`
+	Default   string `json:"default" comment:""`
+	Remark    string `json:"remark" comment:""`
+	common.ControlBy
+}
+
+func (s *SysDictDataUpdateReq) Generate(model *models.SysDictData) {
+	model.DictCode = s.Id
+	model.DictSort = s.DictSort
+	model.DictLabel = s.DictLabel
+	model.DictValue = s.DictValue
+	model.DictType = s.DictType
+	model.CssClass = s.CssClass
+	model.ListClass = s.ListClass
+	model.IsDefault = s.IsDefault
+	model.Status = s.Status
+	model.Default = s.Default
+	model.Remark = s.Remark
+}
+
+func (s *SysDictDataUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+type SysDictDataGetReq struct {
+	Id int `uri:"dictCode"`
+}
+
+func (s *SysDictDataGetReq) GetId() interface{} {
+	return s.Id
+}
+
+type SysDictDataDeleteReq struct {
+	Ids              []int `json:"ids"`
+	common.ControlBy `json:"-"`
+}
+
+func (s *SysDictDataDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/sys_dict_type.go b/app/admin/service/dto/sys_dict_type.go
new file mode 100644
index 0000000..db66432
--- /dev/null
+++ b/app/admin/service/dto/sys_dict_type.go
@@ -0,0 +1,89 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type SysDictTypeGetPageReq struct {
+	dto.Pagination `search:"-"`
+	DictId         []int  `form:"dictId" search:"type:in;column:dict_id;table:sys_dict_type"`
+	DictName       string `form:"dictName" search:"type:icontains;column:dict_name;table:sys_dict_type"`
+	DictType       string `form:"dictType" search:"type:icontains;column:dict_type;table:sys_dict_type"`
+	Status         int    `form:"status" search:"type:exact;column:status;table:sys_dict_type"`
+}
+
+type SysDictTypeOrder struct {
+	DictIdOrder string `search:"type:order;column:dict_id;table:sys_dict_type" form:"dictIdOrder"`
+}
+
+func (m *SysDictTypeGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type SysDictTypeInsertReq struct {
+	Id       int    `uri:"id"`
+	DictName string `json:"dictName"`
+	DictType string `json:"dictType"`
+	Status   int    `json:"status"`
+	Remark   string `json:"remark"`
+	common.ControlBy
+}
+
+func (s *SysDictTypeInsertReq) Generate(model *models.SysDictType) {
+	if s.Id != 0 {
+		model.ID = s.Id
+	}
+	model.DictName = s.DictName
+	model.DictType = s.DictType
+	model.Status = s.Status
+	model.Remark = s.Remark
+
+}
+
+func (s *SysDictTypeInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type SysDictTypeUpdateReq struct {
+	Id       int    `uri:"id"`
+	DictName string `json:"dictName"`
+	DictType string `json:"dictType"`
+	Status   int    `json:"status"`
+	Remark   string `json:"remark"`
+	common.ControlBy
+}
+
+func (s *SysDictTypeUpdateReq) Generate(model *models.SysDictType) {
+	if s.Id != 0 {
+		model.ID = s.Id
+	}
+	model.DictName = s.DictName
+	model.DictType = s.DictType
+	model.Status = s.Status
+	model.Remark = s.Remark
+
+}
+
+func (s *SysDictTypeUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+type SysDictTypeGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *SysDictTypeGetReq) GetId() interface{} {
+	return s.Id
+}
+
+type SysDictTypeDeleteReq struct {
+	Ids []int `json:"ids"`
+	common.ControlBy
+}
+
+func (s *SysDictTypeDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/sys_login_log.go b/app/admin/service/dto/sys_login_log.go
new file mode 100644
index 0000000..42a6e45
--- /dev/null
+++ b/app/admin/service/dto/sys_login_log.go
@@ -0,0 +1,57 @@
+package dto
+
+import (
+	"time"
+
+	"go-admin/common/dto"
+)
+
+type SysLoginLogGetPageReq struct {
+	dto.Pagination `search:"-"`
+	Username       string `form:"username" search:"type:exact;column:username;table:sys_login_log" comment:"用户名"`
+	Status         string `form:"status" search:"type:exact;column:status;table:sys_login_log" comment:"状态"`
+	Ipaddr         string `form:"ipaddr" search:"type:exact;column:ipaddr;table:sys_login_log" comment:"ip地址"`
+	LoginLocation  string `form:"loginLocation" search:"type:exact;column:login_location;table:sys_login_log" comment:"归属地"`
+	BeginTime      string `form:"beginTime" search:"type:gte;column:ctime;table:sys_login_log" comment:"创建时间"`
+	EndTime        string `form:"endTime" search:"type:lte;column:ctime;table:sys_login_log" comment:"创建时间"`
+	SysLoginLogOrder
+}
+
+type SysLoginLogOrder struct {
+	CreatedAtOrder string `search:"type:order;column:created_at;table:sys_login_log" form:"createdAtOrder"`
+}
+
+func (m *SysLoginLogGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type SysLoginLogControl struct {
+	ID            int       `uri:"Id" comment:"主键"` // 主键
+	Username      string    `json:"username" comment:"用户名"`
+	Status        string    `json:"status" comment:"状态"`
+	Ipaddr        string    `json:"ipaddr" comment:"ip地址"`
+	LoginLocation string    `json:"loginLocation" comment:"归属地"`
+	Browser       string    `json:"browser" comment:"浏览器"`
+	Os            string    `json:"os" comment:"系统"`
+	Platform      string    `json:"platform" comment:"固件"`
+	LoginTime     time.Time `json:"loginTime" comment:"登录时间"`
+	Remark        string    `json:"remark" comment:"备注"`
+	Msg           string    `json:"msg" comment:"信息"`
+}
+
+type SysLoginLogGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *SysLoginLogGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// SysLoginLogDeleteReq 功能删除请求参数
+type SysLoginLogDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *SysLoginLogDeleteReq) GetId() interface{} {
+	return s.Ids
+}
\ No newline at end of file
diff --git a/app/admin/service/dto/sys_menu.go b/app/admin/service/dto/sys_menu.go
new file mode 100644
index 0000000..67f4674
--- /dev/null
+++ b/app/admin/service/dto/sys_menu.go
@@ -0,0 +1,159 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	common "go-admin/common/models"
+
+	"go-admin/common/dto"
+)
+
+// SysMenuGetPageReq 列表或者搜索使用结构体
+type SysMenuGetPageReq struct {
+	dto.Pagination `search:"-"`
+	Title          string `form:"title" search:"type:contains;column:title;table:sys_menu" comment:"菜单名称"`  // 菜单名称
+	Visible        int    `form:"visible" search:"type:exact;column:visible;table:sys_menu" comment:"显示状态"` // 显示状态
+}
+
+func (m *SysMenuGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type SysMenuInsertReq struct {
+	MenuId     int             `uri:"id" comment:"编码"`            // 编码
+	MenuName   string          `form:"menuName" comment:"菜单name"` //菜单name
+	Title      string          `form:"title" comment:"显示名称"`      //显示名称
+	Icon       string          `form:"icon" comment:"图标"`         //图标
+	Path       string          `form:"path" comment:"路径"`         //路径
+	Paths      string          `form:"paths" comment:"id路径"`      //id路径
+	MenuType   string          `form:"menuType" comment:"菜单类型"`   //菜单类型
+	SysApi     []models.SysApi `form:"sysApi"`
+	Apis       []int           `form:"apis"`
+	Action     string          `form:"action" comment:"请求方式"`      //请求方式
+	Permission string          `form:"permission" comment:"权限编码"`  //权限编码
+	ParentId   int             `form:"parentId" comment:"上级菜单"`    //上级菜单
+	NoCache    bool            `form:"noCache" comment:"是否缓存"`     //是否缓存
+	Breadcrumb string          `form:"breadcrumb" comment:"是否面包屑"` //是否面包屑
+	Component  string          `form:"component" comment:"组件"`     //组件
+	Sort       int             `form:"sort" comment:"排序"`          //排序
+	Visible    string          `form:"visible" comment:"是否显示"`     //是否显示
+	IsFrame    string          `form:"isFrame" comment:"是否frame"`  //是否frame
+	common.ControlBy
+}
+
+func (s *SysMenuInsertReq) Generate(model *models.SysMenu) {
+	if s.MenuId != 0 {
+		model.MenuId = s.MenuId
+	}
+	model.MenuName = s.MenuName
+	model.Title = s.Title
+	model.Icon = s.Icon
+	model.Path = s.Path
+	model.Paths = s.Paths
+	model.MenuType = s.MenuType
+	model.Action = s.Action
+	model.SysApi = s.SysApi
+	model.Permission = s.Permission
+	model.ParentId = s.ParentId
+	model.NoCache = s.NoCache
+	model.Breadcrumb = s.Breadcrumb
+	model.Component = s.Component
+	model.Sort = s.Sort
+	model.Visible = s.Visible
+	model.IsFrame = s.IsFrame
+	if s.CreateBy != 0 {
+		model.CreateBy = s.CreateBy
+	}
+	if s.UpdateBy != 0 {
+		model.UpdateBy = s.UpdateBy
+	}
+}
+
+func (s *SysMenuInsertReq) GetId() interface{} {
+	return s.MenuId
+}
+
+type SysMenuUpdateReq struct {
+	MenuId     int             `uri:"id" comment:"编码"`            // 编码
+	MenuName   string          `form:"menuName" comment:"菜单name"` //菜单name
+	Title      string          `form:"title" comment:"显示名称"`      //显示名称
+	Icon       string          `form:"icon" comment:"图标"`         //图标
+	Path       string          `form:"path" comment:"路径"`         //路径
+	Paths      string          `form:"paths" comment:"id路径"`      //id路径
+	MenuType   string          `form:"menuType" comment:"菜单类型"`   //菜单类型
+	SysApi     []models.SysApi `form:"sysApi"`
+	Apis       []int           `form:"apis"`
+	Action     string          `form:"action" comment:"请求方式"`      //请求方式
+	Permission string          `form:"permission" comment:"权限编码"`  //权限编码
+	ParentId   int             `form:"parentId" comment:"上级菜单"`    //上级菜单
+	NoCache    bool            `form:"noCache" comment:"是否缓存"`     //是否缓存
+	Breadcrumb string          `form:"breadcrumb" comment:"是否面包屑"` //是否面包屑
+	Component  string          `form:"component" comment:"组件"`     //组件
+	Sort       int             `form:"sort" comment:"排序"`          //排序
+	Visible    string          `form:"visible" comment:"是否显示"`     //是否显示
+	IsFrame    string          `form:"isFrame" comment:"是否frame"`  //是否frame
+	common.ControlBy
+}
+
+func (s *SysMenuUpdateReq) Generate(model *models.SysMenu) {
+	if s.MenuId != 0 {
+		model.MenuId = s.MenuId
+	}
+	model.MenuName = s.MenuName
+	model.Title = s.Title
+	model.Icon = s.Icon
+	model.Path = s.Path
+	model.Paths = s.Paths
+	model.MenuType = s.MenuType
+	model.Action = s.Action
+	model.SysApi = s.SysApi
+	model.Permission = s.Permission
+	model.ParentId = s.ParentId
+	model.NoCache = s.NoCache
+	model.Breadcrumb = s.Breadcrumb
+	model.Component = s.Component
+	model.Sort = s.Sort
+	model.Visible = s.Visible
+	model.IsFrame = s.IsFrame
+	if s.CreateBy != 0 {
+		model.CreateBy = s.CreateBy
+	}
+	if s.UpdateBy != 0 {
+		model.UpdateBy = s.UpdateBy
+	}
+}
+
+func (s *SysMenuUpdateReq) GetId() interface{} {
+	return s.MenuId
+}
+
+type SysMenuGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *SysMenuGetReq) GetId() interface{} {
+	return s.Id
+}
+
+type SysMenuDeleteReq struct {
+	Ids []int `json:"ids"`
+	common.ControlBy
+}
+
+func (s *SysMenuDeleteReq) GetId() interface{} {
+	return s.Ids
+}
+
+type MenuLabel struct {
+	Id       int         `json:"id,omitempty" gorm:"-"`
+	Label    string      `json:"label,omitempty" gorm:"-"`
+	Children []MenuLabel `json:"children,omitempty" gorm:"-"`
+}
+
+type MenuRole struct {
+	models.SysMenu
+	IsSelect bool `json:"is_select" gorm:"-"`
+}
+
+type SelectRole struct {
+	RoleId int `uri:"roleId"`
+}
diff --git a/app/admin/service/dto/sys_opera_log.go b/app/admin/service/dto/sys_opera_log.go
new file mode 100644
index 0000000..5df36eb
--- /dev/null
+++ b/app/admin/service/dto/sys_opera_log.go
@@ -0,0 +1,102 @@
+package dto
+
+import (
+	"time"
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+const (
+	OperaStatusEnabel  = "1" // 状态-正常
+	OperaStatusDisable = "2" // 状态-关闭
+)
+
+type SysOperaLogGetPageReq struct {
+	dto.Pagination `search:"-"`
+	Title          string `form:"title" search:"type:contains;column:title;table:sys_opera_log" comment:"操作模块"`
+	Method         string `form:"method" search:"type:contains;column:method;table:sys_opera_log" comment:"函数"`
+	RequestMethod  string `form:"requestMethod" search:"type:contains;column:request_method;table:sys_opera_log" comment:"请求方式: GET POST PUT DELETE"`
+	OperUrl        string `form:"operUrl" search:"type:contains;column:oper_url;table:sys_opera_log" comment:"访问地址"`
+	OperIp         string `form:"operIp" search:"type:exact;column:oper_ip;table:sys_opera_log" comment:"客户端ip"`
+	Status         int    `form:"status" search:"type:exact;column:status;table:sys_opera_log" comment:"状态 1:正常 2:关闭"`
+	BeginTime      string `form:"beginTime" search:"type:gte;column:created_at;table:sys_opera_log" comment:"创建时间"`
+	EndTime        string `form:"endTime" search:"type:lte;column:created_at;table:sys_opera_log" comment:"更新时间"`
+	SysOperaLogOrder
+}
+
+type SysOperaLogOrder struct {
+	CreatedAtOrder string `search:"type:order;column:created_at;table:sys_opera_log" form:"createdAtOrder"`
+}
+
+func (m *SysOperaLogGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type SysOperaLogControl struct {
+	ID            int       `uri:"Id" comment:"编码"` // 编码
+	Title         string    `json:"title" comment:"操作模块"`
+	BusinessType  string    `json:"businessType" comment:"操作类型"`
+	BusinessTypes string    `json:"businessTypes" comment:""`
+	Method        string    `json:"method" comment:"函数"`
+	RequestMethod string    `json:"requestMethod" comment:"请求方式"`
+	OperatorType  string    `json:"operatorType" comment:"操作类型"`
+	OperName      string    `json:"operName" comment:"操作者"`
+	DeptName      string    `json:"deptName" comment:"部门名称"`
+	OperUrl       string    `json:"operUrl" comment:"访问地址"`
+	OperIp        string    `json:"operIp" comment:"客户端ip"`
+	OperLocation  string    `json:"operLocation" comment:"访问位置"`
+	OperParam     string    `json:"operParam" comment:"请求参数"`
+	Status        string    `json:"status" comment:"操作状态"`
+	OperTime      time.Time `json:"operTime" comment:"操作时间"`
+	JsonResult    string    `json:"jsonResult" comment:"返回数据"`
+	Remark        string    `json:"remark" comment:"备注"`
+	LatencyTime   string    `json:"latencyTime" comment:"耗时"`
+	UserAgent     string    `json:"userAgent" comment:"ua"`
+}
+
+func (s *SysOperaLogControl) Generate() (*models.SysOperaLog, error) {
+	return &models.SysOperaLog{
+		Model:         common.Model{Id: s.ID},
+		Title:         s.Title,
+		BusinessType:  s.BusinessType,
+		BusinessTypes: s.BusinessTypes,
+		Method:        s.Method,
+		RequestMethod: s.RequestMethod,
+		OperatorType:  s.OperatorType,
+		OperName:      s.OperName,
+		DeptName:      s.DeptName,
+		OperUrl:       s.OperUrl,
+		OperIp:        s.OperIp,
+		OperLocation:  s.OperLocation,
+		OperParam:     s.OperParam,
+		Status:        s.Status,
+		OperTime:      s.OperTime,
+		JsonResult:    s.JsonResult,
+		Remark:        s.Remark,
+		LatencyTime:   s.LatencyTime,
+		UserAgent:     s.UserAgent,
+	}, nil
+}
+
+func (s *SysOperaLogControl) GetId() interface{} {
+	return s.ID
+}
+
+type SysOperaLogGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *SysOperaLogGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// SysOperaLogDeleteReq 功能删除请求参数
+type SysOperaLogDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *SysOperaLogDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/sys_post.go b/app/admin/service/dto/sys_post.go
new file mode 100644
index 0000000..2b432a7
--- /dev/null
+++ b/app/admin/service/dto/sys_post.go
@@ -0,0 +1,111 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	common "go-admin/common/models"
+
+	"go-admin/common/dto"
+)
+
+// SysPostPageReq 列表或者搜索使用结构体
+type SysPostPageReq struct {
+	dto.Pagination `search:"-"`
+	PostId         int    `form:"postId" search:"type:exact;column:post_id;table:sys_post" comment:"id"`        // id
+	PostName       string `form:"postName" search:"type:contains;column:post_name;table:sys_post" comment:"名称"` // 名称
+	PostCode       string `form:"postCode" search:"type:contains;column:post_code;table:sys_post" comment:"编码"` // 编码
+	Sort           int    `form:"sort" search:"type:exact;column:sort;table:sys_post" comment:"排序"`             // 排序
+	Status         int    `form:"status" search:"type:exact;column:status;table:sys_post" comment:"状态"`         // 状态
+	Remark         string `form:"remark" search:"type:exact;column:remark;table:sys_post" comment:"备注"`         // 备注
+}
+
+func (m *SysPostPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+// SysPostInsertReq 增使用的结构体
+type SysPostInsertReq struct {
+	PostId   int    `uri:"id"  comment:"id"`
+	PostName string `form:"postName"  comment:"名称"`
+	PostCode string `form:"postCode" comment:"编码"`
+	Sort     int    `form:"sort" comment:"排序"`
+	Status   int    `form:"status"   comment:"状态"`
+	Remark   string `form:"remark"   comment:"备注"`
+	common.ControlBy
+}
+
+func (s *SysPostInsertReq) Generate(model *models.SysPost) {
+	model.PostName = s.PostName
+	model.PostCode = s.PostCode
+	model.Sort = s.Sort
+	model.Status = s.Status
+	model.Remark = s.Remark
+	if s.ControlBy.UpdateBy != 0 {
+		model.UpdateBy = s.UpdateBy
+	}
+	if s.ControlBy.CreateBy != 0 {
+		model.CreateBy = s.CreateBy
+	}
+}
+
+// GetId 获取数据对应的ID
+func (s *SysPostInsertReq) GetId() interface{} {
+	return s.PostId
+}
+
+// SysPostUpdateReq 改使用的结构体
+type SysPostUpdateReq struct {
+	PostId   int    `uri:"id"  comment:"id"`
+	PostName string `form:"postName"  comment:"名称"`
+	PostCode string `form:"postCode" comment:"编码"`
+	Sort     int    `form:"sort" comment:"排序"`
+	Status   int    `form:"status"   comment:"状态"`
+	Remark   string `form:"remark"   comment:"备注"`
+	common.ControlBy
+}
+
+func (s *SysPostUpdateReq) Generate(model *models.SysPost) {
+	model.PostId = s.PostId
+	model.PostName = s.PostName
+	model.PostCode = s.PostCode
+	model.Sort = s.Sort
+	model.Status = s.Status
+	model.Remark = s.Remark
+	if s.ControlBy.UpdateBy != 0 {
+		model.UpdateBy = s.UpdateBy
+	}
+	if s.ControlBy.CreateBy != 0 {
+		model.CreateBy = s.CreateBy
+	}
+}
+
+func (s *SysPostUpdateReq) GetId() interface{} {
+	return s.PostId
+}
+
+// SysPostGetReq 获取单个的结构体
+type SysPostGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *SysPostGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// SysPostDeleteReq 删除的结构体
+type SysPostDeleteReq struct {
+	Ids []int `json:"ids"`
+	common.ControlBy
+}
+
+func (s *SysPostDeleteReq) Generate(model *models.SysPost) {
+	if s.ControlBy.UpdateBy != 0 {
+		model.UpdateBy = s.UpdateBy
+	}
+	if s.ControlBy.CreateBy != 0 {
+		model.CreateBy = s.CreateBy
+	}
+}
+
+func (s *SysPostDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/dto/sys_role.go b/app/admin/service/dto/sys_role.go
new file mode 100644
index 0000000..789b85e
--- /dev/null
+++ b/app/admin/service/dto/sys_role.go
@@ -0,0 +1,164 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+	common "go-admin/common/models"
+
+	"go-admin/common/dto"
+)
+
+type SysRoleGetPageReq struct {
+	dto.Pagination `search:"-"`
+
+	RoleId    int    `form:"roleId" search:"type:exact;column:role_id;table:sys_role" comment:"角色编码"`     // 角色编码
+	RoleName  string `form:"roleName" search:"type:exact;column:role_name;table:sys_role" comment:"角色名称"` // 角色名称
+	Status    string `form:"status" search:"type:exact;column:status;table:sys_role" comment:"状态"`        // 状态
+	RoleKey   string `form:"roleKey" search:"type:exact;column:role_key;table:sys_role" comment:"角色代码"`   // 角色代码
+	RoleSort  int    `form:"roleSort" search:"type:exact;column:role_sort;table:sys_role" comment:"角色排序"` // 角色排序
+	Flag      string `form:"flag" search:"type:exact;column:flag;table:sys_role" comment:"标记"`            // 标记
+	Remark    string `form:"remark" search:"type:exact;column:remark;table:sys_role" comment:"备注"`        // 备注
+	Admin     bool   `form:"admin" search:"type:exact;column:admin;table:sys_role" comment:"是否管理员"`
+	DataScope string `form:"dataScope" search:"type:exact;column:data_scope;table:sys_role" comment:"是否管理员"`
+}
+
+type SysRoleOrder struct {
+	RoleIdOrder    string `search:"type:order;column:role_id;table:sys_role" form:"roleIdOrder"`
+	RoleNameOrder  string `search:"type:order;column:role_name;table:sys_role" form:"roleNameOrder"`
+	RoleSortOrder  string `search:"type:order;column:role_sort;table:sys_role" form:"usernameOrder"`
+	StatusOrder    string `search:"type:order;column:status;table:sys_role" form:"statusOrder"`
+	CreatedAtOrder string `search:"type:order;column:created_at;table:sys_role" form:"createdAtOrder"`
+}
+
+func (m *SysRoleGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type SysRoleInsertReq struct {
+	RoleId    int              `uri:"id" comment:"角色编码"`        // 角色编码
+	RoleName  string           `form:"roleName" comment:"角色名称"` // 角色名称
+	Status    string           `form:"status" comment:"状态"`     // 状态 1禁用 2正常
+	RoleKey   string           `form:"roleKey" comment:"角色代码"`  // 角色代码
+	RoleSort  int              `form:"roleSort" comment:"角色排序"` // 角色排序
+	Flag      string           `form:"flag" comment:"标记"`       // 标记
+	Remark    string           `form:"remark" comment:"备注"`     // 备注
+	Admin     bool             `form:"admin" comment:"是否管理员"`
+	DataScope string           `form:"dataScope"`
+	SysMenu   []models.SysMenu `form:"sysMenu"`
+	MenuIds   []int            `form:"menuIds"`
+	SysDept   []models.SysDept `form:"sysDept"`
+	DeptIds   []int            `form:"deptIds"`
+	common.ControlBy
+}
+
+func (s *SysRoleInsertReq) Generate(model *models.SysRole) {
+	if s.RoleId != 0 {
+		model.RoleId = s.RoleId
+	}
+	model.RoleName = s.RoleName
+	model.Status = s.Status
+	model.RoleKey = s.RoleKey
+	model.RoleSort = s.RoleSort
+	model.Flag = s.Flag
+	model.Remark = s.Remark
+	model.Admin = s.Admin
+	model.DataScope = s.DataScope
+	model.SysMenu = &s.SysMenu
+	model.SysDept = s.SysDept
+}
+
+func (s *SysRoleInsertReq) GetId() interface{} {
+	return s.RoleId
+}
+
+type SysRoleUpdateReq struct {
+	RoleId    int              `uri:"id" comment:"角色编码"`        // 角色编码
+	RoleName  string           `form:"roleName" comment:"角色名称"` // 角色名称
+	Status    string           `form:"status" comment:"状态"`     // 状态
+	RoleKey   string           `form:"roleKey" comment:"角色代码"`  // 角色代码
+	RoleSort  int              `form:"roleSort" comment:"角色排序"` // 角色排序
+	Flag      string           `form:"flag" comment:"标记"`       // 标记
+	Remark    string           `form:"remark" comment:"备注"`     // 备注
+	Admin     bool             `form:"admin" comment:"是否管理员"`
+	DataScope string           `form:"dataScope"`
+	SysMenu   []models.SysMenu `form:"sysMenu"`
+	MenuIds   []int            `form:"menuIds"`
+	SysDept   []models.SysDept `form:"sysDept"`
+	DeptIds   []int            `form:"deptIds"`
+	common.ControlBy
+}
+
+func (s *SysRoleUpdateReq) Generate(model *models.SysRole) {
+	if s.RoleId != 0 {
+		model.RoleId = s.RoleId
+	}
+	model.RoleName = s.RoleName
+	model.Status = s.Status
+	model.RoleKey = s.RoleKey
+	model.RoleSort = s.RoleSort
+	model.Flag = s.Flag
+	model.Remark = s.Remark
+	model.Admin = s.Admin
+	model.DataScope = s.DataScope
+	model.SysMenu = &s.SysMenu
+	model.SysDept = s.SysDept
+}
+
+func (s *SysRoleUpdateReq) GetId() interface{} {
+	return s.RoleId
+}
+
+type UpdateStatusReq struct {
+	RoleId int    `form:"roleId" comment:"角色编码"` // 角色编码
+	Status string `form:"status" comment:"状态"`   // 状态
+	common.ControlBy
+}
+
+func (s *UpdateStatusReq) Generate(model *models.SysRole) {
+	if s.RoleId != 0 {
+		model.RoleId = s.RoleId
+	}
+	model.Status = s.Status
+}
+
+func (s *UpdateStatusReq) GetId() interface{} {
+	return s.RoleId
+}
+
+type SysRoleByName struct {
+	RoleName string `form:"role"` // 角色编码
+}
+
+type SysRoleGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *SysRoleGetReq) GetId() interface{} {
+	return s.Id
+}
+
+type SysRoleDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *SysRoleDeleteReq) GetId() interface{} {
+	return s.Ids
+}
+
+// RoleDataScopeReq 角色数据权限修改
+type RoleDataScopeReq struct {
+	RoleId    int    `json:"roleId" binding:"required"`
+	DataScope string `json:"dataScope" binding:"required"`
+	DeptIds   []int  `json:"deptIds"`
+}
+
+func (s *RoleDataScopeReq) Generate(model *models.SysRole) {
+	if s.RoleId != 0 {
+		model.RoleId = s.RoleId
+	}
+	model.DataScope = s.DataScope
+	model.DeptIds = s.DeptIds
+}
+
+type DeptIdList struct {
+	DeptId int `json:"DeptId"`
+}
diff --git a/app/admin/service/dto/sys_user.go b/app/admin/service/dto/sys_user.go
new file mode 100644
index 0000000..b1de094
--- /dev/null
+++ b/app/admin/service/dto/sys_user.go
@@ -0,0 +1,189 @@
+package dto
+
+import (
+	"go-admin/app/admin/models"
+
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type SysUserGetPageReq struct {
+	dto.Pagination `search:"-"`
+	UserId         int    `form:"userId" search:"type:exact;column:user_id;table:sys_user" comment:"用户ID"`
+	Username       string `form:"username" search:"type:contains;column:username;table:sys_user" comment:"用户名"`
+	NickName       string `form:"nickName" search:"type:contains;column:nick_name;table:sys_user" comment:"昵称"`
+	Phone          string `form:"phone" search:"type:contains;column:phone;table:sys_user" comment:"手机号"`
+	RoleId         string `form:"roleId" search:"type:exact;column:role_id;table:sys_user" comment:"角色ID"`
+	Sex            string `form:"sex" search:"type:exact;column:sex;table:sys_user" comment:"性别"`
+	Email          string `form:"email" search:"type:contains;column:email;table:sys_user" comment:"邮箱"`
+	PostId         string `form:"postId" search:"type:exact;column:post_id;table:sys_user" comment:"岗位"`
+	Status         string `form:"status" search:"type:exact;column:status;table:sys_user" comment:"状态"`
+	DeptJoin       `search:"type:left;on:dept_id:dept_id;table:sys_user;join:sys_dept"`
+	SysUserOrder
+}
+
+type SysUserOrder struct {
+	UserIdOrder    string `search:"type:order;column:user_id;table:sys_user" form:"userIdOrder"`
+	UsernameOrder  string `search:"type:order;column:username;table:sys_user" form:"usernameOrder"`
+	StatusOrder    string `search:"type:order;column:status;table:sys_user" form:"statusOrder"`
+	CreatedAtOrder string `search:"type:order;column:created_at;table:sys_user" form:"createdAtOrder"`
+}
+
+type DeptJoin struct {
+	DeptId string `search:"type:contains;column:dept_path;table:sys_dept" form:"deptId"`
+}
+
+func (m *SysUserGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type ResetSysUserPwdReq struct {
+	UserId   int    `json:"userId" comment:"用户ID" vd:"$>0"` // 用户ID
+	Password string `json:"password" comment:"密码" vd:"len($)>0"`
+	common.ControlBy
+}
+
+func (s *ResetSysUserPwdReq) GetId() interface{} {
+	return s.UserId
+}
+
+func (s *ResetSysUserPwdReq) Generate(model *models.SysUser) {
+	if s.UserId != 0 {
+		model.UserId = s.UserId
+	}
+	model.Password = s.Password
+}
+
+type UpdateSysUserAvatarReq struct {
+	UserId int    `json:"userId" comment:"用户ID" vd:"len($)>0"` // 用户ID
+	Avatar string `json:"avatar" comment:"头像" vd:"len($)>0"`
+	common.ControlBy
+}
+
+func (s *UpdateSysUserAvatarReq) GetId() interface{} {
+	return s.UserId
+}
+
+func (s *UpdateSysUserAvatarReq) Generate(model *models.SysUser) {
+	if s.UserId != 0 {
+		model.UserId = s.UserId
+	}
+	model.Avatar = s.Avatar
+}
+
+type UpdateSysUserStatusReq struct {
+	UserId int    `json:"userId" comment:"用户ID" vd:"$>0"` // 用户ID
+	Status string `json:"status" comment:"状态" vd:"len($)>0"`
+	common.ControlBy
+}
+
+func (s *UpdateSysUserStatusReq) GetId() interface{} {
+	return s.UserId
+}
+
+func (s *UpdateSysUserStatusReq) Generate(model *models.SysUser) {
+	if s.UserId != 0 {
+		model.UserId = s.UserId
+	}
+	model.Status = s.Status
+}
+
+type SysUserInsertReq struct {
+	UserId   int    `json:"userId" comment:"用户ID"` // 用户ID
+	Username string `json:"username" comment:"用户名" vd:"len($)>0"`
+	Password string `json:"password" comment:"密码"`
+	NickName string `json:"nickName" comment:"昵称" vd:"len($)>0"`
+	Phone    string `json:"phone" comment:"手机号" vd:"len($)>0"`
+	RoleId   int    `json:"roleId" comment:"角色ID"`
+	Avatar   string `json:"avatar" comment:"头像"`
+	Sex      string `json:"sex" comment:"性别"`
+	Email    string `json:"email" comment:"邮箱" vd:"len($)>0,email"`
+	DeptId   int    `json:"deptId" comment:"部门" vd:"$>0"`
+	PostId   int    `json:"postId" comment:"岗位"`
+	Remark   string `json:"remark" comment:"备注"`
+	Status   string `json:"status" comment:"状态" vd:"len($)>0" default:"1"`
+	common.ControlBy
+}
+
+func (s *SysUserInsertReq) Generate(model *models.SysUser) {
+	if s.UserId != 0 {
+		model.UserId = s.UserId
+	}
+	model.Username = s.Username
+	model.Password = s.Password
+	model.NickName = s.NickName
+	model.Phone = s.Phone
+	model.RoleId = s.RoleId
+	model.Avatar = s.Avatar
+	model.Sex = s.Sex
+	model.Email = s.Email
+	model.DeptId = s.DeptId
+	model.PostId = s.PostId
+	model.Remark = s.Remark
+	model.Status = s.Status
+	model.CreateBy = s.CreateBy
+}
+
+func (s *SysUserInsertReq) GetId() interface{} {
+	return s.UserId
+}
+
+type SysUserUpdateReq struct {
+	UserId   int    `json:"userId" comment:"用户ID"` // 用户ID
+	Username string `json:"username" comment:"用户名" vd:"len($)>0"`
+	NickName string `json:"nickName" comment:"昵称" vd:"len($)>0"`
+	Phone    string `json:"phone" comment:"手机号" vd:"len($)>0"`
+	RoleId   int    `json:"roleId" comment:"角色ID"`
+	Avatar   string `json:"avatar" comment:"头像"`
+	Sex      string `json:"sex" comment:"性别"`
+	Email    string `json:"email" comment:"邮箱" vd:"len($)>0,email"`
+	DeptId   int    `json:"deptId" comment:"部门" vd:"$>0"`
+	PostId   int    `json:"postId" comment:"岗位"`
+	Remark   string `json:"remark" comment:"备注"`
+	Status   string `json:"status" comment:"状态" default:"1"`
+	common.ControlBy
+}
+
+func (s *SysUserUpdateReq) Generate(model *models.SysUser) {
+	if s.UserId != 0 {
+		model.UserId = s.UserId
+	}
+	model.Username = s.Username
+	model.NickName = s.NickName
+	model.Phone = s.Phone
+	model.RoleId = s.RoleId
+	model.Avatar = s.Avatar
+	model.Sex = s.Sex
+	model.Email = s.Email
+	model.DeptId = s.DeptId
+	model.PostId = s.PostId
+	model.Remark = s.Remark
+	model.Status = s.Status
+}
+
+func (s *SysUserUpdateReq) GetId() interface{} {
+	return s.UserId
+}
+
+type SysUserById struct {
+	dto.ObjectById
+	common.ControlBy
+}
+
+func (s *SysUserById) GetId() interface{} {
+	if len(s.Ids) > 0 {
+		s.Ids = append(s.Ids, s.Id)
+		return s.Ids
+	}
+	return s.Id
+}
+
+func (s *SysUserById) GenerateM() (common.ActiveRecord, error) {
+	return &models.SysUser{}, nil
+}
+
+// PassWord 密码
+type PassWord struct {
+	NewPassword string `json:"newPassword" vd:"len($)>0"`
+	OldPassword string `json:"oldPassword" vd:"len($)>0"`
+}
diff --git a/app/admin/service/dto/vts_recharge.go b/app/admin/service/dto/vts_recharge.go
new file mode 100644
index 0000000..55eaa07
--- /dev/null
+++ b/app/admin/service/dto/vts_recharge.go
@@ -0,0 +1,176 @@
+package dto
+
+import (
+	"github.com/shopspring/decimal"
+	"time"
+
+	"go-admin/app/admin/models"
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type VtsRechargeGetPageReq struct {
+	dto.Pagination `search:"-"`
+	CoinCode       string `form:"coinCode"  search:"type:exact;column:coin_code;table:vts_recharge" comment:"币种"`
+	OrderNo        string `form:"orderNo"  search:"type:exact;column:order_no;table:vts_recharge" comment:"订单号"`
+	AdUserId       int64  `form:"adUserId"  search:"type:exact;column:ad_user_id;table:vts_recharge" comment:"用户id"`
+	VtsRechargeOrder
+}
+
+type VtsRechargeOrder struct {
+	Id              string `form:"idOrder"  search:"type:order;column:id;table:vts_recharge"`
+	CoinCode        string `form:"coinCodeOrder"  search:"type:order;column:coin_code;table:vts_recharge"`
+	TranType        string `form:"tranTypeOrder"  search:"type:order;column:tran_type;table:vts_recharge"`
+	OrderNo         string `form:"orderNoOrder"  search:"type:order;column:order_no;table:vts_recharge"`
+	AdUserId        string `form:"adUserIdOrder"  search:"type:order;column:ad_user_id;table:vts_recharge"`
+	Amount          string `form:"amountOrder"  search:"type:order;column:amount;table:vts_recharge"`
+	PriceCurrency   string `form:"priceCurrencyOrder"  search:"type:order;column:price_currency;table:vts_recharge"`
+	ReceiveAmount   string `form:"receiveAmountOrder"  search:"type:order;column:receive_amount;table:vts_recharge"`
+	PayAmount       string `form:"payAmountOrder"  search:"type:order;column:pay_amount;table:vts_recharge"`
+	PayCurrency     string `form:"payCurrencyOrder"  search:"type:order;column:pay_currency;table:vts_recharge"`
+	UnderpaidAmount string `form:"underpaidAmountOrder"  search:"type:order;column:underpaid_amount;table:vts_recharge"`
+	OverpaidAmount  string `form:"overpaidAmountOrder"  search:"type:order;column:overpaid_amount;table:vts_recharge"`
+	IsRefundable    string `form:"isRefundableOrder"  search:"type:order;column:is_refundable;table:vts_recharge"`
+	WalletCreateAt  string `form:"walletCreateAtOrder"  search:"type:order;column:wallet_create_at;table:vts_recharge"`
+	WalletId        string `form:"walletIdOrder"  search:"type:order;column:wallet_id;table:vts_recharge"`
+	Fee             string `form:"feeOrder"  search:"type:order;column:fee;table:vts_recharge"`
+	CallbackAt      string `form:"callbackAtOrder"  search:"type:order;column:callback_at;table:vts_recharge"`
+	Status          string `form:"statusOrder"  search:"type:order;column:status;table:vts_recharge"`
+	ConfirmStatus   string `form:"confirmStatusOrder"  search:"type:order;column:confirm_status;table:vts_recharge"`
+	Remark          string `form:"remarkOrder"  search:"type:order;column:remark;table:vts_recharge"`
+	CreatedAt       string `form:"createdAtOrder"  search:"type:order;column:created_at;table:vts_recharge"`
+	UpdatedAt       string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:vts_recharge"`
+	DeletedAt       string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:vts_recharge"`
+	CreateBy        string `form:"createByOrder"  search:"type:order;column:create_by;table:vts_recharge"`
+	UpdateBy        string `form:"updateByOrder"  search:"type:order;column:update_by;table:vts_recharge"`
+}
+
+func (m *VtsRechargeGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type VtsRechargeInsertReq struct {
+	Id              int             `json:"-" comment:""` //
+	CoinCode        string          `json:"coinCode" comment:"币种"`
+	TranType        int             `json:"tranType" comment:"类型:1-线上 2-内部"`
+	OrderNo         string          `json:"orderNo" comment:"订单号"`
+	AdUserId        int             `json:"adUserId" comment:"用户id"`
+	Amount          decimal.Decimal `json:"amount" comment:"订单价格"`
+	PriceCurrency   string          `json:"priceCurrency" comment:"CoinGate结算货币代码"`
+	ReceiveAmount   decimal.Decimal `json:"receiveAmount" comment:"实收数量"`
+	PayAmount       decimal.Decimal `json:"payAmount" comment:"实际支付数量"`
+	PayCurrency     string          `json:"payCurrency" comment:"实际支付的加密货币"`
+	UnderpaidAmount decimal.Decimal `json:"underpaidAmount" comment:"买家少付数量"`
+	OverpaidAmount  decimal.Decimal `json:"overpaidAmount" comment:"买家多付数量"`
+	IsRefundable    int             `json:"isRefundable" comment:"指示购物者是否可以请求发票退款"`
+	WalletCreateAt  time.Time       `json:"walletCreateAt" comment:"第三方创建时间"`
+	WalletId        int             `json:"walletId" comment:"第三方钱包订单"`
+	Fee             decimal.Decimal `json:"fee" comment:"手续费"`
+	CallbackAt      time.Time       `json:"callbackAt" comment:"回调时间"`
+	Status          string          `json:"status" comment:"状态"`
+	ConfirmStatus   string          `json:"confirmStatus" comment:"确认状态"`
+	Remark          string          `json:"remark" comment:"备注"`
+	common.ControlBy
+}
+
+func (s *VtsRechargeInsertReq) Generate(model *models.VtsRecharge) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.CoinCode = s.CoinCode
+	model.TranType = s.TranType
+	model.OrderNo = s.OrderNo
+	model.AdUserId = s.AdUserId
+	model.Amount = s.Amount
+	model.PriceCurrency = s.PriceCurrency
+	model.ReceiveAmount = s.ReceiveAmount
+	model.PayAmount = s.PayAmount
+	model.PayCurrency = s.PayCurrency
+	model.UnderpaidAmount = s.UnderpaidAmount
+	model.OverpaidAmount = s.OverpaidAmount
+	model.IsRefundable = s.IsRefundable
+	model.WalletCreateAt = s.WalletCreateAt
+	model.WalletId = s.WalletId
+	model.Fee = s.Fee
+	model.CallbackAt = s.CallbackAt
+	model.Status = s.Status
+	model.ConfirmStatus = s.ConfirmStatus
+	model.Remark = s.Remark
+	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
+}
+
+func (s *VtsRechargeInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type VtsRechargeUpdateReq struct {
+	Id              int             `uri:"id" comment:""` //
+	CoinCode        string          `json:"coinCode" comment:"币种"`
+	TranType        int             `json:"tranType" comment:"类型:1-线上 2-内部"`
+	OrderNo         string          `json:"orderNo" comment:"订单号"`
+	AdUserId        int             `json:"adUserId" comment:"用户id"`
+	Amount          decimal.Decimal `json:"amount" comment:"订单价格"`
+	PriceCurrency   string          `json:"priceCurrency" comment:"CoinGate结算货币代码"`
+	ReceiveAmount   decimal.Decimal `json:"receiveAmount" comment:"实收数量"`
+	PayAmount       decimal.Decimal `json:"payAmount" comment:"实际支付数量"`
+	PayCurrency     string          `json:"payCurrency" comment:"实际支付的加密货币"`
+	UnderpaidAmount decimal.Decimal `json:"underpaidAmount" comment:"买家少付数量"`
+	OverpaidAmount  decimal.Decimal `json:"overpaidAmount" comment:"买家多付数量"`
+	IsRefundable    int             `json:"isRefundable" comment:"指示购物者是否可以请求发票退款"`
+	WalletCreateAt  time.Time       `json:"walletCreateAt" comment:"第三方创建时间"`
+	WalletId        int             `json:"walletId" comment:"第三方钱包订单"`
+	Fee             decimal.Decimal `json:"fee" comment:"手续费"`
+	CallbackAt      time.Time       `json:"callbackAt" comment:"回调时间"`
+	Status          string          `json:"status" comment:"状态"`
+	ConfirmStatus   string          `json:"confirmStatus" comment:"确认状态"`
+	Remark          string          `json:"remark" comment:"备注"`
+	common.ControlBy
+}
+
+func (s *VtsRechargeUpdateReq) Generate(model *models.VtsRecharge) {
+	if s.Id == 0 {
+		model.Model = common.Model{Id: s.Id}
+	}
+	model.CoinCode = s.CoinCode
+	model.TranType = s.TranType
+	model.OrderNo = s.OrderNo
+	model.AdUserId = s.AdUserId
+	model.Amount = s.Amount
+	model.PriceCurrency = s.PriceCurrency
+	model.ReceiveAmount = s.ReceiveAmount
+	model.PayAmount = s.PayAmount
+	model.PayCurrency = s.PayCurrency
+	model.UnderpaidAmount = s.UnderpaidAmount
+	model.OverpaidAmount = s.OverpaidAmount
+	model.IsRefundable = s.IsRefundable
+	model.WalletCreateAt = s.WalletCreateAt
+	model.WalletId = s.WalletId
+	model.Fee = s.Fee
+	model.CallbackAt = s.CallbackAt
+	model.Status = s.Status
+	model.ConfirmStatus = s.ConfirmStatus
+	model.Remark = s.Remark
+	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
+}
+
+func (s *VtsRechargeUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+// VtsRechargeGetReq 功能获取请求参数
+type VtsRechargeGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *VtsRechargeGetReq) GetId() interface{} {
+	return s.Id
+}
+
+// VtsRechargeDeleteReq 功能删除请求参数
+type VtsRechargeDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *VtsRechargeDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/app/admin/service/line_account_setting.go b/app/admin/service/line_account_setting.go
new file mode 100644
index 0000000..3bd1ba6
--- /dev/null
+++ b/app/admin/service/line_account_setting.go
@@ -0,0 +1,109 @@
+package service
+
+import (
+	"errors"
+
+    "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineAccountSetting struct {
+	service.Service
+}
+
+// GetPage 获取LineAccountSetting列表
+func (e *LineAccountSetting) GetPage(c *dto.LineAccountSettingGetPageReq, p *actions.DataPermission, list *[]models.LineAccountSetting, count *int64) error {
+	var err error
+	var data models.LineAccountSetting
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineAccountSettingService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineAccountSetting对象
+func (e *LineAccountSetting) Get(d *dto.LineAccountSettingGetReq, p *actions.DataPermission, model *models.LineAccountSetting) error {
+	var data models.LineAccountSetting
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineAccountSetting error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineAccountSetting对象
+func (e *LineAccountSetting) Insert(c *dto.LineAccountSettingInsertReq) error {
+    var err error
+    var data models.LineAccountSetting
+    c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineAccountSettingService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineAccountSetting对象
+func (e *LineAccountSetting) Update(c *dto.LineAccountSettingUpdateReq, p *actions.DataPermission) error {
+    var err error
+    var data = models.LineAccountSetting{}
+    e.Orm.Scopes(
+            actions.Permission(data.TableName(), p),
+        ).First(&data, c.GetId())
+    c.Generate(&data)
+
+    db := e.Orm.Save(&data)
+    if err = db.Error; err != nil {
+        e.Log.Errorf("LineAccountSettingService Save error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权更新该数据")
+    }
+    return nil
+}
+
+// Remove 删除LineAccountSetting
+func (e *LineAccountSetting) Remove(d *dto.LineAccountSettingDeleteReq, p *actions.DataPermission) error {
+	var data models.LineAccountSetting
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+        e.Log.Errorf("Service RemoveLineAccountSetting error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权删除该数据")
+    }
+	return nil
+}
diff --git a/app/admin/service/line_api_group.go b/app/admin/service/line_api_group.go
new file mode 100644
index 0000000..f79a60e
--- /dev/null
+++ b/app/admin/service/line_api_group.go
@@ -0,0 +1,217 @@
+package service
+
+import (
+	"errors"
+	"fmt"
+	"strconv"
+	"strings"
+
+	"github.com/bytedance/sonic"
+	"github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	"go-admin/common/const/rediskey"
+	cDto "go-admin/common/dto"
+	commondto "go-admin/common/dto"
+	"go-admin/common/helper"
+)
+
+type LineApiGroup struct {
+	service.Service
+}
+
+// GetPage 获取LineApiGroup列表
+func (e *LineApiGroup) GetPage(c *dto.LineApiGroupGetPageReq, p *actions.DataPermission, list *[]models.LineApiGroup, count *int64) error {
+	var err error
+	var data models.LineApiGroup
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineApiGroupService GetPage error:%s \r\n", err)
+		return err
+	}
+
+	for j, group := range *list {
+		split := strings.Split(group.ApiUserId, ",")
+		var (
+			aApiUserName string
+			bApiUserName string
+		)
+		for i, s := range split {
+			if i == 0 {
+				e.Orm.Model(&models.LineApiUser{}).Where("id = ?", s).Select("api_name").Scan(&aApiUserName)
+				(*list)[j].AApiName = aApiUserName
+			} else {
+				e.Orm.Model(&models.LineApiUser{}).Where("id = ?", s).Select("api_name").Scan(&bApiUserName)
+				(*list)[j].BApiName = bApiUserName
+			}
+		}
+
+	}
+
+	return nil
+}
+
+// Get 获取LineApiGroup对象
+func (e *LineApiGroup) Get(d *dto.LineApiGroupGetReq, p *actions.DataPermission, model *models.LineApiGroup) error {
+	var data models.LineApiGroup
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineApiGroup error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineApiGroup对象
+func (e *LineApiGroup) Insert(c *dto.LineApiGroupInsertReq) error {
+	var err error
+	var data models.LineApiGroup
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineApiGroupService Insert error:%s \r\n", err)
+		return err
+	}
+
+	SetApiGroupCache(data)
+
+	return nil
+}
+
+func SetApiGroupCache(data models.LineApiGroup) {
+	apiUserId := 0
+	childApiUserId := 0
+	ids := strings.Split(data.ApiUserId, ",")
+
+	if len(ids) == 2 {
+		apiUserId, _ = strconv.Atoi(ids[0])
+		childApiUserId, _ = strconv.Atoi(ids[1])
+
+		groupCache := commondto.ApiGroupDto{
+			Id:             data.Id,
+			Name:           data.GroupName,
+			ApiUserId:      apiUserId,
+			ChildApiUserId: childApiUserId,
+		}
+
+		groupVal, _ := sonic.MarshalString(&groupCache)
+
+		if groupVal != "" {
+			if err := helper.DefaultRedis.SetString(fmt.Sprintf(rediskey.ApiGroup, data.Id), groupVal); err != nil {
+				logger.Errorf("api group redis set error:%s", err)
+			}
+		}
+
+		SaveApiInfo(apiUserId, data.Id)
+		SaveApiInfo(childApiUserId, data.Id)
+	}
+}
+
+func SaveApiInfo(apiUserId int, groupId int) {
+	apiInfoVal, _ := helper.DefaultRedis.GetString(fmt.Sprintf(rediskey.API_USER, apiUserId))
+	var data models.LineApiUser
+
+	if apiInfoVal != "" {
+		_ = sonic.UnmarshalString(apiInfoVal, &data)
+
+		if data.Id > 0 {
+			data.GroupId = int64(groupId)
+		}
+
+		apiInfoVal, _ := sonic.MarshalString(&data)
+
+		if apiInfoVal != "" {
+			if err := helper.DefaultRedis.SetString(fmt.Sprintf(rediskey.API_USER, apiUserId), apiInfoVal); err != nil {
+				logger.Errorf("api user redis set error:%s", err)
+			}
+		}
+	}
+}
+
+// Update 修改LineApiGroup对象
+func (e *LineApiGroup) Update(c *dto.LineApiGroupUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var data = models.LineApiGroup{}
+	e.Orm.Scopes(
+		actions.Permission(data.TableName(), p),
+	).First(&data, c.GetId())
+	c.Generate(&data)
+
+	db := e.Orm.Save(&data)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("LineApiGroupService Save error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+
+	SetApiGroupCache(data)
+
+	return nil
+}
+
+// Remove 删除LineApiGroup
+func (e *LineApiGroup) Remove(d *dto.LineApiGroupDeleteReq, p *actions.DataPermission) error {
+	var data models.LineApiGroup
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveLineApiGroup error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+	userIds := make([]models.LineApiUser, 0)
+	e.Orm.Model(&models.LineApiUser{}).Where("group_id in  ?  ", d.GetId()).Select("id").Find(&userIds)
+
+	e.Orm.Model(&models.LineApiUser{}).Where("group_id in  ?  ", d.GetId()).Updates(map[string]interface{}{
+		"subordinate": "0",
+		"group_id":    0,
+	})
+
+	keys := make([]string, 0)
+	for _, id := range d.Ids {
+		key := fmt.Sprintf(rediskey.ApiGroup, id)
+		keys = append(keys, key)
+	}
+	if _, err := helper.DefaultRedis.BatchDeleteKeys(keys); err != nil {
+		e.Log.Error("删除用户组失败,err:", err)
+	}
+
+	for _, item := range userIds {
+		if item.Id == 0 {
+			continue
+		}
+
+		SaveApiInfo(item.Id, 0)
+	}
+
+	return nil
+}
diff --git a/app/admin/service/line_api_user.go b/app/admin/service/line_api_user.go
new file mode 100644
index 0000000..cf14bee
--- /dev/null
+++ b/app/admin/service/line_api_user.go
@@ -0,0 +1,335 @@
+package service
+
+import (
+	"errors"
+	"fmt"
+	"strings"
+
+	"github.com/bytedance/sonic"
+	"github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	"go-admin/common/const/rediskey"
+	cDto "go-admin/common/dto"
+	"go-admin/common/global"
+	"go-admin/common/helper"
+	"go-admin/models/binancedto"
+	"go-admin/services/excservice"
+)
+
+type LineApiUser struct {
+	service.Service
+}
+
+// GetPage 获取LineApiUser列表
+func (e *LineApiUser) GetPage(c *dto.LineApiUserGetPageReq, p *actions.DataPermission, list *[]models.LineApiUser, count *int64) error {
+	var err error
+	var data models.LineApiUser
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineApiUserService GetPage error:%s \r\n", err)
+		return err
+	}
+
+	var userSub binancedto.UserSubscribeState
+	for index := range *list {
+		val, _ := helper.DefaultRedis.GetString(fmt.Sprintf(global.USER_SUBSCRIBE, (*list)[index].ApiKey))
+
+		if val != "" {
+			sonic.Unmarshal([]byte(val), &userSub)
+
+			if userSub.FuturesLastTime != nil {
+				(*list)[index].FuturesLastTime = userSub.FuturesLastTime.Format("2006-01-02 15:04:05")
+			}
+
+			if userSub.SpotLastTime != nil {
+				(*list)[index].SpotLastTime = userSub.SpotLastTime.Format("2006-01-02 15:04:05")
+			}
+		}
+	}
+	return nil
+}
+
+// Get 获取LineApiUser对象
+func (e *LineApiUser) Get(d *dto.LineApiUserGetReq, p *actions.DataPermission, model *models.LineApiUser) error {
+	var data models.LineApiUser
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineApiUser error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineApiUser对象
+func (e *LineApiUser) Insert(c *dto.LineApiUserInsertReq) error {
+	var err error
+	var data models.LineApiUser
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineApiUserService Insert error:%s \r\n", err)
+		return err
+	}
+
+	e.saveCache(data)
+	val, _ := sonic.MarshalString(&data)
+
+	if val != "" {
+		if err := helper.DefaultRedis.RPushList(rediskey.ApiUserActiveList, val); err != nil {
+			logger.Error("添加待连接队列失败")
+		}
+	}
+
+	return nil
+}
+
+/*
+重启ws
+*/
+func (e *LineApiUser) restartWebsocket(data models.LineApiUser) {
+	socket, ok := excservice.SpotSockets[data.ApiKey]
+
+	if ok && socket != nil {
+		socket.Stop()
+	}
+
+	fuSocket, ok := excservice.FutureSockets[data.ApiKey]
+
+	if ok && fuSocket != nil {
+		fuSocket.Stop()
+	}
+
+	e.saveCache(data)
+
+	OpenUserBinanceWebsocket(data)
+}
+
+// 保存缓存
+func (e *LineApiUser) saveCache(data models.LineApiUser) {
+	val, _ := sonic.MarshalString(&data)
+
+	if val != "" {
+		key := fmt.Sprintf(rediskey.API_USER, data.Id)
+
+		if err := helper.DefaultRedis.SetString(key, val); err != nil {
+			e.Log.Error("缓存api user失败:", err)
+		}
+	}
+}
+
+/*
+打开用户websocket订阅
+*/
+func OpenUserBinanceWebsocket(item models.LineApiUser) {
+	proxyType := ""
+	ipAddress := ""
+	ips := strings.Split(strings.ReplaceAll(item.IpAddress, ":", ":"), "://")
+
+	if len(ips) == 2 {
+		proxyType = ips[0]
+
+		if item.UserPass != "" {
+			ipAddress = fmt.Sprintf("%s@%s", item.UserPass, ips[1])
+		} else {
+			ipAddress = ips[1]
+		}
+	}
+
+	//现货
+	if wm, ok := excservice.SpotSockets[item.ApiKey]; ok {
+		wm.Restart(item.ApiKey, item.ApiSecret, proxyType, ipAddress)
+	} else {
+		spotSocket := excservice.NewBinanceWebSocketManager(0, item.ApiKey, item.ApiSecret, proxyType, ipAddress)
+
+		spotSocket.Start()
+		excservice.SpotSockets[item.ApiKey] = spotSocket
+	}
+
+	if wm, ok := excservice.FutureSockets[item.ApiKey]; ok {
+		wm.Restart(item.ApiKey, item.ApiSecret, proxyType, ipAddress)
+	} else {
+		//合约
+		futureSocket := excservice.NewBinanceWebSocketManager(1, item.ApiKey, item.ApiSecret, proxyType, ipAddress)
+
+		futureSocket.Start()
+		excservice.FutureSockets[item.ApiKey] = futureSocket
+	}
+}
+
+// Update 修改LineApiUser对象
+func (e *LineApiUser) Update(c *dto.LineApiUserUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var data = models.LineApiUser{}
+	e.Orm.Scopes(
+		actions.Permission(data.TableName(), p),
+	).First(&data, c.GetId())
+	oldApiKey := data.ApiKey
+
+	c.Generate(&data)
+
+	db := e.Orm.Save(&data)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("LineApiUserService Save error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+
+	e.saveCache(data)
+
+	//旧key和新的key不一样,则关闭旧的websocket
+	if oldApiKey != data.ApiKey {
+		if err := helper.DefaultRedis.RPushList(rediskey.ApiUserDeleteList, oldApiKey); err != nil {
+			logger.Error("写入待关闭websocket api key 失败:", err)
+		}
+	}
+
+	val, _ := sonic.MarshalString(&data)
+
+	if val != "" {
+		if err := helper.DefaultRedis.RPushList(rediskey.ApiUserActiveList, val); err != nil {
+			logger.Error("写入待激活websocket api key 失败:", err)
+		}
+	}
+
+	return nil
+}
+
+// Remove 删除LineApiUser
+func (e *LineApiUser) Remove(d *dto.LineApiUserDeleteReq, p *actions.DataPermission) error {
+	var data models.LineApiUser
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveLineApiUser error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+
+	//移除缓存
+	delKeys := make([]string, 0)
+	for _, id := range d.Ids {
+		key := fmt.Sprintf(rediskey.API_USER, id)
+		delKeys = append(delKeys, key)
+	}
+
+	_, err := helper.DefaultRedis.BatchDeleteKeys(delKeys)
+
+	if err != nil {
+		e.Log.Error("批量删除api_user key失败", err)
+	}
+
+	return nil
+}
+
+// Bind 绑定从属关系
+func (e *LineApiUser) Bind(req *dto.LineApiUserBindSubordinateReq, p *actions.DataPermission) error {
+	split := strings.Split(req.UserIdStr, ",")
+	if len(split) != 2 {
+		return errors.New("绑定关系必须是两个账号")
+	}
+
+	for _, s := range split {
+		var apiUserinfo models.LineApiUser
+		e.Orm.Model(&models.LineApiUser{}).Where("id = ? AND subordinate <> '0'", s).Find(&apiUserinfo)
+		if apiUserinfo.Id > 0 {
+			return errors.New("该用户已经绑定关系")
+		}
+	}
+
+	group := models.LineApiGroup{
+		GroupName: req.GroupName,
+		ApiUserId: req.UserIdStr,
+	}
+
+	err := e.Orm.Transaction(func(tx *gorm.DB) error {
+
+		err := tx.Model(&models.LineApiGroup{}).Create(&group).Error
+		if err != nil {
+			return err
+		}
+
+		for i, s := range split {
+			if i == 0 {
+				err = e.Orm.Model(&models.LineApiUser{}).Where("id = ?", s).Updates(map[string]interface{}{
+					"subordinate": "1",
+					"group_id":    group.Id,
+				}).Error
+				if err != nil {
+					return err
+				}
+			} else {
+				err = e.Orm.Model(&models.LineApiUser{}).Where("id = ?", s).Updates(map[string]interface{}{
+					"subordinate": "2",
+					"group_id":    group.Id,
+				}).Error
+				if err != nil {
+					return err
+				}
+			}
+		}
+		return nil
+
+	})
+	if err != nil {
+		return errors.New("操作失败")
+	}
+
+	SetApiGroupCache(group)
+	return nil
+}
+
+// GetUser 获取未绑定的用户列表
+func (e *LineApiUser) GetUser(list *[]models.LineApiUser) error {
+	var err error
+	var data models.LineApiUser
+
+	err = e.Orm.Model(&data).Where("subordinate = '0'").Find(list).Error
+	if err != nil {
+		e.Log.Errorf("LineApiUserService error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// GetMainUser 获取主账号
+func (e *LineApiUser) GetMainUser(list *[]models.LineApiUser) error {
+	var err error
+	var data models.LineApiUser
+
+	err = e.Orm.Model(&data).Where("subordinate = '1' AND group_id > 0").Find(list).Error
+	if err != nil {
+		e.Log.Errorf("LineApiUserService error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
diff --git a/app/admin/service/line_coinnetwork.go b/app/admin/service/line_coinnetwork.go
new file mode 100644
index 0000000..c10c412
--- /dev/null
+++ b/app/admin/service/line_coinnetwork.go
@@ -0,0 +1,109 @@
+package service
+
+import (
+	"errors"
+
+    "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineCoinnetwork struct {
+	service.Service
+}
+
+// GetPage 获取LineCoinnetwork列表
+func (e *LineCoinnetwork) GetPage(c *dto.LineCoinnetworkGetPageReq, p *actions.DataPermission, list *[]models.LineCoinnetwork, count *int64) error {
+	var err error
+	var data models.LineCoinnetwork
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineCoinnetworkService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineCoinnetwork对象
+func (e *LineCoinnetwork) Get(d *dto.LineCoinnetworkGetReq, p *actions.DataPermission, model *models.LineCoinnetwork) error {
+	var data models.LineCoinnetwork
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineCoinnetwork error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineCoinnetwork对象
+func (e *LineCoinnetwork) Insert(c *dto.LineCoinnetworkInsertReq) error {
+    var err error
+    var data models.LineCoinnetwork
+    c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineCoinnetworkService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineCoinnetwork对象
+func (e *LineCoinnetwork) Update(c *dto.LineCoinnetworkUpdateReq, p *actions.DataPermission) error {
+    var err error
+    var data = models.LineCoinnetwork{}
+    e.Orm.Scopes(
+            actions.Permission(data.TableName(), p),
+        ).First(&data, c.GetId())
+    c.Generate(&data)
+
+    db := e.Orm.Save(&data)
+    if err = db.Error; err != nil {
+        e.Log.Errorf("LineCoinnetworkService Save error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权更新该数据")
+    }
+    return nil
+}
+
+// Remove 删除LineCoinnetwork
+func (e *LineCoinnetwork) Remove(d *dto.LineCoinnetworkDeleteReq, p *actions.DataPermission) error {
+	var data models.LineCoinnetwork
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+        e.Log.Errorf("Service RemoveLineCoinnetwork error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权删除该数据")
+    }
+	return nil
+}
diff --git a/app/admin/service/line_cointonetwork.go b/app/admin/service/line_cointonetwork.go
new file mode 100644
index 0000000..ad0b495
--- /dev/null
+++ b/app/admin/service/line_cointonetwork.go
@@ -0,0 +1,109 @@
+package service
+
+import (
+	"errors"
+
+    "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineCointonetwork struct {
+	service.Service
+}
+
+// GetPage 获取LineCointonetwork列表
+func (e *LineCointonetwork) GetPage(c *dto.LineCointonetworkGetPageReq, p *actions.DataPermission, list *[]models.LineCointonetwork, count *int64) error {
+	var err error
+	var data models.LineCointonetwork
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineCointonetworkService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineCointonetwork对象
+func (e *LineCointonetwork) Get(d *dto.LineCointonetworkGetReq, p *actions.DataPermission, model *models.LineCointonetwork) error {
+	var data models.LineCointonetwork
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineCointonetwork error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineCointonetwork对象
+func (e *LineCointonetwork) Insert(c *dto.LineCointonetworkInsertReq) error {
+    var err error
+    var data models.LineCointonetwork
+    c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineCointonetworkService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineCointonetwork对象
+func (e *LineCointonetwork) Update(c *dto.LineCointonetworkUpdateReq, p *actions.DataPermission) error {
+    var err error
+    var data = models.LineCointonetwork{}
+    e.Orm.Scopes(
+            actions.Permission(data.TableName(), p),
+        ).First(&data, c.GetId())
+    c.Generate(&data)
+
+    db := e.Orm.Save(&data)
+    if err = db.Error; err != nil {
+        e.Log.Errorf("LineCointonetworkService Save error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权更新该数据")
+    }
+    return nil
+}
+
+// Remove 删除LineCointonetwork
+func (e *LineCointonetwork) Remove(d *dto.LineCointonetworkDeleteReq, p *actions.DataPermission) error {
+	var data models.LineCointonetwork
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+        e.Log.Errorf("Service RemoveLineCointonetwork error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权删除该数据")
+    }
+	return nil
+}
diff --git a/app/admin/service/line_direction.go b/app/admin/service/line_direction.go
new file mode 100644
index 0000000..3a3e482
--- /dev/null
+++ b/app/admin/service/line_direction.go
@@ -0,0 +1,222 @@
+package service
+
+import (
+	"errors"
+	"fmt"
+	"go-admin/pkg/utility"
+	"strings"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineDirection struct {
+	service.Service
+}
+
+// GetPage 获取LineDirection列表
+func (e *LineDirection) GetPage(c *dto.LineDirectionGetPageReq, p *actions.DataPermission, list *[]models.LineDirection, count *int64) error {
+	var err error
+	var data models.LineDirection
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineDirectionService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineDirection对象
+func (e *LineDirection) Get(d *dto.LineDirectionGetReq, p *actions.DataPermission, model *models.LineDirection) error {
+	var data models.LineDirection
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineDirection error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineDirection对象
+func (e *LineDirection) Insert(c *dto.LineDirectionInsertReq) error {
+	var err error
+	var data models.LineDirection
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineDirectionService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineDirection对象
+func (e *LineDirection) Update(c *dto.LineDirectionUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var data = models.LineDirection{}
+	e.Orm.Scopes(
+		actions.Permission(data.TableName(), p),
+	).First(&data, c.GetId())
+	c.Generate(&data)
+
+	db := e.Orm.Save(&data)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("LineDirectionService Save error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	return nil
+}
+
+// Remove 删除LineDirection
+func (e *LineDirection) Remove(d *dto.LineDirectionDeleteReq, p *actions.DataPermission) error {
+	var data models.LineDirection
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveLineDirection error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+	return nil
+}
+
+// AddDirection 新增预估方向
+func (e *LineDirection) AddDirection(req dto.AddDirectionReq) error {
+	var accountInfo models.LineAccountSetting
+	e.Orm.Model(&models.LineAccountSetting{}).Where("user_name = ?", req.AccountName).Find(&accountInfo)
+	if accountInfo.Id <= 0 || accountInfo.Password != req.Password {
+		return errors.New("账号密码错误请重新输入")
+	}
+
+	req.BuyPoint1 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(req.BuyPoint1, ",", "."), "。", "."), " ", "")
+	req.BuyPoint2 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(req.BuyPoint2, ",", "."), "。", "."), " ", "")
+	req.BuyPoint3 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(req.BuyPoint3, ",", "."), "。", "."), " ", "")
+	req.SellPoint1 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(req.SellPoint1, ",", "."), "。", "."), " ", "")
+	req.SellPoint2 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(req.SellPoint2, ",", "."), "。", "."), " ", "")
+	req.SellPoint3 = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(req.SellPoint3, ",", "."), "。", "."), " ", "")
+
+	req.Symbol = utility.ReplaceSuffix(strings.ReplaceAll(req.Symbol, " ", ""), "4小时", "USDT")
+	req.Symbol = strings.ReplaceAll(req.Symbol, "1小时", "USDT")
+	req.Symbol = strings.ReplaceAll(req.Symbol, "1日", "USDT")
+	req.Symbol = strings.ReplaceAll(req.Symbol, "四小时", "USDT")
+	req.Symbol = strings.ReplaceAll(req.Symbol, "一小时", "USDT")
+	req.Symbol = strings.ReplaceAll(req.Symbol, "一日", "USDT")
+
+	symbolType := utility.StringToInt(req.Type)
+
+	direction := models.LineDirection{
+		Symbol:     req.Symbol,
+		Type:       int64(symbolType),
+		BuyPoint1:  req.BuyPoint1,
+		BuyPoint2:  req.BuyPoint2,
+		BuyPoint3:  req.BuyPoint3,
+		SellPoint1: req.SellPoint1,
+		SellPoint2: req.SellPoint2,
+		SellPoint3: req.SellPoint3,
+		Direction:  req.Direction,
+		AiAnswer:   req.AiAnswer,
+	}
+	var directionInfo models.LineDirection
+	e.Orm.Model(&models.LineDirection{}).Where("symbol = ? AND type = ?", req.Symbol, symbolType).Find(&directionInfo)
+	if directionInfo.Id > 0 {
+		e.Orm.Model(&models.LineDirection{}).Where("id = ?", directionInfo.Id).Delete(&models.LineDirection{})
+	}
+	err := e.Orm.Model(&models.LineDirection{}).Create(&direction).Error
+	if err != nil {
+		return fmt.Errorf("生成数据失败 err:%s", err)
+	}
+
+	return nil
+}
+
+// 重新统计aicoin 分组
+func (e *LineDirection) ReloadGroup() error {
+	directions := make([]models.LineDirection, 0)
+	groups := make([]models.LineSymbolGroup, 0)
+	spotSymbols := make(map[string][]string)
+	futSymbols := make(map[string][]string)
+	groupNames := make([]string, 0)
+
+	if err := e.Orm.Model(&models.LineDirection{}).Find(&directions).Error; err != nil {
+		return err
+	}
+	for _, v := range directions {
+		if v.Type == 1 {
+			spotSymbols[v.Direction] = append(spotSymbols[v.Direction], v.Symbol)
+		} else {
+			futSymbols[v.Direction] = append(futSymbols[v.Direction], v.Symbol)
+		}
+	}
+
+	for key, item := range spotSymbols {
+		groupName := fmt.Sprintf("现货-%s", key)
+
+		group := models.LineSymbolGroup{
+			GroupName: groupName,
+			Type:      "1",
+			GroupType: "1",
+			Symbol:    strings.Join(item, ","),
+		}
+
+		groupNames = append(groupNames, groupName)
+		groups = append(groups, group)
+	}
+
+	for key, item := range futSymbols {
+		groupName := fmt.Sprintf("合约-%s", key)
+
+		group := models.LineSymbolGroup{
+			GroupName: groupName,
+			Type:      "2",
+			GroupType: "1",
+			Symbol:    strings.Join(item, ","),
+		}
+
+		groupNames = append(groupNames, groupName)
+		groups = append(groups, group)
+	}
+
+	err := e.Orm.Transaction(func(tx *gorm.DB) error {
+		if err2 := tx.Delete(&models.LineSymbolGroup{}, "group_name in ?", groupNames).Error; err2 != nil {
+			return err2
+		}
+		if err2 := tx.Create(&groups).Error; err2 != nil {
+			return err2
+		}
+
+		return nil
+	})
+
+	return err
+}
diff --git a/app/admin/service/line_order_template_logs.go b/app/admin/service/line_order_template_logs.go
new file mode 100644
index 0000000..f0083aa
--- /dev/null
+++ b/app/admin/service/line_order_template_logs.go
@@ -0,0 +1,109 @@
+package service
+
+import (
+	"errors"
+
+    "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineOrderTemplateLogs struct {
+	service.Service
+}
+
+// GetPage 获取LineOrderTemplateLogs列表
+func (e *LineOrderTemplateLogs) GetPage(c *dto.LineOrderTemplateLogsGetPageReq, p *actions.DataPermission, list *[]models.LineOrderTemplateLogs, count *int64) error {
+	var err error
+	var data models.LineOrderTemplateLogs
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineOrderTemplateLogsService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineOrderTemplateLogs对象
+func (e *LineOrderTemplateLogs) Get(d *dto.LineOrderTemplateLogsGetReq, p *actions.DataPermission, model *models.LineOrderTemplateLogs) error {
+	var data models.LineOrderTemplateLogs
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineOrderTemplateLogs error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineOrderTemplateLogs对象
+func (e *LineOrderTemplateLogs) Insert(c *dto.LineOrderTemplateLogsInsertReq) error {
+    var err error
+    var data models.LineOrderTemplateLogs
+    c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineOrderTemplateLogsService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineOrderTemplateLogs对象
+func (e *LineOrderTemplateLogs) Update(c *dto.LineOrderTemplateLogsUpdateReq, p *actions.DataPermission) error {
+    var err error
+    var data = models.LineOrderTemplateLogs{}
+    e.Orm.Scopes(
+            actions.Permission(data.TableName(), p),
+        ).First(&data, c.GetId())
+    c.Generate(&data)
+
+    db := e.Orm.Save(&data)
+    if err = db.Error; err != nil {
+        e.Log.Errorf("LineOrderTemplateLogsService Save error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权更新该数据")
+    }
+    return nil
+}
+
+// Remove 删除LineOrderTemplateLogs
+func (e *LineOrderTemplateLogs) Remove(d *dto.LineOrderTemplateLogsDeleteReq, p *actions.DataPermission) error {
+	var data models.LineOrderTemplateLogs
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+        e.Log.Errorf("Service RemoveLineOrderTemplateLogs error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权删除该数据")
+    }
+	return nil
+}
diff --git a/app/admin/service/line_pre_order.go b/app/admin/service/line_pre_order.go
new file mode 100644
index 0000000..f9b88b8
--- /dev/null
+++ b/app/admin/service/line_pre_order.go
@@ -0,0 +1,1308 @@
+package service
+
+import (
+	"errors"
+	"fmt"
+	"go-admin/common/const/rediskey"
+	"go-admin/common/global"
+	"go-admin/common/helper"
+	models2 "go-admin/models"
+	"go-admin/models/binancedto"
+	"go-admin/pkg/utility"
+	"go-admin/pkg/utility/snowflakehelper"
+	"go-admin/services/binanceservice"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/bytedance/sonic"
+	"github.com/jinzhu/copier"
+	"github.com/shopspring/decimal"
+
+	"github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LinePreOrder struct {
+	service.Service
+}
+
+// GetPage 获取LinePreOrder列表
+func (e *LinePreOrder) GetPage(c *dto.LinePreOrderGetPageReq, p *actions.DataPermission, list *[]models.LinePreOrder, count *int64) error {
+	var err error
+	var data models.LinePreOrder
+	tx := e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).Where("pid = 0").Joins("JOIN line_api_user on line_api_user.id = line_pre_order.api_id").
+		Joins("JOIN line_pre_order_status on line_pre_order_status.order_sn = line_pre_order.order_sn").
+		Select("line_pre_order.*,line_api_user.api_name,line_pre_order_status.add_position_status,line_pre_order_status.hedge_status")
+	if c.AddPositionStatus >= 0 {
+		tx.Where("line_pre_order_status.add_position_status = ?", c.AddPositionStatus)
+	}
+
+	if c.HedgeStatus >= 0 {
+		tx.Where("line_pre_order_status.hedge_status = ?", c.HedgeStatus)
+	}
+
+	err = tx.
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LinePreOrderService GetPage error:%s \r\n", err)
+		return err
+	}
+	for i, order := range *list {
+		var childNum int64
+		e.Orm.Model(&models.LinePreOrder{}).Where("pid = ?", order.Id).Count(&childNum)
+		(*list)[i].ChildNum = childNum
+	}
+	return nil
+}
+
+// GetOrderPage 获取LinePreOrder列表
+func (e *LinePreOrder) GetOrderPage(c *dto.LinePreOrderGetPageReq, p *actions.DataPermission, list *[]models.LinePreOrder, count *int64) error {
+	var err error
+	var data models.LinePreOrder
+	tx := e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).Where("pid = 0 AND status != '0'").Joins("JOIN line_api_user on line_api_user.id = line_pre_order.api_id").
+		Joins("JOIN line_pre_order_status on line_pre_order_status.order_id = line_pre_order.id").
+		Select("line_pre_order.*,line_api_user.api_name,line_pre_order_status.add_position_status,line_pre_order_status.hedge_status")
+	if c.AddPositionStatus >= 0 {
+		tx.Where("line_pre_order_status.add_position_status = ?", c.AddPositionStatus)
+	}
+
+	if c.HedgeStatus >= 0 {
+		tx.Where("line_pre_order_status.hedge_status = ?", c.HedgeStatus)
+	}
+	err = tx.
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	//err = e.Orm.Model(&data).
+	//	Scopes(
+	//		cDto.MakeCondition(c.GetNeedSearch()),
+	//		cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+	//		actions.Permission(data.TableName(), p),
+	//	).Where("pid = 0 AND status != '0'").Joins("JOIN line_api_user on line_api_user.id = line_pre_order.api_id").Select("line_pre_order.*,line_api_user.api_name").
+	//	Find(list).Limit(-1).Offset(-1).
+	//	Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LinePreOrderService GetChildPage error:%s \r\n", err)
+		return err
+	}
+	for i, order := range *list {
+		var childNum int64
+		e.Orm.Model(&models.LinePreOrder{}).Where("pid = ?", order.Id).Count(&childNum)
+		(*list)[i].ChildNum = childNum
+	}
+	return nil
+}
+
+// GetAllPage 获取LinePreOrder列表
+func (e *LinePreOrder) GetAllPage(c *dto.LinePreOrderGetPageReq, p *actions.DataPermission, list *[]models.LinePreOrder, count *int64) error {
+	var err error
+	var data models.LinePreOrder
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LinePreOrderService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// GetChildList 获取子订单列表
+func (e *LinePreOrder) GetChildList(req *dto.GetChildOrderReq, p *actions.DataPermission, order *[]models.LinePreOrder) error {
+	err := e.Orm.Model(&models.LinePreOrder{}).Where("pid = ?", req.Id).
+		Order("id asc").
+		Joins("JOIN line_api_user on line_api_user.id = line_pre_order.api_id").Select("line_pre_order.*,line_api_user.api_name").
+		Find(order).Error
+	if err != nil {
+		e.Log.Errorf("LinePreOrderService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+
+}
+
+// Get 获取LinePreOrder对象
+func (e *LinePreOrder) Get(d *dto.LinePreOrderGetReq, p *actions.DataPermission, model *models.LinePreOrder) error {
+	var data models.LinePreOrder
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLinePreOrder error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LinePreOrder对象
+func (e *LinePreOrder) Insert(c *dto.LinePreOrderInsertReq) error {
+	var err error
+	var data models.LinePreOrder
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LinePreOrderService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LinePreOrder对象
+func (e *LinePreOrder) Update(c *dto.LinePreOrderUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var data = models.LinePreOrder{}
+	e.Orm.Scopes(
+		actions.Permission(data.TableName(), p),
+	).First(&data, c.GetId())
+	c.Generate(&data)
+
+	db := e.Orm.Save(&data)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("LinePreOrderService Save error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	return nil
+}
+
+// Remove 删除LinePreOrder
+func (e *LinePreOrder) Remove(d *dto.LinePreOrderDeleteReq, p *actions.DataPermission) error {
+	var data models.LinePreOrder
+	var list []models.LinePreOrder
+	e.Orm.Model(&models.LinePreOrder{}).Where("id in ?", d.GetId()).Find(&list)
+	//for _, order := range list {
+	//if order.Status != "0" {
+	//	return errors.New(fmt.Sprintf("订单id %d 已被触发 无法被删除", order.Id))
+	//}
+	//}
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Unscoped().Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveLinePreOrder error:%s \r\n", err)
+		return err
+	}
+	ints := make([]int, 0)
+	stoplossMarket, _ := helper.DefaultRedis.GetAllList(rediskey.StoplossMarkt)
+	stoploss := binancedto.StoplossMarket{}
+	apiIds := make([]int, 0)
+
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+
+	//删除的缓存
+	for _, order := range list {
+		redisList := dto.PreOrderRedisList{
+			Id:          order.Id,
+			Symbol:      order.Symbol,
+			Price:       order.Price,
+			Site:        order.Site,
+			ApiId:       order.ApiId,
+			OrderSn:     order.OrderSn,
+			QuoteSymbol: order.QuoteSymbol,
+		}
+
+		if !utility.ContainsInt(apiIds, order.ApiId) {
+			apiIds = append(apiIds, order.ApiId)
+		}
+
+		tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf("%s:%s", global.TICKER_SPOT, order.Symbol))
+		redisList.Price = utility.StringToDecimal(redisList.Price).Truncate(int32(tradeSet.PriceDigit)).String()
+		marshal, _ := sonic.Marshal(redisList)
+		if order.SymbolType == 1 {
+			helper.DefaultRedis.LRem(rediskey.PreFutOrderList, string(marshal))
+		} else {
+			helper.DefaultRedis.LRem(rediskey.PreSpotOrderList, string(marshal))
+		}
+
+		binanceservice.MainClosePositionClearCache(order.Id, order.CoverType)
+
+		helper.DefaultRedis.DeleteString(fmt.Sprintf(rediskey.SpotHedgeClosePosition, order.Id, order.Symbol))
+		helper.DefaultRedis.DeleteString(fmt.Sprintf(rediskey.FuturesHedgeClosePosition, order.Id, order.Symbol))
+
+		helper.DefaultRedis.DeleteString(fmt.Sprintf(rediskey.HoldeA, order.Id))
+		helper.DefaultRedis.DeleteString(fmt.Sprintf(rediskey.HoldeB, order.Id))
+		helper.DefaultRedis.DeleteString(fmt.Sprintf(rediskey.HedgeClosePosition, order.Id))
+
+		for _, st := range stoplossMarket {
+			sonic.Unmarshal([]byte(st), &stoploss)
+
+			if stoploss.Pid == order.Id {
+				helper.DefaultRedis.LRem(rediskey.StoplossMarkt, st)
+			}
+		}
+
+		ints = append(ints, order.Id)
+	}
+
+	if len(apiIds) > 0 {
+		apiSymbols := make([]models.LinePreOrder, 0)
+		userHold := make(map[int][]string)
+
+		e.Orm.Model(&models.LinePreOrder{}).Where("pid = 0 AND status IN ('1','5','9','13') AND api_id IN ?", apiIds).
+			Group("api_id,symbol,quote_symbol").
+			Select("api_id,symbol,quote_symbol").
+			Find(&apiSymbols)
+
+		for _, apiId := range apiIds {
+			bre := false
+
+			for _, api := range apiSymbols {
+				if apiId == api.ApiId {
+					coin := utility.ReplaceSuffix(api.Symbol, api.QuoteSymbol, "")
+					userHold[api.ApiId] = append(userHold[api.ApiId], coin)
+					bre = true
+				}
+			}
+
+			if !bre {
+				userHold[apiId] = make([]string, 0)
+			}
+		}
+
+		for key, val := range userHold {
+			key := fmt.Sprintf(rediskey.UserHolding, key)
+
+			if len(val) > 0 {
+				if err := helper.DefaultRedis.SetListCache(key, 0, val...); err != nil {
+					logger.Errorf("重新设置用户持仓失败 apiid:%v,err:%v", key, err)
+				}
+			} else {
+				if err := helper.DefaultRedis.SetEmptyListCache(key, 0); err != nil {
+					logger.Errorf("重新设置用户持仓为空 失败 apiid:%v,err:%v", key, err)
+				}
+			}
+		}
+	}
+
+	if len(ints) > 0 {
+		e.Orm.Model(&models.LinePreOrder{}).Where("pid >0 AND pid in ?", ints).Unscoped().Delete(&models.LinePreOrder{})
+	}
+	return nil
+}
+
+// AddPreOrder 单个添加
+func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataPermission, errs *[]error, tickerSymbol string) error {
+	apiUserIds := strings.Split(req.ApiUserId, ",")
+	if req.SaveTemplate == "2" || req.SaveTemplate == "1" { //2 = 只保存模板 1= 保存模板并下单
+		var templateLog dto.LineAddPreOrderReq
+		copier.Copy(&templateLog, req)
+		//templateLog := *req
+		templateLog.SaveTemplate = "0"
+		templateLog.TemplateName = ""
+		marshal, _ := sonic.Marshal(templateLog)
+		saveTemplateParams := models.LineOrderTemplateLogs{
+			Name:   req.TemplateName,
+			UserId: 0,
+			Params: string(marshal),
+			Type:   1,
+			Switch: "0",
+		}
+		e.Orm.Model(&models.LineOrderTemplateLogs{}).Create(&saveTemplateParams)
+	}
+	if req.SaveTemplate == "2" {
+		return nil
+	}
+	var key string
+	//var tickerSymbol string
+	if req.OrderType == global.SYMBOL_SPOT {
+		key = fmt.Sprintf("%s:%s", global.TICKER_SPOT, req.Symbol)
+		//tickerSymbol = helper.DefaultRedis.Get(rediskey.SpotSymbolTicker).Val()
+	} else {
+		key = fmt.Sprintf("%s:%s", global.TICKER_FUTURES, req.Symbol)
+		//tickerSymbol = helper.DefaultRedis.Get(rediskey.FutSymbolTicker).Val()
+	}
+
+	for _, id := range apiUserIds {
+		if req.Site == "SELL" && req.OrderType == global.SYMBOL_SPOT {
+			*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%s 获取交易对:%s 现货不支持卖出操作", id, req.Symbol)))
+			continue
+		}
+		var AddOrder models.LinePreOrder
+		var profitOrder models.LinePreOrder
+		var stopOrder models.LinePreOrder
+
+		//获取交易对
+		tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, key)
+		orderCount := e.CheckRepeatOrder(req.OrderType, id, req.Site, tradeSet.Coin)
+		if orderCount > 0 {
+			*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%s 获取交易对:%s 该交易对已存在,请勿重复下单", id, req.Symbol)))
+			continue
+		}
+		var tickerPrice decimal.Decimal
+		ticker := models2.TradeSet{}
+		tickerVal := ""
+
+		if req.SymbolType == 1 {
+			tickerVal, _ = helper.DefaultRedis.GetString(fmt.Sprintf(global.TICKER_SPOT, req.ExchangeType))
+		} else {
+			tickerVal, _ = helper.DefaultRedis.GetString(fmt.Sprintf(global.TICKER_FUTURES, req.ExchangeType))
+		}
+
+		if tickerVal == "" {
+			logger.Error("获取交易对:%s 现货ticker失败", req.Symbol)
+			continue
+		}
+		err := sonic.Unmarshal([]byte(tickerVal), &ticker)
+
+		if ticker.LastPrice == "" {
+			logger.Error("获取交易对:%s 现货ticker失败,err:%v", req.Symbol, err)
+			continue
+		}
+
+		if tickerPrice.Equal(decimal.Zero) { //redis 没有这个值
+			*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%s 获取交易对:%s 交易行情出错", id, req.Symbol)))
+			continue
+		}
+
+		AddOrder.SignPriceType = "new"
+		AddOrder.BuyPrice = req.BuyPrice     //购买多少U
+		AddOrder.SymbolType = req.SymbolType //交易对类型1= 现货 2 = 合约
+		AddOrder.OrderType = req.OrderType   //订单类型
+		AddOrder.CoverType = req.CoverType   //对冲类型 0=无对冲 1= 现货对合约 2=合约对合约 3 合约对现货
+		if req.ExpireHour == 0 {             //过期时间默认为4个小时
+			req.ExpireHour = 4
+		}
+		AddOrder.ExpireTime = time.Now().Add(time.Duration(req.ExpireHour) * time.Hour) //过期时间
+		AddOrder.MainOrderType = req.MainOrderType
+		AddOrder.HedgeOrderType = req.HedgeOrderType
+		AddOrder.Site = req.Site
+		if req.PricePattern == "percentage" {
+			AddOrder.Rate = req.Price
+			orderPrice, _ := decimal.NewFromString(req.Price)    //下单价百分比 10%
+			priceRate := orderPrice.Div(decimal.NewFromInt(100)) //下单价除100 =0.1
+			AddOrder.SignPrice = tickerPrice.String()
+			if strings.ToUpper(req.Site) == "BUY" { //购买方向
+				//实际下单价格
+				truncate := tickerPrice.Mul(decimal.NewFromInt(1).Sub(priceRate)).Truncate(int32(tradeSet.PriceDigit))
+				AddOrder.Price = truncate.String()
+			} else {
+				truncate := tickerPrice.Mul(decimal.NewFromInt(1).Add(priceRate)).Truncate(int32(tradeSet.PriceDigit))
+				AddOrder.Price = truncate.String()
+			}
+
+		} else { //实际价格下单
+			AddOrder.Price = utility.StringToDecimal(req.Price).Truncate(int32(tradeSet.PriceDigit)).String()
+			AddOrder.SignPrice = req.Price
+			AddOrder.SignPriceType = "mixture"
+			AddOrder.Rate = "0"
+		}
+		buyPrice, _ := decimal.NewFromString(req.BuyPrice) //购买多少U
+		var symbolInfo models.LineSymbol
+		e.Orm.Model(&models.LineSymbol{}).Where("type = ? AND symbol = ?", req.SymbolType, req.Symbol).Find(&symbolInfo)
+		//计算购买数量  判断是否是否是U本位
+		if symbolInfo.QuoteAsset != "USDT" { //不是U本位
+			//获取币本位兑换u的价格
+			ticker2 := models2.TradeSet{}
+			tickerVal, _ := helper.DefaultRedis.GetString(fmt.Sprintf(global.TICKER_SPOT, req.ExchangeType, strings.ToUpper(symbolInfo.QuoteAsset+"USDT")))
+
+			if tickerVal == "" {
+				logger.Error("查询行情失败")
+				continue
+			}
+
+			err = sonic.Unmarshal([]byte(tickerVal), &ticker2)
+
+			if ticker2.LastPrice == "" {
+				logger.Errorf("查询行情失败 %s err:%v", strings.ToUpper(symbolInfo.QuoteAsset+"USDT"), err)
+				continue
+			}
+			//LTCBTC --> LTCUSDT
+			uTickerPrice, _ := decimal.NewFromString(ticker2.LastPrice) //94069
+			//换算成U
+			//div := decimal.NewFromInt(1).Div(uTickerPrice) //0.0000106365
+			//在换算成对应交易对对应的价值
+			//LTCBTC --> LTCUSDT == LTCUSDT -- 100.502
+			div := tickerPrice.Div(decimal.NewFromInt(1).Div(uTickerPrice))
+			//计算下单数量
+			AddOrder.Num = buyPrice.Div(div).Truncate(int32(tradeSet.AmountDigit)).String()
+		} else {
+			fromString, _ := decimal.NewFromString(AddOrder.Price)
+			AddOrder.Num = buyPrice.Div(fromString).Truncate(int32(tradeSet.AmountDigit)).String()
+		}
+		if utility.StringToFloat64(AddOrder.Num) < tradeSet.MinQty {
+			*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%s 获取交易对:%s 小于最小下单数量", id, req.Symbol)))
+			continue
+		}
+		AddOrder.OrderSn = strconv.FormatInt(snowflakehelper.GetOrderId(), 10)
+		AddOrder.ApiId, _ = strconv.Atoi(id)
+		AddOrder.Symbol = req.Symbol
+		AddOrder.QuoteSymbol = symbolInfo.QuoteAsset
+		AddOrder.Pid = 0
+		AddOrder.GroupId = "0"
+		AddOrder.AdminId = "0"
+		AddOrder.Status = 0
+		copier.Copy(&profitOrder, &AddOrder)
+		copier.Copy(&stopOrder, &AddOrder)
+
+		err = e.Orm.Model(&models.LinePreOrder{}).Omit("id", "save_template", "template_name").Create(&AddOrder).Error
+		if err != nil {
+			*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%s 获取交易对:%s 生成订单失败", id, req.Symbol)))
+			continue
+		}
+
+		preOrderStatus := models.LinePreOrderStatus{}
+		preOrderStatus.OrderId = AddOrder.Id
+		preOrderStatus.OrderSn = AddOrder.OrderSn
+
+		e.Orm.Model(&models.LinePreOrderStatus{}).Create(&preOrderStatus)
+
+		list := dto.PreOrderRedisList{
+			Id:          AddOrder.Id,
+			Symbol:      AddOrder.Symbol,
+			Price:       AddOrder.Price,
+			Site:        AddOrder.Site,
+			ApiId:       AddOrder.ApiId,
+			OrderSn:     AddOrder.OrderSn,
+			QuoteSymbol: AddOrder.QuoteSymbol,
+		}
+		marshal, _ := sonic.Marshal(&list)
+		var preKey string
+		if AddOrder.OrderType == global.SYMBOL_SPOT {
+			preKey = rediskey.PreSpotOrderList
+		} else {
+			preKey = rediskey.PreFutOrderList
+		}
+		helper.DefaultRedis.LPushList(preKey, string(marshal))
+
+		//是否有止盈止损订单
+		if req.Profit != "" {
+			if strings.ToUpper(req.Site) == "BUY" {
+				profitOrder.Site = "SELL"
+				profitOrder.Price = decimal.NewFromFloat(utility.StringToFloat64(AddOrder.Price) * (1 + utility.StringToFloat64(req.Profit)/100)).Truncate(int32(tradeSet.PriceDigit)).String()
+			} else {
+				profitOrder.Site = "BUY"
+				profitOrder.Price = decimal.NewFromFloat(utility.StringToFloat64(AddOrder.Price) * (1 - utility.StringToFloat64(req.Profit)/100)).Truncate(int32(tradeSet.PriceDigit)).String()
+			}
+			profitOrder.OrderSn = strconv.FormatInt(snowflakehelper.GetOrderId(), 10)
+			profitOrder.Pid = AddOrder.Id
+			profitOrder.OrderType = 2
+			profitOrder.Status = 0
+			profitOrder.Rate = req.Profit
+
+			e.Orm.Model(&models.LinePreOrder{}).Omit("id", "save_template", "template_name").Create(&profitOrder)
+		}
+
+		if req.StopPrice != "" {
+			if strings.ToUpper(req.Site) == "BUY" {
+				stopOrder.Site = "SELL"
+				stopOrder.Price = decimal.NewFromFloat(utility.StringToFloat64(AddOrder.Price) * (1 - utility.StringToFloat64(req.StopPrice)/100)).Truncate(int32(tradeSet.PriceDigit)).String()
+			} else {
+				stopOrder.Site = "BUY"
+				stopOrder.Price = decimal.NewFromFloat(utility.StringToFloat64(AddOrder.Price) * (1 + utility.StringToFloat64(req.StopPrice)/100)).Truncate(int32(tradeSet.PriceDigit)).String()
+			}
+			stopOrder.OrderSn = strconv.FormatInt(snowflakehelper.GetOrderId(), 10)
+			stopOrder.Pid = AddOrder.Id
+			stopOrder.OrderType = 1
+			stopOrder.Status = 0
+			stopOrder.Rate = req.StopPrice
+
+			e.Orm.Model(&models.LinePreOrder{}).Omit("id", "save_template", "template_name").Create(&stopOrder)
+		}
+	}
+
+	return nil
+}
+
+// CheckRepeatOrder 检查重复下单 检查基础货币
+func (e *LinePreOrder) CheckRepeatOrder(orderType int, apiUserId, site, baseCoin string) int64 {
+	var count int64
+	e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol like ? AND order_type = ? AND site = ? AND `status` != '2' AND `status`!='4' AND `status` != '0' AND `status` != '6'", apiUserId, baseCoin+"%", orderType, site).Count(&count)
+	return count
+}
+
+// AddBatchPreOrder 批量添加
+func (e *LinePreOrder) AddBatchPreOrder(batchReq *dto.LineBatchAddPreOrderReq, p *actions.DataPermission, errs *[]error) error {
+	if batchReq.SaveTemplate == "2" || batchReq.SaveTemplate == "1" { //2 = 只保存模板 1= 保存模板并下单
+		var templateLog dto.LineBatchAddPreOrderReq
+		copier.Copy(&templateLog, batchReq)
+		//templateLog = *batchReq
+		templateLog.SaveTemplate = "0"
+		templateLog.TemplateName = ""
+		marshal, _ := sonic.Marshal(templateLog)
+		saveTemplateParams := models.LineOrderTemplateLogs{
+			Name:   batchReq.TemplateName,
+			UserId: 0,
+			Params: string(marshal),
+			Type:   2,
+			Switch: "0",
+		}
+		e.Orm.Model(&models.LineOrderTemplateLogs{}).Create(&saveTemplateParams)
+	}
+
+	if batchReq.SaveTemplate == "2" {
+		return nil
+	}
+
+	if batchReq.SymbolGroupId != "" {
+		var symbolGroupInfo models.LineSymbolGroup
+		e.Orm.Model(&models.LineSymbolGroup{}).Where("id = ?", utility.StringToInt(batchReq.SymbolGroupId)).Find(&symbolGroupInfo)
+		if symbolGroupInfo.Id <= 0 || symbolGroupInfo.Symbol == "" {
+			*errs = append(*errs, errors.New(fmt.Sprintf("选择的交易对组:%s不存在或交易对组的交易对为空", batchReq.SymbolGroupId)))
+			return nil
+		}
+		batchReq.Symbol = symbolGroupInfo.Symbol
+	}
+
+	//脚本次数
+	if batchReq.OrderNum > 0 {
+		var tickerSymbol string
+		if batchReq.SymbolType == global.SYMBOL_SPOT {
+			tickerSymbol = helper.DefaultRedis.Get(rediskey.SpotSymbolTicker).Val()
+		} else {
+			tickerSymbol = helper.DefaultRedis.Get(rediskey.FutSymbolTicker).Val()
+		}
+		apiUserIds := strings.Split(batchReq.ApiUserId, ",")
+		if batchReq.Script == "1" {
+			//scriptLogs := make([]models.LinePreScript, 0)
+			logParams := *batchReq
+			for _, id := range apiUserIds {
+				for j := 1; j <= batchReq.OrderNum; j++ {
+					var log models.LinePreScript
+					logParams.SaveTemplate = "0"
+					logParams.TemplateName = ""
+					logParams.Script = ""
+					marshal, _ := sonic.Marshal(logParams)
+					log.ApiId = int64(utility.StringToInt(id))
+					log.ScriptNum = int64(j)
+					log.ScriptParams = string(marshal)
+					log.AdminId = 0
+					log.Status = "0"
+					//scriptLogs = append(scriptLogs, log)
+					err := e.Orm.Model(&models.LinePreScript{}).Create(&log).Error
+					if err != nil {
+						*errs = append(*errs, errors.New(fmt.Sprintf("记录脚本失败:%+v", err.Error())))
+						return nil
+					}
+					helper.DefaultRedis.RPushList(rediskey.PreOrderScriptList, utility.IntToString(log.Id))
+				}
+			}
+
+			return nil
+		}
+		for _, id := range apiUserIds {
+			for j := 0; j < batchReq.OrderNum; j++ {
+				symbols := strings.Split(batchReq.Symbol, ",")
+				for _, symbol := range symbols {
+					var req dto.LineAddPreOrderReq
+					req.ExchangeType = batchReq.ExchangeType
+					req.OrderType = batchReq.OrderType
+					req.Symbol = symbol
+					req.ApiUserId = id
+					req.Site = batchReq.Site
+					req.BuyPrice = batchReq.BuyPrice
+					req.PricePattern = batchReq.PricePattern
+					req.Price = batchReq.Price
+					req.Profit = batchReq.Profit
+					req.StopPrice = batchReq.StopPrice
+					req.PriceType = batchReq.PriceType
+					req.CoverType = batchReq.CoverType
+					req.ExpireHour = batchReq.ExpireHour
+					req.MainOrderType = batchReq.MainOrderType
+					req.HedgeOrderType = batchReq.HedgeOrderType
+
+					e.AddPreOrder(&req, p, errs, tickerSymbol)
+				}
+			}
+		}
+		return nil
+	} else {
+		*errs = append(*errs, errors.New("请选择运行次数"))
+		return nil
+	}
+}
+
+// QuickAddPreOrder 模板快速下单
+func (e *LinePreOrder) QuickAddPreOrder(quickReq *dto.QuickAddPreOrderReq, p *actions.DataPermission, errs *[]error) error {
+	templateLogs := make([]models.LineOrderTemplateLogs, 0)
+	e.Orm.Model(&models.LineOrderTemplateLogs{}).Where("id in ?", strings.Split(quickReq.Ids, ",")).Find(&templateLogs)
+	for _, log := range templateLogs {
+		//单独添加
+		if log.Type == 1 {
+			var addPreOrderParams dto.LineAddPreOrderReq
+			sonic.Unmarshal([]byte(log.Params), &addPreOrderParams)
+
+			var tickerSymbol string
+			if addPreOrderParams.OrderType == global.SYMBOL_SPOT {
+				tickerSymbol = helper.DefaultRedis.Get(rediskey.SpotSymbolTicker).Val()
+			} else {
+				tickerSymbol = helper.DefaultRedis.Get(rediskey.FutSymbolTicker).Val()
+			}
+			err := e.AddPreOrder(&addPreOrderParams, p, errs, tickerSymbol)
+			if err != nil {
+				*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%s 获取交易对:%s 生成订单失败", addPreOrderParams.ApiUserId, addPreOrderParams.Symbol)))
+				continue
+			}
+		}
+
+		//批量添加
+		if log.Type == 2 {
+			var batchAddPreOrder dto.LineBatchAddPreOrderReq
+			sonic.Unmarshal([]byte(log.Params), &batchAddPreOrder)
+			e.AddBatchPreOrder(&batchAddPreOrder, p, errs)
+		}
+	}
+	return nil
+}
+
+// Lever 设置杠杆
+func (e *LinePreOrder) Lever(req *dto.LeverReq, p *actions.DataPermission, errs *[]error) {
+	users := make([]models.LineApiUser, 0)
+	err := e.Orm.Model(&models.LineApiUser{}).Where("id in  ? ", strings.Split(req.ApiUserIds, ",")).Find(&users).Error
+	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+		*errs = append(*errs, errors.New(fmt.Sprintf("设置杠杆失败:%+v", err.Error())))
+		return
+	}
+	var symbols string
+	if req.Symbol != "" {
+		symbols = req.Symbol
+	} else {
+		var symbolGroupInfo models.LineSymbolGroup
+		e.Orm.Model(&models.LineSymbolGroup{}).Where("id = ?", req.GroupId).Find(&symbolGroupInfo)
+		symbols = symbolGroupInfo.Symbol
+	}
+
+	if req.IsAll == 1 {
+		lineSymbols := make([]models.LineSymbol, 0)
+		futSymbols := make([]string, 0)
+		e.Orm.Model(&models.LineSymbol{}).Where("type = '2' AND switch = '1'").Find(&lineSymbols)
+		for _, symbol := range lineSymbols {
+			futSymbols = append(futSymbols, symbol.Symbol)
+		}
+		if len(futSymbols) != 0 {
+			symbols = strings.Join(futSymbols, ",")
+		}
+	}
+
+	for _, user := range users {
+		var client *helper.BinanceClient
+		if user.UserPass == "" {
+			client, _ = helper.NewBinanceClient(user.ApiKey, user.ApiSecret, "", user.IpAddress)
+		} else {
+			client, _ = helper.NewBinanceClient(user.ApiKey, user.ApiSecret, "socks5", user.UserPass+"@"+user.IpAddress)
+		}
+		//client.SendFuturesRequestAuth("/")
+		symbolsSlice := strings.Split(symbols, ",")
+		for _, s := range symbolsSlice {
+			params := map[string]string{
+				"leverage": utility.IntToString(req.Leverage),
+				"symbol":   s,
+			}
+			resp, _, err := client.SendFuturesRequestAuth("/fapi/v1/leverage", "POST", params)
+			if err != nil {
+				*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 交易对:%s 设置杠杆失败:%+v", user.Id, s, err.Error())))
+				continue
+			}
+			var dataMap map[string]interface{}
+			if err := sonic.Unmarshal(resp, &dataMap); err != nil {
+				*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 交易对:%s 设置杠杆失败:%+v", user.Id, s, err.Error())))
+				continue
+			}
+
+			if _, ok := dataMap["leverage"]; !ok {
+				*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 交易对:%s 设置杠杆失败:%+v", user.Id, s, dataMap["message"])))
+				continue
+			}
+		}
+	}
+	return
+}
+
+// MarginType 设置仓位模式
+func (e *LinePreOrder) MarginType(req *dto.MarginTypeReq, p *actions.DataPermission, errs *[]error) {
+	users := make([]models.LineApiUser, 0)
+	err := e.Orm.Model(&models.LineApiUser{}).Where("id in  ? ", strings.Split(req.ApiUserIds, ",")).Find(&users).Error
+	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+		*errs = append(*errs, errors.New(fmt.Sprintf("设置杠杆失败:%+v", err.Error())))
+		return
+	}
+	var symbols string
+	if req.Symbol != "" {
+		symbols = req.Symbol
+	} else {
+		var symbolGroupInfo models.LineSymbolGroup
+		e.Orm.Model(&models.LineSymbolGroup{}).Where("id = ?", req.GroupId).Find(&symbolGroupInfo)
+		symbols = symbolGroupInfo.Symbol
+	}
+
+	if req.IsAll == 1 {
+		lineSymbols := make([]models.LineSymbol, 0)
+		futSymbols := make([]string, 0)
+		e.Orm.Model(&models.LineSymbol{}).Where("type = '2' AND switch = '1'").Find(&lineSymbols)
+		for _, symbol := range lineSymbols {
+			futSymbols = append(futSymbols, symbol.Symbol)
+		}
+		if len(futSymbols) != 0 {
+			symbols = strings.Join(futSymbols, ",")
+		}
+	}
+
+	for _, user := range users {
+		var client *helper.BinanceClient
+		if user.UserPass == "" {
+			client, _ = helper.NewBinanceClient(user.ApiKey, user.ApiSecret, "", user.IpAddress)
+		} else {
+			client, _ = helper.NewBinanceClient(user.ApiKey, user.ApiSecret, "socks5", user.UserPass+"@"+user.IpAddress)
+		}
+		//client.SendFuturesRequestAuth("/")
+		symbolsSlice := strings.Split(symbols, ",")
+		for _, s := range symbolsSlice {
+			params := map[string]string{
+				"marginType": req.MarginType,
+				"symbol":     s,
+			}
+			resp, _, err := client.SendFuturesRequestAuth("/fapi/v1/marginType", "POST", params)
+			if err != nil {
+				*errs = append(*errs, fmt.Errorf("api_id:%d 交易对:%s 设置仓位失败:%+v", user.Id, s, err.Error()))
+				continue
+			}
+			var dataMap map[string]interface{}
+			if err := sonic.Unmarshal(resp, &dataMap); err != nil {
+				*errs = append(*errs, fmt.Errorf("api_id:%d 交易对:%s 设置仓位失败:%+v", user.Id, s, err.Error()))
+				continue
+			}
+			code, ok := dataMap["code"]
+			if !ok {
+				*errs = append(*errs, fmt.Errorf("api_id:%d 交易对:%s 设置仓位失败:%+v", user.Id, s, dataMap["message"]))
+				continue
+			}
+			if code.(float64) != 200 {
+				*errs = append(*errs, fmt.Errorf("api_id:%d 交易对:%s 设置仓位失败:%+v", user.Id, s, dataMap["message"]))
+				continue
+			}
+		}
+	}
+}
+
+// CancelOpenOrder 取消委托
+func (e *LinePreOrder) CancelOpenOrder(req *dto.CancelOpenOrderReq, errs *[]error) {
+	newClientOrderIdList := make([]string, 0)
+	var apiUserInfo models.LineApiUser
+	e.Orm.Model(&models.LineApiUser{}).Where("id = ?", req.ApiId).Find(&apiUserInfo)
+	futApi := binanceservice.FutRestApi{}
+	spotApi := binanceservice.SpotRestApi{}
+
+	//取消指定订单号的委托
+	if req.OrderSn != "" && req.Symbol != "" {
+		var err error
+		var orderInfo models.LinePreOrder
+		e.Orm.Model(&models.LinePreOrder{}).Where("symbol = ? AND order_sn = ? AND status = '5'", req.Symbol, req.OrderSn).Find(&orderInfo)
+		if orderInfo.Id <= 0 {
+			*errs = append(*errs, errors.New(fmt.Sprintf("取消委托失败:%+v", "未找到可以取消的委托")))
+			return
+		}
+		if req.OrderType == 1 { //现货
+			err = spotApi.CancelOpenOrderByOrderSn(apiUserInfo, req.Symbol, req.OrderSn)
+		} else {
+			newClientOrderIdList = append(newClientOrderIdList, req.OrderSn)
+			err = futApi.CancelBatchFutOrder(apiUserInfo, req.Symbol, newClientOrderIdList)
+		}
+		if err != nil {
+			*errs = append(*errs, errors.New(fmt.Sprintf("取消委托失败:%+v", err.Error())))
+			return
+		}
+	} else {
+		var orderList []models.LinePreOrder
+		e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND pid = 0 status = '5' AND order_type = ?", req.ApiId, strconv.Itoa(req.OrderType)).Find(&orderList)
+		if len(orderList) <= 0 {
+			*errs = append(*errs, errors.New(fmt.Sprintf("没有可撤销的委托")))
+			return
+		}
+		for _, order := range orderList {
+
+			if order.OrderType == global.SYMBOL_SPOT {
+				err := spotApi.CancelOpenOrderByOrderSn(apiUserInfo, req.Symbol, req.OrderSn)
+				if err != nil {
+					*errs = append(*errs, errors.New(fmt.Sprintf("取消委托失败:%+v", err.Error())))
+					continue
+				}
+			} else {
+				err := futApi.CancelBatchFutOrder(apiUserInfo, order.Symbol, []string{order.OrderSn})
+				if err != nil {
+					*errs = append(*errs, errors.New(fmt.Sprintf("取消委托失败:%+v", err.Error())))
+					continue
+				}
+			}
+		}
+	}
+}
+
+// ClearAll 一键清除数据
+func (e *LinePreOrder) ClearAll() error {
+	_, err := helper.DefaultRedis.BatchDeleteKeys([]string{rediskey.PreSpotOrderList, rediskey.PreFutOrderList,
+		rediskey.SpotStopLossList, rediskey.FuturesStopLossList, rediskey.SpotAddPositionList, rediskey.FuturesAddPositionList,
+	})
+	if err != nil {
+		e.Log.Errorf("Service RemoveLinePreOrder error:%s \r\n", err)
+		return err
+	}
+	prefixs := []string{
+		"api_user_hold",
+		"spot_trigger_lock",
+		"fut_trigger_lock",
+		"fut_trigger_stop_lock",
+		"spot_trigger_stop_lock",
+		"spot_addposition_trigger",
+		"fut_addposition_trigger",
+		"spot_hedge_close_position",
+		"futures_hedge_close_position",
+		"spot_callback",
+		"fut_callback",
+		"holde_a",
+		"holde_b",
+		"stop_loss_markt",
+	}
+	err = helper.DefaultRedis.DeleteKeysByPrefix(prefixs...)
+	if err != nil {
+		e.Log.Errorf("Service RemoveLinePreOrder error:%s \r\n", err)
+		return err
+	}
+	e.Orm.Model(&models.LinePreOrder{}).Exec("TRUNCATE TABLE line_pre_order")
+	e.Orm.Model(&models.LinePreOrder{}).Exec("TRUNCATE TABLE line_pre_order_status")
+	return err
+}
+
+func (e *LinePreOrder) ManuallyCover(req dto.ManuallyCover, p *actions.DataPermission, errs *[]error) {
+	symbols := strings.Split(req.Symbols, ",")
+	futApi := binanceservice.FutRestApi{}
+	spotApi := binanceservice.SpotRestApi{}
+	addPositionService := binanceservice.AddPosition{Db: e.Orm}
+
+	var wg sync.WaitGroup // 用于等待所有协程完成
+	var mu sync.Mutex     // 用于保护错误切片的并发访问
+	for _, symbol := range symbols {
+		wg.Add(1) // 增加协程计数
+		go func(symbol string) {
+			defer wg.Done() // 协程完成后减少计数
+			if err := addPositionService.ProcessSymbol(req, symbol, &futApi, &spotApi, errs); err != nil {
+				mu.Lock() // 加锁保护错误切片
+				*errs = append(*errs, err)
+				mu.Unlock() // 解锁
+			}
+		}(symbol)
+	}
+	wg.Wait() // 等待所有协程完成
+}
+
+// GetTargetSymbol 获取目标交易对信息
+func (e *LinePreOrder) GetTargetSymbol(symbol string, symbolType int) (string, bool, models.LineSymbol, error) {
+	var targetSymbol string
+	var notUsdt bool
+	var symbolInfo models.LineSymbol
+
+	// 处理非 USDT 交易对
+	if !strings.HasSuffix(symbol, "USDT") {
+		notUsdt = true
+		if err := e.Orm.Model(&models.LineSymbol{}).Where("symbol = ? AND type = ?", symbol, utility.IntToString(symbolType)).Find(&symbolInfo).Error; err != nil {
+			return "", false, models.LineSymbol{}, err
+		}
+		if symbolInfo.Id <= 0 {
+			return "", false, models.LineSymbol{}, fmt.Errorf("未找到交易对信息")
+		}
+		targetSymbol = symbolInfo.BaseAsset + "USDT"
+	} else {
+		targetSymbol = symbol
+	}
+
+	return targetSymbol, notUsdt, symbolInfo, nil
+}
+
+func (e *LinePreOrder) GetOrderInfo(req dto.ManuallyCover, symbol, orderType, site, status string) (models.LinePreOrder, error) {
+	var orderInfo models.LinePreOrder
+	if err := e.Orm.Model(models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND order_type = ? AND site = ? AND status = ?", req.ApiId, symbol, orderType, site, status).Find(&orderInfo).Error; err != nil {
+		return models.LinePreOrder{}, err
+	}
+	if orderInfo.Id <= 0 {
+		return models.LinePreOrder{}, fmt.Errorf("未找到主仓信息")
+	}
+	return orderInfo, nil
+}
+
+func (e *LinePreOrder) GetFutOrderInfo(req dto.ManuallyCover, symbol, orderType, status string) (models.LinePreOrder, error) {
+	var orderInfo models.LinePreOrder
+	if err := e.Orm.Model(models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND order_type = ? AND status = ? AND cover_type = 2", req.ApiId, symbol, orderType, status).Find(&orderInfo).Error; err != nil {
+		return models.LinePreOrder{}, err
+	}
+	if orderInfo.Id <= 0 {
+		return models.LinePreOrder{}, fmt.Errorf("未找到主仓信息")
+	}
+	return orderInfo, nil
+}
+
+// GetFutSpotOrderInfo 获取合约对现货的订单信息
+func (e *LinePreOrder) GetFutSpotOrderInfo(req dto.ManuallyCover, symbol, orderType, status string) (models.LinePreOrder, error) {
+	var orderInfo models.LinePreOrder
+	if err := e.Orm.Model(models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND order_type = ? AND status = ? AND cover_type = 3", req.ApiId, symbol, orderType, status).Find(&orderInfo).Error; err != nil {
+		return models.LinePreOrder{}, err
+	}
+	if orderInfo.Id <= 0 {
+		return models.LinePreOrder{}, fmt.Errorf("未找到主仓信息")
+	}
+	return orderInfo, nil
+}
+
+// CalculateAmount 计算加仓数量
+func (e *LinePreOrder) CalculateAmount(req dto.ManuallyCover, totalNum, lastPrice decimal.Decimal, amountDigit int, notUsdt bool, symbolInfo models.LineSymbol) (decimal.Decimal, error) {
+	var amt decimal.Decimal
+	if req.CoverType == 1 {
+		decimalValue := utility.StringToDecimal(req.Value).Div(decimal.NewFromInt(100))
+		amt = totalNum.Mul(decimalValue)
+	} else {
+		decimalValue := utility.StringToDecimal(req.Value)
+		if notUsdt {
+			tickerSymbolMaps := make([]dto.Ticker, 0)
+			tickerSymbol := helper.DefaultRedis.Get(rediskey.SpotSymbolTicker).Val()
+			if err := sonic.Unmarshal([]byte(tickerSymbol), &tickerSymbolMaps); err != nil {
+				return decimal.Zero, err
+			}
+
+			var tickerPrice decimal.Decimal
+			for _, symbolMap := range tickerSymbolMaps {
+				if symbolMap.Symbol == strings.ToUpper(symbolInfo.BaseAsset+"USDT") {
+					tickerPrice, _ = decimal.NewFromString(symbolMap.Price)
+					break
+				}
+			}
+
+			for _, symbolMap := range tickerSymbolMaps {
+				if symbolMap.Symbol == strings.ToUpper(symbolInfo.QuoteAsset+"USDT") {
+					uTickerPrice, _ := decimal.NewFromString(symbolMap.Price)
+					div := tickerPrice.Div(decimal.NewFromInt(1).Div(uTickerPrice))
+					amt = decimalValue.Div(div)
+					break
+				}
+			}
+		} else {
+			amt = decimalValue.Div(lastPrice)
+		}
+	}
+	return amt.Truncate(int32(amountDigit)), nil
+}
+
+// SpotClosePosition 现货单个交易对平仓
+func (e *LinePreOrder) SpotClosePosition(position *dto.ClosePosition, errs *[]error) {
+	var apiUserInfo models.LineApiUser
+	e.Orm.Model(&models.LineApiUser{}).Where("id = ?", position.ApiId).Find(&apiUserInfo)
+	client := binanceservice.GetClient(&apiUserInfo)
+
+	resp, _, err := client.SendSpotAuth("/api/v3/account", "GET", map[string]interface{}{
+		"omitZeroBalances": true,
+	})
+
+	if err != nil {
+		*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 获取账户信息失败", position.ApiId)))
+		return
+	}
+	var balanceInfo binanceservice.SpotAccountInfo
+	sonic.Unmarshal(resp, &balanceInfo)
+
+	if len(balanceInfo.Balances) == 0 {
+		*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 没有可平仓的交易对", position.ApiId)))
+	}
+
+	//查询已经开仓的现货交易对
+	var spotList []models.LinePreOrder
+	if position.Symbol == "" { //全平
+		e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ?  AND status = '9' AND pid = 0 AND order_type = '1'", position.ApiId).Find(&spotList)
+	} else {
+		e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND status = '9' AND pid = 0 AND order_type = '1'", position.ApiId, position.Symbol).Find(&spotList)
+	}
+	if len(spotList) <= 0 {
+		*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 没有可平仓的交易对", position.ApiId)))
+	}
+	api := binanceservice.SpotRestApi{}
+
+	for _, list := range spotList {
+		for _, balance := range balanceInfo.Balances {
+			suffix := utility.ReplaceSuffix(list.Symbol, list.QuoteSymbol, "")
+			if utility.StringToDecimal(balance.Free).GreaterThan(decimal.Zero) && balance.Asset == suffix {
+				//锁仓数量大于0
+				if utility.StringToDecimal(balance.Locked).GreaterThan(decimal.Zero) {
+					//撤销之前的委托
+					client.SendSpotAuth("/api/v3/openOrders", "DELETE", map[string]string{
+						"symbol": list.Symbol,
+					})
+				}
+				key := fmt.Sprintf("%s:%s", global.TICKER_SPOT, list.Symbol)
+				tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, key)
+				total := utility.StringToDecimal(balance.Free).Add(utility.StringToDecimal(balance.Locked)).Truncate(int32(tradeSet.AmountDigit))
+				lastPrice := api.GetSpotSymbolLastPrice(list.Symbol)
+				var price decimal.Decimal
+				paramsMaps := make(map[string]string)
+				if total.GreaterThan(decimal.NewFromFloat(tradeSet.MinQty)) {
+					paramsMaps = map[string]string{
+						"symbol":           list.Symbol,
+						"side":             "SELL",
+						"quantity":         total.String(),
+						"type":             "LIMIT",
+						"newClientOrderId": utility.Int64ToString(snowflakehelper.GetOrderId()),
+						"timeInForce":      "GTC",
+					}
+					price = lastPrice.Mul(decimal.NewFromInt(1).Sub(utility.StringToDecimal(position.Rate).Div(decimal.NewFromInt(100)))).Truncate(int32(tradeSet.PriceDigit))
+					paramsMaps["price"] = price.String()
+				} else {
+					*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 下单数量小于最小下单数量", position.ApiId)))
+					continue
+				}
+				order := models.LinePreOrder{
+					ExchangeType:   global.EXCHANGE_BINANCE,
+					Pid:            list.Id,
+					ApiId:          list.ApiId,
+					GroupId:        "0",
+					Symbol:         list.Symbol,
+					QuoteSymbol:    list.QuoteSymbol,
+					SignPrice:      lastPrice.String(),
+					SignPriceType:  "new",
+					Rate:           position.Rate,
+					Price:          price.String(),
+					Num:            total.String(),
+					BuyPrice:       "0",
+					Site:           "SELL",
+					OrderSn:        paramsMaps["newClientOrderId"],
+					OrderType:      3,
+					Desc:           "",
+					Status:         0,
+					AdminId:        "0",
+					CloseType:      0,
+					CoverType:      list.CoverType,
+					ExpireTime:     time.Now().Add(time.Hour * 24 * 30),
+					MainOrderType:  list.MainOrderType,
+					HedgeOrderType: list.HedgeOrderType,
+					Child:          nil,
+				}
+				err := e.Orm.Model(&models.LinePreOrder{}).Create(&order).Error
+				if err != nil {
+					*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 生成订单失败:%s", position.ApiId, err.Error())))
+					continue
+				}
+
+				//下订单
+				_, _, err = client.SendSpotAuth("/api/v3/order", "POST", paramsMaps)
+				if err != nil {
+					*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 币安下订单失败:%s", position.ApiId, err.Error())))
+					continue
+				}
+				binanceservice.MainClosePositionClearCache(list.Id, list.CoverType)
+			}
+		}
+	}
+}
+
+// FutClosePosition 合约平仓
+func (e *LinePreOrder) FutClosePosition(position *dto.ClosePosition, errs *[]error) {
+	var apiUserInfo models.LineApiUser
+	e.Orm.Model(&models.LineApiUser{}).Where("id = ?", position.ApiId).Find(&apiUserInfo)
+	//client := binanceservice.GetClient(&apiUserInfo)
+
+	//查询已经开仓的合约交易对
+	var futList []models.LinePreOrder
+	if position.Symbol == "" {
+		e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND status = '13' AND pid = 0 AND order_type = '2'", position.ApiId).Find(&futList)
+	} else {
+		e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND status = '13' AND pid = 0 AND order_type = '2'", position.ApiId, position.Symbol).Find(&futList)
+	}
+	if len(futList) <= 0 {
+		*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 没有可平仓的交易对", position.ApiId)))
+		return
+	}
+
+	api := binanceservice.FutRestApi{}
+
+	for _, list := range futList {
+		risks, err := api.GetPositionV3(&apiUserInfo, list.Symbol)
+		if err != nil {
+			*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 获取仓位信息时 没有可平仓的交易对 err: %s", position.ApiId, err)))
+			continue
+		}
+
+		key := fmt.Sprintf(global.TICKER_FUTURES, list.SymbolType, list.Symbol)
+		tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, key)
+		lastPrice := api.GetFutSymbolLastPrice(list.Symbol)
+		for _, risk := range risks {
+			positionAmt := utility.StringToDecimal(risk.PositionAmt)
+			var riskSide string
+			var orderSide string
+			if positionAmt.GreaterThan(decimal.Zero) {
+				riskSide = "BUY"
+			} else {
+				riskSide = "SELL"
+			}
+			if riskSide == list.Site {
+				var price decimal.Decimal
+				if list.Site == "BUY" && risk.PositionSide == "LONG" { //做多
+					//根据仓位数量去平多
+					orderSide = "SELL"
+					price = lastPrice.Mul(decimal.NewFromInt(1).Add(utility.StringToDecimal(position.Rate).Div(decimal.NewFromInt(100)))).Truncate(int32(tradeSet.PriceDigit))
+				} else if list.Site == "SELL" && risk.PositionSide == "SHORT" {
+					orderSide = "BUY"
+					price = lastPrice.Mul(decimal.NewFromInt(1).Sub(utility.StringToDecimal(position.Rate).Div(decimal.NewFromInt(100)))).Truncate(int32(tradeSet.PriceDigit))
+				}
+
+				if price.LessThanOrEqual(decimal.Zero) {
+					continue
+				}
+
+				if positionAmt.Abs().LessThanOrEqual(decimal.NewFromFloat(tradeSet.MinQty)) {
+					*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 下单数量小于最小下单数量", position.ApiId)))
+					continue
+				}
+
+				order := models.LinePreOrder{
+					Pid:            list.Id,
+					ApiId:          list.ApiId,
+					GroupId:        "0",
+					Symbol:         list.Symbol,
+					QuoteSymbol:    list.QuoteSymbol,
+					SignPrice:      lastPrice.String(),
+					SignPriceType:  "new",
+					Rate:           position.Rate,
+					Price:          price.String(),
+					Num:            positionAmt.Abs().String(),
+					BuyPrice:       "0",
+					Site:           orderSide,
+					OrderSn:        utility.Int64ToString(snowflakehelper.GetOrderId()),
+					OrderType:      3,
+					Desc:           "",
+					Status:         0,
+					AdminId:        "0",
+					CloseType:      0,
+					CoverType:      list.CoverType,
+					ExpireTime:     time.Now().Add(24 * 30 * time.Hour),
+					MainOrderType:  list.MainOrderType,
+					HedgeOrderType: list.HedgeOrderType,
+					Child:          nil,
+				}
+				err = e.Orm.Model(&models.LinePreOrder{}).Create(&order).Error
+				if err != nil {
+					*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 生成平仓单错误:%s", position.ApiId, err)))
+					continue
+				}
+
+				//撤销合约的委托
+				api.CancelAllFutOrder(apiUserInfo, list.Symbol)
+				//side=BUY&positionSide=LONG是开多,
+				//side=SELL&positionSide=LONG是平多,
+				//side=SELL&positionSide=SHORT是开空,
+				//side=BUY&positionSide=SHORT是平空。
+				if orderSide != "" {
+					if orderSide == "BUY" { //平空
+						err = api.ClosePosition(list.Symbol, order.OrderSn, utility.StringToDecimal(order.Num), "BUY", "SHORT", apiUserInfo, "LIMIT", "0", price)
+					} else { // 平多
+						err = api.ClosePosition(list.Symbol, order.OrderSn, utility.StringToDecimal(order.Num), "SELL", "LONG", apiUserInfo, "LIMIT", "0", price)
+					}
+					if err != nil {
+						*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 币安平仓单错误:%s", position.ApiId, err)))
+						continue
+					}
+					// 主单平仓删除缓存
+					binanceservice.MainClosePositionClearCache(list.Id, list.CoverType)
+				}
+			}
+		}
+	}
+
+}
+
+// ClearUnTriggered 清除待触发的交易对
+func (e *LinePreOrder) ClearUnTriggered() error {
+	var orderLists []models.LinePreOrder
+	e.Orm.Model(&models.LinePreOrder{}).Where("pid = 0 AND status = '0'").Find(&orderLists).Unscoped().Delete(&models.LinePreOrder{})
+
+	for _, order := range orderLists {
+		redisList := dto.PreOrderRedisList{
+			Id:          order.Id,
+			Symbol:      order.Symbol,
+			Price:       order.Price,
+			Site:        order.Site,
+			ApiId:       order.ApiId,
+			OrderSn:     order.OrderSn,
+			QuoteSymbol: order.QuoteSymbol,
+		}
+		tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf("%s:%s", global.TICKER_SPOT, order.Symbol))
+		redisList.Price = utility.StringToDecimal(redisList.Price).Truncate(int32(tradeSet.PriceDigit)).String()
+		marshal, _ := sonic.Marshal(redisList)
+		if order.SymbolType == 1 {
+			helper.DefaultRedis.LRem(rediskey.PreFutOrderList, string(marshal))
+		} else {
+			helper.DefaultRedis.LRem(rediskey.PreSpotOrderList, string(marshal))
+		}
+		e.Orm.Model(&models.LinePreOrder{}).Where("pid = ?", order.Id).Unscoped().Delete(&models.LinePreOrder{})
+	}
+	return nil
+}
+
+func (e *LinePreOrder) QueryOrder(req *dto.QueryOrderReq) (res interface{}, err error) {
+	var apiUserInfo models.LineApiUser
+	e.Orm.Model(&models.LineApiUser{}).Where("id = ?", req.ApiId).Find(&apiUserInfo)
+	var client *helper.BinanceClient
+
+	if apiUserInfo.UserPass == "" {
+		client, _ = helper.NewBinanceClient(apiUserInfo.ApiKey, apiUserInfo.ApiSecret, "", apiUserInfo.IpAddress)
+	} else {
+		client, _ = helper.NewBinanceClient(apiUserInfo.ApiKey, apiUserInfo.ApiSecret, "socks5", apiUserInfo.UserPass+"@"+apiUserInfo.IpAddress)
+	}
+	params := map[string]string{"symbol": req.Symbol, "origClientOrderId": req.OrderSn}
+	if req.OrderType == 1 { //现货
+		var resp dto.QuickAddPreOrderReq
+		auth, code, err := client.SendSpotAuth("/api/v3/order", "GET", params)
+		if code != 200 {
+			return nil, err
+		}
+
+		if err != nil {
+			return nil, err
+		}
+		sonic.Unmarshal(auth, &resp)
+		return resp, nil
+	}
+
+	if req.OrderType == 2 {
+		var resp dto.FutQueryOrderResp
+		auth, code, err := client.SendFuturesRequestAuth("/fapi/v1/order", "GET", params)
+		if code != 200 {
+			return nil, err
+		}
+		if err != nil {
+			return nil, err
+		}
+		sonic.Unmarshal(auth, &resp)
+		return resp, nil
+	}
+	return nil, err
+}
diff --git a/app/admin/service/line_pre_order_status.go b/app/admin/service/line_pre_order_status.go
new file mode 100644
index 0000000..4a36bd8
--- /dev/null
+++ b/app/admin/service/line_pre_order_status.go
@@ -0,0 +1,109 @@
+package service
+
+import (
+	"errors"
+
+    "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LinePreOrderStatus struct {
+	service.Service
+}
+
+// GetPage 获取LinePreOrderStatus列表
+func (e *LinePreOrderStatus) GetPage(c *dto.LinePreOrderStatusGetPageReq, p *actions.DataPermission, list *[]models.LinePreOrderStatus, count *int64) error {
+	var err error
+	var data models.LinePreOrderStatus
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LinePreOrderStatusService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LinePreOrderStatus对象
+func (e *LinePreOrderStatus) Get(d *dto.LinePreOrderStatusGetReq, p *actions.DataPermission, model *models.LinePreOrderStatus) error {
+	var data models.LinePreOrderStatus
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLinePreOrderStatus error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LinePreOrderStatus对象
+func (e *LinePreOrderStatus) Insert(c *dto.LinePreOrderStatusInsertReq) error {
+    var err error
+    var data models.LinePreOrderStatus
+    c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LinePreOrderStatusService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LinePreOrderStatus对象
+func (e *LinePreOrderStatus) Update(c *dto.LinePreOrderStatusUpdateReq, p *actions.DataPermission) error {
+    var err error
+    var data = models.LinePreOrderStatus{}
+    e.Orm.Scopes(
+            actions.Permission(data.TableName(), p),
+        ).First(&data, c.GetId())
+    c.Generate(&data)
+
+    db := e.Orm.Save(&data)
+    if err = db.Error; err != nil {
+        e.Log.Errorf("LinePreOrderStatusService Save error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权更新该数据")
+    }
+    return nil
+}
+
+// Remove 删除LinePreOrderStatus
+func (e *LinePreOrderStatus) Remove(d *dto.LinePreOrderStatusDeleteReq, p *actions.DataPermission) error {
+	var data models.LinePreOrderStatus
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+        e.Log.Errorf("Service RemoveLinePreOrderStatus error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权删除该数据")
+    }
+	return nil
+}
diff --git a/app/admin/service/line_pre_script.go b/app/admin/service/line_pre_script.go
new file mode 100644
index 0000000..c4eb0d1
--- /dev/null
+++ b/app/admin/service/line_pre_script.go
@@ -0,0 +1,109 @@
+package service
+
+import (
+	"errors"
+
+    "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LinePreScript struct {
+	service.Service
+}
+
+// GetPage 获取LinePreScript列表
+func (e *LinePreScript) GetPage(c *dto.LinePreScriptGetPageReq, p *actions.DataPermission, list *[]models.LinePreScript, count *int64) error {
+	var err error
+	var data models.LinePreScript
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LinePreScriptService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LinePreScript对象
+func (e *LinePreScript) Get(d *dto.LinePreScriptGetReq, p *actions.DataPermission, model *models.LinePreScript) error {
+	var data models.LinePreScript
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLinePreScript error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LinePreScript对象
+func (e *LinePreScript) Insert(c *dto.LinePreScriptInsertReq) error {
+    var err error
+    var data models.LinePreScript
+    c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LinePreScriptService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LinePreScript对象
+func (e *LinePreScript) Update(c *dto.LinePreScriptUpdateReq, p *actions.DataPermission) error {
+    var err error
+    var data = models.LinePreScript{}
+    e.Orm.Scopes(
+            actions.Permission(data.TableName(), p),
+        ).First(&data, c.GetId())
+    c.Generate(&data)
+
+    db := e.Orm.Save(&data)
+    if err = db.Error; err != nil {
+        e.Log.Errorf("LinePreScriptService Save error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权更新该数据")
+    }
+    return nil
+}
+
+// Remove 删除LinePreScript
+func (e *LinePreScript) Remove(d *dto.LinePreScriptDeleteReq, p *actions.DataPermission) error {
+	var data models.LinePreScript
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+        e.Log.Errorf("Service RemoveLinePreScript error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权删除该数据")
+    }
+	return nil
+}
diff --git a/app/admin/service/line_price_limit.go b/app/admin/service/line_price_limit.go
new file mode 100644
index 0000000..30fd41e
--- /dev/null
+++ b/app/admin/service/line_price_limit.go
@@ -0,0 +1,249 @@
+package service
+
+import (
+	"errors"
+	"fmt"
+	"go-admin/common/global"
+	"go-admin/common/helper"
+	ext "go-admin/config"
+	models2 "go-admin/models"
+	"go-admin/pkg/utility"
+	"sort"
+
+	"github.com/bytedance/sonic"
+	"github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LinePriceLimit struct {
+	service.Service
+}
+
+// GetPage 获取LinePriceLimit列表
+func (e *LinePriceLimit) GetPage(c *dto.LinePriceLimitGetPageReq, p *actions.DataPermission, list *[]models.LinePriceLimit, count *int64) error {
+	var err error
+	var data models.LinePriceLimit
+	tx := e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		)
+
+	if c.StartRange != "" {
+		tx = tx.Where("`range` >= ?", utility.StringToFloat64(c.StartRange))
+	}
+	if c.EndRange != "" {
+		tx = tx.Where("`range` <= ?", utility.StringToFloat64(c.EndRange))
+	}
+	err = tx.Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LinePriceLimitService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LinePriceLimit对象
+func (e *LinePriceLimit) Get(d *dto.LinePriceLimitGetReq, p *actions.DataPermission, model *models.LinePriceLimit) error {
+	var data models.LinePriceLimit
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLinePriceLimit error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LinePriceLimit对象
+func (e *LinePriceLimit) Insert(c *dto.LinePriceLimitInsertReq) error {
+	var err error
+	var data models.LinePriceLimit
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LinePriceLimitService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LinePriceLimit对象
+func (e *LinePriceLimit) Update(c *dto.LinePriceLimitUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var data = models.LinePriceLimit{}
+	e.Orm.Scopes(
+		actions.Permission(data.TableName(), p),
+	).First(&data, c.GetId())
+	c.Generate(&data)
+
+	db := e.Orm.Save(&data)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("LinePriceLimitService Save error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	return nil
+}
+
+// Remove 删除LinePriceLimit
+func (e *LinePriceLimit) Remove(d *dto.LinePriceLimitDeleteReq, p *actions.DataPermission) error {
+	var data models.LinePriceLimit
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveLinePriceLimit error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+	return nil
+}
+
+// UpRange 更新涨跌幅
+func (e *LinePriceLimit) UpRange() error {
+	var client *helper.BinanceClient
+	if ext.ExtConfig.ProxyUrl != "" {
+		client, _ = helper.NewBinanceClient("", "", "", "http://127.0.0.1:7890")
+	} else {
+		client, _ = helper.NewBinanceClient("", "", "", "")
+	}
+	request, httpCode, err := client.SendSpotRequest("/api/v3/ticker/24hr", "GET", map[string]string{})
+	if err != nil {
+		return errors.New(fmt.Sprintf("获取现货交易对涨跌幅失败 err:%s", err.Error()))
+	}
+
+	if httpCode != 200 {
+		return errors.New(fmt.Sprintf("获取现货交易对涨跌幅失败 http code:%d", httpCode))
+	}
+	spotTicker24HrAll := make([]dto.Ticker24Hr, 0)
+	spotTicker24Hr := make([]dto.Ticker24Hr, 0)
+
+	if err := sonic.Unmarshal(request, &spotTicker24HrAll); err != nil {
+		logger.Error("反序列化报错", err)
+		return err
+	}
+
+	for _, hr := range spotTicker24HrAll {
+		tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf("%s:%s", global.TICKER_SPOT, hr.Symbol))
+		if tradeSet.Currency != "" && tradeSet.Coin != "" {
+			spotTicker24Hr = append(spotTicker24Hr, hr)
+		}
+	}
+	sort.Slice(spotTicker24Hr, func(i, j int) bool {
+		return utility.StringToFloat64(spotTicker24Hr[i].PriceChangePercent) > utility.StringToFloat64(spotTicker24Hr[j].PriceChangePercent)
+	})
+
+	limits := make([]models.LinePriceLimit, 0)
+	for _, hr := range spotTicker24Hr {
+		var status string
+		if utility.StringToFloat64(hr.PriceChangePercent) > 0 {
+			status = "1"
+		} else {
+			status = "2"
+		}
+		limit := models.LinePriceLimit{
+			Symbol:          hr.Symbol,
+			Type:            "1",
+			DirectionStatus: status,
+			Range:           utility.StringToDecimal(hr.PriceChangePercent),
+		}
+		limits = append(limits, limit)
+	}
+	err = e.Orm.Transaction(func(tx *gorm.DB) error {
+
+		err2 := tx.Model(&models.LinePriceLimit{}).Where("type = ?", "1").Unscoped().Delete(&models.LinePriceLimit{}).Error
+		if err2 != nil {
+			return errors.New(fmt.Sprintf("删除现货交易对涨跌幅失败 err:%d", err))
+		}
+
+		err = tx.Model(&models.LinePriceLimit{}).Create(&limits).Error
+		if err != nil {
+			return errors.New(fmt.Sprintf("更新现货交易对涨跌幅失败 err:%d", err))
+		}
+		return nil
+	})
+	if err != nil {
+		return err
+	}
+
+	//更新合约涨跌幅
+	futuresRequest, code, err := client.SendFuturesRequest("/fapi/v1/ticker/24hr", "GET", map[string]string{})
+	if err != nil {
+		return errors.New(fmt.Sprintf("获取合约交易对涨跌幅失败 err:%s", err.Error()))
+	}
+
+	if code != 200 {
+		return errors.New(fmt.Sprintf("获取合约交易对涨跌幅失败 http code:%d", code))
+	}
+	futTicker24HrAll := make([]dto.FutTicker24Hr, 0)
+	futTicker24Hr := make([]dto.FutTicker24Hr, 0)
+	sonic.Unmarshal(futuresRequest, &futTicker24HrAll)
+	for _, hr := range futTicker24HrAll {
+		tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf("%s:%s", global.TICKER_FUTURES, hr.Symbol))
+		if tradeSet.Currency != "" && tradeSet.Coin != "" {
+			futTicker24Hr = append(futTicker24Hr, hr)
+		}
+	}
+	sort.Slice(futTicker24Hr, func(i, j int) bool {
+		return utility.StringToFloat64(futTicker24Hr[i].PriceChangePercent) > utility.StringToFloat64(futTicker24Hr[j].PriceChangePercent)
+	})
+
+	futLimits := make([]models.LinePriceLimit, 0)
+	for _, hr := range futTicker24Hr {
+		var status string
+		if utility.StringToFloat64(hr.PriceChangePercent) > 0 {
+			status = "1"
+		} else {
+			status = "2"
+		}
+		limit := models.LinePriceLimit{
+			Symbol:          hr.Symbol,
+			Type:            "2",
+			DirectionStatus: status,
+			Range:           utility.StringToDecimal(hr.PriceChangePercent),
+		}
+		futLimits = append(futLimits, limit)
+	}
+
+	err = e.Orm.Transaction(func(tx *gorm.DB) error {
+
+		err2 := tx.Model(&models.LinePriceLimit{}).Where("type = ?", "2").Unscoped().Delete(&models.LinePriceLimit{}).Error
+		if err2 != nil {
+			return errors.New(fmt.Sprintf("删除现货交易对涨跌幅失败 err:%d", err))
+		}
+
+		err = tx.Model(&models.LinePriceLimit{}).Create(&futLimits).Error
+		if err != nil {
+			return errors.New(fmt.Sprintf("更新现货交易对涨跌幅失败 err:%d", err))
+		}
+		return nil
+	})
+	if err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/app/admin/service/line_recharge.go b/app/admin/service/line_recharge.go
new file mode 100644
index 0000000..7fbd301
--- /dev/null
+++ b/app/admin/service/line_recharge.go
@@ -0,0 +1,109 @@
+package service
+
+import (
+	"errors"
+
+    "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineRecharge struct {
+	service.Service
+}
+
+// GetPage 获取LineRecharge列表
+func (e *LineRecharge) GetPage(c *dto.LineRechargeGetPageReq, p *actions.DataPermission, list *[]models.LineRecharge, count *int64) error {
+	var err error
+	var data models.LineRecharge
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineRechargeService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineRecharge对象
+func (e *LineRecharge) Get(d *dto.LineRechargeGetReq, p *actions.DataPermission, model *models.LineRecharge) error {
+	var data models.LineRecharge
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineRecharge error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineRecharge对象
+func (e *LineRecharge) Insert(c *dto.LineRechargeInsertReq) error {
+    var err error
+    var data models.LineRecharge
+    c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineRechargeService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineRecharge对象
+func (e *LineRecharge) Update(c *dto.LineRechargeUpdateReq, p *actions.DataPermission) error {
+    var err error
+    var data = models.LineRecharge{}
+    e.Orm.Scopes(
+            actions.Permission(data.TableName(), p),
+        ).First(&data, c.GetId())
+    c.Generate(&data)
+
+    db := e.Orm.Save(&data)
+    if err = db.Error; err != nil {
+        e.Log.Errorf("LineRechargeService Save error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权更新该数据")
+    }
+    return nil
+}
+
+// Remove 删除LineRecharge
+func (e *LineRecharge) Remove(d *dto.LineRechargeDeleteReq, p *actions.DataPermission) error {
+	var data models.LineRecharge
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+        e.Log.Errorf("Service RemoveLineRecharge error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权删除该数据")
+    }
+	return nil
+}
diff --git a/app/admin/service/line_symbol.go b/app/admin/service/line_symbol.go
new file mode 100644
index 0000000..7567182
--- /dev/null
+++ b/app/admin/service/line_symbol.go
@@ -0,0 +1,463 @@
+package service
+
+import (
+	"errors"
+	"fmt"
+	"strings"
+
+	"github.com/bytedance/sonic"
+	"github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"github.com/shopspring/decimal"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	"go-admin/common/const/rediskey"
+	cDto "go-admin/common/dto"
+	"go-admin/common/global"
+	"go-admin/common/helper"
+	commonModels "go-admin/models"
+	"go-admin/pkg/utility"
+	"go-admin/services/binanceservice"
+)
+
+type LineSymbol struct {
+	service.Service
+}
+
+// GetPage 获取LineSymbol列表
+func (e *LineSymbol) GetPage(c *dto.LineSymbolGetPageReq, p *actions.DataPermission, list *[]models.LineSymbol, count *int64) error {
+	var err error
+	var data models.LineSymbol
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineSymbolService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// GetSamePage 获取LineSymbol列表
+func (e *LineSymbol) GetSamePage(c *dto.LineSymbolGetPageReq, p *actions.DataPermission, list *[]models.LineSymbol, count *int64) error {
+	var err error
+	var data models.LineSymbol
+	tx := e.Orm.Model(&data).
+		Scopes(
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		)
+
+	scopes := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		)
+	if c.Symbol != "" {
+		tx.Where("symbol = ?", c.Symbol)
+		scopes.Where("symbol = ?", c.Symbol)
+	}
+	err = scopes.Select("count(id) as number").Group("symbol").Having("number > ?", 1).Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineSymbolService GetSamePage count:%s \r\n", err)
+		return err
+	}
+	err = tx.Select("count(id) as number,symbol").Group("symbol").Having("number > ?", 1).
+		Find(list).Limit(-1).Offset(-1).
+		Error
+
+	if err != nil {
+		e.Log.Errorf("LineSymbolService GetSamePage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineSymbol对象
+func (e *LineSymbol) Get(d *dto.LineSymbolGetReq, p *actions.DataPermission, model *models.LineSymbol) error {
+	var data models.LineSymbol
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineSymbol error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineSymbol对象
+func (e *LineSymbol) Insert(c *dto.LineSymbolInsertReq) error {
+	var err error
+	var data models.LineSymbol
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineSymbolService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineSymbol对象
+func (e *LineSymbol) Update(c *dto.LineSymbolUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var data = models.LineSymbol{}
+	e.Orm.Scopes(
+		actions.Permission(data.TableName(), p),
+	).First(&data, c.GetId())
+	c.Generate(&data)
+
+	db := e.Orm.Omit("api_id").Save(&data)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("LineSymbolService Save error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	return nil
+}
+
+// Remove 删除LineSymbol
+func (e *LineSymbol) Remove(d *dto.LineSymbolDeleteReq, p *actions.DataPermission) error {
+	var data models.LineSymbol
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveLineSymbol error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+	return nil
+}
+
+func (e *LineSymbol) GetSymbol() (data []models.LineSymbol, err error) {
+	var (
+		spotSymbol, futSymbol []models.LineSymbol
+	)
+	err = e.Orm.Model(&models.LineSymbol{}).Where("type = '1' AND switch = 1").Find(&spotSymbol).Error
+	if err != nil {
+		e.Log.Errorf("Service GetSpotSymbol error:%s \r\n", err)
+		return data, err
+	}
+	err = e.Orm.Model(&models.LineSymbol{}).Where("type = '2' AND switch = 1").Find(&futSymbol).Error
+	if err != nil {
+		e.Log.Errorf("Service GetFutSymbol error:%s \r\n", err)
+		return data, err
+	}
+	//取两个的交集
+	symbols := intersection(spotSymbol, futSymbol)
+	return symbols, nil
+}
+
+// 泛型交集函数
+func intersection[T comparable](slice1, slice2 []T) []T {
+	result := []T{}
+	seen := make(map[T]bool)
+
+	for _, v := range slice1 {
+		seen[v] = true
+	}
+
+	for _, v := range slice2 {
+		if seen[v] {
+			result = append(result, v)
+			delete(seen, v) // 防止重复添加
+		}
+	}
+
+	return result
+}
+
+// 重设现货交易对
+func (e *LineSymbol) ResetSpotSymbol() error {
+	tradeSets, deleteSymbols, err := binanceservice.GetSpotSymbols()
+
+	if err != nil {
+		logger.Error("获取币安现货交易对失败")
+		return err
+	}
+	symbols := make([]models.LineSymbol, 0)
+
+	sysConfig := SysConfig{Service: service.Service{Orm: e.Orm}}
+
+	var req = new(dto.SysConfigByKeyReq)
+	var resp = new(dto.GetSysConfigByKEYForServiceResp)
+	req.ConfigKey = "quote_volume_24hr"
+	sysConfig.GetWithKey(req, resp)
+	symbolBlack := make([]models.LineSymbolBlack, 0)
+	e.Orm.Model(&models.LineSymbolBlack{}).Where("type = '1'").Find(&symbolBlack)
+
+	type Ticker struct {
+		Symbol string `json:"symbol"`
+		Price  string `json:"price"`
+	}
+	tickerSymbol := helper.DefaultRedis.Get(rediskey.SpotSymbolTicker).Val()
+	tickerSymbolMaps := make([]Ticker, 0)
+	sonic.Unmarshal([]byte(tickerSymbol), &tickerSymbolMaps)
+	oldMapSymbols, err := getMapSymbol(e, "1")
+	if err != nil {
+		return err
+	}
+
+	for symbol, tradeSet := range tradeSets {
+
+		key := fmt.Sprintf("%s:%s", global.TICKER_SPOT, symbol)
+
+		//判断是否在黑名单里面
+		for _, black := range symbolBlack {
+			if black.Symbol == symbol {
+				helper.DefaultRedis.DeleteString(key)
+				deleteSymbols = append(deleteSymbols, symbol)
+				continue
+			}
+		}
+
+		val := helper.DefaultRedis.Get(key).Val()
+		var spotTicker24h commonModels.TradeSet
+		sonic.Unmarshal([]byte(val), &spotTicker24h)
+		//成交量
+		if spotTicker24h.Currency == "USDT" {
+			if utility.StringToFloat64(spotTicker24h.QuoteVolume) < utility.StringToFloat64(resp.ConfigValue) {
+				helper.DefaultRedis.DeleteString(key)
+				deleteSymbols = append(deleteSymbols, symbol)
+				continue
+			}
+		} else {
+
+			var tickerPrice decimal.Decimal
+			for _, symbolMap := range tickerSymbolMaps {
+				if symbolMap.Symbol == strings.ToUpper(spotTicker24h.Currency+"USDT") {
+					tickerPrice, _ = decimal.NewFromString(symbolMap.Price)
+				}
+			}
+			if tickerPrice.GreaterThan(decimal.Zero) {
+				mul := decimal.NewFromFloat(utility.StringToFloat64(spotTicker24h.QuoteVolume)).Mul(tickerPrice)
+				if mul.LessThan(decimal.NewFromFloat(utility.StringToFloat64(resp.ConfigValue))) {
+					helper.DefaultRedis.DeleteString(key)
+					deleteSymbols = append(deleteSymbols, symbol)
+					continue
+				}
+			}
+		}
+		lineSymbol, _ := oldMapSymbols[symbol]
+
+		if lineSymbol.Id <= 0 {
+			lineSymbol.Symbol = symbol
+			lineSymbol.BaseAsset = tradeSet.Coin
+			lineSymbol.QuoteAsset = tradeSet.Currency
+			lineSymbol.Switch = "1"
+			lineSymbol.Type = "1"
+			if lineSymbol.Symbol == "" {
+				continue
+			}
+			symbols = append(symbols, lineSymbol)
+		}
+	}
+
+	groups, err := getSymbolGroups(e, "1")
+	if err != nil {
+		return err
+	}
+
+	if len(deleteSymbols) > 0 {
+		for _, symbol := range deleteSymbols {
+			for _, group := range groups {
+				if group.Id > 0 && strings.Contains(group.Symbol, symbol) {
+					split := strings.Split(group.Symbol, ",")
+					value := utility.RemoveByValue(split, symbol)
+					join := strings.Join(value, ",")
+					e.Orm.Model(&models.LineSymbolGroup{}).Where("id = ?", group.Id).Update("symbol", join)
+				}
+			}
+		}
+
+		batchDeleteBySymbols(deleteSymbols, "1", e)
+	}
+
+	if len(symbols) > 0 {
+		err := e.Orm.Model(&models.LineSymbol{}).Omit("api_id").Create(&symbols).Error
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// 批量删除 根据交易对名
+// symbolType 1-现货 2-合约
+func batchDeleteBySymbols(deleteSymbols []string, symbolType string, e *LineSymbol) {
+	deleteSymbolArray := utility.SplitSlice(deleteSymbols, 100)
+
+	for _, item := range deleteSymbolArray {
+		e.Orm.Model(&models.LineSymbol{}).Where("type = ? AND symbol IN ? ", symbolType, item).Unscoped().Delete(&models.LineSymbol{})
+	}
+}
+
+// 获取交易对分组
+// symbolType 1-现货 2-合约
+func getSymbolGroups(e *LineSymbol, symbolType string) ([]models.LineSymbolGroup, error) {
+	groups := make([]models.LineSymbolGroup, 0)
+
+	if err := e.Orm.Model(&models.LineSymbolGroup{}).Where("type = ? ", symbolType).Find(&groups).Error; err != nil {
+		return nil, err
+	}
+	return groups, nil
+}
+
+// 获取所有交易对
+// symbolType 1-现货 2-合约
+func getMapSymbol(e *LineSymbol, symbolType string) (map[string]models.LineSymbol, error) {
+	oldSymbols := make([]models.LineSymbol, 0)
+	oldMapSymbols := make(map[string]models.LineSymbol)
+
+	if err := e.Orm.Model(&models.LineSymbol{}).Where(" type = ?", symbolType).Find(&oldSymbols).Error; err != nil {
+		return nil, errors.New("获取现有交易对失败")
+	}
+
+	for _, item := range oldSymbols {
+		oldMapSymbols[item.Symbol] = item
+	}
+	return oldMapSymbols, nil
+}
+
+// 重设合约交易对
+func (e *LineSymbol) ResetFuturesSymbol() error {
+	tradeSets := make(map[string]commonModels.TradeSet, 0)
+
+	if err := binanceservice.GetAndReloadSymbols(&tradeSets); err != nil {
+		logger.Error("定时同步合约交易对失败", err)
+	}
+	//获取交易对24小时行情
+	deleteSymbols, err := binanceservice.InitSymbolsTicker24h(&tradeSets)
+	if err != nil {
+		return err
+	}
+
+	sysConfig := SysConfig{Service: service.Service{Orm: e.Orm}}
+	var req = new(dto.SysConfigByKeyReq)
+	var resp = new(dto.GetSysConfigByKEYForServiceResp)
+	req.ConfigKey = "quote_volume_24hr"
+	sysConfig.GetWithKey(req, resp)
+	symbols := make([]models.LineSymbol, 0)
+	symbolBlack := make([]models.LineSymbolBlack, 0)
+
+	type Ticker struct {
+		Symbol string `json:"symbol"`
+		Price  string `json:"price"`
+	}
+	tickerSymbol := helper.DefaultRedis.Get(rediskey.FutSymbolTicker).Val()
+	tickerSymbolMaps := make([]Ticker, 0)
+	sonic.Unmarshal([]byte(tickerSymbol), &tickerSymbolMaps)
+	oldMapSymbols, err := getMapSymbol(e, "2")
+	if err != nil {
+		return err
+	}
+
+	e.Orm.Model(&models.LineSymbolBlack{}).Where("type = 2").Find(&symbolBlack)
+	for symbol, tradeSet := range tradeSets {
+
+		key := fmt.Sprintf("%s:%s", global.TICKER_FUTURES, symbol)
+
+		//判断是否在黑名单里面
+		for _, black := range symbolBlack {
+			if black.Symbol == symbol {
+				helper.DefaultRedis.DeleteString(key)
+				deleteSymbols = append(deleteSymbols, symbol)
+				continue
+			}
+		}
+		val := helper.DefaultRedis.Get(key).Val()
+		var spotTicker24h commonModels.TradeSet
+		sonic.Unmarshal([]byte(val), &spotTicker24h)
+		//成交量
+		if spotTicker24h.Currency == "USDT" {
+			if utility.StringToFloat64(spotTicker24h.QuoteVolume) < utility.StringToFloat64(resp.ConfigValue) {
+				helper.DefaultRedis.DeleteString(key)
+				deleteSymbols = append(deleteSymbols, symbol)
+				continue
+			}
+		} else {
+			var tickerPrice decimal.Decimal
+			for _, symbolMap := range tickerSymbolMaps {
+				if symbolMap.Symbol == strings.ToUpper(spotTicker24h.Currency+"USDT") {
+					tickerPrice, _ = decimal.NewFromString(symbolMap.Price)
+				}
+			}
+			if tickerPrice.GreaterThan(decimal.Zero) {
+				mul := decimal.NewFromFloat(utility.StringToFloat64(spotTicker24h.QuoteVolume)).Mul(tickerPrice)
+				if mul.LessThan(decimal.NewFromFloat(utility.StringToFloat64(resp.ConfigValue))) {
+					helper.DefaultRedis.DeleteString(key)
+					deleteSymbols = append(deleteSymbols, symbol)
+					continue
+				}
+			}
+		}
+		lineSymbol, _ := oldMapSymbols[symbol]
+
+		if lineSymbol.Id <= 0 {
+			lineSymbol.Symbol = symbol
+			lineSymbol.BaseAsset = tradeSet.Coin
+			lineSymbol.QuoteAsset = tradeSet.Currency
+			lineSymbol.Switch = "1"
+			lineSymbol.Type = "2"
+			if lineSymbol.Symbol == "" {
+				continue
+			}
+			symbols = append(symbols, lineSymbol)
+		}
+	}
+
+	groups, err := getSymbolGroups(e, "2")
+	if err != nil {
+		return err
+	}
+
+	if len(deleteSymbols) > 0 {
+		for _, symbol := range deleteSymbols {
+			//如果在交易对组里面
+			for _, group := range groups {
+				if group.Id > 0 {
+					split := strings.Split(group.Symbol, ",")
+					value := utility.RemoveByValue(split, symbol)
+					join := strings.Join(value, ",")
+					e.Orm.Model(&models.LineSymbolGroup{}).Where("id = ?", group.Id).Update("symbol", join)
+				}
+			}
+		}
+
+		batchDeleteBySymbols(deleteSymbols, "2", e)
+	}
+
+	if len(symbols) > 0 {
+		err = e.Orm.Model(&models.LineSymbol{}).Omit("api_id").Create(&symbols).Error
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
diff --git a/app/admin/service/line_symbol_black.go b/app/admin/service/line_symbol_black.go
new file mode 100644
index 0000000..4c1e7f9
--- /dev/null
+++ b/app/admin/service/line_symbol_black.go
@@ -0,0 +1,164 @@
+package service
+
+import (
+	"errors"
+	"go-admin/pkg/utility"
+	"strings"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineSymbolBlack struct {
+	service.Service
+}
+
+// GetPage 获取LineSymbolBlack列表
+func (e *LineSymbolBlack) GetPage(c *dto.LineSymbolBlackGetPageReq, p *actions.DataPermission, list *[]models.LineSymbolBlack, count *int64) error {
+	var err error
+	var data models.LineSymbolBlack
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineSymbolBlackService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineSymbolBlack对象
+func (e *LineSymbolBlack) Get(d *dto.LineSymbolBlackGetReq, p *actions.DataPermission, model *models.LineSymbolBlack) error {
+	var data models.LineSymbolBlack
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineSymbolBlack error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineSymbolBlack对象
+func (e *LineSymbolBlack) Insert(c *dto.LineSymbolBlackInsertReq) error {
+	var err error
+	var data models.LineSymbolBlack
+	c.Generate(&data)
+	//判断是否已经在用这个交易对
+	groups := make([]models.LineSymbolGroup, 0)
+	sql := "SELECT * FROM line_symbol_group WHERE FIND_IN_SET( ? , symbol) AND type = ? AND deleted_at is NULL;"
+	e.Orm.Model(&models.LineSymbolGroup{}).Raw(sql, c.Symbol, c.Type).Scan(&groups)
+
+	for _, group := range groups {
+		if group.Id > 0 {
+			split := strings.Split(group.Symbol, ",")
+			value := utility.RemoveByValue(split, c.Symbol)
+			join := strings.Join(value, ",")
+			e.Orm.Model(&models.LineSymbolGroup{}).Where("id = ?", group.Id).Update("symbol", join)
+		}
+	}
+
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineSymbolBlackService Insert error:%s \r\n", err)
+		return err
+	}
+
+	return e.reloadSymbol(c.Type)
+}
+
+func (e *LineSymbolBlack) reloadSymbol(symbolType string) error {
+	symbolService := LineSymbol{Service: e.Service}
+
+	if symbolType == "1" {
+		if err := symbolService.ResetSpotSymbol(); err != nil {
+			return errors.New("黑名单添加成功 更新现货交易对失败")
+		}
+	} else if symbolType == "2" {
+		if err := symbolService.ResetFuturesSymbol(); err != nil {
+			return errors.New("黑名单添加成功 更新合约交易对失败")
+		}
+	}
+
+	return nil
+}
+
+// Update 修改LineSymbolBlack对象
+func (e *LineSymbolBlack) Update(c *dto.LineSymbolBlackUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var data = models.LineSymbolBlack{}
+	e.Orm.Scopes(
+		actions.Permission(data.TableName(), p),
+	).First(&data, c.GetId())
+	c.Generate(&data)
+	//判断是否已经在用这个交易对
+	groups := make([]models.LineSymbolGroup, 0)
+	sql := "SELECT * FROM line_symbol_group WHERE FIND_IN_SET( ? , symbol) AND type = ? AND deleted_at is NULL;"
+	e.Orm.Model(&models.LineSymbolGroup{}).Raw(sql, c.Symbol, c.Type).Scan(&groups)
+
+	for _, group := range groups {
+		if group.Id > 0 {
+			split := strings.Split(group.Symbol, ",")
+			value := utility.RemoveByValue(split, c.Symbol)
+			join := strings.Join(value, ",")
+			e.Orm.Model(&models.LineSymbolGroup{}).Where("id = ?", group.Id).Update("symbol", join)
+		}
+	}
+
+	db := e.Orm.Save(&data)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("LineSymbolBlackService Save error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	return e.reloadSymbol(c.Type)
+}
+
+// Remove 删除LineSymbolBlack
+func (e *LineSymbolBlack) Remove(d *dto.LineSymbolBlackDeleteReq, p *actions.DataPermission) error {
+	var data models.LineSymbolBlack
+	types := make([]string, 0)
+
+	e.Orm.Model(&data).Where("id in ?", d.GetId()).Select("type").Distinct().Find(&types)
+
+	for _, v := range types {
+		if v != "" {
+			e.reloadSymbol(v)
+		}
+	}
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveLineSymbolBlack error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+	return nil
+}
diff --git a/app/admin/service/line_symbol_group.go b/app/admin/service/line_symbol_group.go
new file mode 100644
index 0000000..1dc0bb9
--- /dev/null
+++ b/app/admin/service/line_symbol_group.go
@@ -0,0 +1,116 @@
+package service
+
+import (
+	"errors"
+	"strings"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineSymbolGroup struct {
+	service.Service
+}
+
+// GetPage 获取LineSymbolGroup列表
+func (e *LineSymbolGroup) GetPage(c *dto.LineSymbolGroupGetPageReq, p *actions.DataPermission, list *[]models.LineSymbolGroup, count *int64) error {
+	var err error
+	var data models.LineSymbolGroup
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineSymbolGroupService GetPage error:%s \r\n", err)
+		return err
+	}
+
+	for index := range *list {
+		symbols := strings.Split((*list)[index].Symbol, ",")
+
+		(*list)[index].Count = len(symbols)
+	}
+	return nil
+}
+
+// Get 获取LineSymbolGroup对象
+func (e *LineSymbolGroup) Get(d *dto.LineSymbolGroupGetReq, p *actions.DataPermission, model *models.LineSymbolGroup) error {
+	var data models.LineSymbolGroup
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineSymbolGroup error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineSymbolGroup对象
+func (e *LineSymbolGroup) Insert(c *dto.LineSymbolGroupInsertReq) error {
+	var err error
+	var data models.LineSymbolGroup
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineSymbolGroupService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineSymbolGroup对象
+func (e *LineSymbolGroup) Update(c *dto.LineSymbolGroupUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var data = models.LineSymbolGroup{}
+	e.Orm.Scopes(
+		actions.Permission(data.TableName(), p),
+	).First(&data, c.GetId())
+	c.Generate(&data)
+
+	db := e.Orm.Save(&data)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("LineSymbolGroupService Save error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	return nil
+}
+
+// Remove 删除LineSymbolGroup
+func (e *LineSymbolGroup) Remove(d *dto.LineSymbolGroupDeleteReq, p *actions.DataPermission) error {
+	var data models.LineSymbolGroup
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveLineSymbolGroup error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+	return nil
+}
diff --git a/app/admin/service/line_system_setting.go b/app/admin/service/line_system_setting.go
new file mode 100644
index 0000000..3aa9baa
--- /dev/null
+++ b/app/admin/service/line_system_setting.go
@@ -0,0 +1,131 @@
+package service
+
+import (
+	"errors"
+
+	"github.com/bytedance/sonic"
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	"go-admin/common/const/rediskey"
+	cDto "go-admin/common/dto"
+	"go-admin/common/helper"
+)
+
+type LineSystemSetting struct {
+	service.Service
+}
+
+// GetPage 获取LineSystemSetting列表
+func (e *LineSystemSetting) GetPage(c *dto.LineSystemSettingGetPageReq, p *actions.DataPermission, list *[]models.LineSystemSetting, count *int64) error {
+	var err error
+	var data models.LineSystemSetting
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineSystemSettingService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineSystemSetting对象
+func (e *LineSystemSetting) Get(d *dto.LineSystemSettingGetReq, p *actions.DataPermission, model *models.LineSystemSetting) error {
+	var data models.LineSystemSetting
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineSystemSetting error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineSystemSetting对象
+func (e *LineSystemSetting) Insert(c *dto.LineSystemSettingInsertReq) error {
+	var err error
+	var data models.LineSystemSetting
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineSystemSettingService Insert error:%s \r\n", err)
+		return err
+	}
+
+	val, _ := sonic.MarshalString(data)
+
+	if val != "" {
+		if err := helper.DefaultRedis.SetString(rediskey.SystemSetting, val); err != nil {
+			e.Log.Error("LineSystemSettingService Update redis set error:%s \r\n", err)
+		}
+	}
+
+	return nil
+}
+
+// Update 修改LineSystemSetting对象
+func (e *LineSystemSetting) Update(c *dto.LineSystemSettingUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var data = models.LineSystemSetting{}
+	e.Orm.Scopes(
+		actions.Permission(data.TableName(), p),
+	).First(&data, c.GetId())
+	c.Generate(&data)
+
+	db := e.Orm.Save(&data)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("LineSystemSettingService Save error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+
+	val, _ := sonic.MarshalString(data)
+
+	if val != "" {
+		if err := helper.DefaultRedis.SetString(rediskey.SystemSetting, val); err != nil {
+			e.Log.Error("LineSystemSettingService Update redis set error:%s \r\n", err)
+		}
+	}
+
+	return nil
+}
+
+// Remove 删除LineSystemSetting
+func (e *LineSystemSetting) Remove(d *dto.LineSystemSettingDeleteReq, p *actions.DataPermission) error {
+	var data models.LineSystemSetting
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveLineSystemSetting error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+
+	return nil
+}
diff --git a/app/admin/service/line_uduncoin.go b/app/admin/service/line_uduncoin.go
new file mode 100644
index 0000000..5c5e3b6
--- /dev/null
+++ b/app/admin/service/line_uduncoin.go
@@ -0,0 +1,109 @@
+package service
+
+import (
+	"errors"
+
+    "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineUduncoin struct {
+	service.Service
+}
+
+// GetPage 获取LineUduncoin列表
+func (e *LineUduncoin) GetPage(c *dto.LineUduncoinGetPageReq, p *actions.DataPermission, list *[]models.LineUduncoin, count *int64) error {
+	var err error
+	var data models.LineUduncoin
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineUduncoinService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineUduncoin对象
+func (e *LineUduncoin) Get(d *dto.LineUduncoinGetReq, p *actions.DataPermission, model *models.LineUduncoin) error {
+	var data models.LineUduncoin
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineUduncoin error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineUduncoin对象
+func (e *LineUduncoin) Insert(c *dto.LineUduncoinInsertReq) error {
+    var err error
+    var data models.LineUduncoin
+    c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineUduncoinService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineUduncoin对象
+func (e *LineUduncoin) Update(c *dto.LineUduncoinUpdateReq, p *actions.DataPermission) error {
+    var err error
+    var data = models.LineUduncoin{}
+    e.Orm.Scopes(
+            actions.Permission(data.TableName(), p),
+        ).First(&data, c.GetId())
+    c.Generate(&data)
+
+    db := e.Orm.Save(&data)
+    if err = db.Error; err != nil {
+        e.Log.Errorf("LineUduncoinService Save error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权更新该数据")
+    }
+    return nil
+}
+
+// Remove 删除LineUduncoin
+func (e *LineUduncoin) Remove(d *dto.LineUduncoinDeleteReq, p *actions.DataPermission) error {
+	var data models.LineUduncoin
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+        e.Log.Errorf("Service RemoveLineUduncoin error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权删除该数据")
+    }
+	return nil
+}
diff --git a/app/admin/service/line_user.go b/app/admin/service/line_user.go
new file mode 100644
index 0000000..363b4bc
--- /dev/null
+++ b/app/admin/service/line_user.go
@@ -0,0 +1,564 @@
+package service
+
+import (
+	"errors"
+	"fmt"
+	"go-admin/common/const/rediskey"
+	"go-admin/common/global"
+	"go-admin/common/helper"
+	statuscode "go-admin/common/status_code"
+	ext "go-admin/config"
+	"go-admin/models/coingatedto"
+	"go-admin/pkg/coingate"
+	"go-admin/pkg/cryptohelper/aeshelper"
+	"go-admin/pkg/timehelper"
+	"go-admin/pkg/udunhelper"
+	"go-admin/pkg/utility"
+	"go-admin/pkg/utility/seqs"
+	"go-admin/services/binanceservice"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/bytedance/sonic"
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"github.com/shopspring/decimal"
+	"go.uber.org/zap"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineUser struct {
+	service.Service
+}
+
+// GetPage 获取LineUser列表
+func (e *LineUser) GetPage(c *dto.LineUserGetPageReq, p *actions.DataPermission, list *[]models.LineUser, count *int64) error {
+	var err error
+	var data models.LineUser
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineUserService GetPage error:%s \r\n", err)
+		return err
+	}
+	for i, user := range *list {
+		var apiUserinfo models.LineApiUser
+		e.Orm.Model(&models.LineApiUser{}).Where("user_id = ?", user.Id).Find(&apiUserinfo)
+		(*list)[i].OpenStatus = int(apiUserinfo.OpenStatus)
+	}
+	return nil
+}
+
+// Get 获取LineUser对象
+func (e *LineUser) Get(d *dto.LineUserGetReq, p *actions.DataPermission, model *models.LineUser) error {
+	var data models.LineUser
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineUser error:%s \r\n", err)
+		return err
+	}
+	var apiUserinfo models.LineApiUser
+	e.Orm.Model(&models.LineApiUser{}).Where("user_id = ?", d.GetId()).Find(&apiUserinfo)
+	model.OpenStatus = int(apiUserinfo.OpenStatus)
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineUser对象
+func (e *LineUser) Insert(c *dto.LineUserInsertReq) error {
+	var err error
+	var data models.LineUser
+	c.Generate(&data)
+	data.LoginTime = time.Now()
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineUserService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineUser对象
+func (e *LineUser) Update(c *dto.LineUserUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var data = models.LineUser{}
+	e.Orm.Scopes(
+		actions.Permission(data.TableName(), p),
+	).First(&data, c.GetId())
+	c.Generate(&data)
+
+	if c.OpenStatus >= 0 {
+		e.Orm.Model(&models.LineApiUser{}).Where("user_id = ?", c.GetId()).Update("open_status", c.OpenStatus)
+	}
+
+	db := e.Orm.Save(&data)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("LineUserService Save error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	return nil
+}
+
+// Remove 删除LineUser
+func (e *LineUser) Remove(d *dto.LineUserDeleteReq, p *actions.DataPermission) error {
+	var data models.LineUser
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveLineUser error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+	return nil
+}
+
+// UserVerifyEmail 用户核验邮箱
+func (e *LineUser) UserVerifyEmail(email string) (code int) {
+	//修改用户的状态
+	err := e.Orm.Model(&models.LineUser{}).Where("email = ? AND status = 'verify' ", email).Update("status", "normal").Error
+	if err != nil {
+		e.Log.Errorf("Service UserVerifyEmail error:%s \r\n", err)
+		return statuscode.ServerError
+	}
+	return statuscode.OK
+}
+
+// AddApiKey 用户添加apikey
+func (e *LineUser) AddApiKey(userId int, req *dto.AddApiKeyReq) int {
+	var apiUser models.LineApiUser
+	err2 := e.Orm.Model(&models.LineApiUser{}).Where("user_id = ?", userId).Find(&apiUser).Error
+	if err2 != nil && !errors.Is(err2, gorm.ErrRecordNotFound) {
+		e.Log.Errorf("Service AddApiKey error:%s \r\n", err2)
+		return statuscode.ServerError
+	}
+	if apiUser.ApiKey != "" && apiUser.ApiSecret != "" {
+		return statuscode.UserApiKeyExists
+	}
+
+	var proxyUrl, proxyType string
+	if ext.ExtConfig.ProxyUrl != "" {
+		proxyUrl = "127.0.0.1:7890"
+		proxyType = "http"
+	}
+	////验证api是否可用
+	binanceClient, err := helper.NewBinanceClient(req.ApiKey, req.ApiSecret, proxyType, proxyUrl)
+	//binanceClient := binanceservice.GetClient(&apiUser)
+
+	params := map[string]int64{
+		"recvWindow": 10000,
+	}
+
+	httpResp, _, err2 := binanceClient.SendSpotAuth("/sapi/v1/account/apiRestrictions", "GET", params)
+	if err2 != nil {
+		e.Log.Errorf("Service AddApiKey SendSpotAuth error:", err2)
+		return statuscode.UserApiKeyInvalid
+	}
+	var apiRestrictions dto.ApiRestrictions
+	sonic.Unmarshal(httpResp, &apiRestrictions)
+	if !apiRestrictions.EnableSpotAndMarginTrading {
+		return statuscode.UserApiKeyPermissionError
+	}
+
+	if !apiRestrictions.EnableFutures {
+		return statuscode.UserApiKeyPermissionError
+	}
+
+	err = e.Orm.Model(&models.LineApiUser{}).Create(&models.LineApiUser{
+		UserId:      int64(userId),
+		ApiName:     req.ApiName,
+		ApiKey:      req.ApiKey,
+		ApiSecret:   req.ApiSecret,
+		Affiliation: 3,
+		AdminShow:   0,
+		Site:        "3",
+		Subordinate: "0",
+		OpenStatus:  0,
+	}).Error
+
+	if err != nil {
+		e.Log.Errorf("Service AddApiKey error:%s \r\n", err)
+		return statuscode.ServerError
+	}
+	var data models.LineApiUser
+	e.Orm.Model(&models.LineApiUser{}).Where("user_id = ?", userId).Find(&data)
+
+	apiUserService := LineApiUser{Service: e.Service}
+	apiUserService.restartWebsocket(data)
+
+	return statuscode.OK
+}
+
+// UpdateApiKey 修改apikey
+func (e *LineUser) UpdateApiKey(userId int, req *dto.AddApiKeyReq) int {
+	var apiUser models.LineApiUser
+	err2 := e.Orm.Model(&models.LineApiUser{}).Where("user_id = ?", userId).Find(&apiUser).Error
+	if err2 != nil && !errors.Is(err2, gorm.ErrRecordNotFound) {
+		e.Log.Errorf("Service UpdateApiKey error:%s \r\n", err2)
+		return statuscode.ServerError
+	}
+	if apiUser.ApiKey == "" || apiUser.ApiSecret == "" {
+		return statuscode.UserApiKeyNotExists
+	}
+
+	if apiUser.ApiKey == req.ApiKey || apiUser.ApiSecret == req.ApiSecret {
+		return statuscode.UserApiKeyExists
+	}
+
+	var proxyUrl, proxyType string
+	if ext.ExtConfig.ProxyUrl != "" {
+		proxyUrl = "127.0.0.1:7890"
+		proxyType = "http"
+	}
+	////验证api是否可用
+	client, _ := helper.NewBinanceClient(req.ApiKey, req.ApiSecret, proxyType, proxyUrl)
+
+	//client := binanceservice.GetClient(&apiUser)
+	params := map[string]int64{
+		"recvWindow": 10000,
+	}
+	httpResp, _, err2 := client.SendSpotAuth("/sapi/v1/account/apiRestrictions", "GET", params)
+	if err2 != nil {
+		e.Log.Errorf("Service AddApiKey SendSpotAuth error:", err2)
+		return statuscode.UserApiKeyInvalid
+	}
+	var apiRestrictions dto.ApiRestrictions
+	sonic.Unmarshal(httpResp, &apiRestrictions)
+	if !apiRestrictions.EnableSpotAndMarginTrading {
+		return statuscode.UserApiKeyPermissionError
+	}
+
+	if !apiRestrictions.EnableFutures {
+		return statuscode.UserApiKeyPermissionError
+	}
+
+	err2 = e.Orm.Model(&models.LineApiUser{}).Where("id = ?", apiUser.Id).Updates(map[string]interface{}{
+		"api_key":    req.ApiKey,
+		"api_secret": req.ApiSecret,
+		"api_name":   req.ApiName,
+	}).Error
+	if err2 != nil {
+		e.Log.Errorf("Service UpdateApiKey error:%s \r\n", err2)
+		return statuscode.ServerError
+	}
+	apiUser.ApiKey = req.ApiKey
+	apiUser.ApiSecret = req.ApiSecret
+	apiUser.ApiName = req.ApiName
+
+	apiUserService := LineApiUser{Service: e.Service}
+	apiUserService.restartWebsocket(apiUser)
+	return statuscode.OK
+}
+
+func (e *LineUser) RechargeNetworkList(req *dto.RechargeListReq) (data []models.VtsCoinToNetWorkResp, code int) {
+	//获取充值网络列表
+	sql := `SELECT coin_id,coin_code,detail_code,network_id,network_name,token_name,transfer_fee FROM line_cointonetwork WHERE is_deposit = 3 AND coin_code = ?`
+	var list []models.VtsCoinToNetWorkDB
+
+	err := e.Orm.Table("line_cointonetwork").Raw(sql, req.Coin).Find(&list).Error
+	if err != nil {
+		e.Log.Errorf("Service RechargeNetworkList error:%s \r\n", err)
+		return data, statuscode.ServerError
+	}
+	coin := req.Coin
+	resp := make([]models.VtsCoinToNetWorkResp, 0)
+	var tickerData []binanceservice.Ticker
+	val := helper.DefaultRedis.Get(rediskey.SpotSymbolTicker).Val()
+	if val != "" {
+		sonic.Unmarshal([]byte(val), &tickerData)
+	}
+
+	for _, v1 := range list {
+		if strings.EqualFold(coin, "USDT") {
+			res := models.VtsCoinToNetWorkResp{
+				CoinId:      v1.CoinId,
+				CoinCode:    v1.CoinCode,
+				DetailCode:  v1.DetailCode,
+				NetWorkId:   v1.NetworkId,
+				NetWorkName: v1.NetWorkName,
+				TokenName:   v1.TokenName,
+				TransferFee: utility.FloatCutStr(v1.TransferFee, 8),
+			}
+			res.TransferFeeUsdt = res.TransferFee //utility.FloatCutStr(v1.TransferFee, 8)
+			resp = append(resp, res)
+			continue
+		}
+
+		for _, v2 := range tickerData {
+			if v1.CoinCode+"USDT" == v2.Symbol {
+				res := models.VtsCoinToNetWorkResp{
+					CoinId:      v1.CoinId,
+					CoinCode:    v1.CoinCode,
+					DetailCode:  v1.DetailCode,
+					NetWorkId:   v1.NetworkId,
+					NetWorkName: v1.NetWorkName,
+					TokenName:   v1.TokenName,
+					TransferFee: utility.FloatCutStr(v1.TransferFee, 8),
+					//TransferFeeUsdt string `json:"transfer_fee_usdt"`
+				}
+				res.TransferFeeUsdt = utility.FloatCutStr(v1.TransferFee*utility.StringToFloat64(v2.Price), 8)
+				resp = append(resp, res)
+			}
+		}
+	}
+	return resp, statuscode.OK
+}
+
+func (e *LineUser) RechargeNetworkAddress(req *dto.RechargeAddressListReq) (data models.RechargeAddressListResp, code int) {
+	//查询区块确认数
+	sql := `SELECT id,network_name,token_name,arrival_num,unlock_num,unlock_time,fee FROM line_coinnetwork where id = ?`
+	var networkInfo models.VtsCoinNetWorkDB
+	err := e.Orm.Model(&models.LineCoinnetwork{}).Exec(sql, req.NetWorkId).Find(&networkInfo).Error
+	if err != nil {
+		e.Log.Errorf("Service line_coinnetwork sql error:%s \r\n", err)
+		return data, statuscode.ServerError
+	}
+	//查询地址
+	addressSql := `SELECT address FROM line_wallet WHERE user_id = ? AND coin_network_id = ?`
+	//e.Orm.Model(&models.)
+	var address string
+	err = e.Orm.Table("line_wallet").Exec(addressSql, req.UserId, req.NetWorkId).Scan(&address).Error
+	if err != nil {
+		e.Log.Errorf("Service addressSql error:%s \r\n", err)
+		return data, statuscode.ServerError
+	}
+	if len(address) == 0 {
+		//创建一个地址并且写入到数据库
+		//通过币获取第三方钱包先关信息
+		var uduncionInfo models.LineUduncoin
+		err := e.Orm.Model(&models.LineUduncoin{}).Where("main_symbol = ?", networkInfo.NetworkName).Find(&uduncionInfo).Error
+		if err != nil {
+			e.Log.Errorf("Service query uduncionInfo error:%s \r\n", err)
+			return data, statuscode.ServerError
+		}
+		base := udunhelper.BaseRequest{Timestamp: time.Now().Unix(), Nonce: seqs.Rand().RandInt(600000)}
+		call := udunhelper.CallbackRequest{MainCoinType: utility.StringAsInteger(uduncionInfo.MainCoinType)}
+		ad := udunhelper.CreateAddress(base, []*udunhelper.CallbackRequest{&call})
+		if ad.Code != 200 || ad.Message != "SUCCESS" {
+			fmt.Println("ad:", ad)
+			e.Log.Errorf("创建地址出错:%s \r\n", err)
+			return data, statuscode.ServerError
+		}
+		address = ad.Data.Address
+		//写入数据库
+
+		err = e.Orm.Model(&models.LineWallet{}).Create(&models.LineWallet{
+			UserId:        int64(req.UserId),
+			CoinId:        0,
+			CoinCode:      req.CoinCode,
+			Address:       address,
+			CoinNetworkId: req.NetWorkId,
+		}).Error
+		if err != nil {
+			e.Log.Errorf("RechargeNetworkAddress AddWalletItem", zap.Error(err))
+		}
+	}
+
+	return models.RechargeAddressListResp{
+		Address:    address,
+		MinNum:     utility.FloatCutStr(1, 8),
+		ArrivalNum: networkInfo.ArrivalNum, //充值区块确认数
+		UnlockNum:  networkInfo.UnlockNum,  //提现解锁确认数
+	}, statuscode.OK
+}
+
+// FundingTrend 资金走势
+func (e *LineUser) FundingTrend(userId int) (resp []models.LineUserFundingTrendResp, code int) {
+	var data []models.LineUserFundingTrend
+	err := e.Orm.Model(&models.LineUserFundingTrend{}).Where("user_id = ?", userId).Order("id desc").Limit(10).Find(&data).Error
+	if err != nil {
+		e.Log.Errorf("RechargeNetworkAddress AddWalletItem", zap.Error(err))
+		return []models.LineUserFundingTrendResp{}, statuscode.ServerError
+	}
+	//resps := make([]models.LineUserFundingTrendResp, len(data))
+	for _, datum := range data {
+		trendResp := models.LineUserFundingTrendResp{
+			UserId:    datum.UserId,
+			Funding:   datum.Funding,
+			CreatedAt: timehelper.ConvertTimeToString(datum.CreatedAt),
+		}
+		resp = append(resp, trendResp)
+	}
+	return resp, statuscode.OK
+}
+
+// PreOrder 预下单
+func (e *LineUser) PreOrder(userId int, req *dto.VtsRechargePreOrderReq, resp *dto.VtsRechargePreOrderResp) error {
+	sysConfig := SysConfig{Service: e.Service}
+	configReq := []string{global.SYS_CONFIG_CALLBACK, global.COINGATE_STATUS_CANCELED, global.SYS_CONFIG_SUCCESS}
+	configResp := make(map[string]dto.GetSysConfigByKEYForServiceResp)
+	err := sysConfig.GetWithKeys(&configReq, &configResp)
+
+	if err != nil {
+		e.Log.Error("获取支付配置失败", err)
+		return err
+	}
+	callBack, exits := configResp[global.SYS_CONFIG_CALLBACK]
+
+	if !exits {
+		e.Log.Errorf("获取支付回调地址不存在")
+		return errors.New("获取支付回调地址不存在")
+	}
+	preOrder := models.VtsRecharge{
+		Amount:         req.Amount,
+		AdUserId:       userId,
+		CoinCode:       req.CoinCode,
+		PriceCurrency:  req.CoinCode,
+		OrderNo:        helper.GetOrderNo(),
+		TranType:       global.TRAN_TYPE_WALLET,
+		Status:         global.COINGATE_STATUS_DEFAULT,
+		WalletCreateAt: time.Now(),
+		CallbackAt:     time.Now(),
+	}
+	err = e.Orm.Save(&preOrder).Error
+
+	if err != nil {
+		e.Log.Errorf("保存订单错误:", err)
+		return err
+	}
+	coinGateReq := coingatedto.OrderRequest{}
+	coinGateReq.OrderID = preOrder.OrderNo
+	coinGateReq.PriceAmount = preOrder.Amount
+	coinGateReq.PriceCurrency = preOrder.CoinCode
+	coinGateReq.ReceiveCurrency = preOrder.CoinCode
+	coinGateReq.Title = fmt.Sprintf("recharge_%s", strconv.Itoa(userId))
+	coinGateReq.CallbackURL = callBack.ConfigValue
+	token, _ := aeshelper.PswEncrypt(fmt.Sprintf("%s:%s:%s", coinGateReq.OrderID, coinGateReq.PriceAmount, coinGateReq.PriceCurrency))
+	coinGateReq.Token = token
+
+	if cancel, exits := configResp[global.SYS_CONFIG_CANCECL]; exits {
+		coinGateReq.CancelUrl = cancel.ConfigValue
+	}
+
+	if success, exits := configResp[global.SYS_CONFIG_SUCCESS]; exits {
+		coinGateReq.SuccessUrl = success.ConfigValue
+	}
+
+	paymentResp, err := coingate.GetPaymentUrl(ext.ExtConfig.CoinGate.Endpoint, ext.ExtConfig.CoinGate.Auth, &coinGateReq)
+
+	if err != nil {
+		e.Log.Error("发起支付失败", err)
+		e.Orm.Model(preOrder).Update("remark", utility.StringCut(err.Error(), 500))
+		return err
+	}
+
+	// 解析格式:RFC3339
+	t, err := time.Parse(time.RFC3339, paymentResp.CreatedAt)
+
+	if err != nil {
+		t = time.Now()
+	}
+
+	err = e.Orm.Model(preOrder).Updates(&models.VtsRecharge{WalletCreateAt: t, WalletId: paymentResp.ID, Status: paymentResp.Status}).Error
+
+	if err != nil {
+		e.Log.Error("修改订单状态失败", err)
+		return err
+	}
+
+	resp.PaymentUrl = paymentResp.PaymentURL
+	resp.PriceAmount = paymentResp.PriceAmount
+	resp.PriceCurrency = paymentResp.PriceCurrency
+
+	return nil
+}
+
+func (e *LineUser) CallBack(req *coingatedto.OrderCallBackResponse) error {
+	token, err := aeshelper.PswEncrypt(fmt.Sprintf("%s:%s:%s", req.OrderID, utility.StringAsDecimal(req.PriceAmount), req.PriceCurrency))
+
+	if err != nil {
+		return err
+	}
+
+	if token != req.Token {
+		return errors.New("token 和参数不一致")
+	}
+	recharge := models.VtsRecharge{}
+	err = e.Orm.Model(recharge).Where("order_no=?", req.OrderID).First(&recharge).Error
+
+	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+		return err
+	}
+
+	if recharge.Id == 0 {
+		return errors.New("不存在的充值记录:" + req.OrderID)
+	}
+
+	switch recharge.Status {
+	case global.COINGATE_STATUS_PAID:
+		//退款可以修改
+		if req.Status != global.COINGATE_STATUS_PARTIALLY_REFUNDED && req.Status != global.COINGATE_STATUS_REFUNDED {
+			return errors.New("已成功的订单无法修改:" + req.OrderID)
+		}
+	}
+
+	fee := decimal.Zero
+
+	for _, item := range req.Fees {
+		fee = fee.Add(utility.StrToDecimal(item.Amount))
+	}
+
+	err = e.Orm.Transaction(func(tx *gorm.DB) error {
+		receiveAmount := utility.StrToDecimal(req.ReceiveAmount)
+		confirmStatus := ""
+
+		if req.Status == global.COINGATE_STATUS_PAID {
+
+			err = tx.Model(&models.LineUser{}).Where("id = ?", recharge.AdUserId).Update("money", gorm.Expr("money + ?", req.PayAmount)).Error
+			if err != nil {
+				return err
+			}
+
+			confirmStatus = global.RECHARGE_CONFIRM_STATUS_UNCONFIRMED
+		}
+
+		err = tx.Model(recharge).Updates(map[string]interface{}{
+			"wallet_id":        req.ID,
+			"receive_amount":   receiveAmount,
+			"pay_amount":       utility.StrToDecimal(req.PayAmount),
+			"pay_currency":     req.PayCurrency,
+			"underpaid_amount": utility.StrToDecimal(req.UnderpaidAmount),
+			"overpaid_amount":  utility.StrToDecimal(req.OverpaidAmount),
+			"is_refundable":    req.IsRefundable,
+			"fee":              fee,
+			"status":           req.Status,
+			"confirm_status":   confirmStatus,
+		}).Error
+
+		if err != nil {
+			return err
+		}
+
+		return nil
+	})
+
+	return err
+}
diff --git a/app/admin/service/line_user_funding_trend.go b/app/admin/service/line_user_funding_trend.go
new file mode 100644
index 0000000..fd013ad
--- /dev/null
+++ b/app/admin/service/line_user_funding_trend.go
@@ -0,0 +1,109 @@
+package service
+
+import (
+	"errors"
+
+    "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineUserFundingTrend struct {
+	service.Service
+}
+
+// GetPage 获取LineUserFundingTrend列表
+func (e *LineUserFundingTrend) GetPage(c *dto.LineUserFundingTrendGetPageReq, p *actions.DataPermission, list *[]models.LineUserFundingTrend, count *int64) error {
+	var err error
+	var data models.LineUserFundingTrend
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineUserFundingTrendService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineUserFundingTrend对象
+func (e *LineUserFundingTrend) Get(d *dto.LineUserFundingTrendGetReq, p *actions.DataPermission, model *models.LineUserFundingTrend) error {
+	var data models.LineUserFundingTrend
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineUserFundingTrend error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineUserFundingTrend对象
+func (e *LineUserFundingTrend) Insert(c *dto.LineUserFundingTrendInsertReq) error {
+    var err error
+    var data models.LineUserFundingTrend
+    c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineUserFundingTrendService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineUserFundingTrend对象
+func (e *LineUserFundingTrend) Update(c *dto.LineUserFundingTrendUpdateReq, p *actions.DataPermission) error {
+    var err error
+    var data = models.LineUserFundingTrend{}
+    e.Orm.Scopes(
+            actions.Permission(data.TableName(), p),
+        ).First(&data, c.GetId())
+    c.Generate(&data)
+
+    db := e.Orm.Save(&data)
+    if err = db.Error; err != nil {
+        e.Log.Errorf("LineUserFundingTrendService Save error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权更新该数据")
+    }
+    return nil
+}
+
+// Remove 删除LineUserFundingTrend
+func (e *LineUserFundingTrend) Remove(d *dto.LineUserFundingTrendDeleteReq, p *actions.DataPermission) error {
+	var data models.LineUserFundingTrend
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+        e.Log.Errorf("Service RemoveLineUserFundingTrend error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权删除该数据")
+    }
+	return nil
+}
diff --git a/app/admin/service/line_user_profit_logs.go b/app/admin/service/line_user_profit_logs.go
new file mode 100644
index 0000000..2326ae6
--- /dev/null
+++ b/app/admin/service/line_user_profit_logs.go
@@ -0,0 +1,133 @@
+package service
+
+import (
+	"database/sql"
+	"errors"
+	"time"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineUserProfitLogs struct {
+	service.Service
+}
+
+// GetPage 获取LineUserProfitLogs列表
+func (e *LineUserProfitLogs) GetPage(c *dto.LineUserProfitLogsGetPageReq, p *actions.DataPermission, list *[]models.LineUserProfitLogs, count *int64) error {
+	var err error
+	var data models.LineUserProfitLogs
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineUserProfitLogsService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineUserProfitLogs对象
+func (e *LineUserProfitLogs) Get(d *dto.LineUserProfitLogsGetReq, p *actions.DataPermission, model *models.LineUserProfitLogs) error {
+	var data models.LineUserProfitLogs
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineUserProfitLogs error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineUserProfitLogs对象
+func (e *LineUserProfitLogs) Insert(c *dto.LineUserProfitLogsInsertReq) error {
+	var err error
+	var data models.LineUserProfitLogs
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineUserProfitLogsService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineUserProfitLogs对象
+func (e *LineUserProfitLogs) Update(c *dto.LineUserProfitLogsUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var data = models.LineUserProfitLogs{}
+	e.Orm.Scopes(
+		actions.Permission(data.TableName(), p),
+	).First(&data, c.GetId())
+	c.Generate(&data)
+
+	db := e.Orm.Save(&data)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("LineUserProfitLogsService Save error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	return nil
+}
+
+// Remove 删除LineUserProfitLogs
+func (e *LineUserProfitLogs) Remove(d *dto.LineUserProfitLogsDeleteReq, p *actions.DataPermission) error {
+	var data models.LineUserProfitLogs
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveLineUserProfitLogs error:%s \r\n", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+	return nil
+}
+
+// GetProfitInfoByApiId 获取盈利统计
+// apiId api-user 的id
+// totalProfit 总盈利
+// todayProfit 今日盈利
+func (e *LineUserProfitLogs) GetProfitInfoByApiId(apiId int) (totalProfit, todayProfit sql.NullFloat64) {
+	//var totalProfit, todayProfit decimal.Decimal
+	e.Orm.Model(&models.LineUserProfitLogs{}).Where("api_id = ?", apiId).Select("SUM(amount) as total_profit").Scan(&totalProfit)
+	e.Orm.Model(&models.LineUserProfitLogs{}).Where("api_id = ? AND created_at >= ?", apiId, time.Now().Truncate(24*time.Hour)).Select("SUM(amount) as today_profit").Scan(&todayProfit)
+	return
+}
+
+// GetProfitInfoByUserId 获取盈利统计
+// apiId api-user 的id
+// totalProfit 总盈利
+// todayProfit 今日盈利
+func (e *LineUserProfitLogs) GetProfitInfoByUserId(userId int) (totalProfit, todayProfit sql.NullFloat64) {
+	//var totalProfit, todayProfit decimal.Decimal
+	e.Orm.Model(&models.LineUserProfitLogs{}).Where("user_id = ?", userId).Select("SUM(amount) as total_profit").Scan(&totalProfit)
+	e.Orm.Model(&models.LineUserProfitLogs{}).Where("user_id = ? AND created_at >= ?", userId, time.Now().Truncate(24*time.Hour)).Select("SUM(amount) as today_profit").Scan(&todayProfit)
+	return
+}
diff --git a/app/admin/service/line_wallet.go b/app/admin/service/line_wallet.go
new file mode 100644
index 0000000..5def123
--- /dev/null
+++ b/app/admin/service/line_wallet.go
@@ -0,0 +1,109 @@
+package service
+
+import (
+	"errors"
+
+    "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type LineWallet struct {
+	service.Service
+}
+
+// GetPage 获取LineWallet列表
+func (e *LineWallet) GetPage(c *dto.LineWalletGetPageReq, p *actions.DataPermission, list *[]models.LineWallet, count *int64) error {
+	var err error
+	var data models.LineWallet
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("LineWalletService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取LineWallet对象
+func (e *LineWallet) Get(d *dto.LineWalletGetReq, p *actions.DataPermission, model *models.LineWallet) error {
+	var data models.LineWallet
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetLineWallet error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建LineWallet对象
+func (e *LineWallet) Insert(c *dto.LineWalletInsertReq) error {
+    var err error
+    var data models.LineWallet
+    c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("LineWalletService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改LineWallet对象
+func (e *LineWallet) Update(c *dto.LineWalletUpdateReq, p *actions.DataPermission) error {
+    var err error
+    var data = models.LineWallet{}
+    e.Orm.Scopes(
+            actions.Permission(data.TableName(), p),
+        ).First(&data, c.GetId())
+    c.Generate(&data)
+
+    db := e.Orm.Save(&data)
+    if err = db.Error; err != nil {
+        e.Log.Errorf("LineWalletService Save error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权更新该数据")
+    }
+    return nil
+}
+
+// Remove 删除LineWallet
+func (e *LineWallet) Remove(d *dto.LineWalletDeleteReq, p *actions.DataPermission) error {
+	var data models.LineWallet
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+        e.Log.Errorf("Service RemoveLineWallet error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权删除该数据")
+    }
+	return nil
+}
diff --git a/app/admin/service/sys_api.go b/app/admin/service/sys_api.go
new file mode 100644
index 0000000..b098022
--- /dev/null
+++ b/app/admin/service/sys_api.go
@@ -0,0 +1,121 @@
+package service
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/go-admin-team/go-admin-core/sdk/runtime"
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+	"go-admin/common/global"
+)
+
+type SysApi struct {
+	service.Service
+}
+
+// GetPage 获取SysApi列表
+func (e *SysApi) GetPage(c *dto.SysApiGetPageReq, p *actions.DataPermission, list *[]models.SysApi, count *int64) error {
+	var err error
+	var data models.SysApi
+
+	orm := e.Orm.Debug().Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		)
+	if c.Type != "" {
+		qType := c.Type
+		if qType == "暂无" {
+			qType = ""
+		}
+		if global.Driver == "postgres" {
+			orm = orm.Where("type = ?", qType)
+		} else {
+			orm = orm.Where("`type` = ?", qType)
+		}
+
+	}
+	err = orm.Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("Service GetSysApiPage error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取SysApi对象with id
+func (e *SysApi) Get(d *dto.SysApiGetReq, p *actions.DataPermission, model *models.SysApi) *SysApi {
+	var data models.SysApi
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		FirstOrInit(model, d.GetId()).Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		_ = e.AddError(err)
+		return e
+	}
+	if model.Id == 0 {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetSysApi error: %s", err)
+		_ = e.AddError(err)
+		return e
+	}
+	return e
+}
+
+// Update 修改SysApi对象
+func (e *SysApi) Update(c *dto.SysApiUpdateReq, p *actions.DataPermission) error {
+	var model = models.SysApi{}
+	db := e.Orm.Debug().First(&model, c.GetId())
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	c.Generate(&model)
+	db = e.Orm.Save(&model)
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service UpdateSysApi error:%s", err)
+		return err
+	}
+
+	return nil
+}
+
+// Remove 删除SysApi
+func (e *SysApi) Remove(d *dto.SysApiDeleteReq, p *actions.DataPermission) error {
+	var data models.SysApi
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+		e.Log.Errorf("Service RemoveSysApi error:%s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+	return nil
+}
+
+// CheckStorageSysApi 创建SysApi对象
+func (e *SysApi) CheckStorageSysApi(c *[]runtime.Router) error {
+	for _, v := range *c {
+		err := e.Orm.Debug().Where(models.SysApi{Path: v.RelativePath, Action: v.HttpMethod}).
+			Attrs(models.SysApi{Handle: v.Handler}).
+			FirstOrCreate(&models.SysApi{}).Error
+		if err != nil {
+			err := fmt.Errorf("Service CheckStorageSysApi error: %s \r\n ", err.Error())
+			return err
+		}
+	}
+	return nil
+}
diff --git a/app/admin/service/sys_config.go b/app/admin/service/sys_config.go
new file mode 100644
index 0000000..e90490c
--- /dev/null
+++ b/app/admin/service/sys_config.go
@@ -0,0 +1,226 @@
+package service
+
+import (
+	"errors"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	cDto "go-admin/common/dto"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+)
+
+type SysConfig struct {
+	service.Service
+}
+
+// GetPage 获取SysConfig列表
+func (e *SysConfig) GetPage(c *dto.SysConfigGetPageReq, list *[]models.SysConfig, count *int64) error {
+	err := e.Orm.
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("Service GetSysConfigPage error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取SysConfig对象
+func (e *SysConfig) Get(d *dto.SysConfigGetReq, model *models.SysConfig) error {
+	err := e.Orm.
+		FirstOrInit(model, d.GetId()).
+		Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		_ = e.AddError(err)
+		return err
+	}
+	if model.Id == 0 {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetSysApi error: %s", err)
+		_ = e.AddError(err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建SysConfig对象
+func (e *SysConfig) Insert(c *dto.SysConfigControl) error {
+	var err error
+	var data models.SysConfig
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("Service InsertSysConfig error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改SysConfig对象
+func (e *SysConfig) Update(c *dto.SysConfigControl) error {
+	var err error
+	var model = models.SysConfig{}
+	e.Orm.First(&model, c.GetId())
+	c.Generate(&model)
+	db := e.Orm.Save(&model)
+	err = db.Error
+	if err != nil {
+		e.Log.Errorf("Service UpdateSysConfig error:%s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+
+	}
+	return nil
+}
+
+// SetSysConfig 修改SysConfig对象
+func (e *SysConfig) SetSysConfig(c *[]dto.GetSetSysConfigReq) error {
+	var err error
+	for _, req := range *c {
+		var model = models.SysConfig{}
+		e.Orm.Where("config_key = ?", req.ConfigKey).First(&model)
+		if model.Id != 0 {
+			req.Generate(&model)
+			db := e.Orm.Save(&model)
+			err = db.Error
+			if err != nil {
+				e.Log.Errorf("Service SetSysConfig error:%s", err)
+				return err
+			}
+			if db.RowsAffected == 0 {
+				return errors.New("无权更新该数据")
+			}
+		}
+	}
+	return nil
+}
+
+func (e *SysConfig) GetForSet(c *[]dto.GetSetSysConfigReq) error {
+	var err error
+	var data models.SysConfig
+
+	err = e.Orm.Model(&data).
+		Find(c).Error
+	if err != nil {
+		e.Log.Errorf("Service GetSysConfigPage error:%s", err)
+		return err
+	}
+	return nil
+}
+
+func (e *SysConfig) UpdateForSet(c *[]dto.GetSetSysConfigReq) error {
+	m := *c
+	for _, req := range m {
+		var data models.SysConfig
+		if err := e.Orm.Where("config_key = ?", req.ConfigKey).
+			First(&data).Error; err != nil {
+			e.Log.Errorf("Service GetSysConfigPage error:%s", err)
+			return err
+		}
+		if data.ConfigValue != req.ConfigValue {
+			data.ConfigValue = req.ConfigValue
+
+			if err := e.Orm.Save(&data).Error; err != nil {
+				e.Log.Errorf("Service GetSysConfigPage error:%s", err)
+				return err
+			}
+		}
+
+	}
+
+	return nil
+}
+
+// Remove 删除SysConfig
+func (e *SysConfig) Remove(d *dto.SysConfigDeleteReq) error {
+	var err error
+	var data models.SysConfig
+
+	db := e.Orm.Delete(&data, d.Ids)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Service RemoveSysConfig error:%s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		err = errors.New("无权删除该数据")
+		return err
+	}
+	return nil
+}
+
+// GetWithKey 根据Key获取SysConfig
+func (e *SysConfig) GetWithKey(c *dto.SysConfigByKeyReq, resp *dto.GetSysConfigByKEYForServiceResp) error {
+	var err error
+	var data models.SysConfig
+	err = e.Orm.Table(data.TableName()).Where("config_key = ?", c.ConfigKey).First(resp).Error
+	if err != nil {
+		e.Log.Errorf("At Service GetSysConfigByKEY Error:%s", err)
+		return err
+	}
+
+	return nil
+}
+
+func (e *SysConfig) GetWithKeyList(c *dto.SysConfigGetToSysAppReq, list *[]models.SysConfig) error {
+	err := e.Orm.
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+		).
+		Find(list).Error
+	if err != nil {
+		e.Log.Errorf("Service GetSysConfigByKey error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// 根据keys
+func (e *SysConfig) GetWithKeys(keys *[]string, resp *map[string]dto.GetSysConfigByKEYForServiceResp) error {
+	// noCache := []string{}
+
+	// for _, item := range *keys {
+	// 	key := fmt.Sprintf("%s:%s", global.SYS_CONFIG, item)
+	// 	val, err := helper.DefaultRedis.GetString(key)
+
+	// 	if err != nil || len(val) <= 0 {
+	// 		noCache = append(noCache, item)
+	// 		continue
+	// 	}
+
+	// 	data := dto.GetSysConfigByKEYForServiceResp{}
+	// 	err = sonic.Unmarshal([]byte(val), &data)
+
+	// 	if err != nil {
+	// 		noCache = append(noCache, item)
+	// 		continue
+	// 	}
+	// 	*resp = append(*resp, data)
+	// }
+
+	// if len(noCache) > 0 {
+	list := make([]models.SysConfig, 0)
+	err := e.Orm.Model(&models.SysConfig{}).Where("config_key in ?", *keys).Find(&list).Error
+	if err != nil {
+		e.Log.Errorf("Service GetSysConfigByKey error:%s", err)
+		return err
+	}
+
+	for _, item := range list {
+		itemResp := dto.GetSysConfigByKEYForServiceResp{
+			ConfigKey:   item.ConfigKey,
+			ConfigValue: item.ConfigValue,
+		}
+
+		(*resp)[item.ConfigKey] = itemResp
+	}
+
+	return nil
+}
diff --git a/app/admin/service/sys_dept.go b/app/admin/service/sys_dept.go
new file mode 100644
index 0000000..81ed451
--- /dev/null
+++ b/app/admin/service/sys_dept.go
@@ -0,0 +1,294 @@
+package service
+
+import (
+	"errors"
+	"go-admin/app/admin/models"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+
+	"go-admin/app/admin/service/dto"
+	cDto "go-admin/common/dto"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+)
+
+type SysDept struct {
+	service.Service
+}
+
+// GetPage 获取SysDept列表
+//func (e *SysDept) GetPage(c *dto.SysDeptGetPageReq, list *[]models.SysDept) error {
+//	var err error
+//	var data models.SysDept
+//
+//	err = e.Orm.Model(&data).
+//		Scopes(
+//			cDto.MakeCondition(c.GetNeedSearch()),
+//		).
+//		Find(list).Error
+//	if err != nil {
+//		e.Log.Errorf("db error:%s", err)
+//		return err
+//	}
+//	return nil
+//}
+
+// Get 获取SysDept对象
+func (e *SysDept) Get(d *dto.SysDeptGetReq, model *models.SysDept) error {
+	var err error
+	var data models.SysDept
+
+	err = e.Orm.Model(&data).
+		FirstOrInit(model, d.GetId()).
+		Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		_ = e.AddError(err)
+		return err
+	}
+	if model.DeptId == 0 {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetSysApi error: %s", err)
+		_ = e.AddError(err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建SysDept对象
+func (e *SysDept) Insert(c *dto.SysDeptInsertReq) error {
+	var err error
+	var data models.SysDept
+	c.Generate(&data)
+	tx := e.Orm.Debug().Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	err = tx.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	deptPath := pkg.IntToString(data.DeptId) + "/"
+	if data.ParentId != 0 {
+		var deptP models.SysDept
+		tx.First(&deptP, data.ParentId)
+		deptPath = deptP.DeptPath + deptPath
+	} else {
+		deptPath = "/0/" + deptPath
+	}
+	var mp = map[string]string{}
+	mp["dept_path"] = deptPath
+	if err := tx.Model(&data).Update("dept_path", deptPath).Error; err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改SysDept对象
+func (e *SysDept) Update(c *dto.SysDeptUpdateReq) error {
+	var err error
+	var model = models.SysDept{}
+	tx := e.Orm.Debug().Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	tx.First(&model, c.GetId())
+	c.Generate(&model)
+
+	deptPath := pkg.IntToString(model.DeptId) + "/"
+	if model.ParentId != 0 {
+		var deptP models.SysDept
+		tx.First(&deptP, model.ParentId)
+		deptPath = deptP.DeptPath + deptPath
+	} else {
+		deptPath = "/0/" + deptPath
+	}
+	model.DeptPath = deptPath
+	db := tx.Save(&model)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("UpdateSysDept error:%s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	return nil
+}
+
+// Remove 删除SysDept
+func (e *SysDept) Remove(d *dto.SysDeptDeleteReq) error {
+	var err error
+	var data models.SysDept
+
+	db := e.Orm.Model(&data).Delete(&data, d.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Delete error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		err = errors.New("无权删除该数据")
+		return err
+	}
+	return nil
+}
+
+// GetSysDeptList 获取组织数据
+func (e *SysDept) getList(c *dto.SysDeptGetPageReq, list *[]models.SysDept) error {
+	var err error
+	var data models.SysDept
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+		).
+		Find(list).Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// SetDeptTree 设置组织数据
+func (e *SysDept) SetDeptTree(c *dto.SysDeptGetPageReq) (m []dto.DeptLabel, err error) {
+	var list []models.SysDept
+	err = e.getList(c, &list)
+
+	m = make([]dto.DeptLabel, 0)
+	for i := 0; i < len(list); i++ {
+		if list[i].ParentId != 0 {
+			continue
+		}
+		e := dto.DeptLabel{}
+		e.Id = list[i].DeptId
+		e.Label = list[i].DeptName
+		deptsInfo := deptTreeCall(&list, e)
+
+		m = append(m, deptsInfo)
+	}
+	return
+}
+
+// Call 递归构造组织数据
+func deptTreeCall(deptList *[]models.SysDept, dept dto.DeptLabel) dto.DeptLabel {
+	list := *deptList
+	childrenList := make([]dto.DeptLabel, 0)
+	for j := 0; j < len(list); j++ {
+		if dept.Id != list[j].ParentId {
+			continue
+		}
+		mi := dto.DeptLabel{Id: list[j].DeptId, Label: list[j].DeptName, Children: []dto.DeptLabel{}}
+		ms := deptTreeCall(deptList, mi)
+		childrenList = append(childrenList, ms)
+	}
+	dept.Children = childrenList
+	return dept
+}
+
+// SetDeptPage 设置dept页面数据
+func (e *SysDept) SetDeptPage(c *dto.SysDeptGetPageReq) (m []models.SysDept, err error) {
+	var list []models.SysDept
+	err = e.getList(c, &list)
+	for i := 0; i < len(list); i++ {
+		if list[i].ParentId != 0 {
+			continue
+		}
+		info := e.deptPageCall(&list, list[i])
+		m = append(m, info)
+	}
+	return
+}
+
+func (e *SysDept) deptPageCall(deptlist *[]models.SysDept, menu models.SysDept) models.SysDept {
+	list := *deptlist
+	childrenList := make([]models.SysDept, 0)
+	for j := 0; j < len(list); j++ {
+		if menu.DeptId != list[j].ParentId {
+			continue
+		}
+		mi := models.SysDept{}
+		mi.DeptId = list[j].DeptId
+		mi.ParentId = list[j].ParentId
+		mi.DeptPath = list[j].DeptPath
+		mi.DeptName = list[j].DeptName
+		mi.Sort = list[j].Sort
+		mi.Leader = list[j].Leader
+		mi.Phone = list[j].Phone
+		mi.Email = list[j].Email
+		mi.Status = list[j].Status
+		mi.CreatedAt = list[j].CreatedAt
+		mi.Children = []models.SysDept{}
+		ms := e.deptPageCall(deptlist, mi)
+		childrenList = append(childrenList, ms)
+	}
+	menu.Children = childrenList
+	return menu
+}
+
+// GetWithRoleId 获取角色的部门ID集合
+func (e *SysDept) GetWithRoleId(roleId int) ([]int, error) {
+	deptIds := make([]int, 0)
+	deptList := make([]dto.DeptIdList, 0)
+	if err := e.Orm.Table("sys_role_dept").
+		Select("sys_role_dept.dept_id").
+		Joins("LEFT JOIN sys_dept on sys_dept.dept_id=sys_role_dept.dept_id").
+		Where("role_id = ? ", roleId).
+		Where(" sys_role_dept.dept_id not in(select sys_dept.parent_id from sys_role_dept LEFT JOIN sys_dept on sys_dept.dept_id=sys_role_dept.dept_id where role_id =? )", roleId).
+		Find(&deptList).Error; err != nil {
+		return nil, err
+	}
+	for i := 0; i < len(deptList); i++ {
+		deptIds = append(deptIds, deptList[i].DeptId)
+	}
+	return deptIds, nil
+}
+
+func (e *SysDept) SetDeptLabel() (m []dto.DeptLabel, err error) {
+	list := make([]models.SysDept, 0)
+	err = e.Orm.Find(&list).Error
+	if err != nil {
+		log.Error("find dept list error, %s", err.Error())
+		return
+	}
+	m = make([]dto.DeptLabel, 0)
+	var item dto.DeptLabel
+	for i := range list {
+		if list[i].ParentId != 0 {
+			continue
+		}
+		item = dto.DeptLabel{}
+		item.Id = list[i].DeptId
+		item.Label = list[i].DeptName
+		deptInfo := deptLabelCall(&list, item)
+		m = append(m, deptInfo)
+	}
+	return
+}
+
+// deptLabelCall
+func deptLabelCall(deptList *[]models.SysDept, dept dto.DeptLabel) dto.DeptLabel {
+	list := *deptList
+	var mi dto.DeptLabel
+	childrenList := make([]dto.DeptLabel, 0)
+	for j := 0; j < len(list); j++ {
+		if dept.Id != list[j].ParentId {
+			continue
+		}
+		mi = dto.DeptLabel{Id: list[j].DeptId, Label: list[j].DeptName, Children: []dto.DeptLabel{}}
+		ms := deptLabelCall(deptList, mi)
+		childrenList = append(childrenList, ms)
+	}
+	dept.Children = childrenList
+	return dept
+}
diff --git a/app/admin/service/sys_dict_data.go b/app/admin/service/sys_dict_data.go
new file mode 100644
index 0000000..7b2f6dc
--- /dev/null
+++ b/app/admin/service/sys_dict_data.go
@@ -0,0 +1,120 @@
+package service
+
+import (
+	"errors"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	cDto "go-admin/common/dto"
+)
+
+type SysDictData struct {
+	service.Service
+}
+
+// GetPage 获取列表
+func (e *SysDictData) GetPage(c *dto.SysDictDataGetPageReq, list *[]models.SysDictData, count *int64) error {
+	var err error
+	var data models.SysDictData
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取对象
+func (e *SysDictData) Get(d *dto.SysDictDataGetReq, model *models.SysDictData) error {
+	var err error
+	var data models.SysDictData
+
+	db := e.Orm.Model(&data).
+		First(model, d.GetId())
+	err = db.Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建对象
+func (e *SysDictData) Insert(c *dto.SysDictDataInsertReq) error {
+	var err error
+	var data = new(models.SysDictData)
+	c.Generate(data)
+	err = e.Orm.Create(data).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改对象
+func (e *SysDictData) Update(c *dto.SysDictDataUpdateReq) error {
+	var err error
+	var model = models.SysDictData{}
+	e.Orm.First(&model, c.GetId())
+	c.Generate(&model)
+	db := e.Orm.Save(model)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+
+	}
+	return nil
+}
+
+// Remove 删除
+func (e *SysDictData) Remove(c *dto.SysDictDataDeleteReq) error {
+	var err error
+	var data models.SysDictData
+
+	db := e.Orm.Delete(&data, c.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Delete error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		err = errors.New("无权删除该数据")
+		return err
+	}
+	return nil
+}
+
+// GetAll 获取所有
+func (e *SysDictData) GetAll(c *dto.SysDictDataGetPageReq, list *[]models.SysDictData) error {
+	var err error
+	var data models.SysDictData
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+		).
+		Find(list).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
diff --git a/app/admin/service/sys_dict_type.go b/app/admin/service/sys_dict_type.go
new file mode 100644
index 0000000..bc45fe2
--- /dev/null
+++ b/app/admin/service/sys_dict_type.go
@@ -0,0 +1,124 @@
+package service
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	cDto "go-admin/common/dto"
+)
+
+type SysDictType struct {
+	service.Service
+}
+
+// GetPage 获取列表
+func (e *SysDictType) GetPage(c *dto.SysDictTypeGetPageReq, list *[]models.SysDictType, count *int64) error {
+	var err error
+	var data models.SysDictType
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取对象
+func (e *SysDictType) Get(d *dto.SysDictTypeGetReq, model *models.SysDictType) error {
+	var err error
+
+	db := e.Orm.First(model, d.GetId())
+	err = db.Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建对象
+func (e *SysDictType) Insert(c *dto.SysDictTypeInsertReq) error {
+	var err error
+	var data models.SysDictType
+	c.Generate(&data)
+	var count int64
+	e.Orm.Model(&data).Where("dict_type = ?", data.DictType).Count(&count)
+	if count > 0 {
+		return fmt.Errorf("当前字典类型[%s]已经存在!", data.DictType)
+	}
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改对象
+func (e *SysDictType) Update(c *dto.SysDictTypeUpdateReq) error {
+	var err error
+	var model = models.SysDictType{}
+	e.Orm.First(&model, c.GetId())
+	c.Generate(&model)
+	db := e.Orm.Save(&model)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+
+	}
+	return nil
+}
+
+// Remove 删除
+func (e *SysDictType) Remove(d *dto.SysDictTypeDeleteReq) error {
+	var err error
+	var data models.SysDictType
+
+	db := e.Orm.Delete(&data, d.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Delete error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		err = errors.New("无权删除该数据")
+		return err
+	}
+	return nil
+}
+
+// GetAll 获取所有
+func (e *SysDictType) GetAll(c *dto.SysDictTypeGetPageReq, list *[]models.SysDictType) error {
+	var err error
+	var data models.SysDictType
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+		).
+		Find(list).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
diff --git a/app/admin/service/sys_login_log.go b/app/admin/service/sys_login_log.go
new file mode 100644
index 0000000..3e9f9b8
--- /dev/null
+++ b/app/admin/service/sys_login_log.go
@@ -0,0 +1,69 @@
+package service
+
+import (
+	"errors"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	cDto "go-admin/common/dto"
+)
+
+type SysLoginLog struct {
+	service.Service
+}
+
+// GetPage 获取SysLoginLog列表
+func (e *SysLoginLog) GetPage(c *dto.SysLoginLogGetPageReq, list *[]models.SysLoginLog, count *int64) error {
+	var err error
+	var data models.SysLoginLog
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取SysLoginLog对象
+func (e *SysLoginLog) Get(d *dto.SysLoginLogGetReq, model *models.SysLoginLog) error {
+	var err error
+	db := e.Orm.First(model, d.GetId())
+	err = db.Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Remove 删除SysLoginLog
+func (e *SysLoginLog) Remove(c *dto.SysLoginLogDeleteReq) error {
+	var err error
+	var data models.SysLoginLog
+
+	db := e.Orm.Delete(&data, c.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Delete error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		err = errors.New("无权删除该数据")
+		return err
+	}
+	return nil
+}
diff --git a/app/admin/service/sys_menu.go b/app/admin/service/sys_menu.go
new file mode 100644
index 0000000..7f2b48f
--- /dev/null
+++ b/app/admin/service/sys_menu.go
@@ -0,0 +1,422 @@
+package service
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/pkg/errors"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	cDto "go-admin/common/dto"
+	cModels "go-admin/common/models"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+)
+
+type SysMenu struct {
+	service.Service
+}
+
+// GetPage 获取SysMenu列表
+func (e *SysMenu) GetPage(c *dto.SysMenuGetPageReq, menus *[]models.SysMenu) *SysMenu {
+	var menu = make([]models.SysMenu, 0)
+	err := e.getPage(c, &menu).Error
+	if err != nil {
+		_ = e.AddError(err)
+		return e
+	}
+	for i := 0; i < len(menu); i++ {
+		if menu[i].ParentId != 0 {
+			continue
+		}
+		menusInfo := menuCall(&menu, menu[i])
+		*menus = append(*menus, menusInfo)
+	}
+	return e
+}
+
+// getPage 菜单分页列表
+func (e *SysMenu) getPage(c *dto.SysMenuGetPageReq, list *[]models.SysMenu) *SysMenu {
+	var err error
+	var data models.SysMenu
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.OrderDest("sort", false),
+			cDto.MakeCondition(c.GetNeedSearch()),
+		).Preload("SysApi").
+		Find(list).Error
+	if err != nil {
+		e.Log.Errorf("getSysMenuPage error:%s", err)
+		_ = e.AddError(err)
+		return e
+	}
+	return e
+}
+
+// Get 获取SysMenu对象
+func (e *SysMenu) Get(d *dto.SysMenuGetReq, model *models.SysMenu) *SysMenu {
+	var err error
+	var data models.SysMenu
+
+	db := e.Orm.Model(&data).Preload("SysApi").
+		First(model, d.GetId())
+	err = db.Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("GetSysMenu error:%s", err)
+		_ = e.AddError(err)
+		return e
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		_ = e.AddError(err)
+		return e
+	}
+	apis := make([]int, 0)
+	for _, v := range model.SysApi {
+		apis = append(apis, v.Id)
+	}
+	model.Apis = apis
+	return e
+}
+
+// Insert 创建SysMenu对象
+func (e *SysMenu) Insert(c *dto.SysMenuInsertReq) *SysMenu {
+	var err error
+	var data models.SysMenu
+	c.Generate(&data)
+	tx := e.Orm.Debug().Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	err = tx.Where("id in ?", c.Apis).Find(&data.SysApi).Error
+	if err != nil {
+		tx.Rollback()
+		e.Log.Errorf("db error:%s", err)
+		_ = e.AddError(err)
+	}
+	err = tx.Create(&data).Error
+	if err != nil {
+		tx.Rollback()
+		e.Log.Errorf("db error:%s", err)
+		_ = e.AddError(err)
+	}
+	c.MenuId = data.MenuId
+	err = e.initPaths(tx, &data)
+	if err != nil {
+		tx.Rollback()
+		e.Log.Errorf("db error:%s", err)
+		_ = e.AddError(err)
+	}
+	tx.Commit()
+	return e
+}
+
+func (e *SysMenu) initPaths(tx *gorm.DB, menu *models.SysMenu) error {
+	var err error
+	var data models.SysMenu
+	parentMenu := new(models.SysMenu)
+	if menu.ParentId != 0 {
+		err = tx.Model(&data).First(parentMenu, menu.ParentId).Error
+		if err != nil {
+			return err
+		}
+		if parentMenu.Paths == "" {
+			err = errors.New("父级paths异常,请尝试对当前节点父级菜单进行更新操作!")
+			return err
+		}
+		menu.Paths = parentMenu.Paths + "/" + pkg.IntToString(menu.MenuId)
+	} else {
+		menu.Paths = "/0/" + pkg.IntToString(menu.MenuId)
+	}
+	err = tx.Model(&data).Where("menu_id = ?", menu.MenuId).Update("paths", menu.Paths).Error
+	return err
+}
+
+// Update 修改SysMenu对象
+func (e *SysMenu) Update(c *dto.SysMenuUpdateReq) *SysMenu {
+	var err error
+	tx := e.Orm.Debug().Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	var alist = make([]models.SysApi, 0)
+	var model = models.SysMenu{}
+	tx.Preload("SysApi").First(&model, c.GetId())
+	oldPath := model.Paths
+	tx.Where("id in ?", c.Apis).Find(&alist)
+	err = tx.Model(&model).Association("SysApi").Delete(model.SysApi)
+	if err != nil {
+		e.Log.Errorf("delete policy error:%s", err)
+		_ = e.AddError(err)
+		return e
+	}
+	c.Generate(&model)
+	model.SysApi = alist
+	db := tx.Model(&model).Session(&gorm.Session{FullSaveAssociations: true}).Debug().Save(&model)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error:%s", err)
+		_ = e.AddError(err)
+		return e
+	}
+	if db.RowsAffected == 0 {
+		_ = e.AddError(errors.New("无权更新该数据"))
+		return e
+	}
+	var menuList []models.SysMenu
+	tx.Where("paths like ?", oldPath+"%").Find(&menuList)
+	for _, v := range menuList {
+		v.Paths = strings.Replace(v.Paths, oldPath, model.Paths, 1)
+		tx.Model(&v).Update("paths", v.Paths)
+	}
+	return e
+}
+
+// Remove 删除SysMenu
+func (e *SysMenu) Remove(d *dto.SysMenuDeleteReq) *SysMenu {
+	var err error
+	var data models.SysMenu
+
+	db := e.Orm.Model(&data).Delete(&data, d.Ids)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Delete error: %s", err)
+		_ = e.AddError(err)
+	}
+	if db.RowsAffected == 0 {
+		err = errors.New("无权删除该数据")
+		_ = e.AddError(err)
+	}
+	return e
+}
+
+// GetList 获取菜单数据
+func (e *SysMenu) GetList(c *dto.SysMenuGetPageReq, list *[]models.SysMenu) error {
+	var err error
+	var data models.SysMenu
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+		).
+		Find(list).Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// SetLabel 修改角色中 设置菜单基础数据
+func (e *SysMenu) SetLabel() (m []dto.MenuLabel, err error) {
+	var list []models.SysMenu
+	err = e.GetList(&dto.SysMenuGetPageReq{}, &list)
+
+	m = make([]dto.MenuLabel, 0)
+	for i := 0; i < len(list); i++ {
+		if list[i].ParentId != 0 {
+			continue
+		}
+		e := dto.MenuLabel{}
+		e.Id = list[i].MenuId
+		e.Label = list[i].Title
+		deptsInfo := menuLabelCall(&list, e)
+
+		m = append(m, deptsInfo)
+	}
+	return
+}
+
+// GetSysMenuByRoleName 左侧菜单
+func (e *SysMenu) GetSysMenuByRoleName(roleName ...string) ([]models.SysMenu, error) {
+	var MenuList []models.SysMenu
+	var role models.SysRole
+	var err error
+	admin := false
+	for _, s := range roleName {
+		if s == "admin" {
+			admin = true
+		}
+	}
+
+	if len(roleName) > 0 && admin {
+		var data []models.SysMenu
+		err = e.Orm.Where(" menu_type in ('M','C')").
+			Order("sort").
+			Find(&data).
+			Error
+		MenuList = data
+	} else {
+		err = e.Orm.Model(&role).Preload("SysMenu", func(db *gorm.DB) *gorm.DB {
+			return db.Where(" menu_type in ('M','C')").Order("sort")
+		}).Where("role_name in ?", roleName).Find(&role).
+			Error
+		MenuList = *role.SysMenu
+	}
+
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+	}
+	return MenuList, err
+}
+
+// menuLabelCall 递归构造组织数据
+func menuLabelCall(eList *[]models.SysMenu, dept dto.MenuLabel) dto.MenuLabel {
+	list := *eList
+
+	min := make([]dto.MenuLabel, 0)
+	for j := 0; j < len(list); j++ {
+
+		if dept.Id != list[j].ParentId {
+			continue
+		}
+		mi := dto.MenuLabel{}
+		mi.Id = list[j].MenuId
+		mi.Label = list[j].Title
+		mi.Children = []dto.MenuLabel{}
+		if list[j].MenuType != "F" {
+			ms := menuLabelCall(eList, mi)
+			min = append(min, ms)
+		} else {
+			min = append(min, mi)
+		}
+	}
+	if len(min) > 0 {
+		dept.Children = min
+	} else {
+		dept.Children = nil
+	}
+	return dept
+}
+
+// menuCall 构建菜单树
+func menuCall(menuList *[]models.SysMenu, menu models.SysMenu) models.SysMenu {
+	list := *menuList
+
+	min := make([]models.SysMenu, 0)
+	for j := 0; j < len(list); j++ {
+
+		if menu.MenuId != list[j].ParentId {
+			continue
+		}
+		mi := models.SysMenu{}
+		mi.MenuId = list[j].MenuId
+		mi.MenuName = list[j].MenuName
+		mi.Title = list[j].Title
+		mi.Icon = list[j].Icon
+		mi.Path = list[j].Path
+		mi.MenuType = list[j].MenuType
+		mi.Action = list[j].Action
+		mi.Permission = list[j].Permission
+		mi.ParentId = list[j].ParentId
+		mi.NoCache = list[j].NoCache
+		mi.Breadcrumb = list[j].Breadcrumb
+		mi.Component = list[j].Component
+		mi.Sort = list[j].Sort
+		mi.Visible = list[j].Visible
+		mi.CreatedAt = list[j].CreatedAt
+		mi.SysApi = list[j].SysApi
+		mi.Children = []models.SysMenu{}
+
+		if mi.MenuType != cModels.Button {
+			ms := menuCall(menuList, mi)
+			min = append(min, ms)
+		} else {
+			min = append(min, mi)
+		}
+	}
+	menu.Children = min
+	return menu
+}
+
+func menuDistinct(menuList []models.SysMenu) (result []models.SysMenu) {
+	distinctMap := make(map[int]struct{}, len(menuList))
+	for _, menu := range menuList {
+		if _, ok := distinctMap[menu.MenuId]; !ok {
+			distinctMap[menu.MenuId] = struct{}{}
+			result = append(result, menu)
+		}
+	}
+	return result
+}
+
+func recursiveSetMenu(orm *gorm.DB, mIds []int, menus *[]models.SysMenu) error {
+	if len(mIds) == 0 || menus == nil {
+		return nil
+	}
+	var subMenus []models.SysMenu
+	err := orm.Where(fmt.Sprintf(" menu_type in ('%s', '%s', '%s') and menu_id in ?",
+		cModels.Directory, cModels.Menu, cModels.Button), mIds).Order("sort").Find(&subMenus).Error
+	if err != nil {
+		return err
+	}
+
+	subIds := make([]int, 0)
+	for _, menu := range subMenus {
+		if menu.ParentId != 0 {
+			subIds = append(subIds, menu.ParentId)
+		}
+		if menu.MenuType != cModels.Button {
+			*menus = append(*menus, menu)
+		}
+	}
+	return recursiveSetMenu(orm, subIds, menus)
+}
+
+// SetMenuRole 获取左侧菜单树使用
+func (e *SysMenu) SetMenuRole(roleName string) (m []models.SysMenu, err error) {
+	menus, err := e.getByRoleName(roleName)
+	m = make([]models.SysMenu, 0)
+	for i := 0; i < len(menus); i++ {
+		if menus[i].ParentId != 0 {
+			continue
+		}
+		menusInfo := menuCall(&menus, menus[i])
+		m = append(m, menusInfo)
+	}
+	return
+}
+
+func (e *SysMenu) getByRoleName(roleName string) ([]models.SysMenu, error) {
+	var role models.SysRole
+	var err error
+	data := make([]models.SysMenu, 0)
+
+	if roleName == "admin" {
+		err = e.Orm.Where(" menu_type in ('M','C') and deleted_at is null").
+			Order("sort").
+			Find(&data).
+			Error
+		err = errors.WithStack(err)
+	} else {
+		role.RoleKey = roleName
+		err = e.Orm.Model(&role).Where("role_key = ? ", roleName).Preload("SysMenu").First(&role).Error
+
+		if role.SysMenu != nil {
+			mIds := make([]int, 0)
+			for _, menu := range *role.SysMenu {
+				mIds = append(mIds, menu.MenuId)
+			}
+			if err := recursiveSetMenu(e.Orm, mIds, &data); err != nil {
+				return nil, err
+			}
+
+			data = menuDistinct(data)
+		}
+	}
+
+	sort.Sort(models.SysMenuSlice(data))
+	return data, err
+}
diff --git a/app/admin/service/sys_opera_log.go b/app/admin/service/sys_opera_log.go
new file mode 100644
index 0000000..c94b82c
--- /dev/null
+++ b/app/admin/service/sys_opera_log.go
@@ -0,0 +1,83 @@
+package service
+
+import (
+	"errors"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	cDto "go-admin/common/dto"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+)
+
+type SysOperaLog struct {
+	service.Service
+}
+
+// GetPage 获取SysOperaLog列表
+func (e *SysOperaLog) GetPage(c *dto.SysOperaLogGetPageReq, list *[]models.SysOperaLog, count *int64) error {
+	var err error
+	var data models.SysOperaLog
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("Service GetSysOperaLogPage error:%s", err.Error())
+		return err
+	}
+	return nil
+}
+
+// Get 获取SysOperaLog对象
+func (e *SysOperaLog) Get(d *dto.SysOperaLogGetReq, model *models.SysOperaLog) error {
+	var data models.SysOperaLog
+
+	err := e.Orm.Model(&data).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetSysOperaLog error:%s", err.Error())
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("Service GetSysOperaLog error:%s", err.Error())
+		return err
+	}
+	return nil
+}
+
+// Insert 创建SysOperaLog对象
+func (e *SysOperaLog) Insert(model *models.SysOperaLog) error {
+	var err error
+	var data models.SysOperaLog
+
+	err = e.Orm.Model(&data).
+		Create(model).Error
+	if err != nil {
+		e.Log.Errorf("Service InsertSysOperaLog error:%s", err.Error())
+		return err
+	}
+	return nil
+}
+
+// Remove 删除SysOperaLog
+func (e *SysOperaLog) Remove(d *dto.SysOperaLogDeleteReq) error {
+	var err error
+	var data models.SysOperaLog
+
+	db := e.Orm.Model(&data).Delete(&data, d.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Service RemoveSysOperaLog error:%s", err.Error())
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+	return nil
+}
diff --git a/app/admin/service/sys_post.go b/app/admin/service/sys_post.go
new file mode 100644
index 0000000..04cc0c1
--- /dev/null
+++ b/app/admin/service/sys_post.go
@@ -0,0 +1,104 @@
+package service
+
+import (
+	"errors"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	cDto "go-admin/common/dto"
+)
+
+type SysPost struct {
+	service.Service
+}
+
+// GetPage 获取SysPost列表
+func (e *SysPost) GetPage(c *dto.SysPostPageReq, list *[]models.SysPost, count *int64) error {
+	var err error
+	var data models.SysPost
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("db error:%s \r", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取SysPost对象
+func (e *SysPost) Get(d *dto.SysPostGetReq, model *models.SysPost) error {
+	var err error
+	var data models.SysPost
+
+	db := e.Orm.Model(&data).
+		First(model, d.GetId())
+	err = db.Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建SysPost对象
+func (e *SysPost) Insert(c *dto.SysPostInsertReq) error {
+	var err error
+	var data models.SysPost
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改SysPost对象
+func (e *SysPost) Update(c *dto.SysPostUpdateReq) error {
+	var err error
+	var model = models.SysPost{}
+	e.Orm.First(&model, c.GetId())
+	c.Generate(&model)
+
+	db := e.Orm.Save(&model)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+
+	}
+	return nil
+}
+
+// Remove 删除SysPost
+func (e *SysPost) Remove(d *dto.SysPostDeleteReq) error {
+	var err error
+	var data models.SysPost
+
+	db := e.Orm.Model(&data).Delete(&data, d.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Delete error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		err = errors.New("无权删除该数据")
+		return err
+	}
+	return nil
+}
diff --git a/app/admin/service/sys_role.go b/app/admin/service/sys_role.go
new file mode 100644
index 0000000..f1fee74
--- /dev/null
+++ b/app/admin/service/sys_role.go
@@ -0,0 +1,352 @@
+package service
+
+import (
+	"errors"
+
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"gorm.io/gorm/clause"
+
+	"github.com/casbin/casbin/v2"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	cDto "go-admin/common/dto"
+)
+
+type SysRole struct {
+	service.Service
+}
+
+// GetPage 获取SysRole列表
+func (e *SysRole) GetPage(c *dto.SysRoleGetPageReq, list *[]models.SysRole, count *int64) error {
+	var err error
+	var data models.SysRole
+
+	err = e.Orm.Model(&data).Preload("SysMenu").
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取SysRole对象
+func (e *SysRole) Get(d *dto.SysRoleGetReq, model *models.SysRole) error {
+	var err error
+	db := e.Orm.First(model, d.GetId())
+	err = db.Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	model.MenuIds, err = e.GetRoleMenuId(model.RoleId)
+	if err != nil {
+		e.Log.Errorf("get menuIds error, %s", err.Error())
+		return err
+	}
+	return nil
+}
+
+// Insert 创建SysRole对象
+func (e *SysRole) Insert(c *dto.SysRoleInsertReq, cb *casbin.SyncedEnforcer) error {
+	var err error
+	var data models.SysRole
+	var dataMenu []models.SysMenu
+	err = e.Orm.Preload("SysApi").Where("menu_id in ?", c.MenuIds).Find(&dataMenu).Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	c.SysMenu = dataMenu
+	c.Generate(&data)
+	tx := e.Orm
+	if config.DatabaseConfig.Driver != "sqlite3" {
+		tx := e.Orm.Begin()
+		defer func() {
+			if err != nil {
+				tx.Rollback()
+			} else {
+				tx.Commit()
+			}
+		}()
+	}
+	var count int64
+	err = tx.Model(&data).Where("role_key = ?", c.RoleKey).Count(&count).Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+
+	if count > 0 {
+		err = errors.New("roleKey已存在,需更换在提交!")
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+
+	err = tx.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+
+	mp := make(map[string]interface{}, 0)
+	polices := make([][]string, 0)
+	for _, menu := range dataMenu {
+		for _, api := range menu.SysApi {
+			if mp[data.RoleKey+"-"+api.Path+"-"+api.Action] != "" {
+				mp[data.RoleKey+"-"+api.Path+"-"+api.Action] = ""
+				polices = append(polices, []string{data.RoleKey, api.Path, api.Action})
+			}
+		}
+	}
+
+	if len(polices) <= 0 {
+		return nil
+	}
+
+	// 写入 sys_casbin_rule 权限表里 当前角色数据的记录
+	_, err = cb.AddNamedPolicies("p", polices)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Update 修改SysRole对象
+func (e *SysRole) Update(c *dto.SysRoleUpdateReq, cb *casbin.SyncedEnforcer) error {
+	var err error
+	tx := e.Orm
+	if config.DatabaseConfig.Driver != "sqlite3" {
+		tx := e.Orm.Begin()
+		defer func() {
+			if err != nil {
+				tx.Rollback()
+			} else {
+				tx.Commit()
+			}
+		}()
+	}
+	var model = models.SysRole{}
+	var mlist = make([]models.SysMenu, 0)
+	tx.Preload("SysMenu").First(&model, c.GetId())
+	tx.Preload("SysApi").Where("menu_id in ?", c.MenuIds).Find(&mlist)
+	err = tx.Model(&model).Association("SysMenu").Delete(model.SysMenu)
+	if err != nil {
+		e.Log.Errorf("delete policy error:%s", err)
+		return err
+	}
+	c.Generate(&model)
+	model.SysMenu = &mlist
+	// 更新关联的数据,使用 FullSaveAssociations 模式
+	db := tx.Session(&gorm.Session{FullSaveAssociations: true}).Debug().Save(&model)
+
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+
+	// 清除 sys_casbin_rule 权限表里 当前角色的所有记录
+	_, err = cb.RemoveFilteredPolicy(0, model.RoleKey)
+	if err != nil {
+		e.Log.Errorf("delete policy error:%s", err)
+		return err
+	}
+	mp := make(map[string]interface{}, 0)
+	polices := make([][]string, 0)
+	for _, menu := range mlist {
+		for _, api := range menu.SysApi {
+			if mp[model.RoleKey+"-"+api.Path+"-"+api.Action] != "" {
+				mp[model.RoleKey+"-"+api.Path+"-"+api.Action] = ""
+				//_, err = cb.AddNamedPolicy("p", model.RoleKey, api.Path, api.Action)
+				polices = append(polices, []string{model.RoleKey, api.Path, api.Action})
+			}
+		}
+	}
+	if len(polices) <= 0 {
+		return nil
+	}
+
+	// 写入 sys_casbin_rule 权限表里 当前角色数据的记录
+	_, err = cb.AddNamedPolicies("p", polices)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// Remove 删除SysRole
+func (e *SysRole) Remove(c *dto.SysRoleDeleteReq, cb *casbin.SyncedEnforcer) error {
+	var err error
+	tx := e.Orm
+	if config.DatabaseConfig.Driver != "sqlite3" {
+		tx := e.Orm.Begin()
+		defer func() {
+			if err != nil {
+				tx.Rollback()
+			} else {
+				tx.Commit()
+			}
+		}()
+	}
+	var model = models.SysRole{}
+	tx.Preload("SysMenu").Preload("SysDept").First(&model, c.GetId())
+	//删除 SysRole 时,同时删除角色所有 关联其它表 记录 (SysMenu 和 SysMenu)
+	db := tx.Select(clause.Associations).Delete(&model)
+
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+
+	// 清除 sys_casbin_rule 权限表里 当前角色的所有记录
+	_, _ = cb.RemoveFilteredPolicy(0, model.RoleKey)
+
+	return nil
+}
+
+// GetRoleMenuId 获取角色对应的菜单ids
+func (e *SysRole) GetRoleMenuId(roleId int) ([]int, error) {
+	menuIds := make([]int, 0)
+	model := models.SysRole{}
+	model.RoleId = roleId
+	if err := e.Orm.Model(&model).Preload("SysMenu").First(&model).Error; err != nil {
+		return nil, err
+	}
+	l := *model.SysMenu
+	for i := 0; i < len(l); i++ {
+		menuIds = append(menuIds, l[i].MenuId)
+	}
+	return menuIds, nil
+}
+
+func (e *SysRole) UpdateDataScope(c *dto.RoleDataScopeReq) *SysRole {
+	var err error
+	tx := e.Orm
+	if config.DatabaseConfig.Driver != "sqlite3" {
+		tx := e.Orm.Begin()
+		defer func() {
+			if err != nil {
+				tx.Rollback()
+			} else {
+				tx.Commit()
+			}
+		}()
+	}
+	var dlist = make([]models.SysDept, 0)
+	var model = models.SysRole{}
+	tx.Preload("SysDept").First(&model, c.RoleId)
+	tx.Where("dept_id in ?", c.DeptIds).Find(&dlist)
+	// 删除SysRole 和 SysDept 的关联关系
+	err = tx.Model(&model).Association("SysDept").Delete(model.SysDept)
+	if err != nil {
+		e.Log.Errorf("delete SysDept error:%s", err)
+		_ = e.AddError(err)
+		return e
+	}
+	c.Generate(&model)
+	model.SysDept = dlist
+	// 更新关联的数据,使用 FullSaveAssociations 模式
+	db := tx.Model(&model).Session(&gorm.Session{FullSaveAssociations: true}).Debug().Save(&model)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error:%s", err)
+		_ = e.AddError(err)
+		return e
+	}
+	if db.RowsAffected == 0 {
+		_ = e.AddError(errors.New("无权更新该数据"))
+		return e
+	}
+	return e
+}
+
+// UpdateStatus 修改SysRole对象status
+func (e *SysRole) UpdateStatus(c *dto.UpdateStatusReq) error {
+	var err error
+	tx := e.Orm
+	if config.DatabaseConfig.Driver != "sqlite3" {
+		tx := e.Orm.Begin()
+		defer func() {
+			if err != nil {
+				tx.Rollback()
+			} else {
+				tx.Commit()
+			}
+		}()
+	}
+	var model = models.SysRole{}
+	tx.First(&model, c.GetId())
+	c.Generate(&model)
+	// 更新关联的数据,使用 FullSaveAssociations 模式
+	db := tx.Session(&gorm.Session{FullSaveAssociations: true}).Debug().Save(&model)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	return nil
+}
+
+// GetWithName 获取SysRole对象
+func (e *SysRole) GetWithName(d *dto.SysRoleByName, model *models.SysRole) *SysRole {
+	var err error
+	db := e.Orm.Where("role_name = ?", d.RoleName).First(model)
+	err = db.Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("db error:%s", err)
+		_ = e.AddError(err)
+		return e
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		_ = e.AddError(err)
+		return e
+	}
+	model.MenuIds, err = e.GetRoleMenuId(model.RoleId)
+	if err != nil {
+		e.Log.Errorf("get menuIds error, %s", err.Error())
+		_ = e.AddError(err)
+		return e
+	}
+	return e
+}
+
+// GetById 获取SysRole对象
+func (e *SysRole) GetById(roleId int) ([]string, error) {
+	permissions := make([]string, 0)
+	model := models.SysRole{}
+	model.RoleId = roleId
+	if err := e.Orm.Model(&model).Preload("SysMenu").First(&model).Error; err != nil {
+		return nil, err
+	}
+	l := *model.SysMenu
+	for i := 0; i < len(l); i++ {
+		if l[i].Permission != "" {
+			permissions = append(permissions, l[i].Permission)
+		}
+	}
+	return permissions, nil
+}
diff --git a/app/admin/service/sys_role_menu.go b/app/admin/service/sys_role_menu.go
new file mode 100644
index 0000000..9d5d38b
--- /dev/null
+++ b/app/admin/service/sys_role_menu.go
@@ -0,0 +1,110 @@
+package service
+
+import (
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+)
+
+// SysRoleMenu 即将弃用结构体
+type SysRoleMenu struct {
+	service.Service
+}
+
+//func (e *SysRoleMenu) ReloadRule(tx *gorm.DB, roleId int, menuId []int) (err error) {
+//	var role models.SysRole
+//
+//	msgID := e.MsgID
+//
+//	menu := make([]models.Menu, 0)
+//	roleMenu := make([]models.RoleMenu, len(menuId))
+//	casbinRule := make([]models.CasbinRule, 0)
+//	//先删除所有的
+//	err = e.DeleteRoleMenu(tx, roleId)
+//	if err != nil {
+//		return
+//	}
+//
+//	// 在事务中做一些数据库操作(从这一点使用'tx',而不是'db')
+//	err = tx.Where("role_id = ?", roleId).First(&role).Error
+//	if err != nil {
+//		log.Errorf("msgID[%s] get role error, %s", msgID, err.Error())
+//		return
+//	}
+//	err = tx.Where("menu_id in (?)", menuId).
+//		//Select("path, action, menu_id, menu_type").
+//		Find(&menu).Error
+//	if err != nil {
+//		log.Errorf("msgID[%s] get menu error, %s", msgID, err.Error())
+//		return
+//	}
+//	for i := range menu {
+//		roleMenu[i] = models.RoleMenu{
+//			RoleId:   role.RoleId,
+//			MenuId:   menu[i].MenuId,
+//			RoleName: role.RoleKey,
+//		}
+//		if menu[i].MenuType == "A" {
+//			casbinRule = append(casbinRule, models.CasbinRule{
+//				PType: "p",
+//				V0:    role.RoleKey,
+//				V1:    menu[i].Path,
+//				V2:    menu[i].Action,
+//			})
+//		}
+//	}
+//	err = tx.Create(&roleMenu).Error
+//	if err != nil {
+//		log.Errorf("msgID[%s] batch create role's menu error, %s", msgID, err.Error())
+//		return
+//	}
+//	if len(casbinRule) > 0 {
+//		err = tx.Create(&casbinRule).Error
+//		if err != nil {
+//			log.Errorf("msgID[%s] batch create casbin rule error, %s", msgID, err.Error())
+//			return
+//		}
+//	}
+//
+//	return
+//}
+
+//func (e *SysRoleMenu) DeleteRoleMenu(tx *gorm.DB, roleId int) (err error) {
+//	msgID := e.MsgID
+//	err = tx.Where("role_id = ?", roleId).
+//		Delete(&models.SysRoleDept{}).Error
+//	if err != nil {
+//		log.Errorf("msgID[%s] delete role's dept error, %s", msgID, err.Error())
+//		return
+//	}
+//	err = tx.Where("role_id = ?", roleId).
+//		Delete(&models.RoleMenu{}).Error
+//	if err != nil {
+//		log.Errorf("msgID[%s] delete role's menu error, %s", msgID, err.Error())
+//		return
+//	}
+//	var role models.SysRole
+//	err = tx.Where("role_id = ?", roleId).
+//		First(&role).Error
+//	if err != nil {
+//		log.Errorf("msgID[%s] get role error, %s", msgID, err.Error())
+//		return
+//	}
+//	err = tx.Where("v0 = ?", role.RoleKey).
+//		Delete(&models.CasbinRule{}).Error
+//	if err != nil {
+//		log.Errorf("msgID[%s] delete casbin rule error, %s", msgID, err.Error())
+//		return
+//	}
+//	return
+//}
+//
+//func (e *SysRoleMenu) GetIDS(tx *gorm.DB, roleName string) ([]models.MenuPath, error) {
+//	var r []models.MenuPath
+//	table := tx.Select("sys_menu.path").Table("sys_role_menu")
+//	table = table.Joins("left join sys_role on sys_role.role_id=sys_role_menu.role_id")
+//	table = table.Joins("left join sys_menu on sys_menu.id=sys_role_menu.menu_id")
+//	table = table.Where("sys_role.role_name = ? and sys_menu.type=1", roleName)
+//	if err := table.Find(&r).Error; err != nil {
+//		return nil, err
+//	}
+//	return r, nil
+//}
\ No newline at end of file
diff --git a/app/admin/service/sys_user.go b/app/admin/service/sys_user.go
new file mode 100644
index 0000000..2a03c03
--- /dev/null
+++ b/app/admin/service/sys_user.go
@@ -0,0 +1,266 @@
+package service
+
+import (
+	"errors"
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type SysUser struct {
+	service.Service
+}
+
+// GetPage 获取SysUser列表
+func (e *SysUser) GetPage(c *dto.SysUserGetPageReq, p *actions.DataPermission, list *[]models.SysUser, count *int64) error {
+	var err error
+	var data models.SysUser
+
+	err = e.Orm.Debug().Preload("Dept").
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取SysUser对象
+func (e *SysUser) Get(d *dto.SysUserById, p *actions.DataPermission, model *models.SysUser) error {
+	var data models.SysUser
+
+	err := e.Orm.Model(&data).Debug().
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建SysUser对象
+func (e *SysUser) Insert(c *dto.SysUserInsertReq) error {
+	var err error
+	var data models.SysUser
+	var i int64
+	err = e.Orm.Model(&data).Where("username = ?", c.Username).Count(&i).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	if i > 0 {
+		err := errors.New("用户名已存在!")
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改SysUser对象
+func (e *SysUser) Update(c *dto.SysUserUpdateReq, p *actions.DataPermission) error {
+	var err error
+	var model models.SysUser
+	db := e.Orm.Scopes(
+		actions.Permission(model.TableName(), p),
+	).First(&model, c.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Service UpdateSysUser error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+
+	}
+	c.Generate(&model)
+	update := e.Orm.Model(&model).Where("user_id = ?", &model.UserId).Omit("password", "salt").Updates(&model)
+	if err = update.Error; err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	if update.RowsAffected == 0 {
+		err = errors.New("update userinfo error")
+		log.Warnf("db update error")
+		return err
+	}
+	return nil
+}
+
+// UpdateAvatar 更新用户头像
+func (e *SysUser) UpdateAvatar(c *dto.UpdateSysUserAvatarReq, p *actions.DataPermission) error {
+	var err error
+	var model models.SysUser
+	db := e.Orm.Scopes(
+		actions.Permission(model.TableName(), p),
+	).First(&model, c.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Service UpdateSysUser error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+
+	}
+	err = e.Orm.Table(model.TableName()).Where("user_id =? ", c.UserId).Updates(c).Error
+	if err != nil {
+		e.Log.Errorf("Service UpdateSysUser error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// UpdateStatus 更新用户状态
+func (e *SysUser) UpdateStatus(c *dto.UpdateSysUserStatusReq, p *actions.DataPermission) error {
+	var err error
+	var model models.SysUser
+	db := e.Orm.Scopes(
+		actions.Permission(model.TableName(), p),
+	).First(&model, c.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Service UpdateSysUser error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+
+	}
+	err = e.Orm.Table(model.TableName()).Where("user_id =? ", c.UserId).Updates(c).Error
+	if err != nil {
+		e.Log.Errorf("Service UpdateSysUser error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// ResetPwd 重置用户密码
+func (e *SysUser) ResetPwd(c *dto.ResetSysUserPwdReq, p *actions.DataPermission) error {
+	var err error
+	var model models.SysUser
+	db := e.Orm.Scopes(
+		actions.Permission(model.TableName(), p),
+	).First(&model, c.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("At Service ResetSysUserPwd error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权更新该数据")
+	}
+	c.Generate(&model)
+	err = e.Orm.Omit("username", "nick_name", "phone", "role_id", "avatar", "sex").Save(&model).Error
+	if err != nil {
+		e.Log.Errorf("At Service ResetSysUserPwd error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// Remove 删除SysUser
+func (e *SysUser) Remove(c *dto.SysUserById, p *actions.DataPermission) error {
+	var err error
+	var data models.SysUser
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, c.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("Error found in  RemoveSysUser : %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return errors.New("无权删除该数据")
+	}
+	return nil
+}
+
+// UpdatePwd 修改SysUser对象密码
+func (e *SysUser) UpdatePwd(id int, oldPassword, newPassword string, p *actions.DataPermission) error {
+	var err error
+
+	if newPassword == "" {
+		return nil
+	}
+	c := &models.SysUser{}
+
+	err = e.Orm.Model(c).
+		Scopes(
+			actions.Permission(c.TableName(), p),
+		).Select("UserId", "Password", "Salt").
+		First(c, id).Error
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return errors.New("无权更新该数据")
+		}
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	var ok bool
+	ok, err = pkg.CompareHashAndPassword(c.Password, oldPassword)
+	if err != nil {
+		e.Log.Errorf("CompareHashAndPassword error, %s", err.Error())
+		return err
+	}
+	if !ok {
+		err = errors.New("incorrect Password")
+		e.Log.Warnf("user[%d] %s", id, err.Error())
+		return err
+	}
+	c.Password = newPassword
+	db := e.Orm.Model(c).Where("user_id = ?", id).
+		Select("Password", "Salt").
+		Updates(c)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		err = errors.New("set password error")
+		log.Warnf("db update error")
+		return err
+	}
+	return nil
+}
+
+func (e *SysUser) GetProfile(c *dto.SysUserById, user *models.SysUser, roles *[]models.SysRole, posts *[]models.SysPost) error {
+	err := e.Orm.Preload("Dept").First(user, c.GetId()).Error
+	if err != nil {
+		return err
+	}
+	err = e.Orm.Find(roles, user.RoleId).Error
+	if err != nil {
+		return err
+	}
+	err = e.Orm.Find(posts, user.PostIds).Error
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
diff --git a/app/admin/service/sysdb/sys_status_code.go b/app/admin/service/sysdb/sys_status_code.go
new file mode 100644
index 0000000..fdca061
--- /dev/null
+++ b/app/admin/service/sysdb/sys_status_code.go
@@ -0,0 +1,18 @@
+package sysdb
+
+import (
+	"go-admin/app/admin/models/sysmodel"
+	"log"
+
+	"gorm.io/gorm"
+)
+
+func GetAllStatusCode(orm *gorm.DB) []sysmodel.StatusCode {
+	// sql := `SELECT code, explain, zh_cn, zh_hk, en FROM sys_status_code`
+	var statusCodeList []sysmodel.StatusCode
+	if err := orm.Table("sys_status_code").Find(&statusCodeList).Error; err != nil {
+		log.Println("InitStatusCodeLanguage GetAllStatusCode Error:", err)
+		return statusCodeList
+	}
+	return statusCodeList
+}
diff --git a/app/admin/service/vts_recharge.go b/app/admin/service/vts_recharge.go
new file mode 100644
index 0000000..c21ee44
--- /dev/null
+++ b/app/admin/service/vts_recharge.go
@@ -0,0 +1,109 @@
+package service
+
+import (
+	"errors"
+
+    "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/actions"
+	cDto "go-admin/common/dto"
+)
+
+type VtsRecharge struct {
+	service.Service
+}
+
+// GetPage 获取VtsRecharge列表
+func (e *VtsRecharge) GetPage(c *dto.VtsRechargeGetPageReq, p *actions.DataPermission, list *[]models.VtsRecharge, count *int64) error {
+	var err error
+	var data models.VtsRecharge
+
+	err = e.Orm.Model(&data).
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.Permission(data.TableName(), p),
+		).
+		Find(list).Limit(-1).Offset(-1).
+		Count(count).Error
+	if err != nil {
+		e.Log.Errorf("VtsRechargeService GetPage error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Get 获取VtsRecharge对象
+func (e *VtsRecharge) Get(d *dto.VtsRechargeGetReq, p *actions.DataPermission, model *models.VtsRecharge) error {
+	var data models.VtsRecharge
+
+	err := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).
+		First(model, d.GetId()).Error
+	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+		err = errors.New("查看对象不存在或无权查看")
+		e.Log.Errorf("Service GetVtsRecharge error:%s \r\n", err)
+		return err
+	}
+	if err != nil {
+		e.Log.Errorf("db error:%s", err)
+		return err
+	}
+	return nil
+}
+
+// Insert 创建VtsRecharge对象
+func (e *VtsRecharge) Insert(c *dto.VtsRechargeInsertReq) error {
+    var err error
+    var data models.VtsRecharge
+    c.Generate(&data)
+	err = e.Orm.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("VtsRechargeService Insert error:%s \r\n", err)
+		return err
+	}
+	return nil
+}
+
+// Update 修改VtsRecharge对象
+func (e *VtsRecharge) Update(c *dto.VtsRechargeUpdateReq, p *actions.DataPermission) error {
+    var err error
+    var data = models.VtsRecharge{}
+    e.Orm.Scopes(
+            actions.Permission(data.TableName(), p),
+        ).First(&data, c.GetId())
+    c.Generate(&data)
+
+    db := e.Orm.Save(&data)
+    if err = db.Error; err != nil {
+        e.Log.Errorf("VtsRechargeService Save error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权更新该数据")
+    }
+    return nil
+}
+
+// Remove 删除VtsRecharge
+func (e *VtsRecharge) Remove(d *dto.VtsRechargeDeleteReq, p *actions.DataPermission) error {
+	var data models.VtsRecharge
+
+	db := e.Orm.Model(&data).
+		Scopes(
+			actions.Permission(data.TableName(), p),
+		).Delete(&data, d.GetId())
+	if err := db.Error; err != nil {
+        e.Log.Errorf("Service RemoveVtsRecharge error:%s \r\n", err)
+        return err
+    }
+    if db.RowsAffected == 0 {
+        return errors.New("无权删除该数据")
+    }
+	return nil
+}
diff --git a/app/jobs/apis/sys_job.go b/app/jobs/apis/sys_job.go
new file mode 100644
index 0000000..296138d
--- /dev/null
+++ b/app/jobs/apis/sys_job.go
@@ -0,0 +1,69 @@
+package apis
+
+import (
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+
+	"go-admin/app/jobs/service"
+	"go-admin/common/dto"
+)
+
+type SysJob struct {
+	api.Api
+}
+
+// RemoveJobForService 调用service实现
+func (e SysJob) RemoveJobForService(c *gin.Context) {
+	v := dto.GeneralDelDto{}
+	s := service.SysJob{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&v).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		return
+	}
+
+	s.Cron = sdk.Runtime.GetCrontabKey(c.Request.Host)
+	err = s.RemoveJob(&v)
+	if err != nil {
+		e.Logger.Errorf("RemoveJob error, %s", err.Error())
+		e.Error(500, err, "")
+		return
+	}
+	e.OK(nil, s.Msg)
+}
+
+// StartJobForService 启动job service实现
+func (e SysJob) StartJobForService(c *gin.Context) {
+	e.MakeContext(c)
+	log := e.GetLogger()
+	db, err := e.GetOrm()
+	if err != nil {
+		log.Error(err)
+		return
+	}
+	var v dto.GeneralGetDto
+	err = c.BindUri(&v)
+	if err != nil {
+		log.Warnf("参数验证错误, error: %s", err)
+		e.Error(http.StatusUnprocessableEntity, err, "参数验证失败")
+		return
+	}
+	s := service.SysJob{}
+	s.Orm = db
+	s.Log = log
+	s.Cron = sdk.Runtime.GetCrontabKey(c.Request.Host)
+	err = s.StartJob(&v)
+	if err != nil {
+		log.Errorf("GetCrontabKey error, %s", err.Error())
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(nil, s.Msg)
+}
diff --git a/app/jobs/examples.go b/app/jobs/examples.go
new file mode 100644
index 0000000..73c03dc
--- /dev/null
+++ b/app/jobs/examples.go
@@ -0,0 +1,122 @@
+package jobs
+
+import (
+	"errors"
+	"fmt"
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/const/rediskey"
+	"go-admin/common/helper"
+	"time"
+
+	"github.com/bytedance/sonic"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	sysservice "github.com/go-admin-team/go-admin-core/sdk/service"
+	"gorm.io/gorm"
+)
+
+// InitJob
+// 需要将定义的struct 添加到字典中;
+// 字典 key 可以配置到 自动任务 调用目标 中;
+func InitJob() {
+	jobList = map[string]JobExec{
+		"ExamplesOne": ExamplesOne{},
+		// ...
+		"DeleteExpireOrder": DeleteExpireOrder{}, //定时删除过期数据
+		"UpRange":           UpRange{},           //更新涨跌幅
+		"InitFuturesSymbol": InitFuturesSymbol{}, //定时更新合约交易对
+		"InitSpotSymbol":    InitSpotSymbol{},    //定时更新现货交易对
+		"ClearLogJob":       ClearLogJob{},       //定时清理日志
+		"AutoPlaceOrder":    AutoPlaceOrder{},    //定时下单
+	}
+}
+
+// ExamplesOne
+// 新添加的job 必须按照以下格式定义,并实现Exec函数
+type ExamplesOne struct {
+}
+
+func (t ExamplesOne) Exec(arg interface{}) error {
+	str := time.Now().Format(timeFormat) + " [INFO] JobCore ExamplesOne exec success"
+	// TODO: 这里需要注意 Examples 传入参数是 string 所以 arg.(string);请根据对应的类型进行转化;
+	switch arg.(type) {
+
+	case string:
+		if arg.(string) != "" {
+			fmt.Println("string", arg.(string))
+			fmt.Println(str, arg.(string))
+		} else {
+			fmt.Println("arg is nil")
+			fmt.Println(str, "arg is nil")
+		}
+		break
+	}
+
+	return nil
+}
+
+// DeleteExpireOrder 清理过期订单
+type DeleteExpireOrder struct {
+}
+
+func (receiver DeleteExpireOrder) Exec(arg interface{}) error {
+	dbs := sdk.Runtime.GetDb()
+	var db *gorm.DB
+
+	for _, item := range dbs {
+		db = item
+		break
+	}
+	orders := make([]models.LinePreOrder, 0)
+	err := db.Model(&models.LinePreOrder{}).Where("status = '0' AND expire_time <= ? AND (order_type = 1 or order_type = 2)", time.Now()).Find(&orders).Error
+	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+		return err
+	}
+	for _, order := range orders {
+		//删除止盈止损数据
+		db.Model(&models.LinePreOrder{}).Where("pid = ?", order.Id).Unscoped().Delete(&models.LinePreOrder{})
+		//删除缓存
+		list := dto.PreOrderRedisList{
+			Id:          order.Id,
+			Symbol:      order.Symbol,
+			Price:       order.Price,
+			Site:        order.Site,
+			ApiId:       order.ApiId,
+			OrderSn:     order.OrderSn,
+			QuoteSymbol: order.QuoteSymbol,
+		}
+		marshal, _ := sonic.Marshal(&list)
+		if order.SymbolType == 1 {
+			helper.DefaultRedis.LRem(fmt.Sprintf(rediskey.PreSpotOrderList, order.ExchangeType), string(marshal))
+		} else {
+			helper.DefaultRedis.LRem(fmt.Sprintf(rediskey.PreFutOrderList, order.ExchangeType), string(marshal))
+		}
+		//删除主单
+		db.Model(&models.LinePreOrder{}).Where("id = ?", order.Id).Unscoped().Delete(&models.LinePreOrder{})
+	}
+	return nil
+}
+
+// UpRange 更新涨跌幅
+type UpRange struct {
+}
+
+func (receiver UpRange) Exec(arg interface{}) error {
+	dbs := sdk.Runtime.GetDb()
+	var db *gorm.DB
+
+	for _, item := range dbs {
+		db = item
+		break
+	}
+
+	limit := service.LinePriceLimit{
+		Service: sysservice.Service{Orm: db},
+	}
+	err := limit.UpRange()
+	if err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/app/jobs/jobbase.go b/app/jobs/jobbase.go
new file mode 100644
index 0000000..ea6fe3d
--- /dev/null
+++ b/app/jobs/jobbase.go
@@ -0,0 +1,203 @@
+package jobs
+
+import (
+	"fmt"
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	models2 "go-admin/app/jobs/models"
+	"gorm.io/gorm"
+	"time"
+
+	"github.com/robfig/cron/v3"
+
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/cronjob"
+)
+
+var timeFormat = "2006-01-02 15:04:05"
+var retryCount = 3
+
+var jobList map[string]JobExec
+
+//var lock sync.Mutex
+
+type JobCore struct {
+	InvokeTarget   string
+	Name           string
+	JobId          int
+	EntryId        int
+	CronExpression string
+	Args           string
+}
+
+// HttpJob 任务类型 http
+type HttpJob struct {
+	JobCore
+}
+
+type ExecJob struct {
+	JobCore
+}
+
+func (e *ExecJob) Run() {
+	startTime := time.Now()
+	var obj = jobList[e.InvokeTarget]
+	if obj == nil {
+		log.Warn("[Job] ExecJob Run job nil")
+		return
+	}
+	err := CallExec(obj.(JobExec), e.Args)
+	if err != nil {
+		// 如果失败暂停一段时间重试
+		fmt.Println(time.Now().Format(timeFormat), " [ERROR] mission failed! ", err)
+	}
+	// 结束时间
+	endTime := time.Now()
+
+	// 执行时间
+	latencyTime := endTime.Sub(startTime)
+	//TODO: 待完善部分
+	//str := time.Now().Format(timeFormat) + " [INFO] JobCore " + string(e.EntryId) + "exec success , spend :" + latencyTime.String()
+	//ws.SendAll(str)
+	log.Infof("[Job] JobCore %s exec success , spend :%v", e.Name, latencyTime)
+	return
+}
+
+// Run http 任务接口
+func (h *HttpJob) Run() {
+
+	startTime := time.Now()
+	var count = 0
+	var err error
+	var str string
+	/* 循环 */
+LOOP:
+	if count < retryCount {
+		/* 跳过迭代 */
+		str, err = pkg.Get(h.InvokeTarget)
+		if err != nil {
+			// 如果失败暂停一段时间重试
+			fmt.Println(time.Now().Format(timeFormat), " [ERROR] mission failed! ", err)
+			fmt.Printf(time.Now().Format(timeFormat)+" [INFO] Retry after the task fails %d seconds! %s \n", (count+1)*5, str)
+			time.Sleep(time.Duration(count+1) * 5 * time.Second)
+			count = count + 1
+			goto LOOP
+		}
+	}
+	// 结束时间
+	endTime := time.Now()
+
+	// 执行时间
+	latencyTime := endTime.Sub(startTime)
+	//TODO: 待完善部分
+
+	log.Infof("[Job] JobCore %s exec success , spend :%v", h.Name, latencyTime)
+	return
+}
+
+// Setup 初始化
+func Setup(dbs map[string]*gorm.DB) {
+
+	fmt.Println(time.Now().Format(timeFormat), " [INFO] JobCore Starting...")
+
+	for k, db := range dbs {
+		sdk.Runtime.SetCrontab(k, cronjob.NewWithSeconds())
+		setup(k, db)
+	}
+}
+
+func setup(key string, db *gorm.DB) {
+	crontab := sdk.Runtime.GetCrontabKey(key)
+	sysJob := models2.SysJob{}
+	jobList := make([]models2.SysJob, 0)
+	err := sysJob.GetList(db, &jobList)
+	if err != nil {
+		fmt.Println(time.Now().Format(timeFormat), " [ERROR] JobCore init error", err)
+	}
+	if len(jobList) == 0 {
+		fmt.Println(time.Now().Format(timeFormat), " [INFO] JobCore total:0")
+	}
+
+	_, err = sysJob.RemoveAllEntryID(db)
+	if err != nil {
+		fmt.Println(time.Now().Format(timeFormat), " [ERROR] JobCore remove entry_id error", err)
+	}
+
+	for i := 0; i < len(jobList); i++ {
+		if jobList[i].JobType == 1 {
+			j := &HttpJob{}
+			j.InvokeTarget = jobList[i].InvokeTarget
+			j.CronExpression = jobList[i].CronExpression
+			j.JobId = jobList[i].JobId
+			j.Name = jobList[i].JobName
+
+			sysJob.EntryId, err = AddJob(crontab, j)
+		} else if jobList[i].JobType == 2 {
+			j := &ExecJob{}
+			j.InvokeTarget = jobList[i].InvokeTarget
+			j.CronExpression = jobList[i].CronExpression
+			j.JobId = jobList[i].JobId
+			j.Name = jobList[i].JobName
+			j.Args = jobList[i].Args
+			sysJob.EntryId, err = AddJob(crontab, j)
+		}
+		err = sysJob.Update(db, jobList[i].JobId)
+	}
+
+	// 其中任务
+	crontab.Start()
+	fmt.Println(time.Now().Format(timeFormat), " [INFO] JobCore start success.")
+	// 关闭任务
+	defer crontab.Stop()
+	select {}
+}
+
+// AddJob 添加任务 AddJob(invokeTarget string, jobId int, jobName string, cronExpression string)
+func AddJob(c *cron.Cron, job Job) (int, error) {
+	if job == nil {
+		fmt.Println("unknown")
+		return 0, nil
+	}
+	return job.addJob(c)
+}
+
+func (h *HttpJob) addJob(c *cron.Cron) (int, error) {
+	id, err := c.AddJob(h.CronExpression, h)
+	if err != nil {
+		fmt.Println(time.Now().Format(timeFormat), " [ERROR] JobCore AddJob error", err)
+		return 0, err
+	}
+	EntryId := int(id)
+	return EntryId, nil
+}
+
+func (e *ExecJob) addJob(c *cron.Cron) (int, error) {
+	id, err := c.AddJob(e.CronExpression, e)
+	if err != nil {
+		fmt.Println(time.Now().Format(timeFormat), " [ERROR] JobCore AddJob error", err)
+		return 0, err
+	}
+	EntryId := int(id)
+	return EntryId, nil
+}
+
+// Remove 移除任务
+func Remove(c *cron.Cron, entryID int) chan bool {
+	ch := make(chan bool)
+	go func() {
+		c.Remove(cron.EntryID(entryID))
+		fmt.Println(time.Now().Format(timeFormat), " [INFO] JobCore Remove success ,info entryID :", entryID)
+		ch <- true
+	}()
+	return ch
+}
+
+// 任务停止
+//func Stop() chan bool {
+//	ch := make(chan bool)
+//	go func() {
+//		global.GADMCron.Stop()
+//		ch <- true
+//	}()
+//	return ch
+//}
diff --git a/app/jobs/jobs.go b/app/jobs/jobs.go
new file mode 100644
index 0000000..06603b2
--- /dev/null
+++ b/app/jobs/jobs.go
@@ -0,0 +1,125 @@
+package jobs
+
+import (
+	"errors"
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"go-admin/services/fileservice"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"gorm.io/gorm"
+
+	"github.com/go-admin-team/go-admin-core/logger"
+)
+
+type InitFuturesSymbol struct {
+}
+
+type InitSpotSymbol struct {
+}
+
+type ClearLogJob struct {
+}
+
+type AutoPlaceOrder struct {
+}
+
+// 初始化合约交易对
+func (t InitFuturesSymbol) Exec(arg interface{}) error {
+	str := time.Now().Format(timeFormat) + " [INFO] JobCore InitFuturesSymbol exec success"
+	defer logger.Info(str)
+	dbs := sdk.Runtime.GetDb()
+	var db *gorm.DB
+
+	for _, item := range dbs {
+		db = item
+		break
+	}
+
+	symbolService := service.LineSymbol{}
+	symbolService.Orm = db
+
+	//重置合约交易对
+	symbolService.ResetFuturesSymbol()
+
+	return nil
+}
+
+// 初始化现货交易对
+func (t InitSpotSymbol) Exec(arg interface{}) error {
+	str := time.Now().Format(timeFormat) + " [INFO] JobCore InitSpotSymbol exec success"
+	defer logger.Info(str)
+
+	dbs := sdk.Runtime.GetDb()
+	var db *gorm.DB
+
+	for _, item := range dbs {
+		db = item
+		break
+	}
+
+	symbolService := service.LineSymbol{}
+	symbolService.Orm = db
+
+	//重置现货交易对
+	symbolService.ResetSpotSymbol()
+
+	return nil
+}
+
+// 删除过期日志
+func (t ClearLogJob) Exec(arg interface{}) error {
+	str := time.Now().Format(timeFormat) + " [INFO] JobCore ClearLogJob exec success"
+	defer logger.Info(str)
+	var db *gorm.DB
+
+	for _, item := range sdk.Runtime.GetDb() {
+		db = item
+		break
+	}
+
+	fileservice.ClearLogs(db)
+
+	return nil
+}
+
+// Exec 执行自动下单
+func (t AutoPlaceOrder) Exec(arg interface{}) error {
+	str := time.Now().Format(timeFormat) + " [INFO] JobCore ClearLogJob exec success"
+	defer logger.Info(str)
+	var db *gorm.DB
+
+	for _, item := range sdk.Runtime.GetDb() {
+		db = item
+		break
+	}
+	var templateLogs []models.LineOrderTemplateLogs
+	db.Model(&models.LineOrderTemplateLogs{}).Where("switch = '1'").Find(&templateLogs)
+	if len(templateLogs) > 0 {
+		ids := make([]string, len(templateLogs))
+		for _, log := range templateLogs {
+			ids = append(ids, strconv.Itoa(log.Id))
+		}
+		req := dto.QuickAddPreOrderReq{Ids: strings.Join(ids, ",")}
+		preOrderService := service.LinePreOrder{}
+		preOrderService.Orm = db
+		errs := make([]error, 0)
+		errStr := make([]string, 0)
+		err := preOrderService.QuickAddPreOrder(&req, nil, &errs)
+		if err != nil {
+			return err
+		}
+		if len(errs) > 0 {
+			//e.Logger.Error(err)
+			for _, err2 := range errs {
+				errStr = append(errStr, err2.Error())
+			}
+			return errors.New(strings.Join(errStr, ","))
+		}
+	}
+	return nil
+}
diff --git a/app/jobs/models/sys_job.go b/app/jobs/models/sys_job.go
new file mode 100644
index 0000000..a8cc6bf
--- /dev/null
+++ b/app/jobs/models/sys_job.go
@@ -0,0 +1,61 @@
+package models
+
+import (
+	"go-admin/common/models"
+	"gorm.io/gorm"
+)
+
+type SysJob struct {
+	JobId          int    `json:"jobId" gorm:"primaryKey;autoIncrement"` // 编码
+	JobName        string `json:"jobName" gorm:"size:255;"`              // 名称
+	JobGroup       string `json:"jobGroup" gorm:"size:255;"`             // 任务分组
+	JobType        int    `json:"jobType" gorm:"size:1;"`                // 任务类型
+	CronExpression string `json:"cronExpression" gorm:"size:255;"`       // cron表达式
+	InvokeTarget   string `json:"invokeTarget" gorm:"size:255;"`         // 调用目标
+	Args           string `json:"args" gorm:"size:255;"`                 // 目标参数
+	MisfirePolicy  int    `json:"misfirePolicy" gorm:"size:255;"`        // 执行策略
+	Concurrent     int    `json:"concurrent" gorm:"size:1;"`             // 是否并发
+	Status         int    `json:"status" gorm:"size:1;"`                 // 状态
+	EntryId        int    `json:"entry_id" gorm:"size:11;"`              // job启动时返回的id
+	models.ControlBy
+	models.ModelTime
+
+	DataScope string `json:"dataScope" gorm:"-"`
+}
+
+func (*SysJob) TableName() string {
+	return "sys_job"
+}
+
+func (e *SysJob) Generate() models.ActiveRecord {
+	o := *e
+	return &o
+}
+
+func (e *SysJob) GetId() interface{} {
+	return e.JobId
+}
+
+func (e *SysJob) SetCreateBy(createBy int) {
+	e.CreateBy = createBy
+}
+
+func (e *SysJob) SetUpdateBy(updateBy int) {
+	e.UpdateBy = updateBy
+}
+
+func (e *SysJob) GetList(tx *gorm.DB, list interface{}) (err error) {
+	return tx.Table(e.TableName()).Where("status = ?", 2).Find(list).Error
+}
+
+// Update 更新SysJob
+func (e *SysJob) Update(tx *gorm.DB, id interface{}) (err error) {
+	return tx.Table(e.TableName()).Where(id).Updates(&e).Error
+}
+
+func (e *SysJob) RemoveAllEntryID(tx *gorm.DB) (update SysJob, err error) {
+	if err = tx.Table(e.TableName()).Where("entry_id > ?", 0).Update("entry_id", 0).Error; err != nil {
+		return
+	}
+	return
+}
diff --git a/app/jobs/router/int_router.go b/app/jobs/router/int_router.go
new file mode 100644
index 0000000..ab65faa
--- /dev/null
+++ b/app/jobs/router/int_router.go
@@ -0,0 +1,36 @@
+package router
+
+import (
+	//"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"os"
+
+	"github.com/gin-gonic/gin"
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	common "go-admin/common/middleware"
+)
+
+// InitRouter 路由初始化,不要怀疑,这里用到了
+func InitRouter() {
+	var r *gin.Engine
+	h := sdk.Runtime.GetEngine()
+	if h == nil {
+		log.Fatal("not found engine...")
+		os.Exit(-1)
+	}
+	switch h.(type) {
+	case *gin.Engine:
+		r = h.(*gin.Engine)
+	default:
+		log.Fatal("not support other engine")
+		os.Exit(-1)
+	}
+
+	authMiddleware, err := common.AuthInit()
+	if err != nil {
+		log.Fatalf("JWT Init Error, %s", err.Error())
+	}
+
+	// 注册业务路由
+	initRouter(r, authMiddleware)
+}
diff --git a/app/jobs/router/router.go b/app/jobs/router/router.go
new file mode 100644
index 0000000..8c893a2
--- /dev/null
+++ b/app/jobs/router/router.go
@@ -0,0 +1,42 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+)
+
+var (
+	routerNoCheckRole = make([]func(*gin.RouterGroup), 0)
+	routerCheckRole   = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0)
+)
+
+// initRouter 路由示例
+func initRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine {
+
+	// 无需认证的路由
+	noCheckRoleRouter(r)
+	// 需要认证的路由
+	checkRoleRouter(r, authMiddleware)
+
+	return r
+}
+
+// noCheckRoleRouter 无需认证的路由示例
+func noCheckRoleRouter(r *gin.Engine) {
+	// 可根据业务需求来设置接口版本
+	v1 := r.Group("/api/v1")
+
+	for _, f := range routerNoCheckRole {
+		f(v1)
+	}
+}
+
+// checkRoleRouter 需要认证的路由示例
+func checkRoleRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) {
+	// 可根据业务需求来设置接口版本
+	v1 := r.Group("/api/v1")
+
+	for _, f := range routerCheckRole {
+		f(v1, authMiddleware)
+	}
+}
diff --git a/app/jobs/router/sys_job.go b/app/jobs/router/sys_job.go
new file mode 100644
index 0000000..89723d4
--- /dev/null
+++ b/app/jobs/router/sys_job.go
@@ -0,0 +1,38 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/jobs/apis"
+	models2 "go-admin/app/jobs/models"
+	dto2 "go-admin/app/jobs/service/dto"
+	"go-admin/common/actions"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerSysJobRouter)
+}
+
+// 需认证的路由代码
+func registerSysJobRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+
+	r := v1.Group("/sysjob").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		sysJob := &models2.SysJob{}
+		r.GET("", actions.PermissionAction(), actions.IndexAction(sysJob, new(dto2.SysJobSearch), func() interface{} {
+			list := make([]models2.SysJob, 0)
+			return &list
+		}))
+		r.GET("/:id", actions.PermissionAction(), actions.ViewAction(new(dto2.SysJobById), func() interface{} {
+			return &dto2.SysJobItem{}
+		}))
+		r.POST("", actions.CreateAction(new(dto2.SysJobControl)))
+		r.PUT("", actions.PermissionAction(), actions.UpdateAction(new(dto2.SysJobControl)))
+		r.DELETE("", actions.PermissionAction(), actions.DeleteAction(new(dto2.SysJobById)))
+	}
+	sysJob := apis.SysJob{}
+
+	v1.GET("/job/remove/:id", sysJob.RemoveJobForService)
+	v1.GET("/job/start/:id", sysJob.StartJobForService)
+}
diff --git a/app/jobs/service/dto/sys_job.go b/app/jobs/service/dto/sys_job.go
new file mode 100644
index 0000000..c66bcbd
--- /dev/null
+++ b/app/jobs/service/dto/sys_job.go
@@ -0,0 +1,108 @@
+package dto
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"go-admin/app/jobs/models"
+
+	"go-admin/common/dto"
+	common "go-admin/common/models"
+)
+
+type SysJobSearch struct {
+	dto.Pagination `search:"-"`
+	JobId          int    `form:"jobId" search:"type:exact;column:job_id;table:sys_job"`
+	JobName        string `form:"jobName" search:"type:icontains;column:job_name;table:sys_job"`
+	JobGroup       string `form:"jobGroup" search:"type:exact;column:job_group;table:sys_job"`
+	CronExpression string `form:"cronExpression" search:"type:exact;column:cron_expression;table:sys_job"`
+	InvokeTarget   string `form:"invokeTarget" search:"type:exact;column:invoke_target;table:sys_job"`
+	Status         int    `form:"status" search:"type:exact;column:status;table:sys_job"`
+}
+
+func (m *SysJobSearch) GetNeedSearch() interface{} {
+	return *m
+}
+
+func (m *SysJobSearch) Bind(ctx *gin.Context) error {
+	log := api.GetRequestLogger(ctx)
+	err := ctx.ShouldBind(m)
+	if err != nil {
+		log.Errorf("Bind error: %s", err)
+	}
+	return err
+}
+
+func (m *SysJobSearch) Generate() dto.Index {
+	o := *m
+	return &o
+}
+
+type SysJobControl struct {
+	JobId          int    `json:"jobId"`
+	JobName        string `json:"jobName" validate:"required"` // 名称
+	JobGroup       string `json:"jobGroup"`                    // 任务分组
+	JobType        int    `json:"jobType"`                     // 任务类型
+	CronExpression string `json:"cronExpression"`              // cron表达式
+	InvokeTarget   string `json:"invokeTarget"`                // 调用目标
+	Args           string `json:"args"`                        // 目标参数
+	MisfirePolicy  int    `json:"misfirePolicy"`               // 执行策略
+	Concurrent     int    `json:"concurrent"`                  // 是否并发
+	Status         int    `json:"status"`                      // 状态
+	EntryId        int    `json:"entryId"`                     // job启动时返回的id
+}
+
+func (s *SysJobControl) Bind(ctx *gin.Context) error {
+	return ctx.ShouldBind(s)
+}
+
+func (s *SysJobControl) Generate() dto.Control {
+	cp := *s
+	return &cp
+}
+
+func (s *SysJobControl) GenerateM() (common.ActiveRecord, error) {
+	return &models.SysJob{
+		JobId:          s.JobId,
+		JobName:        s.JobName,
+		JobGroup:       s.JobGroup,
+		JobType:        s.JobType,
+		CronExpression: s.CronExpression,
+		InvokeTarget:   s.InvokeTarget,
+		Args:           s.Args,
+		MisfirePolicy:  s.MisfirePolicy,
+		Concurrent:     s.Concurrent,
+		Status:         s.Status,
+		EntryId:        s.EntryId,
+	}, nil
+}
+
+func (s *SysJobControl) GetId() interface{} {
+	return s.JobId
+}
+
+type SysJobById struct {
+	dto.ObjectById
+}
+
+func (s *SysJobById) Generate() dto.Control {
+	cp := *s
+	return &cp
+}
+
+func (s *SysJobById) GenerateM() (common.ActiveRecord, error) {
+	return &models.SysJob{}, nil
+}
+
+type SysJobItem struct {
+	JobId          int    `json:"jobId"`
+	JobName        string `json:"jobName" validate:"required"` // 名称
+	JobGroup       string `json:"jobGroup"`                    // 任务分组
+	JobType        int    `json:"jobType"`                     // 任务类型
+	CronExpression string `json:"cronExpression"`              // cron表达式
+	InvokeTarget   string `json:"invokeTarget"`                // 调用目标
+	Args           string `json:"args"`                        // 目标参数
+	MisfirePolicy  int    `json:"misfirePolicy"`               // 执行策略
+	Concurrent     int    `json:"concurrent"`                  // 是否并发
+	Status         int    `json:"status"`                      // 状态
+	EntryId        int    `json:"entryId"`                     // job启动时返回的id
+}
diff --git a/app/jobs/service/sys_job.go b/app/jobs/service/sys_job.go
new file mode 100644
index 0000000..a1ab810
--- /dev/null
+++ b/app/jobs/service/sys_job.go
@@ -0,0 +1,93 @@
+package service
+
+import (
+	"errors"
+	"time"
+
+	"github.com/go-admin-team/go-admin-core/sdk/service"
+	"github.com/robfig/cron/v3"
+
+	"go-admin/app/jobs"
+	"go-admin/app/jobs/models"
+	"go-admin/common/dto"
+)
+
+type SysJob struct {
+	service.Service
+	Cron *cron.Cron
+}
+
+// RemoveJob 删除job
+func (e *SysJob) RemoveJob(c *dto.GeneralDelDto) error {
+	var err error
+	var data models.SysJob
+	err = e.Orm.Table(data.TableName()).First(&data, c.Id).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	cn := jobs.Remove(e.Cron, data.EntryId)
+
+	select {
+	case res := <-cn:
+		if res {
+			err = e.Orm.Table(data.TableName()).Where("entry_id = ?", data.EntryId).Update("entry_id", 0).Error
+			if err != nil {
+				e.Log.Errorf("db error: %s", err)
+			}
+			return err
+		}
+	case <-time.After(time.Second * 1):
+		e.Msg = "操作超时!"
+		return nil
+	}
+	return nil
+}
+
+// StartJob 启动任务
+func (e *SysJob) StartJob(c *dto.GeneralGetDto) error {
+	var data models.SysJob
+	var err error
+	err = e.Orm.Table(data.TableName()).First(&data, c.Id).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+
+	if data.Status == 1 {
+		err = errors.New("当前Job是关闭状态不能被启动,请先启用。")
+		return err
+	}
+
+	if data.JobType == 1 {
+		var j = &jobs.HttpJob{}
+		j.InvokeTarget = data.InvokeTarget
+		j.CronExpression = data.CronExpression
+		j.JobId = data.JobId
+		j.Name = data.JobName
+		data.EntryId, err = jobs.AddJob(e.Cron, j)
+		if err != nil {
+			e.Log.Errorf("jobs AddJob[HttpJob] error: %s", err)
+		}
+	} else {
+		var j = &jobs.ExecJob{}
+		j.InvokeTarget = data.InvokeTarget
+		j.CronExpression = data.CronExpression
+		j.JobId = data.JobId
+		j.Name = data.JobName
+		j.Args = data.Args
+		data.EntryId, err = jobs.AddJob(e.Cron, j)
+		if err != nil {
+			e.Log.Errorf("jobs AddJob[ExecJob] error: %s", err)
+		}
+	}
+	if err != nil {
+		return err
+	}
+
+	err = e.Orm.Table(data.TableName()).Where(c.Id).Updates(&data).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+	}
+	return err
+}
diff --git a/app/jobs/type.go b/app/jobs/type.go
new file mode 100644
index 0000000..1b5c30b
--- /dev/null
+++ b/app/jobs/type.go
@@ -0,0 +1,16 @@
+package jobs
+
+import "github.com/robfig/cron/v3"
+
+type Job interface {
+	Run()
+	addJob(*cron.Cron) (int, error)
+}
+
+type JobExec interface {
+	Exec(arg interface{}) error
+}
+
+func CallExec(e JobExec, arg interface{}) error {
+	return e.Exec(arg)
+}
diff --git a/app/other/apis/file.go b/app/other/apis/file.go
new file mode 100644
index 0000000..e0d77f4
--- /dev/null
+++ b/app/other/apis/file.go
@@ -0,0 +1,204 @@
+package apis
+
+import (
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"strings"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/utils"
+	"github.com/google/uuid"
+
+	"go-admin/common/file_store"
+)
+
+type FileResponse struct {
+	Size     int64  `json:"size"`
+	Path     string `json:"path"`
+	FullPath string `json:"full_path"`
+	Name     string `json:"name"`
+	Type     string `json:"type"`
+}
+
+const path = "static/uploadfile/"
+
+type File struct {
+	api.Api
+}
+
+// UploadFile 上传图片
+// @Summary 上传图片
+// @Description 获取JSON
+// @Tags 公共接口
+// @Accept multipart/form-data
+// @Param type query string true "type" (1:单图,2:多图, 3:base64图片)
+// @Param file formData file true "file"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/v1/public/uploadFile [post]
+// @Security Bearer
+func (e File) UploadFile(c *gin.Context) {
+	e.MakeContext(c)
+	tag, _ := c.GetPostForm("type")
+	urlPrefix := fmt.Sprintf("%s://%s/", "http", c.Request.Host)
+	var fileResponse FileResponse
+
+	switch tag {
+	case "1": // 单图
+		var done bool
+		fileResponse, done = e.singleFile(c, fileResponse, urlPrefix)
+		if done {
+			return
+		}
+		e.OK(fileResponse, "上传成功")
+		return
+	case "2": // 多图
+		multipartFile := e.multipleFile(c, urlPrefix)
+		e.OK(multipartFile, "上传成功")
+		return
+	case "3": // base64
+		fileResponse = e.baseImg(c, fileResponse, urlPrefix)
+		e.OK(fileResponse, "上传成功")
+	default:
+		var done bool
+		fileResponse, done = e.singleFile(c, fileResponse, urlPrefix)
+		if done {
+			return
+		}
+		e.OK(fileResponse, "上传成功")
+		return
+	}
+
+}
+
+func (e File) baseImg(c *gin.Context, fileResponse FileResponse, urlPerfix string) FileResponse {
+	files, _ := c.GetPostForm("file")
+	file2list := strings.Split(files, ",")
+	ddd, _ := base64.StdEncoding.DecodeString(file2list[1])
+	guid := uuid.New().String()
+	fileName := guid + ".jpg"
+	err := utils.IsNotExistMkDir(path)
+	if err != nil {
+		e.Error(500, errors.New(""), "初始化文件路径失败")
+	}
+	base64File := path + fileName
+	_ = ioutil.WriteFile(base64File, ddd, 0666)
+	typeStr := strings.Replace(strings.Replace(file2list[0], "data:", "", -1), ";base64", "", -1)
+	fileResponse = FileResponse{
+		Size:     pkg.GetFileSize(base64File),
+		Path:     base64File,
+		FullPath: urlPerfix + base64File,
+		Name:     "",
+		Type:     typeStr,
+	}
+	source, _ := c.GetPostForm("source")
+	err = thirdUpload(source, fileName, base64File)
+	if err != nil {
+		e.Error(200, errors.New(""), "上传第三方失败")
+		return fileResponse
+	}
+	if source != "1" {
+		fileResponse.Path = "/static/uploadfile/" + fileName
+		fileResponse.FullPath = "/static/uploadfile/" + fileName
+	}
+	return fileResponse
+}
+
+func (e File) multipleFile(c *gin.Context, urlPerfix string) []FileResponse {
+	files := c.Request.MultipartForm.File["file"]
+	source, _ := c.GetPostForm("source")
+	var multipartFile []FileResponse
+	for _, f := range files {
+		guid := uuid.New().String()
+		fileName := guid + utils.GetExt(f.Filename)
+
+		err := utils.IsNotExistMkDir(path)
+		if err != nil {
+			e.Error(500, errors.New(""), "初始化文件路径失败")
+		}
+		multipartFileName := path + fileName
+		err1 := c.SaveUploadedFile(f, multipartFileName)
+		fileType, _ := utils.GetType(multipartFileName)
+		if err1 == nil {
+			err := thirdUpload(source, fileName, multipartFileName)
+			if err != nil {
+				e.Error(500, errors.New(""), "上传第三方失败")
+			} else {
+				fileResponse := FileResponse{
+					Size:     pkg.GetFileSize(multipartFileName),
+					Path:     multipartFileName,
+					FullPath: urlPerfix + multipartFileName,
+					Name:     f.Filename,
+					Type:     fileType,
+				}
+				if source != "1" {
+					fileResponse.Path = "/static/uploadfile/" + fileName
+					fileResponse.FullPath = "/static/uploadfile/" + fileName
+				}
+				multipartFile = append(multipartFile, fileResponse)
+			}
+		}
+	}
+	return multipartFile
+}
+
+func (e File) singleFile(c *gin.Context, fileResponse FileResponse, urlPerfix string) (FileResponse, bool) {
+	files, err := c.FormFile("file")
+
+	if err != nil {
+		e.Error(200, errors.New(""), "图片不能为空")
+		return FileResponse{}, true
+	}
+	// 上传文件至指定目录
+	guid := uuid.New().String()
+
+	fileName := guid + utils.GetExt(files.Filename)
+
+	err = utils.IsNotExistMkDir(path)
+	if err != nil {
+		e.Error(500, errors.New(""), "初始化文件路径失败")
+	}
+	singleFile := path + fileName
+	_ = c.SaveUploadedFile(files, singleFile)
+	fileType, _ := utils.GetType(singleFile)
+	fileResponse = FileResponse{
+		Size:     pkg.GetFileSize(singleFile),
+		Path:     singleFile,
+		FullPath: urlPerfix + singleFile,
+		Name:     files.Filename,
+		Type:     fileType,
+	}
+	//source, _ := c.GetPostForm("source")
+	//err = thirdUpload(source, fileName, singleFile)
+	//if err != nil {
+	//	e.Error(200, errors.New(""), "上传第三方失败")
+	//	return FileResponse{}, true
+	//}
+	fileResponse.Path = "/static/uploadfile/" + fileName
+	fileResponse.FullPath = "/static/uploadfile/" + fileName
+	return fileResponse, false
+}
+
+func thirdUpload(source string, name string, path string) error {
+	switch source {
+	case "2":
+		return ossUpload("img/"+name, path)
+	case "3":
+		return qiniuUpload("img/"+name, path)
+	}
+	return nil
+}
+
+func ossUpload(name string, path string) error {
+	oss := file_store.ALiYunOSS{}
+	return oss.UpLoad(name, path)
+}
+
+func qiniuUpload(name string, path string) error {
+	oss := file_store.ALiYunOSS{}
+	return oss.UpLoad(name, path)
+}
diff --git a/app/other/apis/sys_server_monitor.go b/app/other/apis/sys_server_monitor.go
new file mode 100644
index 0000000..c9aee1d
--- /dev/null
+++ b/app/other/apis/sys_server_monitor.go
@@ -0,0 +1,186 @@
+package apis
+
+import (
+	"fmt"
+	"github.com/shirou/gopsutil/v3/net"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"github.com/shirou/gopsutil/v3/cpu"
+	"github.com/shirou/gopsutil/v3/disk"
+	"github.com/shirou/gopsutil/v3/host"
+	"github.com/shirou/gopsutil/v3/mem"
+)
+
+const (
+	B  = 1
+	KB = 1024 * B
+	MB = 1024 * KB
+	GB = 1024 * MB
+)
+
+var (
+	//Version           string
+	//expectDiskFsTypes = []string{
+	//	"apfs", "ext4", "ext3", "ext2", "f2fs", "reiserfs", "jfs", "btrfs",
+	//	"fuseblk", "zfs", "simfs", "ntfs", "fat32", "exfat", "xfs", "fuse.rclone",
+	//}
+	excludeNetInterfaces = []string{
+		"lo", "tun", "docker", "veth", "br-", "vmbr", "vnet", "kube",
+	}
+	//getMacDiskNo = regexp.MustCompile(`\/dev\/disk(\d)s.*`)
+)
+
+var (
+	netInSpeed, netOutSpeed, netInTransfer, netOutTransfer, lastUpdateNetStats uint64
+	cachedBootTime                                                             time.Time
+)
+
+type ServerMonitor struct {
+	api.Api
+}
+
+// GetHourDiffer 获取相差时间
+func GetHourDiffer(startTime, endTime string) int64 {
+	var hour int64
+	t1, err := time.ParseInLocation("2006-01-02 15:04:05", startTime, time.Local)
+	t2, err := time.ParseInLocation("2006-01-02 15:04:05", endTime, time.Local)
+	if err == nil && t1.Before(t2) {
+		diff := t2.Unix() - t1.Unix() //
+		hour = diff / 3600
+		return hour
+	} else {
+		return hour
+	}
+}
+
+// ServerInfo 获取系统信息
+// @Summary 系统信息
+// @Description 获取JSON
+// @Tags 系统信息
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/server-monitor [get]
+// @Security Bearer
+func (e ServerMonitor) ServerInfo(c *gin.Context) {
+	e.Context = c
+
+	sysInfo, err := host.Info()
+	osDic := make(map[string]interface{}, 0)
+	osDic["goOs"] = runtime.GOOS
+	osDic["arch"] = runtime.GOARCH
+	osDic["mem"] = runtime.MemProfileRate
+	osDic["compiler"] = runtime.Compiler
+	osDic["version"] = runtime.Version()
+	osDic["numGoroutine"] = runtime.NumGoroutine()
+	osDic["ip"] = pkg.GetLocaHonst()
+	osDic["projectDir"] = pkg.GetCurrentPath()
+	osDic["hostName"] = sysInfo.Hostname
+	osDic["time"] = time.Now().Format("2006-01-02 15:04:05")
+
+	memory, _ := mem.VirtualMemory()
+	memDic := make(map[string]interface{}, 0)
+	memDic["used"] = memory.Used / MB
+	memDic["total"] = memory.Total / MB
+
+	fmt.Println("mem", int(memory.Total/memory.Used*100))
+	memDic["percent"] = pkg.Round(memory.UsedPercent, 2)
+
+	swapDic := make(map[string]interface{}, 0)
+	swapDic["used"] = memory.SwapTotal - memory.SwapFree
+	swapDic["total"] = memory.SwapTotal
+
+	cpuDic := make(map[string]interface{}, 0)
+	cpuDic["cpuInfo"], _ = cpu.Info()
+	percent, _ := cpu.Percent(0, false)
+	cpuDic["percent"] = pkg.Round(percent[0], 2)
+	cpuDic["cpuNum"], _ = cpu.Counts(false)
+
+	//服务器磁盘信息
+	disklist := make([]disk.UsageStat, 0)
+	//所有分区
+	var diskTotal, diskUsed, diskUsedPercent float64
+	diskInfo, err := disk.Partitions(true)
+	if err == nil {
+		for _, p := range diskInfo {
+			diskDetail, err := disk.Usage(p.Mountpoint)
+			if err == nil {
+				diskDetail.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", diskDetail.UsedPercent), 64)
+				diskDetail.Total = diskDetail.Total / 1024 / 1024
+				diskDetail.Used = diskDetail.Used / 1024 / 1024
+				diskDetail.Free = diskDetail.Free / 1024 / 1024
+				disklist = append(disklist, *diskDetail)
+
+			}
+		}
+	}
+
+	d, _ := disk.Usage("/")
+
+	diskTotal = float64(d.Total / GB)
+	diskUsed = float64(d.Used / GB)
+	diskUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", d.UsedPercent), 64)
+
+	diskDic := make(map[string]interface{}, 0)
+	diskDic["total"] = diskTotal
+	diskDic["used"] = diskUsed
+	diskDic["percent"] = diskUsedPercent
+
+	bootTime, _ := host.BootTime()
+	cachedBootTime = time.Unix(int64(bootTime), 0)
+
+	TrackNetworkSpeed()
+	netDic := make(map[string]interface{}, 0)
+	netDic["in"] = pkg.Round(float64(netInSpeed/KB), 2)
+	netDic["out"] = pkg.Round(float64(netOutSpeed/KB), 2)
+	e.Custom(gin.H{
+		"code":     200,
+		"os":       osDic,
+		"mem":      memDic,
+		"cpu":      cpuDic,
+		"disk":     diskDic,
+		"net":      netDic,
+		"swap":     swapDic,
+		"location": "Aliyun",
+		"bootTime": GetHourDiffer(cachedBootTime.Format("2006-01-02 15:04:05"), time.Now().Format("2006-01-02 15:04:05")),
+	})
+}
+
+func TrackNetworkSpeed() {
+	var innerNetInTransfer, innerNetOutTransfer uint64
+	nc, err := net.IOCounters(true)
+	if err == nil {
+		for _, v := range nc {
+			if isListContainsStr(excludeNetInterfaces, v.Name) {
+				continue
+			}
+			innerNetInTransfer += v.BytesRecv
+			innerNetOutTransfer += v.BytesSent
+		}
+		now := uint64(time.Now().Unix())
+		diff := now - lastUpdateNetStats
+		if diff > 0 {
+			netInSpeed = (innerNetInTransfer - netInTransfer) / diff
+			fmt.Println("netInSpeed", netInSpeed)
+			netOutSpeed = (innerNetOutTransfer - netOutTransfer) / diff
+			fmt.Println("netOutSpeed", netOutSpeed)
+		}
+		netInTransfer = innerNetInTransfer
+		netOutTransfer = innerNetOutTransfer
+		lastUpdateNetStats = now
+	}
+}
+
+func isListContainsStr(list []string, str string) bool {
+	for i := 0; i < len(list); i++ {
+		if strings.Contains(str, list[i]) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/app/other/apis/tools/db_columns.go b/app/other/apis/tools/db_columns.go
new file mode 100644
index 0000000..e0b8390
--- /dev/null
+++ b/app/other/apis/tools/db_columns.go
@@ -0,0 +1,52 @@
+package tools
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/other/models/tools"
+)
+
+// GetDBColumnList 分页列表数据
+// @Summary 分页列表数据 / page list data
+// @Description 数据库表列分页列表 / database table column page list
+// @Tags 工具 / 生成工具
+// @Param tableName query string false "tableName / 数据表名称"
+// @Param pageSize query int false "pageSize / 页条数"
+// @Param pageIndex query int false "pageIndex / 页码"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/db/columns/page [get]
+func (e Gen) GetDBColumnList(c *gin.Context) {
+	e.Context = c
+	log := e.GetLogger()
+	var data tools.DBColumns
+	var err error
+	var pageSize = 10
+	var pageIndex = 1
+
+	if size := c.Request.FormValue("pageSize"); size != "" {
+		pageSize, err = pkg.StringToInt(size)
+	}
+
+	if index := c.Request.FormValue("pageIndex"); index != "" {
+		pageIndex, err = pkg.StringToInt(index)
+	}
+
+	db, err := pkg.GetOrm(c)
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, "数据库连接获取失败")
+		return
+	}
+
+	data.TableName = c.Request.FormValue("tableName")
+	pkg.Assert(data.TableName == "", "table name cannot be empty!", 500)
+	result, count, err := data.GetPage(db, pageSize, pageIndex)
+	if err != nil {
+		log.Errorf("GetPage error, %s", err.Error())
+		e.Error(500, err, "")
+		return
+	}
+	e.PageOK(result, count, pageIndex, pageSize, "查询成功")
+}
diff --git a/app/other/apis/tools/db_tables.go b/app/other/apis/tools/db_tables.go
new file mode 100644
index 0000000..d1ec3c4
--- /dev/null
+++ b/app/other/apis/tools/db_tables.go
@@ -0,0 +1,60 @@
+package tools
+
+import (
+	"errors"
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/app/other/models/tools"
+)
+
+// GetDBTableList 分页列表数据
+// @Summary 分页列表数据 / page list data
+// @Description 数据库表分页列表 / database table page list
+// @Tags 工具 / 生成工具
+// @Param tableName query string false "tableName / 数据表名称"
+// @Param pageSize query int false "pageSize / 页条数"
+// @Param pageIndex query int false "pageIndex / 页码"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/db/tables/page [get]
+func (e Gen) GetDBTableList(c *gin.Context) {
+	//var res response.Response
+	var data tools.DBTables
+	var err error
+	var pageSize = 10
+	var pageIndex = 1
+	e.Context = c
+	log := e.GetLogger()
+	if config.DatabaseConfig.Driver == "sqlite3" || config.DatabaseConfig.Driver == "postgres" {
+		err = errors.New("对不起,sqlite3 或 postgres 不支持代码生成!")
+		log.Warn(err)
+		e.Error(403, err, "")
+		return
+	}
+
+	if size := c.Request.FormValue("pageSize"); size != "" {
+		pageSize, err = pkg.StringToInt(size)
+	}
+
+	if index := c.Request.FormValue("pageIndex"); index != "" {
+		pageIndex, err = pkg.StringToInt(index)
+	}
+
+	db, err := pkg.GetOrm(c)
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, "数据库连接获取失败")
+		return
+	}
+
+	data.TableName = c.Request.FormValue("tableName")
+	result, count, err := data.GetPage(db, pageSize, pageIndex)
+	if err != nil {
+		log.Errorf("GetPage error, %s", err.Error())
+		e.Error(500, err, "")
+		return
+	}
+	e.PageOK(result, count, pageIndex, pageSize, "查询成功")
+}
diff --git a/app/other/apis/tools/gen.go b/app/other/apis/tools/gen.go
new file mode 100644
index 0000000..e9baafc
--- /dev/null
+++ b/app/other/apis/tools/gen.go
@@ -0,0 +1,410 @@
+package tools
+
+import (
+	"bytes"
+	"fmt"
+	"go-admin/app/admin/service"
+	"go-admin/app/admin/service/dto"
+	"strconv"
+	"strings"
+	"text/template"
+	"time"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+
+	"go-admin/app/other/models/tools"
+)
+
+type Gen struct {
+	api.Api
+}
+
+func (e Gen) Preview(c *gin.Context) {
+	e.Context = c
+	log := e.GetLogger()
+	table := tools.SysTables{}
+	id, err := pkg.StringToInt(c.Param("tableId"))
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("tableId接收失败!错误详情:%s", err.Error()))
+		return
+	}
+	table.TableId = id
+	t1, err := template.ParseFiles("template/v4/model.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("model模版读取失败!错误详情:%s", err.Error()))
+		return
+	}
+	t2, err := template.ParseFiles("template/v4/no_actions/apis.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("api模版读取失败!错误详情:%s", err.Error()))
+		return
+	}
+	t3, err := template.ParseFiles("template/v4/js.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("js模版读取失败!错误详情:%s", err.Error()))
+		return
+	}
+	t4, err := template.ParseFiles("template/v4/vue.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("vue模版读取失败!错误详情:%s", err.Error()))
+		return
+	}
+	t5, err := template.ParseFiles("template/v4/no_actions/router_check_role.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("路由模版读取失败!错误详情:%s", err.Error()))
+		return
+	}
+	t6, err := template.ParseFiles("template/v4/dto.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("dto模版读取失败!错误详情:%s", err.Error()))
+		return
+	}
+	t7, err := template.ParseFiles("template/v4/no_actions/service.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("service模版读取失败!错误详情:%s", err.Error()))
+		return
+	}
+
+	db, err := pkg.GetOrm(c)
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, fmt.Sprintf("数据库链接获取失败!错误详情:%s", err.Error()))
+		return
+	}
+
+	tab, _ := table.Get(db,false)
+	var b1 bytes.Buffer
+	err = t1.Execute(&b1, tab)
+	var b2 bytes.Buffer
+	err = t2.Execute(&b2, tab)
+	var b3 bytes.Buffer
+	err = t3.Execute(&b3, tab)
+	var b4 bytes.Buffer
+	err = t4.Execute(&b4, tab)
+	var b5 bytes.Buffer
+	err = t5.Execute(&b5, tab)
+	var b6 bytes.Buffer
+	err = t6.Execute(&b6, tab)
+	var b7 bytes.Buffer
+	err = t7.Execute(&b7, tab)
+
+	mp := make(map[string]interface{})
+	mp["template/model.go.template"] = b1.String()
+	mp["template/api.go.template"] = b2.String()
+	mp["template/js.go.template"] = b3.String()
+	mp["template/vue.go.template"] = b4.String()
+	mp["template/router.go.template"] = b5.String()
+	mp["template/dto.go.template"] = b6.String()
+	mp["template/service.go.template"] = b7.String()
+	e.OK(mp, "")
+}
+
+func (e Gen) GenCode(c *gin.Context) {
+	e.Context = c
+	log := e.GetLogger()
+	table := tools.SysTables{}
+	id, err := pkg.StringToInt(c.Param("tableId"))
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("tableId参数接收失败!错误详情:%s", err.Error()))
+		return
+	}
+
+	db, err := pkg.GetOrm(c)
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, fmt.Sprintf("数据库链接获取失败!错误详情:%s", err.Error()))
+		return
+	}
+
+	table.TableId = id
+	tab, _ := table.Get(db,false)
+
+	e.NOActionsGen(c, tab)
+
+	e.OK("", "Code generated successfully!")
+}
+
+func (e Gen) GenApiToFile(c *gin.Context) {
+	e.Context = c
+	log := e.GetLogger()
+	table := tools.SysTables{}
+	id, err := pkg.StringToInt(c.Param("tableId"))
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("tableId参数获取失败!错误详情:%s", err.Error()))
+		return
+	}
+
+	db, err := pkg.GetOrm(c)
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, fmt.Sprintf("数据库链接获取失败!错误详情:%s", err.Error()))
+		return
+	}
+
+	table.TableId = id
+	tab, _ := table.Get(db,false)
+	e.genApiToFile(c, tab)
+
+	e.OK("", "Code generated successfully!")
+}
+
+func (e Gen) NOActionsGen(c *gin.Context, tab tools.SysTables) {
+	e.Context = c
+	log := e.GetLogger()
+	tab.MLTBName = strings.Replace(tab.TBName, "_", "-", -1)
+
+	basePath := "template/v4/"
+	routerFile := basePath + "no_actions/router_check_role.go.template"
+
+	if tab.IsAuth == 2 {
+		routerFile = basePath + "no_actions/router_no_check_role.go.template"
+	}
+
+	t1, err := template.ParseFiles(basePath + "model.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("model模版读取失败!错误详情:%s", err.Error()))
+		return
+	}
+	t2, err := template.ParseFiles(basePath + "no_actions/apis.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("api模版读取失败!错误详情:%s", err.Error()))
+		return
+	}
+	t3, err := template.ParseFiles(routerFile)
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("路由模版失败!错误详情:%s", err.Error()))
+		return
+	}
+	t4, err := template.ParseFiles(basePath + "js.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("js模版解析失败!错误详情:%s", err.Error()))
+		return
+	}
+	t5, err := template.ParseFiles(basePath + "vue.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("vue模版解析失败!错误详情:%s", err.Error()))
+		return
+	}
+	t6, err := template.ParseFiles(basePath + "dto.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("dto模版解析失败失败!错误详情:%s", err.Error()))
+		return
+	}
+	t7, err := template.ParseFiles(basePath + "no_actions/service.go.template")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("service模版失败!错误详情:%s", err.Error()))
+		return
+	}
+
+	_ = pkg.PathCreate("./app/" + tab.PackageName + "/apis/")
+	_ = pkg.PathCreate("./app/" + tab.PackageName + "/models/")
+	_ = pkg.PathCreate("./app/" + tab.PackageName + "/router/")
+	_ = pkg.PathCreate("./app/" + tab.PackageName + "/service/dto/")
+	_ = pkg.PathCreate(config.GenConfig.FrontPath + "/api/" + tab.PackageName + "/")
+	err = pkg.PathCreate(config.GenConfig.FrontPath + "/views/" + tab.PackageName + "/" + tab.MLTBName + "/")
+	if err != nil {
+		log.Error(err)
+		e.Error(500, err, fmt.Sprintf("views目录创建失败!错误详情:%s", err.Error()))
+		return
+	}
+
+	var b1 bytes.Buffer
+	err = t1.Execute(&b1, tab)
+	var b2 bytes.Buffer
+	err = t2.Execute(&b2, tab)
+	var b3 bytes.Buffer
+	err = t3.Execute(&b3, tab)
+	var b4 bytes.Buffer
+	err = t4.Execute(&b4, tab)
+	var b5 bytes.Buffer
+	err = t5.Execute(&b5, tab)
+	var b6 bytes.Buffer
+	err = t6.Execute(&b6, tab)
+	var b7 bytes.Buffer
+	err = t7.Execute(&b7, tab)
+	pkg.FileCreate(b1, "./app/"+tab.PackageName+"/models/"+tab.TBName+".go")
+	pkg.FileCreate(b2, "./app/"+tab.PackageName+"/apis/"+tab.TBName+".go")
+	pkg.FileCreate(b3, "./app/"+tab.PackageName+"/router/"+tab.TBName+".go")
+	pkg.FileCreate(b4, config.GenConfig.FrontPath+"/api/"+tab.PackageName+"/"+tab.MLTBName+".js")
+	pkg.FileCreate(b5, config.GenConfig.FrontPath+"/views/"+tab.PackageName+"/"+tab.MLTBName+"/index.vue")
+	pkg.FileCreate(b6, "./app/"+tab.PackageName+"/service/dto/"+tab.TBName+".go")
+	pkg.FileCreate(b7, "./app/"+tab.PackageName+"/service/"+tab.TBName+".go")
+
+}
+
+func (e Gen) genApiToFile(c *gin.Context, tab tools.SysTables) {
+	err := e.MakeContext(c).
+		MakeOrm().
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	basePath := "template/"
+
+	t1, err := template.ParseFiles(basePath + "api_migrate.template")
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, fmt.Sprintf("数据迁移模版解析失败!错误详情:%s", err.Error()))
+		return
+	}
+	i := strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
+	var b1 bytes.Buffer
+	err = t1.Execute(&b1, struct {
+		tools.SysTables
+		GenerateTime string
+	}{tab, i})
+
+	pkg.FileCreate(b1, "./cmd/migrate/migration/version-local/"+i+"_migrate.go")
+
+}
+
+func (e Gen) GenMenuAndApi(c *gin.Context) {
+	s := service.SysMenu{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	table := tools.SysTables{}
+	id, err := pkg.StringToInt(c.Param("tableId"))
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, fmt.Sprintf("tableId参数解析失败!错误详情:%s", err.Error()))
+		return
+	}
+
+	table.TableId = id
+	tab, _ := table.Get(e.Orm,true)
+	tab.MLTBName = strings.Replace(tab.TBName, "_", "-", -1)
+
+	Mmenu := dto.SysMenuInsertReq{}
+	Mmenu.Title = tab.TableComment
+	Mmenu.Icon = "pass"
+	Mmenu.Path = "/" + tab.MLTBName
+	Mmenu.MenuType = "M"
+	Mmenu.Action = "无"
+	Mmenu.ParentId = 0
+	Mmenu.NoCache = false
+	Mmenu.Component = "Layout"
+	Mmenu.Sort = 0
+	Mmenu.Visible = "0"
+	Mmenu.IsFrame = "0"
+	Mmenu.CreateBy = 1
+	s.Insert(&Mmenu)
+
+	Cmenu := dto.SysMenuInsertReq{}
+	Cmenu.MenuName = tab.ClassName + "Manage"
+	Cmenu.Title = tab.TableComment
+	Cmenu.Icon = "pass"
+	Cmenu.Path = "/" + tab.PackageName + "/" + tab.MLTBName
+	Cmenu.MenuType = "C"
+	Cmenu.Action = "无"
+	Cmenu.Permission = tab.PackageName + ":" + tab.BusinessName + ":list"
+	Cmenu.ParentId = Mmenu.MenuId
+	Cmenu.NoCache = false
+	Cmenu.Component = "/" + tab.PackageName + "/" + tab.MLTBName + "/index"
+	Cmenu.Sort = 0
+	Cmenu.Visible = "0"
+	Cmenu.IsFrame = "0"
+	Cmenu.CreateBy = 1
+	Cmenu.UpdateBy = 1
+	s.Insert(&Cmenu)
+
+	MList := dto.SysMenuInsertReq{}
+	MList.MenuName = ""
+	MList.Title = "分页获取" + tab.TableComment
+	MList.Icon = ""
+	MList.Path = tab.TBName
+	MList.MenuType = "F"
+	MList.Action = "无"
+	MList.Permission = tab.PackageName + ":" + tab.BusinessName + ":query"
+	MList.ParentId = Cmenu.MenuId
+	MList.NoCache = false
+	MList.Sort = 0
+	MList.Visible = "0"
+	MList.IsFrame = "0"
+	MList.CreateBy = 1
+	MList.UpdateBy = 1
+	s.Insert(&MList)
+
+	MCreate := dto.SysMenuInsertReq{}
+	MCreate.MenuName = ""
+	MCreate.Title = "创建" + tab.TableComment
+	MCreate.Icon = ""
+	MCreate.Path = tab.TBName
+	MCreate.MenuType = "F"
+	MCreate.Action = "无"
+	MCreate.Permission = tab.PackageName + ":" + tab.BusinessName + ":add"
+	MCreate.ParentId = Cmenu.MenuId
+	MCreate.NoCache = false
+	MCreate.Sort = 0
+	MCreate.Visible = "0"
+	MCreate.IsFrame = "0"
+	MCreate.CreateBy = 1
+	MCreate.UpdateBy = 1
+	s.Insert(&MCreate)
+
+	MUpdate := dto.SysMenuInsertReq{}
+	MUpdate.MenuName = ""
+	MUpdate.Title = "修改" + tab.TableComment
+	MUpdate.Icon = ""
+	MUpdate.Path = tab.TBName
+	MUpdate.MenuType = "F"
+	MUpdate.Action = "无"
+	MUpdate.Permission = tab.PackageName + ":" + tab.BusinessName + ":edit"
+	MUpdate.ParentId = Cmenu.MenuId
+	MUpdate.NoCache = false
+	MUpdate.Sort = 0
+	MUpdate.Visible = "0"
+	MUpdate.IsFrame = "0"
+	MUpdate.CreateBy = 1
+	MUpdate.UpdateBy = 1
+	s.Insert(&MUpdate)
+
+	MDelete := dto.SysMenuInsertReq{}
+	MDelete.MenuName = ""
+	MDelete.Title = "删除" + tab.TableComment
+	MDelete.Icon = ""
+	MDelete.Path = tab.TBName
+	MDelete.MenuType = "F"
+	MDelete.Action = "无"
+	MDelete.Permission = tab.PackageName + ":" + tab.BusinessName + ":remove"
+	MDelete.ParentId = Cmenu.MenuId
+	MDelete.NoCache = false
+	MDelete.Sort = 0
+	MDelete.Visible = "0"
+	MDelete.IsFrame = "0"
+	MDelete.CreateBy = 1
+	MDelete.UpdateBy = 1
+	s.Insert(&MDelete)
+
+	e.OK("", "数据生成成功!")
+}
diff --git a/app/other/apis/tools/sys_tables.go b/app/other/apis/tools/sys_tables.go
new file mode 100644
index 0000000..ea7dee7
--- /dev/null
+++ b/app/other/apis/tools/sys_tables.go
@@ -0,0 +1,361 @@
+package tools
+
+import (
+	"strings"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"gorm.io/gorm"
+
+	"go-admin/app/other/models/tools"
+)
+
+type SysTable struct {
+	api.Api
+}
+
+// GetPage 分页列表数据
+// @Summary 分页列表数据
+// @Description 生成表分页列表
+// @Tags 工具 / 生成工具
+// @Param tableName query string false "tableName / 数据表名称"
+// @Param pageSize query int false "pageSize / 页条数"
+// @Param pageIndex query int false "pageIndex / 页码"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys/tables/page [get]
+func (e SysTable) GetPage(c *gin.Context) {
+	e.Context = c
+	log := e.GetLogger()
+	var data tools.SysTables
+	var err error
+	var pageSize = 10
+	var pageIndex = 1
+
+	if size := c.Request.FormValue("pageSize"); size != "" {
+		pageSize, err = pkg.StringToInt(size)
+	}
+
+	if index := c.Request.FormValue("pageIndex"); index != "" {
+		pageIndex, err = pkg.StringToInt(index)
+	}
+
+	db, err := e.GetOrm()
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, "数据库连接获取失败")
+		return
+	}
+
+	data.TBName = c.Request.FormValue("tableName")
+	data.TableComment = c.Request.FormValue("tableComment")
+	result, count, err := data.GetPage(db, pageSize, pageIndex)
+	if err != nil {
+		log.Errorf("GetPage error, %s", err.Error())
+		e.Error(500, err, "")
+		return
+	}
+	e.PageOK(result, count, pageIndex, pageSize, "查询成功")
+}
+
+// Get
+// @Summary 获取配置
+// @Description 获取JSON
+// @Tags 工具 / 生成工具
+// @Param configKey path int true "configKey"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/v1/sys/tables/info/{tableId} [get]
+// @Security Bearer
+func (e SysTable) Get(c *gin.Context) {
+	e.Context = c
+	log := e.GetLogger()
+	db, err := e.GetOrm()
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, "数据库连接获取失败")
+		return
+	}
+
+	var data tools.SysTables
+	data.TableId, _ = pkg.StringToInt(c.Param("tableId"))
+	result, err := data.Get(db,true)
+	if err != nil {
+		log.Errorf("Get error, %s", err.Error())
+		e.Error(500, err, "")
+		return
+	}
+
+	mp := make(map[string]interface{})
+	mp["list"] = result.Columns
+	mp["info"] = result
+	e.OK(mp, "")
+}
+
+func (e SysTable) GetSysTablesInfo(c *gin.Context) {
+	e.Context = c
+	log := e.GetLogger()
+	db, err := e.GetOrm()
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, "数据库连接获取失败")
+		return
+	}
+
+	var data tools.SysTables
+	if c.Request.FormValue("tableName") != "" {
+		data.TBName = c.Request.FormValue("tableName")
+	}
+	result, err := data.Get(db,true)
+	if err != nil {
+		log.Errorf("Get error, %s", err.Error())
+		e.Error(500, err, "抱歉未找到相关信息")
+		return
+	}
+
+	mp := make(map[string]interface{})
+	mp["list"] = result.Columns
+	mp["info"] = result
+	e.OK(mp, "")
+	//res.Data = mp
+	//c.JSON(http.StatusOK, res.ReturnOK())
+}
+
+func (e SysTable) GetSysTablesTree(c *gin.Context) {
+	e.Context = c
+	log := e.GetLogger()
+	db, err := e.GetOrm()
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, "数据库连接获取失败")
+		return
+	}
+
+	var data tools.SysTables
+	result, err := data.GetTree(db)
+	if err != nil {
+		log.Errorf("GetTree error, %s", err.Error())
+		e.Error(500, err, "抱歉未找到相关信息")
+		return
+	}
+
+	e.OK(result, "")
+}
+
+// Insert
+// @Summary 添加表结构
+// @Description 添加表结构
+// @Tags 工具 / 生成工具
+// @Accept  application/json
+// @Product application/json
+// @Param tables query string false "tableName / 数据表名称"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/v1/sys/tables/info [post]
+// @Security Bearer
+func (e SysTable) Insert(c *gin.Context) {
+	e.Context = c
+	log := e.GetLogger()
+	db, err := e.GetOrm()
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, "数据库连接获取失败")
+		return
+	}
+
+	tablesList := strings.Split(c.Request.FormValue("tables"), ",")
+	for i := 0; i < len(tablesList); i++ {
+
+		data, err := genTableInit(db, tablesList, i, c)
+		if err != nil {
+			log.Errorf("genTableInit error, %s", err.Error())
+			e.Error(500, err, "")
+			return
+		}
+
+		_, err = data.Create(db)
+		if err != nil {
+			log.Errorf("Create error, %s", err.Error())
+			e.Error(500, err, "")
+			return
+		}
+	}
+	e.OK(nil, "添加成功")
+
+}
+
+func genTableInit(tx *gorm.DB, tablesList []string, i int, c *gin.Context) (tools.SysTables, error) {
+	var data tools.SysTables
+	var dbTable tools.DBTables
+	var dbColumn tools.DBColumns
+	data.TBName = tablesList[i]
+	data.CreateBy = 0
+
+	dbTable.TableName = data.TBName
+	dbtable, err := dbTable.Get(tx)
+	if err != nil {
+		return data, err
+	}
+
+	dbColumn.TableName = data.TBName
+	tablenamelist := strings.Split(dbColumn.TableName, "_")
+	for i := 0; i < len(tablenamelist); i++ {
+		strStart := string([]byte(tablenamelist[i])[:1])
+		strend := string([]byte(tablenamelist[i])[1:])
+		// 大驼峰表名 结构体使用
+		data.ClassName += strings.ToUpper(strStart) + strend
+		// 小驼峰表名 js函数名和权限标识使用
+		if i == 0 {
+			data.BusinessName += strings.ToLower(strStart) + strend
+		} else {
+			data.BusinessName += strings.ToUpper(strStart) + strend
+		}
+		//data.PackageName += strings.ToLower(strStart) + strings.ToLower(strend)
+		//data.ModuleName += strings.ToLower(strStart) + strings.ToLower(strend)
+	}
+	//data.ModuleFrontName = strings.ReplaceAll(data.ModuleName, "_", "-")
+	data.PackageName = "admin"
+	data.TplCategory = "crud"
+	data.Crud = true
+	// 中横线表名称,接口路径、前端文件夹名称和js名称使用
+	data.ModuleName = strings.Replace(data.TBName, "_", "-", -1)
+	dbcolumn, err := dbColumn.GetList(tx)
+	data.CreateBy = 0
+	data.TableComment = dbtable.TableComment
+	if dbtable.TableComment == "" {
+		data.TableComment = data.ClassName
+	}
+
+	data.FunctionName = data.TableComment
+	//data.BusinessName = data.ModuleName
+	data.IsLogicalDelete = "1"
+	data.LogicalDelete = true
+	data.LogicalDeleteColumn = "is_del"
+	data.IsActions = 2
+	data.IsDataScope = 1
+	data.IsAuth = 1
+
+	data.FunctionAuthor = "wenjianzhang"
+	for i := 0; i < len(dbcolumn); i++ {
+		var column tools.SysColumns
+		column.ColumnComment = dbcolumn[i].ColumnComment
+		column.ColumnName = dbcolumn[i].ColumnName
+		column.ColumnType = dbcolumn[i].ColumnType
+		column.Sort = i + 1
+		column.Insert = true
+		column.IsInsert = "1"
+		column.QueryType = "EQ"
+		column.IsPk = "0"
+
+		namelist := strings.Split(dbcolumn[i].ColumnName, "_")
+		for i := 0; i < len(namelist); i++ {
+			strStart := string([]byte(namelist[i])[:1])
+			strend := string([]byte(namelist[i])[1:])
+			column.GoField += strings.ToUpper(strStart) + strend
+			if i == 0 {
+				column.JsonField = strings.ToLower(strStart) + strend
+			} else {
+				column.JsonField += strings.ToUpper(strStart) + strend
+			}
+		}
+		if strings.Contains(dbcolumn[i].ColumnKey, "PR") {
+			column.IsPk = "1"
+			column.Pk = true
+			data.PkColumn = dbcolumn[i].ColumnName
+			//column.GoField = strings.ToUpper(column.GoField)
+			//column.JsonField = strings.ToUpper(column.JsonField)
+			data.PkGoField = column.GoField
+			data.PkJsonField = column.JsonField
+		}
+		column.IsRequired = "0"
+		if strings.Contains(dbcolumn[i].IsNullable, "NO") {
+			column.IsRequired = "1"
+			column.Required = true
+		}
+
+		if strings.Contains(dbcolumn[i].ColumnType, "int") {
+			if strings.Contains(dbcolumn[i].ColumnKey, "PR") {
+				column.GoType = "int"
+			} else {
+				column.GoType = "string"
+			}
+			column.HtmlType = "input"
+		} else if strings.Contains(dbcolumn[i].ColumnType, "timestamp") {
+			column.GoType = "time.Time"
+			column.HtmlType = "datetime"
+		} else if strings.Contains(dbcolumn[i].ColumnType, "datetime") {
+			column.GoType = "time.Time"
+			column.HtmlType = "datetime"
+		} else {
+			column.GoType = "string"
+			column.HtmlType = "input"
+		}
+
+		data.Columns = append(data.Columns, column)
+	}
+	return data, err
+}
+
+// Update
+// @Summary 修改表结构
+// @Description 修改表结构
+// @Tags 工具 / 生成工具
+// @Accept  application/json
+// @Product application/json
+// @Param data body tools.SysTables true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/v1/sys/tables/info [put]
+// @Security Bearer
+func (e SysTable) Update(c *gin.Context) {
+	var data tools.SysTables
+	err := c.Bind(&data)
+	pkg.HasError(err, "数据解析失败", 500)
+
+	e.Context = c
+	log := e.GetLogger()
+	db, err := e.GetOrm()
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, "数据库连接获取失败")
+		return
+	}
+
+	data.UpdateBy = 0
+	result, err := data.Update(db)
+	if err != nil {
+		log.Errorf("Update error, %s", err.Error())
+		e.Error(500, err, "")
+		return
+	}
+	e.OK(result, "修改成功")
+}
+
+// Delete
+// @Summary 删除表结构
+// @Description 删除表结构
+// @Tags 工具 / 生成工具
+// @Param tableId path int true "tableId"
+// @Success 200 {string} string	"{"code": 200, "message": "删除成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "删除失败"}"
+// @Router /api/v1/sys/tables/info/{tableId} [delete]
+func (e SysTable) Delete(c *gin.Context) {
+	e.Context = c
+	log := e.GetLogger()
+	db, err := e.GetOrm()
+	if err != nil {
+		log.Errorf("get db connection error, %s", err.Error())
+		e.Error(500, err, "数据库连接获取失败")
+		return
+	}
+
+	var data tools.SysTables
+	IDS := pkg.IdsStrToIdsIntGroup("tableId", c)
+	_, err = data.BatchDelete(db, IDS)
+	if err != nil {
+		log.Errorf("BatchDelete error, %s", err.Error())
+		e.Error(500, err, "删除失败")
+		return
+	}
+	e.OK(nil, "删除成功")
+}
diff --git a/app/other/models/tools/db_columns.go b/app/other/models/tools/db_columns.go
new file mode 100644
index 0000000..46d9bc6
--- /dev/null
+++ b/app/other/models/tools/db_columns.go
@@ -0,0 +1,70 @@
+package tools
+
+import (
+	"errors"
+
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"gorm.io/gorm"
+)
+
+type DBColumns struct {
+	TableSchema            string `gorm:"column:TABLE_SCHEMA" json:"tableSchema"`
+	TableName              string `gorm:"column:TABLE_NAME" json:"tableName"`
+	ColumnName             string `gorm:"column:COLUMN_NAME" json:"columnName"`
+	ColumnDefault          string `gorm:"column:COLUMN_DEFAULT" json:"columnDefault"`
+	IsNullable             string `gorm:"column:IS_NULLABLE" json:"isNullable"`
+	DataType               string `gorm:"column:DATA_TYPE" json:"dataType"`
+	CharacterMaximumLength string `gorm:"column:CHARACTER_MAXIMUM_LENGTH" json:"characterMaximumLength"`
+	CharacterSetName       string `gorm:"column:CHARACTER_SET_NAME" json:"characterSetName"`
+	ColumnType             string `gorm:"column:COLUMN_TYPE" json:"columnType"`
+	ColumnKey              string `gorm:"column:COLUMN_KEY" json:"columnKey"`
+	Extra                  string `gorm:"column:EXTRA" json:"extra"`
+	ColumnComment          string `gorm:"column:COLUMN_COMMENT" json:"columnComment"`
+}
+
+func (e *DBColumns) GetPage(tx *gorm.DB, pageSize int, pageIndex int) ([]DBColumns, int, error) {
+	var doc []DBColumns
+	var count int64
+	table := new(gorm.DB)
+
+	if config.DatabaseConfig.Driver == "mysql" {
+		table = tx.Table("information_schema.`COLUMNS`")
+		table = table.Where("table_schema= ? ", config.GenConfig.DBName)
+
+		if e.TableName != "" {
+			return nil, 0, errors.New("table name cannot be empty!")
+		}
+
+		table = table.Where("TABLE_NAME = ?", e.TableName)
+	}
+
+	if err := table.Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Offset(-1).Limit(-1).Count(&count).Error; err != nil {
+		return nil, 0, err
+	}
+	//table.Count(&count)
+	return doc, int(count), nil
+
+}
+
+func (e *DBColumns) GetList(tx *gorm.DB) ([]DBColumns, error) {
+	var doc []DBColumns
+	table := new(gorm.DB)
+
+	if e.TableName == "" {
+		return nil, errors.New("table name cannot be empty!")
+	}
+
+	if config.DatabaseConfig.Driver == "mysql" {
+		table = tx.Table("information_schema.columns")
+		table = table.Where("table_schema= ? ", config.GenConfig.DBName)
+
+		table = table.Where("TABLE_NAME = ?", e.TableName).Order("ORDINAL_POSITION asc")
+	} else {
+		pkg.Assert(true, "目前只支持mysql数据库", 500)
+	}
+	if err := table.Find(&doc).Error; err != nil {
+		return doc, err
+	}
+	return doc, nil
+}
\ No newline at end of file
diff --git a/app/other/models/tools/db_tables.go b/app/other/models/tools/db_tables.go
new file mode 100644
index 0000000..77c4927
--- /dev/null
+++ b/app/other/models/tools/db_tables.go
@@ -0,0 +1,62 @@
+package tools
+
+import (
+	"errors"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+
+	"gorm.io/gorm"
+
+	config2 "github.com/go-admin-team/go-admin-core/sdk/config"
+)
+
+type DBTables struct {
+	TableName      string `gorm:"column:TABLE_NAME" json:"tableName"`
+	Engine         string `gorm:"column:ENGINE" json:"engine"`
+	TableRows      string `gorm:"column:TABLE_ROWS" json:"tableRows"`
+	TableCollation string `gorm:"column:TABLE_COLLATION" json:"tableCollation"`
+	CreateTime     string `gorm:"column:CREATE_TIME" json:"createTime"`
+	UpdateTime     string `gorm:"column:UPDATE_TIME" json:"updateTime"`
+	TableComment   string `gorm:"column:TABLE_COMMENT" json:"tableComment"`
+}
+
+func (e *DBTables) GetPage(tx *gorm.DB, pageSize int, pageIndex int) ([]DBTables, int, error) {
+	var doc []DBTables
+	table := new(gorm.DB)
+	var count int64
+
+	if config2.DatabaseConfig.Driver == "mysql" {
+		table = tx.Table("information_schema.tables")
+		table = table.Where("TABLE_NAME not in (select table_name from `" + config2.GenConfig.DBName + "`.sys_tables) ")
+		table = table.Where("table_schema= ? ", config2.GenConfig.DBName)
+
+		if e.TableName != "" {
+			table = table.Where("TABLE_NAME = ?", e.TableName)
+		}
+		if err := table.Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Offset(-1).Limit(-1).Count(&count).Error; err != nil {
+			return nil, 0, err
+		}
+	} else {
+		pkg.Assert(true, "目前只支持mysql数据库", 500)
+	}
+
+	//table.Count(&count)
+	return doc, int(count), nil
+}
+
+func (e *DBTables) Get(tx *gorm.DB) (DBTables, error) {
+	var doc DBTables
+	if config2.DatabaseConfig.Driver == "mysql" {
+		table := tx.Table("information_schema.tables")
+		table = table.Where("table_schema= ? ", config2.GenConfig.DBName)
+		if e.TableName == "" {
+			return doc, errors.New("table name cannot be empty!")
+		}
+		table = table.Where("TABLE_NAME = ?", e.TableName)
+		if err := table.First(&doc).Error; err != nil {
+			return doc, err
+		}
+	} else {
+		pkg.Assert(true, "目前只支持mysql数据库", 500)
+	}
+	return doc, nil
+}
diff --git a/app/other/models/tools/sys_columns.go b/app/other/models/tools/sys_columns.go
new file mode 100644
index 0000000..ff6b8dd
--- /dev/null
+++ b/app/other/models/tools/sys_columns.go
@@ -0,0 +1,101 @@
+package tools
+
+import (
+	common "go-admin/common/models"
+
+	"gorm.io/gorm"
+)
+
+type SysColumns struct {
+	ColumnId           int          `gorm:"primaryKey;autoIncrement" json:"columnId"`
+	TableId            int          `gorm:"" json:"tableId"`
+	ColumnName         string       `gorm:"size:128;" json:"columnName"`
+	ColumnComment      string       `gorm:"column:column_comment;size:128;" json:"columnComment"`
+	ColumnType         string       `gorm:"column:column_type;size:128;" json:"columnType"`
+	GoType             string       `gorm:"column:go_type;size:128;" json:"goType"`
+	GoField            string       `gorm:"column:go_field;size:128;" json:"goField"`
+	JsonField          string       `gorm:"column:json_field;size:128;" json:"jsonField"`
+	IsPk               string       `gorm:"column:is_pk;size:4;" json:"isPk"`
+	IsIncrement        string       `gorm:"column:is_increment;size:4;" json:"isIncrement"`
+	IsRequired         string       `gorm:"column:is_required;size:4;" json:"isRequired"`
+	IsInsert           string       `gorm:"column:is_insert;size:4;" json:"isInsert"`
+	IsEdit             string       `gorm:"column:is_edit;size:4;" json:"isEdit"`
+	IsList             string       `gorm:"column:is_list;size:4;" json:"isList"`
+	IsQuery            string       `gorm:"column:is_query;size:4;" json:"isQuery"`
+	QueryType          string       `gorm:"column:query_type;size:128;" json:"queryType"`
+	HtmlType           string       `gorm:"column:html_type;size:128;" json:"htmlType"`
+	DictType           string       `gorm:"column:dict_type;size:128;" json:"dictType"`
+	Sort               int          `gorm:"column:sort;" json:"sort"`
+	List               string       `gorm:"column:list;size:1;" json:"list"`
+	Pk                 bool         `gorm:"column:pk;size:1;" json:"pk"`
+	Required           bool         `gorm:"column:required;size:1;" json:"required"`
+	SuperColumn        bool         `gorm:"column:super_column;size:1;" json:"superColumn"`
+	UsableColumn       bool         `gorm:"column:usable_column;size:1;" json:"usableColumn"`
+	Increment          bool         `gorm:"column:increment;size:1;" json:"increment"`
+	Insert             bool         `gorm:"column:insert;size:1;" json:"insert"`
+	Edit               bool         `gorm:"column:edit;size:1;" json:"edit"`
+	Query              bool         `gorm:"column:query;size:1;" json:"query"`
+	Remark             string       `gorm:"column:remark;size:255;" json:"remark"`
+	FkTableName        string       `gorm:"" json:"fkTableName"`
+	FkTableNameClass   string       `gorm:"" json:"fkTableNameClass"`
+	FkTableNamePackage string       `gorm:"" json:"fkTableNamePackage"`
+	FkCol              []SysColumns `gorm:"-" json:"fkCol"`
+	FkLabelId          string       `gorm:"" json:"fkLabelId"`
+	FkLabelName        string       `gorm:"size:255;" json:"fkLabelName"`
+	CreateBy           int          `gorm:"column:create_by;size:20;" json:"createBy"`
+	UpdateBy           int          `gorm:"column:update_By;size:20;" json:"updateBy"`
+
+	common.ModelTime
+}
+
+func (*SysColumns) TableName() string {
+	return "sys_columns"
+}
+
+func (e *SysColumns) GetList(tx *gorm.DB, exclude bool) ([]SysColumns, error) {
+	var doc []SysColumns
+	table := tx.Table("sys_columns")
+	table = table.Where("table_id = ? ", e.TableId)
+	if exclude {
+		notIn := make([]string, 0, 6)
+		notIn = append(notIn, "id")
+		notIn = append(notIn, "create_by")
+		notIn = append(notIn, "update_by")
+		notIn = append(notIn, "created_at")
+		notIn = append(notIn, "updated_at")
+		notIn = append(notIn, "deleted_at")
+		table = table.Where(" column_name not in(?)", notIn)
+	}
+
+	if err := table.Find(&doc).Error; err != nil {
+		return nil, err
+	}
+	return doc, nil
+}
+
+func (e *SysColumns) Create(tx *gorm.DB) (SysColumns, error) {
+	var doc SysColumns
+	e.CreateBy = 0
+	result := tx.Table("sys_columns").Create(&e)
+	if result.Error != nil {
+		err := result.Error
+		return doc, err
+	}
+	doc = *e
+	return doc, nil
+}
+
+func (e *SysColumns) Update(tx *gorm.DB) (update SysColumns, err error) {
+	if err = tx.Table("sys_columns").First(&update, e.ColumnId).Error; err != nil {
+		return
+	}
+
+	//参数1:是要修改的数据
+	//参数2:是修改的数据
+	e.UpdateBy = 0
+	if err = tx.Table("sys_columns").Model(&update).Updates(&e).Error; err != nil {
+		return
+	}
+
+	return
+}
diff --git a/app/other/models/tools/sys_tables.go b/app/other/models/tools/sys_tables.go
new file mode 100644
index 0000000..4417a3e
--- /dev/null
+++ b/app/other/models/tools/sys_tables.go
@@ -0,0 +1,234 @@
+package tools
+
+import (
+	common "go-admin/common/models"
+	"strings"
+
+	"gorm.io/gorm"
+)
+
+type SysTables struct {
+	TableId             int    `gorm:"primaryKey;autoIncrement" json:"tableId"`        //表编码
+	TBName              string `gorm:"column:table_name;size:255;" json:"tableName"`   //表名称
+	MLTBName            string `gorm:"-" json:"-"`                                     //表名称
+	TableComment        string `gorm:"size:255;" json:"tableComment"`                  //表备注
+	ClassName           string `gorm:"size:255;" json:"className"`                     //类名
+	TplCategory         string `gorm:"size:255;" json:"tplCategory"`                   //
+	PackageName         string `gorm:"size:255;" json:"packageName"`                   //包名
+	ModuleName          string `gorm:"size:255;" json:"moduleName"`                    //go文件名
+	ModuleFrontName     string `gorm:"size:255;comment:前端文件名;" json:"moduleFrontName"` //前端文件名
+	BusinessName        string `gorm:"size:255;" json:"businessName"`                  //
+	FunctionName        string `gorm:"size:255;" json:"functionName"`                  //功能名称
+	FunctionAuthor      string `gorm:"size:255;" json:"functionAuthor"`                //功能作者
+	PkColumn            string `gorm:"size:255;" json:"pkColumn"`
+	PkGoField           string `gorm:"size:255;" json:"pkGoField"`
+	PkJsonField         string `gorm:"size:255;" json:"pkJsonField"`
+	Options             string `gorm:"size:255;" json:"options"`
+	TreeCode            string `gorm:"size:255;" json:"treeCode"`
+	TreeParentCode      string `gorm:"size:255;" json:"treeParentCode"`
+	TreeName            string `gorm:"size:255;" json:"treeName"`
+	Tree                bool   `gorm:"size:1;default:0;" json:"tree"`
+	Crud                bool   `gorm:"size:1;default:1;" json:"crud"`
+	Remark              string `gorm:"size:255;" json:"remark"`
+	IsDataScope         int    `gorm:"size:1;" json:"isDataScope"`
+	IsActions           int    `gorm:"size:1;" json:"isActions"`
+	IsAuth              int    `gorm:"size:1;" json:"isAuth"`
+	IsLogicalDelete     string `gorm:"size:1;" json:"isLogicalDelete"`
+	LogicalDelete       bool   `gorm:"size:1;" json:"logicalDelete"`
+	LogicalDeleteColumn string `gorm:"size:128;" json:"logicalDeleteColumn"`
+	common.ModelTime
+	common.ControlBy
+	DataScope string       `gorm:"-" json:"dataScope"`
+	Params    Params       `gorm:"-" json:"params"`
+	Columns   []SysColumns `gorm:"-" json:"columns"`
+}
+
+func (*SysTables) TableName() string {
+	return "sys_tables"
+}
+
+type Params struct {
+	TreeCode       string `gorm:"-" json:"treeCode"`
+	TreeParentCode string `gorm:"-" json:"treeParentCode"`
+	TreeName       string `gorm:"-" json:"treeName"`
+}
+
+func (e *SysTables) GetPage(tx *gorm.DB, pageSize int, pageIndex int) ([]SysTables, int, error) {
+	var doc []SysTables
+
+	table := tx.Table("sys_tables")
+
+	if e.TBName != "" {
+		table = table.Where("table_name = ?", e.TBName)
+	}
+	if e.TableComment != "" {
+		table = table.Where("table_comment = ?", e.TableComment)
+	}
+
+	var count int64
+
+	if err := table.Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Offset(-1).Limit(-1).Count(&count).Error; err != nil {
+		return nil, 0, err
+	}
+	//table.Where("`deleted_at` IS NULL").Count(&count)
+	return doc, int(count), nil
+}
+
+func (e *SysTables) Get(tx *gorm.DB, exclude bool) (SysTables, error) {
+	var doc SysTables
+	var err error
+	table := tx.Table("sys_tables")
+
+	if e.TBName != "" {
+		table = table.Where("table_name = ?", e.TBName)
+	}
+	if e.TableId != 0 {
+		table = table.Where("table_id = ?", e.TableId)
+	}
+	if e.TableComment != "" {
+		table = table.Where("table_comment = ?", e.TableComment)
+	}
+
+	if err := table.First(&doc).Error; err != nil {
+		return doc, err
+	}
+	var col SysColumns
+	col.TableId = doc.TableId
+	if doc.Columns, err = col.GetList(tx, exclude); err != nil {
+		return doc, err
+	}
+
+	return doc, nil
+}
+
+func (e *SysTables) GetTree(tx *gorm.DB) ([]SysTables, error) {
+	var doc []SysTables
+	var err error
+	table := tx.Table("sys_tables")
+
+	if e.TBName != "" {
+		table = table.Where("table_name = ?", e.TBName)
+	}
+	if e.TableId != 0 {
+		table = table.Where("table_id = ?", e.TableId)
+	}
+	if e.TableComment != "" {
+		table = table.Where("table_comment = ?", e.TableComment)
+	}
+
+	if err := table.Find(&doc).Error; err != nil {
+		return doc, err
+	}
+	for i := 0; i < len(doc); i++ {
+		var col SysColumns
+		//col.FkCol = append(col.FkCol, SysColumns{ColumnId: 0, ColumnName: "请选择"})
+		col.TableId = doc[i].TableId
+		if doc[i].Columns, err = col.GetList(tx, false); err != nil {
+			return doc, err
+		}
+
+	}
+
+	return doc, nil
+}
+
+func (e *SysTables) Create(tx *gorm.DB) (SysTables, error) {
+	var doc SysTables
+	e.CreateBy = 0
+	result := tx.Table("sys_tables").Create(&e)
+	if result.Error != nil {
+		err := result.Error
+		return doc, err
+	}
+	doc = *e
+	for i := 0; i < len(e.Columns); i++ {
+		e.Columns[i].TableId = doc.TableId
+
+		_, _ = e.Columns[i].Create(tx)
+	}
+
+	return doc, nil
+}
+
+func (e *SysTables) Update(tx *gorm.DB) (update SysTables, err error) {
+	//if err = orm.Eloquent.Table("sys_tables").First(&update, e.TableId).Error; err != nil {
+	//	return
+	//}
+
+	//参数1:是要修改的数据
+	//参数2:是修改的数据
+	e.UpdateBy = 0
+	if err = tx.Table("sys_tables").Where("table_id = ?", e.TableId).Updates(&e).Error; err != nil {
+		return
+	}
+
+	tableNames := make([]string, 0)
+	for i := range e.Columns {
+		if e.Columns[i].FkTableName != "" {
+			tableNames = append(tableNames, e.Columns[i].FkTableName)
+		}
+	}
+
+	tables := make([]SysTables, 0)
+	tableMap := make(map[string]*SysTables)
+	if len(tableNames) > 0 {
+		if err = tx.Table("sys_tables").Where("table_name in (?)", tableNames).Find(&tables).Error; err != nil {
+			return
+		}
+		for i := range tables {
+			tableMap[tables[i].TBName] = &tables[i]
+		}
+	}
+
+	for i := 0; i < len(e.Columns); i++ {
+		if e.Columns[i].FkTableName != "" {
+			t, ok := tableMap[e.Columns[i].FkTableName]
+			if ok {
+				e.Columns[i].FkTableNameClass = t.ClassName
+				t.MLTBName = strings.Replace(t.TBName, "_", "-", -1)
+				e.Columns[i].FkTableNamePackage = t.MLTBName
+			} else {
+				tableNameList := strings.Split(e.Columns[i].FkTableName, "_")
+				e.Columns[i].FkTableNameClass = ""
+				//e.Columns[i].FkTableNamePackage = ""
+				for a := 0; a < len(tableNameList); a++ {
+					strStart := string([]byte(tableNameList[a])[:1])
+					strEnd := string([]byte(tableNameList[a])[1:])
+					e.Columns[i].FkTableNameClass += strings.ToUpper(strStart) + strEnd
+					//e.Columns[i].FkTableNamePackage += strings.ToLower(strStart) + strings.ToLower(strEnd)
+				}
+			}
+		}
+		_, _ = e.Columns[i].Update(tx)
+	}
+	return
+}
+
+func (e *SysTables) Delete(db *gorm.DB) (success bool, err error) {
+	tx := db.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	if err = tx.Table("sys_tables").Delete(SysTables{}, "table_id = ?", e.TableId).Error; err != nil {
+		success = false
+		return
+	}
+	if err = tx.Table("sys_columns").Delete(SysColumns{}, "table_id = ?", e.TableId).Error; err != nil {
+		success = false
+		return
+	}
+	success = true
+	return
+}
+
+func (e *SysTables) BatchDelete(tx *gorm.DB, id []int) (Result bool, err error) {
+	if err = tx.Unscoped().Table(e.TableName()).Where(" table_id in (?)", id).Delete(&SysColumns{}).Error; err != nil {
+		return
+	}
+	Result = true
+	return
+}
diff --git a/app/other/router/file.go b/app/other/router/file.go
new file mode 100644
index 0000000..c3bd3ac
--- /dev/null
+++ b/app/other/router/file.go
@@ -0,0 +1,20 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/other/apis"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerFileRouter)
+}
+
+// 需认证的路由代码
+func registerFileRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	var api = apis.File{}
+	r := v1.Group("").Use(authMiddleware.MiddlewareFunc())
+	{
+		r.POST("/public/uploadFile", api.UploadFile)
+	}
+}
diff --git a/app/other/router/gen_router.go b/app/other/router/gen_router.go
new file mode 100644
index 0000000..c3c356b
--- /dev/null
+++ b/app/other/router/gen_router.go
@@ -0,0 +1,56 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/admin/apis"
+	"go-admin/app/other/apis/tools"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, sysNoCheckRoleRouter, registerDBRouter, registerSysTableRouter)
+}
+
+func sysNoCheckRoleRouter(v1 *gin.RouterGroup ,authMiddleware *jwt.GinJWTMiddleware) {
+	r1 := v1.Group("")
+	{
+		sys := apis.System{}
+		r1.GET("/captcha", sys.GenerateCaptchaHandler)
+	}
+
+	r := v1.Group("").Use(authMiddleware.MiddlewareFunc())
+	{
+		gen := tools.Gen{}
+		r.GET("/gen/preview/:tableId", gen.Preview)
+		r.GET("/gen/toproject/:tableId", gen.GenCode)
+		r.GET("/gen/apitofile/:tableId", gen.GenApiToFile)
+		r.GET("/gen/todb/:tableId", gen.GenMenuAndApi)
+		sysTable := tools.SysTable{}
+		r.GET("/gen/tabletree", sysTable.GetSysTablesTree)
+	}
+}
+
+func registerDBRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	db := v1.Group("/db").Use(authMiddleware.MiddlewareFunc())
+	{
+		gen := tools.Gen{}
+		db.GET("/tables/page", gen.GetDBTableList)
+		db.GET("/columns/page", gen.GetDBColumnList)
+	}
+}
+
+func registerSysTableRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	tables := v1.Group("/sys/tables")
+	{
+		sysTable := tools.SysTable{}
+		tables.Group("").Use(authMiddleware.MiddlewareFunc()).GET("/page", sysTable.GetPage)
+		tablesInfo := tables.Group("/info").Use(authMiddleware.MiddlewareFunc())
+		{
+			tablesInfo.POST("", sysTable.Insert)
+			tablesInfo.PUT("", sysTable.Update)
+			tablesInfo.DELETE("/:tableId", sysTable.Delete)
+			tablesInfo.GET("/:tableId", sysTable.Get)
+			tablesInfo.GET("", sysTable.GetSysTablesInfo)
+		}
+	}
+}
\ No newline at end of file
diff --git a/app/other/router/init_router.go b/app/other/router/init_router.go
new file mode 100644
index 0000000..708f93e
--- /dev/null
+++ b/app/other/router/init_router.go
@@ -0,0 +1,36 @@
+package router
+
+import (
+	"os"
+
+	"github.com/gin-gonic/gin"
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	common "go-admin/common/middleware"
+)
+
+// InitRouter 路由初始化,不要怀疑,这里用到了
+func InitRouter() {
+	var r *gin.Engine
+	h := sdk.Runtime.GetEngine()
+	if h == nil {
+		log.Fatal("not found engine...")
+		os.Exit(-1)
+	}
+	switch h.(type) {
+	case *gin.Engine:
+		r = h.(*gin.Engine)
+	default:
+		log.Fatal("not support other engine")
+		os.Exit(-1)
+	}
+	// the jwt middleware
+	authMiddleware, err := common.AuthInit()
+	if err != nil {
+		log.Fatalf("JWT Init Error, %s", err.Error())
+	}
+
+	// 注册业务路由
+	// TODO: 这里可存放业务路由,里边并无实际路由只有演示代码
+	initRouter(r, authMiddleware)
+}
diff --git a/app/other/router/monitor.go b/app/other/router/monitor.go
new file mode 100644
index 0000000..cdbe7ad
--- /dev/null
+++ b/app/other/router/monitor.go
@@ -0,0 +1,23 @@
+package router
+
+import (
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/tools/transfer"
+	"github.com/prometheus/client_golang/prometheus/promhttp"
+)
+
+func init() {
+	routerNoCheckRole = append(routerNoCheckRole, registerMonitorRouter)
+}
+
+// 需认证的路由代码
+func registerMonitorRouter(v1 *gin.RouterGroup) {
+	v1.GET("/metrics", transfer.Handler(promhttp.Handler()))
+	//健康检查
+	v1.GET("/health", func(c *gin.Context) {
+		c.Status(http.StatusOK)
+	})
+
+}
\ No newline at end of file
diff --git a/app/other/router/router.go b/app/other/router/router.go
new file mode 100644
index 0000000..8c893a2
--- /dev/null
+++ b/app/other/router/router.go
@@ -0,0 +1,42 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+)
+
+var (
+	routerNoCheckRole = make([]func(*gin.RouterGroup), 0)
+	routerCheckRole   = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0)
+)
+
+// initRouter 路由示例
+func initRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine {
+
+	// 无需认证的路由
+	noCheckRoleRouter(r)
+	// 需要认证的路由
+	checkRoleRouter(r, authMiddleware)
+
+	return r
+}
+
+// noCheckRoleRouter 无需认证的路由示例
+func noCheckRoleRouter(r *gin.Engine) {
+	// 可根据业务需求来设置接口版本
+	v1 := r.Group("/api/v1")
+
+	for _, f := range routerNoCheckRole {
+		f(v1)
+	}
+}
+
+// checkRoleRouter 需要认证的路由示例
+func checkRoleRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) {
+	// 可根据业务需求来设置接口版本
+	v1 := r.Group("/api/v1")
+
+	for _, f := range routerCheckRole {
+		f(v1, authMiddleware)
+	}
+}
diff --git a/app/other/router/sys_server_monitor.go b/app/other/router/sys_server_monitor.go
new file mode 100644
index 0000000..ffa91a1
--- /dev/null
+++ b/app/other/router/sys_server_monitor.go
@@ -0,0 +1,21 @@
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/app/other/apis"
+	"go-admin/common/middleware"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerSysServerMonitorRouter)
+}
+
+// 需认证的路由代码
+func registerSysServerMonitorRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	api := apis.ServerMonitor{}
+	r := v1.Group("/server-monitor").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
+	{
+		r.GET("", api.ServerInfo)
+	}
+}
diff --git a/app/other/service/dto/sys_tables.go b/app/other/service/dto/sys_tables.go
new file mode 100644
index 0000000..2e8b923
--- /dev/null
+++ b/app/other/service/dto/sys_tables.go
@@ -0,0 +1,6 @@
+package dto
+
+type SysTableSearch struct {
+	TBName       string `form:"tableName" search:"type:exact;column:table_name;table:table_name"`
+	TableComment string `form:"tableComment" search:"type:icontains;column:table_comment;table:table_comment"`
+}
diff --git a/cmd/api/jobs.go b/cmd/api/jobs.go
new file mode 100644
index 0000000..e95caf8
--- /dev/null
+++ b/cmd/api/jobs.go
@@ -0,0 +1,8 @@
+package api
+
+import "go-admin/app/jobs/router"
+
+func init() {
+	//注册路由 fixme 其他应用的路由,在本目录新建文件放在init方法
+	AppRouters = append(AppRouters, router.InitRouter)
+}
diff --git a/cmd/api/other.go b/cmd/api/other.go
new file mode 100644
index 0000000..4c291be
--- /dev/null
+++ b/cmd/api/other.go
@@ -0,0 +1,8 @@
+package api
+
+import "go-admin/app/other/router"
+
+func init() {
+	//注册路由 fixme 其他应用的路由,在本目录新建文件放在init方法
+	AppRouters = append(AppRouters, router.InitRouter)
+}
diff --git a/cmd/api/server.go b/cmd/api/server.go
new file mode 100644
index 0000000..ba08d16
--- /dev/null
+++ b/cmd/api/server.go
@@ -0,0 +1,214 @@
+package api
+
+import (
+	"context"
+	"fmt"
+	"go-admin/common/helper"
+	"go-admin/common/service/sysservice/sysstatuscode"
+	"go-admin/config/serverinit"
+	"go-admin/pkg/utility"
+	"log"
+	"net/http"
+	"os"
+	"os/signal"
+	"time"
+
+	"github.com/pkg/errors"
+	"gorm.io/gorm"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/config/source/file"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/spf13/cobra"
+
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/router"
+	"go-admin/app/jobs"
+	"go-admin/common/database"
+	"go-admin/common/global"
+	common "go-admin/common/middleware"
+	"go-admin/common/middleware/handler"
+	"go-admin/common/storage"
+	ext "go-admin/config"
+)
+
+var (
+	configYml string
+	apiCheck  bool
+	StartCmd  = &cobra.Command{
+		Use:          "server",
+		Short:        "Start API server",
+		Example:      "go-admin server -c config/settings.yml",
+		SilenceUsage: true,
+		PreRun: func(cmd *cobra.Command, args []string) {
+			setup()
+		},
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return run()
+		},
+	}
+)
+
+var AppRouters = make([]func(), 0)
+
+func init() {
+	StartCmd.PersistentFlags().StringVarP(&configYml, "config", "c", "config/settings.yml", "Start server with provided configuration file")
+	StartCmd.PersistentFlags().BoolVarP(&apiCheck, "api", "a", false, "Start server with check api data")
+
+	//注册路由 fixme 其他应用的路由,在本目录新建文件放在init方法
+	AppRouters = append(AppRouters, router.InitRouter)
+}
+
+func setup() {
+	// 注入配置扩展项
+	config.ExtendConfig = &ext.ExtConfig
+	//1. 读取配置
+	config.Setup(
+		file.NewSource(file.WithPath(configYml)),
+		database.Setup,
+		storage.Setup,
+	)
+	//注册监听函数
+	queue := sdk.Runtime.GetMemoryQueue("")
+	queue.Register(global.LoginLog, models.SaveLoginLog)
+	queue.Register(global.OperateLog, models.SaveOperaLog)
+	queue.Register(global.ApiCheck, models.SaveSysApi)
+	go queue.Run()
+
+	usageStr := `starting api server...`
+	log.Println(usageStr)
+}
+
+func run() error {
+	if config.ApplicationConfig.Mode == pkg.ModeProd.String() {
+		gin.SetMode(gin.ReleaseMode)
+	}
+	initRouter()
+	dbs := sdk.Runtime.GetDb()
+	var db *gorm.DB
+
+	for _, item := range dbs {
+		db = item
+		break
+	}
+	for _, f := range AppRouters {
+		f()
+	}
+
+	//初始化 status code 描述
+	sysstatuscode.InitStatusCodeLanguage(db)
+
+	//初始redis 链接
+	helper.InitDefaultRedis(ext.ExtConfig.Redis.Addr, ext.ExtConfig.Redis.Password, ext.ExtConfig.Redis.Db)
+	helper.InitLockRedisConn(ext.ExtConfig.Redis.Addr, ext.ExtConfig.Redis.Password, utility.IntToString(ext.ExtConfig.Redis.Db))
+
+	//初始化雪花算法配置
+	err := helper.InitSnowflakeNode()
+	if err != nil {
+		log.Printf("InitSnowflakeNode  error, %s \n", err.Error())
+	}
+
+	//业务需要配置-初始化
+	serverinit.BusinessInit(db)
+
+	srv := &http.Server{
+		Addr:    fmt.Sprintf("%s:%d", config.ApplicationConfig.Host, config.ApplicationConfig.Port),
+		Handler: sdk.Runtime.GetEngine(),
+	}
+
+	go func() {
+		jobs.InitJob()
+		jobs.Setup(sdk.Runtime.GetDb())
+
+	}()
+
+	if apiCheck {
+		var routers = sdk.Runtime.GetRouter()
+		q := sdk.Runtime.GetMemoryQueue("")
+		mp := make(map[string]interface{})
+		mp["List"] = routers
+		message, err := sdk.Runtime.GetStreamMessage("", global.ApiCheck, mp)
+		if err != nil {
+			log.Printf("GetStreamMessage error, %s \n", err.Error())
+			//日志报错错误,不中断请求
+		} else {
+			err = q.Append(message)
+			if err != nil {
+				log.Printf("Append message error, %s \n", err.Error())
+			}
+		}
+	}
+
+	go func() {
+		// 服务连接
+		if config.SslConfig.Enable {
+			if err := srv.ListenAndServeTLS(config.SslConfig.Pem, config.SslConfig.KeyStr); err != nil && !errors.Is(err, http.ErrServerClosed) {
+				log.Fatal("listen: ", err)
+			}
+		} else {
+			if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
+				log.Fatal("listen: ", err)
+			}
+		}
+	}()
+	fmt.Println(pkg.Red(string(global.LogoContent)))
+	tip()
+	fmt.Println(pkg.Green("Server run at:"))
+	fmt.Printf("-  Local:   %s://localhost:%d/ \r\n", "http", config.ApplicationConfig.Port)
+	fmt.Printf("-  Network: %s://%s:%d/ \r\n", "http", pkg.GetLocaHonst(), config.ApplicationConfig.Port)
+	fmt.Println(pkg.Green("Swagger run at:"))
+	fmt.Printf("-  Local:   http://localhost:%d/swagger/admin/index.html \r\n", config.ApplicationConfig.Port)
+	fmt.Printf("-  Network: %s://%s:%d/swagger/admin/index.html \r\n", "http", pkg.GetLocaHonst(), config.ApplicationConfig.Port)
+	fmt.Printf("%s Enter Control + C Shutdown Server \r\n", pkg.GetCurrentTimeStr())
+	// 等待中断信号以优雅地关闭服务器(设置 5 秒的超时时间)
+	quit := make(chan os.Signal, 1)
+	signal.Notify(quit, os.Interrupt)
+	<-quit
+
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	fmt.Printf("%s Shutdown Server ... \r\n", pkg.GetCurrentTimeStr())
+
+	if err := srv.Shutdown(ctx); err != nil {
+		log.Fatal("Server Shutdown:", err)
+	}
+	log.Println("Server exiting")
+
+	return nil
+}
+
+//var Router runtime.Router
+
+func tip() {
+	usageStr := `欢迎使用 ` + pkg.Green(`go-admin `+global.Version) + ` 可以使用 ` + pkg.Red(`-h`) + ` 查看命令`
+	fmt.Printf("%s \n\n", usageStr)
+}
+
+func initRouter() {
+	var r *gin.Engine
+	h := sdk.Runtime.GetEngine()
+	if h == nil {
+		h = gin.New()
+		sdk.Runtime.SetEngine(h)
+	}
+	switch h.(type) {
+	case *gin.Engine:
+		r = h.(*gin.Engine)
+	default:
+		log.Fatal("not support other engine")
+		//os.Exit(-1)
+	}
+	if config.SslConfig.Enable {
+		r.Use(handler.TlsHandler())
+	}
+	//r.Use(middleware.Metrics())
+	r.Use(common.Sentinel()).
+		Use(common.RequestId(pkg.TrafficKey)).
+		Use(api.SetRequestLogger)
+
+	common.InitMiddleware(r)
+
+}
diff --git a/cmd/app/server.go b/cmd/app/server.go
new file mode 100644
index 0000000..013ac38
--- /dev/null
+++ b/cmd/app/server.go
@@ -0,0 +1,90 @@
+package app
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/utils"
+	"github.com/spf13/cobra"
+	"text/template"
+)
+
+var (
+	appName  string
+	StartCmd = &cobra.Command{
+		Use:     "app",
+		Short:   "Create a new app",
+		Long:    "Use when you need to create a new app",
+		Example: "go-admin app -n admin",
+		Run: func(cmd *cobra.Command, args []string) {
+			run()
+		},
+	}
+)
+
+func init() {
+	StartCmd.PersistentFlags().StringVarP(&appName, "name", "n", "", "Start server with provided configuration file")
+}
+
+func run() {
+
+	fmt.Println(`start init`)
+	//1. 读取配置
+
+	fmt.Println(`generate migration file`)
+	_ = genFile()
+
+}
+
+func genFile() error {
+	if appName == "" {
+		return errors.New("arg `name` invalid :name is empty")
+	}
+	path := "app/"
+	appPath := path + appName
+	err := utils.IsNotExistMkDir(appPath)
+	if err != nil {
+		return err
+	}
+	apiPath := appPath + "/apis/"
+	err = utils.IsNotExistMkDir(apiPath)
+	if err != nil {
+		return err
+	}
+	modelsPath := appPath + "/models/"
+	err = utils.IsNotExistMkDir(modelsPath)
+	if err != nil {
+		return err
+	}
+	routerPath := appPath + "/router/"
+	err = utils.IsNotExistMkDir(routerPath)
+	if err != nil {
+		return err
+	}
+	servicePath := appPath + "/service/"
+	err = utils.IsNotExistMkDir(servicePath)
+	if err != nil {
+		return err
+	}
+	dtoPath := appPath + "/service/dto/"
+	err = utils.IsNotExistMkDir(dtoPath)
+	if err != nil {
+		return err
+	}
+
+	t1, err := template.ParseFiles("template/cmd_api.template")
+	if err != nil {
+		return err
+	}
+	m := map[string]string{}
+	m["appName"] = appName
+	var b1 bytes.Buffer
+	err = t1.Execute(&b1, m)
+	pkg.FileCreate(b1, "./cmd/api/"+appName+".go")
+	t2, err := template.ParseFiles("template/router.template")
+	var b2 bytes.Buffer
+	err = t2.Execute(&b2, nil)
+	pkg.FileCreate(b2, appPath+"/router/router.go")
+	return nil
+}
diff --git a/cmd/cobra.go b/cmd/cobra.go
new file mode 100644
index 0000000..6ac1c03
--- /dev/null
+++ b/cmd/cobra.go
@@ -0,0 +1,60 @@
+package cmd
+
+import (
+	"errors"
+	"fmt"
+	"go-admin/cmd/app"
+	"go-admin/cmd/usersubscribe"
+	"go-admin/common/global"
+	"os"
+
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+
+	"github.com/spf13/cobra"
+
+	"go-admin/cmd/api"
+	"go-admin/cmd/config"
+	"go-admin/cmd/migrate"
+	"go-admin/cmd/version"
+)
+
+var rootCmd = &cobra.Command{
+	Use:          "go-admin",
+	Short:        "go-admin",
+	SilenceUsage: true,
+	Long:         `go-admin`,
+	Args: func(cmd *cobra.Command, args []string) error {
+		if len(args) < 1 {
+			tip()
+			return errors.New(pkg.Red("requires at least one arg"))
+		}
+		return nil
+	},
+	PersistentPreRunE: func(*cobra.Command, []string) error { return nil },
+	Run: func(cmd *cobra.Command, args []string) {
+		tip()
+	},
+}
+
+func tip() {
+	usageStr := `欢迎使用 ` + pkg.Green(`go-admin `+global.Version) + ` 可以使用 ` + pkg.Red(`-h`) + ` 查看命令`
+	usageStr1 := `也可以参考 https://doc.go-admin.dev/guide/ksks 的相关内容`
+	fmt.Printf("%s\n", usageStr)
+	fmt.Printf("%s\n", usageStr1)
+}
+
+func init() {
+	rootCmd.AddCommand(api.StartCmd)
+	rootCmd.AddCommand(usersubscribe.StartCmd)
+	rootCmd.AddCommand(migrate.StartCmd)
+	rootCmd.AddCommand(version.StartCmd)
+	rootCmd.AddCommand(config.StartCmd)
+	rootCmd.AddCommand(app.StartCmd)
+}
+
+// Execute : apply commands
+func Execute() {
+	if err := rootCmd.Execute(); err != nil {
+		os.Exit(-1)
+	}
+}
diff --git a/cmd/config/server.go b/cmd/config/server.go
new file mode 100644
index 0000000..52ce85b
--- /dev/null
+++ b/cmd/config/server.go
@@ -0,0 +1,63 @@
+package config
+
+import (
+	"encoding/json"
+	"fmt"
+
+	"github.com/go-admin-team/go-admin-core/config/source/file"
+	"github.com/spf13/cobra"
+
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+)
+
+var (
+	configYml string
+	StartCmd  = &cobra.Command{
+		Use:     "config",
+		Short:   "Get Application config info",
+		Example: "go-admin config -c config/settings.yml",
+		Run: func(cmd *cobra.Command, args []string) {
+			run()
+		},
+	}
+)
+
+func init() {
+	StartCmd.PersistentFlags().StringVarP(&configYml, "config", "c", "config/settings.yml", "Start server with provided configuration file")
+}
+
+func run() {
+	config.Setup(file.NewSource(file.WithPath(configYml)))
+
+	application, errs := json.MarshalIndent(config.ApplicationConfig, "", "   ") //转换成JSON返回的是byte[]
+	if errs != nil {
+		fmt.Println(errs.Error())
+	}
+	fmt.Println("application:", string(application))
+
+	jwt, errs := json.MarshalIndent(config.JwtConfig, "", "   ") //转换成JSON返回的是byte[]
+	if errs != nil {
+		fmt.Println(errs.Error())
+	}
+	fmt.Println("jwt:", string(jwt))
+
+	// todo 需要兼容
+	database, errs := json.MarshalIndent(config.DatabasesConfig, "", "   ") //转换成JSON返回的是byte[]
+	if errs != nil {
+		fmt.Println(errs.Error())
+	}
+	fmt.Println("database:", string(database))
+
+	gen, errs := json.MarshalIndent(config.GenConfig, "", "   ") //转换成JSON返回的是byte[]
+	if errs != nil {
+		fmt.Println(errs.Error())
+	}
+	fmt.Println("gen:", string(gen))
+
+	loggerConfig, errs := json.MarshalIndent(config.LoggerConfig, "", "   ") //转换成JSON返回的是byte[]
+	if errs != nil {
+		fmt.Println(errs.Error())
+	}
+	fmt.Println("logger:", string(loggerConfig))
+
+}
diff --git a/cmd/migrate/migration/init.go b/cmd/migrate/migration/init.go
new file mode 100644
index 0000000..739e6b4
--- /dev/null
+++ b/cmd/migrate/migration/init.go
@@ -0,0 +1,66 @@
+package migration
+
+import (
+	"log"
+	"path/filepath"
+	"sort"
+	"sync"
+
+	"gorm.io/gorm"
+)
+
+var Migrate = &Migration{
+	version: make(map[string]func(db *gorm.DB, version string) error),
+}
+
+type Migration struct {
+	db      *gorm.DB
+	version map[string]func(db *gorm.DB, version string) error
+	mutex   sync.Mutex
+}
+
+func (e *Migration) GetDb() *gorm.DB {
+	return e.db
+}
+
+func (e *Migration) SetDb(db *gorm.DB) {
+	e.db = db
+}
+
+func (e *Migration) SetVersion(k string, f func(db *gorm.DB, version string) error) {
+	e.mutex.Lock()
+	defer e.mutex.Unlock()
+	e.version[k] = f
+}
+
+func (e *Migration) Migrate() {
+	versions := make([]string, 0)
+	for k := range e.version {
+		versions = append(versions, k)
+	}
+	if !sort.StringsAreSorted(versions) {
+		sort.Strings(versions)
+	}
+	var err error
+	var count int64
+	for _, v := range versions {
+		err = e.db.Table("sys_migration").Where("version = ?", v).Count(&count).Error
+		if err != nil {
+			log.Fatalln(err)
+		}
+		if count > 0 {
+			log.Println(count)
+			count = 0
+			continue
+		}
+		err = (e.version[v])(e.db.Debug(), v)
+		if err != nil {
+			log.Fatalln(err)
+		}
+	}
+}
+
+func GetFilename(s string) string {
+	s = filepath.Base(s)
+	return s[:13]
+}
diff --git a/cmd/migrate/migration/models/by.go b/cmd/migrate/migration/models/by.go
new file mode 100644
index 0000000..c9dd906
--- /dev/null
+++ b/cmd/migrate/migration/models/by.go
@@ -0,0 +1,22 @@
+package models
+
+import (
+	"time"
+
+	"gorm.io/gorm"
+)
+
+type ControlBy struct {
+	CreateBy int `json:"createBy" gorm:"index;comment:创建者"`
+	UpdateBy int `json:"updateBy" gorm:"index;comment:更新者"`
+}
+
+type Model struct {
+	Id int `json:"id" gorm:"primaryKey;autoIncrement;comment:主键编码"`
+}
+
+type ModelTime struct {
+	CreatedAt time.Time      `json:"createdAt" gorm:"comment:创建时间"`
+	UpdatedAt time.Time      `json:"updatedAt" gorm:"comment:最后更新时间"`
+	DeletedAt gorm.DeletedAt `json:"-" gorm:"index;comment:删除时间"`
+}
diff --git a/cmd/migrate/migration/models/casbin_rule.go b/cmd/migrate/migration/models/casbin_rule.go
new file mode 100644
index 0000000..bab7203
--- /dev/null
+++ b/cmd/migrate/migration/models/casbin_rule.go
@@ -0,0 +1,17 @@
+package models
+
+// CasbinRule sys_casbin_rule
+type CasbinRule struct {
+	ID    uint   `gorm:"primaryKey;autoIncrement"`
+	Ptype string `gorm:"size:512;uniqueIndex:unique_index"`
+	V0    string `gorm:"size:512;uniqueIndex:unique_index"`
+	V1    string `gorm:"size:512;uniqueIndex:unique_index"`
+	V2    string `gorm:"size:512;uniqueIndex:unique_index"`
+	V3    string `gorm:"size:512;uniqueIndex:unique_index"`
+	V4    string `gorm:"size:512;uniqueIndex:unique_index"`
+	V5    string `gorm:"size:512;uniqueIndex:unique_index"`
+}
+
+func (CasbinRule) TableName() string {
+	return "sys_casbin_rule"
+}
diff --git a/cmd/migrate/migration/models/initdb.go b/cmd/migrate/migration/models/initdb.go
new file mode 100644
index 0000000..ba7f4ca
--- /dev/null
+++ b/cmd/migrate/migration/models/initdb.go
@@ -0,0 +1,72 @@
+package models
+
+import (
+	"fmt"
+	"go-admin/common/global"
+	"io/ioutil"
+	"log"
+	"strings"
+
+	"gorm.io/gorm"
+)
+
+func InitDb(db *gorm.DB) (err error) {
+	filePath := "config/db.sql"
+	if global.Driver == "postgres" {
+		filePath := "config/db.sql"
+		if err = ExecSql(db, filePath); err != nil {
+			return err
+		}
+		filePath = "config/pg.sql"
+		err = ExecSql(db, filePath)
+	} else if global.Driver == "mysql" {
+		filePath = "config/db-begin-mysql.sql"
+		if err = ExecSql(db, filePath); err != nil {
+			return err
+		}
+		filePath = "config/db.sql"
+		if err = ExecSql(db, filePath); err != nil {
+			return err
+		}
+		filePath = "config/db-end-mysql.sql"
+		err = ExecSql(db, filePath)
+	} else {
+		err = ExecSql(db, filePath)
+	}
+	return err
+}
+
+func ExecSql(db *gorm.DB, filePath string) error {
+	sql, err := Ioutil(filePath)
+	if err != nil {
+		fmt.Println("数据库基础数据初始化脚本读取失败!原因:", err.Error())
+		return err
+	}
+	sqlList := strings.Split(sql, ";")
+	for i := 0; i < len(sqlList)-1; i++ {
+		if strings.Contains(sqlList[i], "--") {
+			fmt.Println(sqlList[i])
+			continue
+		}
+		sql := strings.Replace(sqlList[i]+";", "\n", "", -1)
+		sql = strings.TrimSpace(sql)
+		if err = db.Exec(sql).Error; err != nil {
+			log.Printf("error sql: %s", sql)
+			if !strings.Contains(err.Error(), "Query was empty") {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func Ioutil(filePath string) (string, error) {
+	if contents, err := ioutil.ReadFile(filePath); err == nil {
+		//因为contents是[]byte类型,直接转换成string类型后会多一行空格,需要使用strings.Replace替换换行符
+		result := strings.Replace(string(contents), "\n", "", 1)
+		fmt.Println("Use ioutil.ReadFile to read a file:", result)
+		return result, nil
+	} else {
+		return "", err
+	}
+}
diff --git a/cmd/migrate/migration/models/model.go b/cmd/migrate/migration/models/model.go
new file mode 100644
index 0000000..4a1c439
--- /dev/null
+++ b/cmd/migrate/migration/models/model.go
@@ -0,0 +1,11 @@
+package models
+
+import (
+	"time"
+)
+
+type BaseModel struct {
+	CreatedAt time.Time  `json:"createdAt"`
+	UpdatedAt time.Time  `json:"updatedAt"`
+	DeletedAt *time.Time `json:"deletedAt"`
+}
diff --git a/cmd/migrate/migration/models/role_dept.go b/cmd/migrate/migration/models/role_dept.go
new file mode 100644
index 0000000..0aae705
--- /dev/null
+++ b/cmd/migrate/migration/models/role_dept.go
@@ -0,0 +1,10 @@
+package models
+
+type SysRoleDept struct {
+	RoleId int `gorm:"size:11;primaryKey"`
+	DeptId int `gorm:"size:11;primaryKey"`
+}
+
+func (SysRoleDept) TableName() string {
+	return "sys_role_dept"
+}
diff --git a/cmd/migrate/migration/models/sys_api.go b/cmd/migrate/migration/models/sys_api.go
new file mode 100644
index 0000000..8d75170
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_api.go
@@ -0,0 +1,16 @@
+package models
+
+type SysApi struct {
+	Id     int    `json:"id" gorm:"primaryKey;autoIncrement;comment:主键编码"`
+	Handle string `json:"handle" gorm:"size:128;comment:handle"`
+	Title  string `json:"title" gorm:"size:128;comment:标题"`
+	Path   string `json:"path" gorm:"size:128;comment:地址"`
+	Type   string `json:"type" gorm:"size:16;comment:接口类型"`
+	Action string `json:"action" gorm:"size:16;comment:请求类型"`
+	ModelTime
+	ControlBy
+}
+
+func (SysApi) TableName() string {
+	return "sys_api"
+}
\ No newline at end of file
diff --git a/cmd/migrate/migration/models/sys_columns.go b/cmd/migrate/migration/models/sys_columns.go
new file mode 100644
index 0000000..2c8377e
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_columns.go
@@ -0,0 +1,44 @@
+package models
+
+type SysColumns struct {
+	ColumnId           int    `gorm:"primaryKey;autoIncrement" json:"columnId"`
+	TableId            int    `gorm:"" json:"tableId"`
+	ColumnName         string `gorm:"size:128;" json:"columnName"`
+	ColumnComment      string `gorm:"column:column_comment;size:128;" json:"columnComment"`
+	ColumnType         string `gorm:"column:column_type;size:128;" json:"columnType"`
+	GoType             string `gorm:"column:go_type;size:128;" json:"goType"`
+	GoField            string `gorm:"column:go_field;size:128;" json:"goField"`
+	JsonField          string `gorm:"column:json_field;size:128;" json:"jsonField"`
+	IsPk               string `gorm:"column:is_pk;size:4;" json:"isPk"`
+	IsIncrement        string `gorm:"column:is_increment;size:4;" json:"isIncrement"`
+	IsRequired         string `gorm:"column:is_required;size:4;" json:"isRequired"`
+	IsInsert           string `gorm:"column:is_insert;size:4;" json:"isInsert"`
+	IsEdit             string `gorm:"column:is_edit;size:4;" json:"isEdit"`
+	IsList             string `gorm:"column:is_list;size:4;" json:"isList"`
+	IsQuery            string `gorm:"column:is_query;size:4;" json:"isQuery"`
+	QueryType          string `gorm:"column:query_type;size:128;" json:"queryType"`
+	HtmlType           string `gorm:"column:html_type;size:128;" json:"htmlType"`
+	DictType           string `gorm:"column:dict_type;size:128;" json:"dictType"`
+	Sort               int    `gorm:"column:sort;" json:"sort"`
+	List               string `gorm:"column:list;size:1;" json:"list"`
+	Pk                 bool   `gorm:"column:pk;size:1;" json:"pk"`
+	Required           bool   `gorm:"column:required;size:1;" json:"required"`
+	SuperColumn        bool   `gorm:"column:super_column;size:1;" json:"superColumn"`
+	UsableColumn       bool   `gorm:"column:usable_column;size:1;" json:"usableColumn"`
+	Increment          bool   `gorm:"column:increment;size:1;" json:"increment"`
+	Insert             bool   `gorm:"column:insert;size:1;" json:"insert"`
+	Edit               bool   `gorm:"column:edit;size:1;" json:"edit"`
+	Query              bool   `gorm:"column:query;size:1;" json:"query"`
+	Remark             string `gorm:"column:remark;size:255;" json:"remark"`
+	FkTableName        string `gorm:"" json:"fkTableName"`
+	FkTableNameClass   string `gorm:"" json:"fkTableNameClass"`
+	FkTableNamePackage string `gorm:"" json:"fkTableNamePackage"`
+	FkLabelId          string `gorm:"" json:"fkLabelId"`
+	FkLabelName        string `gorm:"size:255;" json:"fkLabelName"`
+	ModelTime
+	ControlBy
+}
+
+func (SysColumns) TableName() string {
+	return "sys_columns"
+}
diff --git a/cmd/migrate/migration/models/sys_config.go b/cmd/migrate/migration/models/sys_config.go
new file mode 100644
index 0000000..bd79da3
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_config.go
@@ -0,0 +1,17 @@
+package models
+
+type SysConfig struct {
+	Model
+	ConfigName  string `json:"configName" gorm:"type:varchar(128);comment:ConfigName"`
+	ConfigKey   string `json:"configKey" gorm:"type:varchar(128);comment:ConfigKey"`
+	ConfigValue string `json:"configValue" gorm:"type:varchar(255);comment:ConfigValue"`
+	ConfigType  string `json:"configType" gorm:"type:varchar(64);comment:ConfigType"`
+	IsFrontend  int    `json:"isFrontend" gorm:"type:varchar(64);comment:是否前台"`
+	Remark      string `json:"remark" gorm:"type:varchar(128);comment:Remark"`
+	ControlBy
+	ModelTime
+}
+
+func (SysConfig) TableName() string {
+	return "sys_config"
+}
diff --git a/cmd/migrate/migration/models/sys_dept.go b/cmd/migrate/migration/models/sys_dept.go
new file mode 100644
index 0000000..5f74c62
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_dept.go
@@ -0,0 +1,19 @@
+package models
+
+type SysDept struct {
+	DeptId   int    `json:"deptId" gorm:"primaryKey;autoIncrement;"` //部门编码
+	ParentId int    `json:"parentId" gorm:""`                        //上级部门
+	DeptPath string `json:"deptPath" gorm:"size:255;"`               //
+	DeptName string `json:"deptName"  gorm:"size:128;"`              //部门名称
+	Sort     int    `json:"sort" gorm:"size:4;"`                     //排序
+	Leader   string `json:"leader" gorm:"size:128;"`                 //负责人
+	Phone    string `json:"phone" gorm:"size:11;"`                   //手机
+	Email    string `json:"email" gorm:"size:64;"`                   //邮箱
+	Status   int    `json:"status" gorm:"size:4;"`                   //状态
+	ControlBy
+	ModelTime
+}
+
+func (SysDept) TableName() string {
+	return "sys_dept"
+}
diff --git a/cmd/migrate/migration/models/sys_dict_data.go b/cmd/migrate/migration/models/sys_dict_data.go
new file mode 100644
index 0000000..c2936c8
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_dict_data.go
@@ -0,0 +1,21 @@
+package models
+
+type DictData struct {
+	DictCode  int    `gorm:"primaryKey;autoIncrement;" json:"dictCode" example:"1"` //字典编码
+	DictSort  int    `gorm:"" json:"dictSort"`                                      //显示顺序
+	DictLabel string `gorm:"size:128;" json:"dictLabel"`                            //数据标签
+	DictValue string `gorm:"size:255;" json:"dictValue"`                            //数据键值
+	DictType  string `gorm:"size:64;" json:"dictType"`                              //字典类型
+	CssClass  string `gorm:"size:128;" json:"cssClass"`                             //
+	ListClass string `gorm:"size:128;" json:"listClass"`                            //
+	IsDefault string `gorm:"size:8;" json:"isDefault"`                              //
+	Status    int    `gorm:"size:4;" json:"status"`                                 //状态
+	Default   string `gorm:"size:8;" json:"default"`                                //
+	Remark    string `gorm:"size:255;" json:"remark"`                               //备注
+	ControlBy
+	ModelTime
+}
+
+func (DictData) TableName() string {
+	return "sys_dict_data"
+}
diff --git a/cmd/migrate/migration/models/sys_dict_type.go b/cmd/migrate/migration/models/sys_dict_type.go
new file mode 100644
index 0000000..4c79e37
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_dict_type.go
@@ -0,0 +1,15 @@
+package models
+
+type DictType struct {
+	DictId   int    `gorm:"primaryKey;autoIncrement;" json:"dictId"`
+	DictName string `gorm:"size:128;" json:"dictName"` //字典名称
+	DictType string `gorm:"size:128;" json:"dictType"` //字典类型
+	Status   int    `gorm:"size:4;" json:"status"`     //状态
+	Remark   string `gorm:"size:255;" json:"remark"`   //备注
+	ControlBy
+	ModelTime
+}
+
+func (DictType) TableName() string {
+	return "sys_dict_type"
+}
diff --git a/cmd/migrate/migration/models/sys_job.go b/cmd/migrate/migration/models/sys_job.go
new file mode 100644
index 0000000..e826d10
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_job.go
@@ -0,0 +1,21 @@
+package models
+
+type SysJob struct {
+	JobId          int    `json:"jobId" gorm:"primaryKey;autoIncrement"` // 编码
+	JobName        string `json:"jobName" gorm:"size:255;"`              // 名称
+	JobGroup       string `json:"jobGroup" gorm:"size:255;"`             // 任务分组
+	JobType        int    `json:"jobType" gorm:"size:1;"`                // 任务类型
+	CronExpression string `json:"cronExpression" gorm:"size:255;"`       // cron表达式
+	InvokeTarget   string `json:"invokeTarget" gorm:"size:255;"`         // 调用目标
+	Args           string `json:"args" gorm:"size:255;"`                 // 目标参数
+	MisfirePolicy  int    `json:"misfirePolicy" gorm:"size:255;"`        // 执行策略
+	Concurrent     int    `json:"concurrent" gorm:"size:1;"`             // 是否并发
+	Status         int    `json:"status" gorm:"size:1;"`                 // 状态
+	EntryId        int    `json:"entry_id" gorm:"size:11;"`              // job启动时返回的id
+	ModelTime
+	ControlBy
+}
+
+func (SysJob) TableName() string {
+	return "sys_job"
+}
diff --git a/cmd/migrate/migration/models/sys_login_log.go b/cmd/migrate/migration/models/sys_login_log.go
new file mode 100644
index 0000000..f4a878b
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_login_log.go
@@ -0,0 +1,26 @@
+package models
+
+import (
+	"time"
+)
+
+type SysLoginLog struct {
+	Model
+	Username      string    `json:"username" gorm:"type:varchar(128);comment:用户名"`
+	Status        string    `json:"status" gorm:"type:varchar(4);comment:状态"`
+	Ipaddr        string    `json:"ipaddr" gorm:"type:varchar(255);comment:ip地址"`
+	LoginLocation string    `json:"loginLocation" gorm:"type:varchar(255);comment:归属地"`
+	Browser       string    `json:"browser" gorm:"type:varchar(255);comment:浏览器"`
+	Os            string    `json:"os" gorm:"type:varchar(255);comment:系统"`
+	Platform      string    `json:"platform" gorm:"type:varchar(255);comment:固件"`
+	LoginTime     time.Time `json:"loginTime" gorm:"type:timestamp;comment:登录时间"`
+	Remark        string    `json:"remark" gorm:"type:varchar(255);comment:备注"`
+	Msg           string    `json:"msg" gorm:"type:varchar(255);comment:信息"`
+	CreatedAt     time.Time `json:"createdAt" gorm:"comment:创建时间"`
+	UpdatedAt     time.Time `json:"updatedAt" gorm:"comment:最后更新时间"`
+	ControlBy
+}
+
+func (SysLoginLog) TableName() string {
+	return "sys_login_log"
+}
diff --git a/cmd/migrate/migration/models/sys_menu.go b/cmd/migrate/migration/models/sys_menu.go
new file mode 100644
index 0000000..c69252f
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_menu.go
@@ -0,0 +1,27 @@
+package models
+
+type SysMenu struct {
+	MenuId     int       `json:"menuId" gorm:"primaryKey;autoIncrement"`
+	MenuName   string    `json:"menuName" gorm:"size:128;"`
+	Title      string    `json:"title" gorm:"size:128;"`
+	Icon       string    `json:"icon" gorm:"size:128;"`
+	Path       string    `json:"path" gorm:"size:128;"`
+	Paths      string    `json:"paths" gorm:"size:128;"`
+	MenuType   string    `json:"menuType" gorm:"size:1;"`
+	Action     string    `json:"action" gorm:"size:16;"`
+	Permission string    `json:"permission" gorm:"size:255;"`
+	ParentId   int       `json:"parentId" gorm:"size:11;"`
+	NoCache    bool      `json:"noCache" gorm:"size:8;"`
+	Breadcrumb string    `json:"breadcrumb" gorm:"size:255;"`
+	Component  string    `json:"component" gorm:"size:255;"`
+	Sort       int       `json:"sort" gorm:"size:4;"`
+	Visible    string    `json:"visible" gorm:"size:1;"`
+	IsFrame    string    `json:"isFrame" gorm:"size:1;DEFAULT:0;"`
+	SysApi     []SysApi  `json:"sysApi" gorm:"many2many:sys_menu_api_rule"`
+	ControlBy
+	ModelTime
+}
+
+func (SysMenu) TableName() string {
+	return "sys_menu"
+}
\ No newline at end of file
diff --git a/cmd/migrate/migration/models/sys_opera_log.go b/cmd/migrate/migration/models/sys_opera_log.go
new file mode 100644
index 0000000..5055b96
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_opera_log.go
@@ -0,0 +1,34 @@
+package models
+
+import (
+	"time"
+)
+
+type SysOperaLog struct {
+	Model
+	Title         string    `json:"title" gorm:"type:varchar(255);comment:操作模块"`
+	BusinessType  string    `json:"businessType" gorm:"type:varchar(128);comment:操作类型"`
+	BusinessTypes string    `json:"businessTypes" gorm:"type:varchar(128);comment:BusinessTypes"`
+	Method        string    `json:"method" gorm:"type:varchar(128);comment:函数"`
+	RequestMethod string    `json:"requestMethod" gorm:"type:varchar(128);comment:请求方式: GET POST PUT DELETE"`
+	OperatorType  string    `json:"operatorType" gorm:"type:varchar(128);comment:操作类型"`
+	OperName      string    `json:"operName" gorm:"type:varchar(128);comment:操作者"`
+	DeptName      string    `json:"deptName" gorm:"type:varchar(128);comment:部门名称"`
+	OperUrl       string    `json:"operUrl" gorm:"type:varchar(255);comment:访问地址"`
+	OperIp        string    `json:"operIp" gorm:"type:varchar(128);comment:客户端ip"`
+	OperLocation  string    `json:"operLocation" gorm:"type:varchar(128);comment:访问位置"`
+	OperParam     string    `json:"operParam" gorm:"type:text;comment:请求参数"`
+	Status        string    `json:"status" gorm:"type:varchar(4);comment:操作状态 1:正常 2:关闭"`
+	OperTime      time.Time `json:"operTime" gorm:"type:timestamp;comment:操作时间"`
+	JsonResult    string    `json:"jsonResult" gorm:"type:varchar(255);comment:返回数据"`
+	Remark        string    `json:"remark" gorm:"type:varchar(255);comment:备注"`
+	LatencyTime   string    `json:"latencyTime" gorm:"type:varchar(128);comment:耗时"`
+	UserAgent     string    `json:"userAgent" gorm:"type:varchar(255);comment:ua"`
+	CreatedAt     time.Time `json:"createdAt" gorm:"comment:创建时间"`
+	UpdatedAt     time.Time `json:"updatedAt" gorm:"comment:最后更新时间"`
+	ControlBy
+}
+
+func (SysOperaLog) TableName() string {
+	return "sys_opera_log"
+}
diff --git a/cmd/migrate/migration/models/sys_post.go b/cmd/migrate/migration/models/sys_post.go
new file mode 100644
index 0000000..195208a
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_post.go
@@ -0,0 +1,16 @@
+package models
+
+type SysPost struct {
+	PostId   int    `gorm:"primaryKey;autoIncrement" json:"postId"` //岗位编号
+	PostName string `gorm:"size:128;" json:"postName"`              //岗位名称
+	PostCode string `gorm:"size:128;" json:"postCode"`              //岗位代码
+	Sort     int    `gorm:"size:4;" json:"sort"`                    //岗位排序
+	Status   int    `gorm:"size:4;" json:"status"`                  //状态
+	Remark   string `gorm:"size:255;" json:"remark"`                //描述
+	ControlBy
+	ModelTime
+}
+
+func (SysPost) TableName() string {
+	return "sys_post"
+}
\ No newline at end of file
diff --git a/cmd/migrate/migration/models/sys_role.go b/cmd/migrate/migration/models/sys_role.go
new file mode 100644
index 0000000..0bd5ee3
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_role.go
@@ -0,0 +1,20 @@
+package models
+
+type SysRole struct {
+	RoleId    int       `json:"roleId" gorm:"primaryKey;autoIncrement"` // 角色编码
+	RoleName  string    `json:"roleName" gorm:"size:128;"`              // 角色名称
+	Status    string    `json:"status" gorm:"size:4;"`                  //
+	RoleKey   string    `json:"roleKey" gorm:"size:128;"`               //角色代码
+	RoleSort  int       `json:"roleSort" gorm:""`                       //角色排序
+	Flag      string    `json:"flag" gorm:"size:128;"`                  //
+	Remark    string    `json:"remark" gorm:"size:255;"`                //备注
+	Admin     bool      `json:"admin" gorm:"size:4;"`
+	DataScope string    `json:"dataScope" gorm:"size:128;"`
+	SysMenu   []SysMenu `json:"sysMenu" gorm:"many2many:sys_role_menu;foreignKey:RoleId;joinForeignKey:role_id;references:MenuId;joinReferences:menu_id;"`
+	ControlBy
+	ModelTime
+}
+
+func (SysRole) TableName() string {
+	return "sys_role"
+}
\ No newline at end of file
diff --git a/cmd/migrate/migration/models/sys_tables.go b/cmd/migrate/migration/models/sys_tables.go
new file mode 100644
index 0000000..0e53032
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_tables.go
@@ -0,0 +1,37 @@
+package models
+
+type SysTables struct {
+	TableId             int    `gorm:"primaryKey;autoIncrement" json:"tableId"`        //表编码
+	TBName              string `gorm:"column:table_name;size:255;" json:"tableName"`   //表名称
+	TableComment        string `gorm:"size:255;" json:"tableComment"`                  //表备注
+	ClassName           string `gorm:"size:255;" json:"className"`                     //类名
+	TplCategory         string `gorm:"size:255;" json:"tplCategory"`                   //
+	PackageName         string `gorm:"size:255;" json:"packageName"`                   //包名
+	ModuleName          string `gorm:"size:255;" json:"moduleName"`                    //go文件名
+	ModuleFrontName     string `gorm:"size:255;comment:前端文件名;" json:"moduleFrontName"` //前端文件名
+	BusinessName        string `gorm:"size:255;" json:"businessName"`                  //
+	FunctionName        string `gorm:"size:255;" json:"functionName"`                  //功能名称
+	FunctionAuthor      string `gorm:"size:255;" json:"functionAuthor"`                //功能作者
+	PkColumn            string `gorm:"size:255;" json:"pkColumn"`
+	PkGoField           string `gorm:"size:255;" json:"pkGoField"`
+	PkJsonField         string `gorm:"size:255;" json:"pkJsonField"`
+	Options             string `gorm:"size:255;" json:"options"`
+	TreeCode            string `gorm:"size:255;" json:"treeCode"`
+	TreeParentCode      string `gorm:"size:255;" json:"treeParentCode"`
+	TreeName            string `gorm:"size:255;" json:"treeName"`
+	Tree                bool   `gorm:"size:1;default:0;" json:"tree"`
+	Crud                bool   `gorm:"size:1;default:1;" json:"crud"`
+	Remark              string `gorm:"size:255;" json:"remark"`
+	IsDataScope         int    `gorm:"size:1;" json:"isDataScope"`
+	IsActions           int    `gorm:"size:1;" json:"isActions"`
+	IsAuth              int    `gorm:"size:1;" json:"isAuth"`
+	IsLogicalDelete     string `gorm:"size:1;" json:"isLogicalDelete"`
+	LogicalDelete       bool   `gorm:"size:1;" json:"logicalDelete"`
+	LogicalDeleteColumn string `gorm:"size:128;" json:"logicalDeleteColumn"`
+	ModelTime
+	ControlBy
+}
+
+func (SysTables) TableName() string {
+	return "sys_tables"
+}
diff --git a/cmd/migrate/migration/models/sys_user.go b/cmd/migrate/migration/models/sys_user.go
new file mode 100644
index 0000000..31e3637
--- /dev/null
+++ b/cmd/migrate/migration/models/sys_user.go
@@ -0,0 +1,48 @@
+package models
+
+import (
+	"golang.org/x/crypto/bcrypt"
+	"gorm.io/gorm"
+)
+
+type SysUser struct {
+	UserId   int    `gorm:"primaryKey;autoIncrement;comment:编码"  json:"userId"`
+	Username string `json:"username" gorm:"type:varchar(64);comment:用户名"`
+	Password string `json:"-" gorm:"type:varchar(128);comment:密码"`
+	NickName string `json:"nickName" gorm:"type:varchar(128);comment:昵称"`
+	Phone    string `json:"phone" gorm:"type:varchar(11);comment:手机号"`
+	RoleId   int    `json:"roleId" gorm:"type:bigint;comment:角色ID"`
+	Salt     string `json:"-" gorm:"type:varchar(255);comment:加盐"`
+	Avatar   string `json:"avatar" gorm:"type:varchar(255);comment:头像"`
+	Sex      string `json:"sex" gorm:"type:varchar(255);comment:性别"`
+	Email    string `json:"email" gorm:"type:varchar(128);comment:邮箱"`
+	DeptId   int    `json:"deptId" gorm:"type:bigint;comment:部门"`
+	PostId   int    `json:"postId" gorm:"type:bigint;comment:岗位"`
+	Remark   string `json:"remark" gorm:"type:varchar(255);comment:备注"`
+	Status   string `json:"status" gorm:"type:varchar(4);comment:状态"`
+	ControlBy
+	ModelTime
+}
+
+func (*SysUser) TableName() string {
+	return "sys_user"
+}
+
+// Encrypt 加密
+func (e *SysUser) Encrypt() (err error) {
+	if e.Password == "" {
+		return
+	}
+
+	var hash []byte
+	if hash, err = bcrypt.GenerateFromPassword([]byte(e.Password), bcrypt.DefaultCost); err != nil {
+		return
+	} else {
+		e.Password = string(hash)
+		return
+	}
+}
+
+func (e *SysUser) BeforeCreate(_ *gorm.DB) error {
+	return e.Encrypt()
+}
diff --git a/cmd/migrate/migration/models/tb_demo.go b/cmd/migrate/migration/models/tb_demo.go
new file mode 100644
index 0000000..7d30541
--- /dev/null
+++ b/cmd/migrate/migration/models/tb_demo.go
@@ -0,0 +1,12 @@
+package models
+
+type TbDemo struct {
+	Model
+	Name string `json:"name" gorm:"type:varchar(128);comment:名称"`
+	ModelTime
+	ControlBy
+}
+
+func (TbDemo) TableName() string {
+	return "tb_demo"
+}
diff --git a/cmd/migrate/migration/version-local/doc.go b/cmd/migrate/migration/version-local/doc.go
new file mode 100644
index 0000000..2cec8bc
--- /dev/null
+++ b/cmd/migrate/migration/version-local/doc.go
@@ -0,0 +1,8 @@
+package version_local
+
+func init() {
+}
+
+/**
+开发者项目的迁移脚本放在这个目录里,init写法参考version目录里的migrate或者自动生成
+*/
diff --git a/cmd/migrate/migration/version/1599190683659_tables.go b/cmd/migrate/migration/version/1599190683659_tables.go
new file mode 100644
index 0000000..df2dafa
--- /dev/null
+++ b/cmd/migrate/migration/version/1599190683659_tables.go
@@ -0,0 +1,53 @@
+package version
+
+import (
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"runtime"
+
+	"go-admin/cmd/migrate/migration"
+	"go-admin/cmd/migrate/migration/models"
+	common "go-admin/common/models"
+
+	"gorm.io/gorm"
+)
+
+func init() {
+	_, fileName, _, _ := runtime.Caller(0)
+	migration.Migrate.SetVersion(migration.GetFilename(fileName), _1599190683659Tables)
+}
+
+func _1599190683659Tables(db *gorm.DB, version string) error {
+	return db.Transaction(func(tx *gorm.DB) error {
+		if config.DatabaseConfig.Driver == "mysql" {
+			tx = tx.Set("gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4")
+		}
+		err := tx.Migrator().AutoMigrate(
+			new(models.SysDept),
+			new(models.SysConfig),
+			new(models.SysTables),
+			new(models.SysColumns),
+			new(models.SysMenu),
+			new(models.SysLoginLog),
+			new(models.SysOperaLog),
+			new(models.SysRoleDept),
+			new(models.SysUser),
+			new(models.SysRole),
+			new(models.SysPost),
+			new(models.DictData),
+			new(models.DictType),
+			new(models.SysJob),
+			new(models.SysConfig),
+			new(models.SysApi),
+			new(models.TbDemo),
+		)
+		if err != nil {
+			return err
+		}
+		if err := models.InitDb(tx); err != nil {
+			return err
+		}
+		return tx.Create(&common.Migration{
+			Version: version,
+		}).Error
+	})
+}
diff --git a/cmd/migrate/migration/version/1653638869132_migrate.go b/cmd/migrate/migration/version/1653638869132_migrate.go
new file mode 100644
index 0000000..59a8fa0
--- /dev/null
+++ b/cmd/migrate/migration/version/1653638869132_migrate.go
@@ -0,0 +1,48 @@
+package version
+
+import (
+	"go-admin/cmd/migrate/migration/models"
+	common "go-admin/common/models"
+	"gorm.io/gorm"
+	"runtime"
+	"strconv"
+
+	"go-admin/cmd/migrate/migration"
+)
+
+func init() {
+	_, fileName, _, _ := runtime.Caller(0)
+	migration.Migrate.SetVersion(migration.GetFilename(fileName), _1653638869132Test)
+}
+
+func _1653638869132Test(db *gorm.DB, version string) error {
+	return db.Transaction(func(tx *gorm.DB) error {
+		var list []models.SysMenu
+		err := tx.Model(&models.SysMenu{}).Order("parent_id,menu_id").Find(&list).Error
+		if err != nil {
+			return err
+		}
+		for _, v := range list {
+			if v.ParentId == 0 {
+				v.Paths = "/0/" + strconv.Itoa(v.MenuId)
+			} else {
+				var e models.SysMenu
+				err = tx.Model(&models.SysMenu{}).Where("menu_id=?", v.ParentId).First(&e).Error
+				if err != nil {
+					if err == gorm.ErrRecordNotFound {
+						continue
+					}
+					return err
+				}
+				v.Paths = e.Paths + "/" + strconv.Itoa(v.MenuId)
+			}
+			err = tx.Model(&v).Update("paths", v.Paths).Error
+			if err != nil {
+				return err
+			}
+		}
+		return tx.Create(&common.Migration{
+			Version: version,
+		}).Error
+	})
+}
diff --git a/cmd/migrate/server.go b/cmd/migrate/server.go
new file mode 100644
index 0000000..b1667ca
--- /dev/null
+++ b/cmd/migrate/server.go
@@ -0,0 +1,118 @@
+package migrate
+
+import (
+	"bytes"
+	"fmt"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"strconv"
+	"text/template"
+	"time"
+
+	"github.com/go-admin-team/go-admin-core/config/source/file"
+	"github.com/spf13/cobra"
+
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"go-admin/cmd/migrate/migration"
+	_ "go-admin/cmd/migrate/migration/version"
+	_ "go-admin/cmd/migrate/migration/version-local"
+	"go-admin/common/database"
+	"go-admin/common/models"
+)
+
+var (
+	configYml string
+	generate  bool
+	goAdmin   bool
+	host      string
+	StartCmd  = &cobra.Command{
+		Use:     "migrate",
+		Short:   "Initialize the database",
+		Example: "go-admin migrate -c config/settings.yml",
+		Run: func(cmd *cobra.Command, args []string) {
+			run()
+		},
+	}
+)
+
+// fixme 在您看不见代码的时候运行迁移,我觉得是不安全的,所以编译后最好不要去执行迁移
+func init() {
+	StartCmd.PersistentFlags().StringVarP(&configYml, "config", "c", "config/settings.yml", "Start server with provided configuration file")
+	StartCmd.PersistentFlags().BoolVarP(&generate, "generate", "g", false, "generate migration file")
+	StartCmd.PersistentFlags().BoolVarP(&goAdmin, "goAdmin", "a", false, "generate go-admin migration file")
+	StartCmd.PersistentFlags().StringVarP(&host, "domain", "d", "*", "select tenant host")
+}
+
+func run() {
+
+	if !generate {
+		fmt.Println(`start init`)
+		//1. 读取配置
+		config.Setup(
+			file.NewSource(file.WithPath(configYml)),
+			initDB,
+		)
+	} else {
+		fmt.Println(`generate migration file`)
+		_ = genFile()
+	}
+}
+
+func migrateModel() error {
+	if host == "" {
+		host = "*"
+	}
+	db := sdk.Runtime.GetDbByKey(host)
+	if db == nil {
+		if len(sdk.Runtime.GetDb()) == 1 && host == "*" {
+			for k, v := range sdk.Runtime.GetDb() {
+				db = v
+				host = k
+				break
+			}
+		}
+	}
+	if db == nil {
+		return fmt.Errorf("未找到数据库配置")
+	}
+	if config.DatabasesConfig[host].Driver == "mysql" {
+		//初始化数据库时候用
+		db.Set("gorm:table_options", "ENGINE=InnoDB CHARSET=utf8mb4")
+	}
+	err := db.Debug().AutoMigrate(&models.Migration{})
+	if err != nil {
+		return err
+	}
+	migration.Migrate.SetDb(db.Debug())
+	migration.Migrate.Migrate()
+	return err
+}
+func initDB() {
+	//3. 初始化数据库链接
+	database.Setup()
+	//4. 数据库迁移
+	fmt.Println("数据库迁移开始")
+	_ = migrateModel()
+	fmt.Println(`数据库基础数据初始化成功`)
+}
+
+func genFile() error {
+	t1, err := template.ParseFiles("template/migrate.template")
+	if err != nil {
+		return err
+	}
+	m := map[string]string{}
+	m["GenerateTime"] = strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
+	m["Package"] = "version_local"
+	if goAdmin {
+		m["Package"] = "version"
+	}
+	var b1 bytes.Buffer
+	err = t1.Execute(&b1, m)
+	if goAdmin {
+		pkg.FileCreate(b1, "./cmd/migrate/migration/version/"+m["GenerateTime"]+"_migrate.go")
+	} else {
+		pkg.FileCreate(b1, "./cmd/migrate/migration/version-local/"+m["GenerateTime"]+"_migrate.go")
+	}
+	return nil
+}
diff --git a/cmd/usersubscribe/usersubscribe.go b/cmd/usersubscribe/usersubscribe.go
new file mode 100644
index 0000000..efb1da7
--- /dev/null
+++ b/cmd/usersubscribe/usersubscribe.go
@@ -0,0 +1,135 @@
+package usersubscribe
+
+import (
+	"context"
+	"fmt"
+	"go-admin/app/admin/models"
+	"go-admin/common/database"
+	"go-admin/common/global"
+	"go-admin/common/helper"
+	"go-admin/common/storage"
+	"go-admin/config/serverinit"
+	"go-admin/pkg/utility"
+	"go-admin/services/fileservice"
+	"log"
+	"os"
+	"os/signal"
+	"strconv"
+	"time"
+
+	ext "go-admin/config"
+
+	"github.com/go-admin-team/go-admin-core/config/source/file"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/spf13/cobra"
+	"gorm.io/gorm"
+)
+
+var (
+	configYml string
+	StartCmd  = &cobra.Command{
+		Use:          "usersubscribe",
+		Short:        "Start usersubscribe server",
+		Example:      "go-admin usersubscribe -c config/settings.yml",
+		SilenceUsage: true,
+		PreRun: func(cmd *cobra.Command, args []string) {
+			setup()
+		},
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return run()
+		},
+	}
+)
+
+func init() {
+	StartCmd.PersistentFlags().StringVarP(&configYml, "config", "c", "config/settings.yml", "Start server with provided configuration file")
+}
+
+func setup() {
+	// 注入配置扩展项
+	config.ExtendConfig = &ext.ExtConfig
+	//1. 读取配置
+	config.Setup(
+		file.NewSource(file.WithPath(configYml)),
+		database.Setup,
+		storage.Setup,
+	)
+	//注册监听函数
+	queue := sdk.Runtime.GetMemoryQueue("")
+	queue.Register(global.LoginLog, models.SaveLoginLog)
+	queue.Register(global.OperateLog, models.SaveOperaLog)
+	// queue.Register(global.ApiCheck, models.SaveSysApi)
+	go queue.Run()
+
+	usageStr := `starting user subscribe server...`
+	log.Println(usageStr)
+}
+
+func run() error {
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	var db *gorm.DB
+	dbs := sdk.Runtime.GetDb()
+
+	for _, item := range dbs {
+		db = item
+		break
+	}
+
+	defaultInit(db, ctx)
+
+	utility.SafeGo(func() {
+		// 启动定时任务
+		clearLogJob(db, ctx)
+	})
+
+	// 等待中断信号以优雅地关闭服务器(设置 5 秒的超时时间)
+	quit := make(chan os.Signal, 1)
+	signal.Notify(quit, os.Interrupt)
+	<-quit
+
+	fmt.Printf("%s Shutdown Server ... \r\n", pkg.GetCurrentTimeStr())
+
+	// if err := srv.Shutdown(ctx); err != nil {
+	// 	log.Fatal("Server Shutdown:", err)
+	// }
+	log.Println("Server exiting")
+
+	return nil
+}
+
+func defaultInit(db *gorm.DB, ctx context.Context) {
+
+	//初始化 默认redis
+	helper.InitDefaultRedis(ext.ExtConfig.Redis.Addr, ext.ExtConfig.Redis.Password, ext.ExtConfig.Redis.Db)
+	helper.InitLockRedisConn(ext.ExtConfig.Redis.Addr, ext.ExtConfig.Redis.Password, strconv.Itoa(ext.ExtConfig.Redis.Db))
+
+	err := helper.DefaultRedis.Ping()
+
+	if err != nil {
+		log.Printf("初始化redis失败!请检查配置")
+		_, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+		cancel()
+	} else {
+		log.Printf("redis初始化成功")
+	}
+
+	//初始化连接
+	serverinit.UserSubscribeInit(db, ctx)
+}
+
+// 定时清理日志
+func clearLogJob(db *gorm.DB, ctx context.Context) {
+	ticker := time.NewTicker(time.Hour * 1)
+	defer ticker.Stop()
+
+	select {
+	case <-ctx.Done():
+		return
+	case <-ticker.C:
+		fileservice.ClearLogs(db)
+	}
+}
diff --git a/cmd/version/server.go b/cmd/version/server.go
new file mode 100644
index 0000000..329e1ea
--- /dev/null
+++ b/cmd/version/server.go
@@ -0,0 +1,26 @@
+package version
+
+import (
+	"fmt"
+	"github.com/spf13/cobra"
+	"go-admin/common/global"
+)
+
+var (
+	StartCmd = &cobra.Command{
+		Use:     "version",
+		Short:   "Get version info",
+		Example: "go-admin version",
+		PreRun: func(cmd *cobra.Command, args []string) {
+
+		},
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return run()
+		},
+	}
+)
+
+func run() error {
+	fmt.Println(global.Version)
+	return nil
+}
diff --git a/common/actions/create.go b/common/actions/create.go
new file mode 100644
index 0000000..81989e5
--- /dev/null
+++ b/common/actions/create.go
@@ -0,0 +1,49 @@
+package actions
+
+import (
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/common/dto"
+	"go-admin/common/models"
+)
+
+// CreateAction 通用新增动作
+func CreateAction(control dto.Control) gin.HandlerFunc {
+	return func(c *gin.Context) {
+		log := api.GetRequestLogger(c)
+		db, err := pkg.GetOrm(c)
+		if err != nil {
+			log.Error(err)
+			return
+		}
+
+		//新增操作
+		req := control.Generate()
+		err = req.Bind(c)
+		if err != nil {
+			response.Error(c, http.StatusUnprocessableEntity, err, err.Error())
+			return
+		}
+		var object models.ActiveRecord
+		object, err = req.GenerateM()
+		if err != nil {
+			response.Error(c, 500, err, "模型生成失败")
+			return
+		}
+		object.SetCreateBy(user.GetUserId(c))
+		err = db.WithContext(c).Create(object).Error
+		if err != nil {
+			log.Errorf("Create error: %s", err)
+			response.Error(c, 500, err, "创建失败")
+			return
+		}
+		response.OK(c, object.GetId(), "创建成功")
+		c.Next()
+	}
+}
diff --git a/common/actions/delete.go b/common/actions/delete.go
new file mode 100644
index 0000000..811b9bf
--- /dev/null
+++ b/common/actions/delete.go
@@ -0,0 +1,61 @@
+package actions
+
+import (
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/common/dto"
+	"go-admin/common/models"
+)
+
+// DeleteAction 通用删除动作
+func DeleteAction(control dto.Control) gin.HandlerFunc {
+	return func(c *gin.Context) {
+		db, err := pkg.GetOrm(c)
+		if err != nil {
+			log.Error(err)
+			return
+		}
+
+		msgID := pkg.GenerateMsgIDFromContext(c)
+		//删除操作
+		req := control.Generate()
+		err = req.Bind(c)
+		if err != nil {
+			log.Errorf("MsgID[%s] Bind error: %s", msgID, err)
+			response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
+			return
+		}
+		var object models.ActiveRecord
+		object, err = req.GenerateM()
+		if err != nil {
+			response.Error(c, 500, err, "模型生成失败")
+			return
+		}
+
+		object.SetUpdateBy(user.GetUserId(c))
+
+		//数据权限检查
+		p := GetPermissionFromContext(c)
+
+		db = db.WithContext(c).Scopes(
+			Permission(object.TableName(), p),
+		).Where(req.GetId()).Delete(object)
+		if err = db.Error; err != nil {
+			log.Errorf("MsgID[%s] Delete error: %s", msgID, err)
+			response.Error(c, 500, err, "删除失败")
+			return
+		}
+		if db.RowsAffected == 0 {
+			response.Error(c, http.StatusForbidden, nil, "无权删除该数据")
+			return
+		}
+		response.OK(c, object.GetId(), "删除成功")
+		c.Next()
+	}
+}
diff --git a/common/actions/index.go b/common/actions/index.go
new file mode 100644
index 0000000..4453094
--- /dev/null
+++ b/common/actions/index.go
@@ -0,0 +1,58 @@
+package actions
+
+import (
+	"errors"
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"gorm.io/gorm"
+
+	"go-admin/common/dto"
+	"go-admin/common/models"
+)
+
+// IndexAction 通用查询动作
+func IndexAction(m models.ActiveRecord, d dto.Index, f func() interface{}) gin.HandlerFunc {
+	return func(c *gin.Context) {
+		db, err := pkg.GetOrm(c)
+		if err != nil {
+			log.Error(err)
+			return
+		}
+
+		msgID := pkg.GenerateMsgIDFromContext(c)
+		list := f()
+		object := m.Generate()
+		req := d.Generate()
+		var count int64
+
+		//查询列表
+		err = req.Bind(c)
+		if err != nil {
+			response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
+			return
+		}
+
+		//数据权限检查
+		p := GetPermissionFromContext(c)
+
+		err = db.WithContext(c).Model(object).
+			Scopes(
+				dto.MakeCondition(req.GetNeedSearch()),
+				dto.Paginate(req.GetPageSize(), req.GetPageIndex()),
+				Permission(object.TableName(), p),
+			).
+			Find(list).Limit(-1).Offset(-1).
+			Count(&count).Error
+		if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+			log.Errorf("MsgID[%s] Index error: %s", msgID, err)
+			response.Error(c, 500, err, "查询失败")
+			return
+		}
+		response.PageOK(c, list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+		c.Next()
+	}
+}
diff --git a/common/actions/permission.go b/common/actions/permission.go
new file mode 100644
index 0000000..82532c4
--- /dev/null
+++ b/common/actions/permission.go
@@ -0,0 +1,96 @@
+package actions
+
+import (
+	"errors"
+
+	"github.com/gin-gonic/gin"
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"gorm.io/gorm"
+)
+
+type DataPermission struct {
+	DataScope string
+	UserId    int
+	DeptId    int
+	RoleId    int
+}
+
+func PermissionAction() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		db, err := pkg.GetOrm(c)
+		if err != nil {
+			log.Error(err)
+			return
+		}
+
+		msgID := pkg.GenerateMsgIDFromContext(c)
+		var p = new(DataPermission)
+		if userId := user.GetUserIdStr(c); userId != "" {
+			p, err = newDataPermission(db, userId)
+			if err != nil {
+				log.Errorf("MsgID[%s] PermissionAction error: %s", msgID, err)
+				response.Error(c, 500, err, "权限范围鉴定错误")
+				c.Abort()
+				return
+			}
+		}
+		c.Set(PermissionKey, p)
+		c.Next()
+	}
+}
+
+func newDataPermission(tx *gorm.DB, userId interface{}) (*DataPermission, error) {
+	var err error
+	p := &DataPermission{}
+
+	err = tx.Table("sys_user").
+		Select("sys_user.user_id", "sys_role.role_id", "sys_user.dept_id", "sys_role.data_scope").
+		Joins("left join sys_role on sys_role.role_id = sys_user.role_id").
+		Where("sys_user.user_id = ?", userId).
+		Scan(p).Error
+	if err != nil {
+		err = errors.New("获取用户数据出错 msg:" + err.Error())
+		return nil, err
+	}
+	return p, nil
+}
+
+func Permission(tableName string, p *DataPermission) func(db *gorm.DB) *gorm.DB {
+	return func(db *gorm.DB) *gorm.DB {
+		if !config.ApplicationConfig.EnableDP {
+			return db
+		}
+		switch p.DataScope {
+		case "2":
+			return db.Where(tableName+".create_by in (select sys_user.user_id from sys_role_dept left join sys_user on sys_user.dept_id=sys_role_dept.dept_id where sys_role_dept.role_id = ?)", p.RoleId)
+		case "3":
+			return db.Where(tableName+".create_by in (SELECT user_id from sys_user where dept_id = ? )", p.DeptId)
+		case "4":
+			return db.Where(tableName+".create_by in (SELECT user_id from sys_user where sys_user.dept_id in(select dept_id from sys_dept where dept_path like ? ))", "%/"+pkg.IntToString(p.DeptId)+"/%")
+		case "5":
+			return db.Where(tableName+".create_by = ?", p.UserId)
+		default:
+			return db
+		}
+	}
+}
+
+func getPermissionFromContext(c *gin.Context) *DataPermission {
+	p := new(DataPermission)
+	if pm, ok := c.Get(PermissionKey); ok {
+		switch pm.(type) {
+		case *DataPermission:
+			p = pm.(*DataPermission)
+		}
+	}
+	return p
+}
+
+// GetPermissionFromContext 提供非action写法数据范围约束
+func GetPermissionFromContext(c *gin.Context) *DataPermission {
+	return getPermissionFromContext(c)
+}
diff --git a/common/actions/type.go b/common/actions/type.go
new file mode 100644
index 0000000..69beb8c
--- /dev/null
+++ b/common/actions/type.go
@@ -0,0 +1,5 @@
+package actions
+
+const (
+	PermissionKey = "dataPermission"
+)
diff --git a/common/actions/update.go b/common/actions/update.go
new file mode 100644
index 0000000..7052334
--- /dev/null
+++ b/common/actions/update.go
@@ -0,0 +1,59 @@
+package actions
+
+import (
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+
+	"go-admin/common/dto"
+	"go-admin/common/models"
+)
+
+// UpdateAction 通用更新动作
+func UpdateAction(control dto.Control) gin.HandlerFunc {
+	return func(c *gin.Context) {
+		db, err := pkg.GetOrm(c)
+		if err != nil {
+			log.Error(err)
+			return
+		}
+
+		msgID := pkg.GenerateMsgIDFromContext(c)
+		req := control.Generate()
+		//更新操作
+		err = req.Bind(c)
+		if err != nil {
+			response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
+			return
+		}
+		var object models.ActiveRecord
+		object, err = req.GenerateM()
+		if err != nil {
+			response.Error(c, 500, err, "模型生成失败")
+			return
+		}
+		object.SetUpdateBy(user.GetUserId(c))
+
+		//数据权限检查
+		p := GetPermissionFromContext(c)
+
+		db = db.WithContext(c).Scopes(
+			Permission(object.TableName(), p),
+		).Where(req.GetId()).Updates(object)
+		if err = db.Error; err != nil {
+			log.Errorf("MsgID[%s] Update error: %s", msgID, err)
+			response.Error(c, 500, err, "更新失败")
+			return
+		}
+		if db.RowsAffected == 0 {
+			response.Error(c, http.StatusForbidden, nil, "无权更新该数据")
+			return
+		}
+		response.OK(c, object.GetId(), "更新成功")
+		c.Next()
+	}
+}
diff --git a/common/actions/view.go b/common/actions/view.go
new file mode 100644
index 0000000..b134f53
--- /dev/null
+++ b/common/actions/view.go
@@ -0,0 +1,67 @@
+package actions
+
+import (
+	"errors"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"gorm.io/gorm"
+
+	"go-admin/common/dto"
+	"go-admin/common/models"
+)
+
+// ViewAction 通用详情动作
+func ViewAction(control dto.Control, f func() interface{}) gin.HandlerFunc {
+	return func(c *gin.Context) {
+		db, err := pkg.GetOrm(c)
+		if err != nil {
+			log.Error(err)
+			return
+		}
+
+		msgID := pkg.GenerateMsgIDFromContext(c)
+		//查看详情
+		req := control.Generate()
+		err = req.Bind(c)
+		if err != nil {
+			response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
+			return
+		}
+		var object models.ActiveRecord
+		object, err = req.GenerateM()
+		if err != nil {
+			response.Error(c, 500, err, "模型生成失败")
+			return
+		}
+
+		var rsp interface{}
+		if f != nil {
+			rsp = f()
+		} else {
+			rsp, _ = req.GenerateM()
+		}
+
+		//数据权限检查
+		p := GetPermissionFromContext(c)
+
+		err = db.Model(object).WithContext(c).Scopes(
+			Permission(object.TableName(), p),
+		).Where(req.GetId()).First(rsp).Error
+
+		if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+			response.Error(c, http.StatusNotFound, nil, "查看对象不存在或无权查看")
+			return
+		}
+		if err != nil {
+			log.Errorf("MsgID[%s] View error: %s", msgID, err)
+			response.Error(c, 500, err, "查看失败")
+			return
+		}
+		response.OK(c, rsp, "查询成功")
+		c.Next()
+	}
+}
diff --git a/common/apis/api.go b/common/apis/api.go
new file mode 100644
index 0000000..4b2c58b
--- /dev/null
+++ b/common/apis/api.go
@@ -0,0 +1,135 @@
+package apis
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"gorm.io/gorm"
+
+	"go-admin/common/service"
+)
+
+type Api struct {
+	Context *gin.Context
+	Logger  *logger.Helper
+	Orm     *gorm.DB
+	Errors  error
+}
+
+func (e *Api) AddError(err error) {
+	if e.Errors == nil {
+		e.Errors = err
+	} else if err != nil {
+		e.Logger.Error(err)
+		e.Errors = fmt.Errorf("%v; %w", e.Errors, err)
+	}
+}
+
+// MakeContext 设置http上下文
+func (e *Api) MakeContext(c *gin.Context) *Api {
+	e.Context = c
+	e.Logger = api.GetRequestLogger(c)
+	return e
+}
+
+// GetLogger 获取上下文提供的日志
+func (e *Api) GetLogger() *logger.Helper {
+	return api.GetRequestLogger(e.Context)
+}
+
+func (e *Api) Bind(d interface{}, bindings ...binding.Binding) *Api {
+	var err error
+	if len(bindings) == 0 {
+		bindings = append(bindings, binding.JSON, nil)
+	}
+	for i := range bindings {
+		switch bindings[i] {
+		case binding.JSON:
+			err = e.Context.ShouldBindWith(d, binding.JSON)
+		case binding.XML:
+			err = e.Context.ShouldBindWith(d, binding.XML)
+		case binding.Form:
+			err = e.Context.ShouldBindWith(d, binding.Form)
+		case binding.Query:
+			err = e.Context.ShouldBindWith(d, binding.Query)
+		case binding.FormPost:
+			err = e.Context.ShouldBindWith(d, binding.FormPost)
+		case binding.FormMultipart:
+			err = e.Context.ShouldBindWith(d, binding.FormMultipart)
+		case binding.ProtoBuf:
+			err = e.Context.ShouldBindWith(d, binding.ProtoBuf)
+		case binding.MsgPack:
+			err = e.Context.ShouldBindWith(d, binding.MsgPack)
+		case binding.YAML:
+			err = e.Context.ShouldBindWith(d, binding.YAML)
+		case binding.Header:
+			err = e.Context.ShouldBindWith(d, binding.Header)
+		default:
+			err = e.Context.ShouldBindUri(d)
+		}
+		if err != nil {
+			e.AddError(err)
+		}
+	}
+	return e
+}
+
+// GetOrm 获取Orm DB
+func (e *Api) GetOrm() (*gorm.DB, error) {
+	db, err := pkg.GetOrm(e.Context)
+	if err != nil {
+		e.Error(500, err, "数据库连接获取失败")
+		return nil, err
+	}
+	return db, nil
+}
+
+// MakeOrm 设置Orm DB
+func (e *Api) MakeOrm() *Api {
+	var err error
+	if e.Logger == nil {
+		err = errors.New("at MakeOrm logger is nil")
+		//e.Logger.Error(500, err, "at MakeOrm logger is nil")
+		e.AddError(err)
+		return e
+	}
+	db, err := pkg.GetOrm(e.Context)
+	if err != nil {
+		e.Logger.Error(500, err, "数据库连接获取失败")
+		e.AddError(err)
+	}
+	e.Orm = db
+	return e
+}
+
+func (e *Api) MakeService(c *service.Service) *Api {
+	c.Log = e.Logger
+	c.Orm = e.Orm
+	return e
+}
+
+// Error 通常错误数据处理
+func (e *Api) Error(code int, err error, msg string) {
+	response.Error(e.Context, code, err, msg)
+}
+
+// OK 通常成功数据处理
+func (e *Api) OK(data interface{}, msg string) {
+	response.OK(e.Context, data, msg)
+}
+
+// PageOK 分页数据处理
+func (e *Api) PageOK(result interface{}, count int, pageIndex int, pageSize int, msg string) {
+	response.PageOK(e.Context, result, count, pageIndex, pageSize, msg)
+}
+
+// Custom 兼容函数
+func (e *Api) Custom(data gin.H) {
+	response.Custum(e.Context, data)
+}
diff --git a/common/const/enum/ad_userinfo_transferopen/ad_userinfo_transferopen.go b/common/const/enum/ad_userinfo_transferopen/ad_userinfo_transferopen.go
new file mode 100644
index 0000000..1da468e
--- /dev/null
+++ b/common/const/enum/ad_userinfo_transferopen/ad_userinfo_transferopen.go
@@ -0,0 +1,7 @@
+package ad_userinfo_transferopen
+
+// 用户是否开启内部转账功能
+const (
+	Close = 1 // 关闭
+	Open  = 3 // 开启
+)
diff --git a/common/const/enum/agent_account_source/agent_account_source.go b/common/const/enum/agent_account_source/agent_account_source.go
new file mode 100644
index 0000000..a06811c
--- /dev/null
+++ b/common/const/enum/agent_account_source/agent_account_source.go
@@ -0,0 +1,6 @@
+package agent_account_source
+
+const (
+	UserRegister   = 1 // 用户注册
+	SystemRegister = 3 // 系统添加
+)
diff --git a/common/const/enum/agent_account_status/agent_account_status.go b/common/const/enum/agent_account_status/agent_account_status.go
new file mode 100644
index 0000000..38db931
--- /dev/null
+++ b/common/const/enum/agent_account_status/agent_account_status.go
@@ -0,0 +1,7 @@
+package agent_account_status
+
+const (
+	Wait    = 1 // 待审核
+	Audited = 3 // 已通过
+	Reject  = 5 // 已拒绝
+)
diff --git a/common/const/enum/agent_reward_category/agent_reward_category.go b/common/const/enum/agent_reward_category/agent_reward_category.go
new file mode 100644
index 0000000..cc07fa6
--- /dev/null
+++ b/common/const/enum/agent_reward_category/agent_reward_category.go
@@ -0,0 +1,6 @@
+package agent_reward_category
+
+const (
+	Straight = 1 // 直客佣金
+	Agent    = 3 // 代理佣金
+)
diff --git a/common/const/enum/businesstype/businesstype.go b/common/const/enum/businesstype/businesstype.go
new file mode 100644
index 0000000..c2f6813
--- /dev/null
+++ b/common/const/enum/businesstype/businesstype.go
@@ -0,0 +1,96 @@
+package businesstype
+
+// BusinessType 操作业务
+type BusinessType int
+
+const (
+	// 注册登录业务
+	Other          BusinessType = 0  // 其他
+	Register       BusinessType = 1  // 注册
+	Login          BusinessType = 2  // 登入
+	ResetPass      BusinessType = 3  // 找回密码
+	ChangePassword BusinessType = 4  // 更改密码
+	ScanLogin      BusinessType = 14 // 扫码登入
+
+	// 身份验证专用业务类型(请勿占用)
+	OpenPhoneAuth    BusinessType = 11
+	ChangePhoneAuth  BusinessType = 21
+	ClosePhoneAuth   BusinessType = 31
+	OpenEmailAuth    BusinessType = 12
+	ChangeEmailAuth  BusinessType = 22
+	CloseEmailAuth   BusinessType = 32
+	OpenGoogleAuth   BusinessType = 13
+	ChangeGoogleAuth BusinessType = 23
+	CloseGoogleAuth  BusinessType = 33
+
+	//提现验证使用
+	WithdrawAuth BusinessType = 201
+	//userkey验证
+	UserKeyAuth BusinessType = 202
+	//地址浦
+	AddAddress BusinessType = 203
+
+	// 以下请从 100 开始定义
+	OtcCaptcha          BusinessType = 100 // OTC 验证码
+	AddPayAccount       BusinessType = 101 // 新增收款账号
+	EditPayAccount      BusinessType = 102 // 编辑收款账号
+	OTCSellerConfirmPay BusinessType = 103 // OTC 卖家已确认收款
+	OTCSellerAppeal     BusinessType = 104 // OTC 买家申诉
+	OTCBuyerPaid        BusinessType = 105 // OTC 买家已付款
+	OTCBuyerAppeal      BusinessType = 106 // OTC 买家申诉
+	AgentEmailCode      BusinessType = 107 // 代理商找回密码验证码
+)
+
+// 业务类型中文映射
+var BusinessTypeMapCN = map[BusinessType]string{
+	Other:          "其它",
+	Register:       "注册",
+	Login:          "登录",
+	ResetPass:      "重置密码",
+	ChangePassword: "修改登录密码",
+
+	OpenPhoneAuth:    "开启手机验证",
+	ChangePhoneAuth:  "更改手机验证",
+	ClosePhoneAuth:   "关闭手机验证",
+	OpenEmailAuth:    "开启邮箱验证",
+	ChangeEmailAuth:  "更改邮箱验证",
+	CloseEmailAuth:   "关闭邮箱验证",
+	OpenGoogleAuth:   "开启谷歌验证",
+	ChangeGoogleAuth: "更改谷歌验证",
+	CloseGoogleAuth:  "关闭谷歌验证",
+
+	WithdrawAuth: "提现验证",
+	UserKeyAuth:  "api验证",
+	AddAddress:   "新增地址浦验证",
+
+	OtcCaptcha:     "OTC验证码",
+	AddPayAccount:  "新增收款账号",
+	EditPayAccount: "编辑收款账号",
+}
+
+// 业务类型英文映射
+var BusinessTypeMapEN = map[BusinessType]string{
+	Other:          "Other",
+	Register:       "Register",
+	Login:          "Login",
+	ResetPass:      "Reset Password",
+	ChangePassword: "Change Login Password",
+
+	OpenPhoneAuth:    "Enable mobile phone verification",
+	ChangePhoneAuth:  "Change phone verification",
+	ClosePhoneAuth:   "Turn off phone verification",
+	OpenEmailAuth:    "Enable mailbox verification",
+	ChangeEmailAuth:  "Change mailbox validation",
+	CloseEmailAuth:   "Turn off mailbox verification",
+	OpenGoogleAuth:   "Turn on Google Authentication",
+	ChangeGoogleAuth: "Change Google Authentication",
+	CloseGoogleAuth:  "Turn off Google Authentication",
+
+	WithdrawAuth: "Withdraw Auth",
+	UserKeyAuth:  "UserKey Auth",
+	AddAddress:   "AddAddress Auth",
+
+	OtcCaptcha:     "otc phone verification",
+	AddPayAccount:  "otc add payaccount",
+	EditPayAccount: "otc edit payaccount",
+}
diff --git a/common/const/enum/cointype/cointype.go b/common/const/enum/cointype/cointype.go
new file mode 100644
index 0000000..a4cf9f8
--- /dev/null
+++ b/common/const/enum/cointype/cointype.go
@@ -0,0 +1,8 @@
+package cointype
+
+// cointype
+const (
+	BTC  int = 1 // BTC
+	USDT int = 2 // USDT
+	USD  int = 3 // USD
+)
diff --git a/common/const/enum/culatortype/calculatortype.go b/common/const/enum/culatortype/calculatortype.go
new file mode 100644
index 0000000..9e45528
--- /dev/null
+++ b/common/const/enum/culatortype/calculatortype.go
@@ -0,0 +1,10 @@
+package culatortype
+
+// CulatorType 计算器
+const (
+	Income      int = 1 // 收益
+	TargetPrice int = 2 // 目标价格
+	FlatPrice   int = 3 // 强平价格
+	OpenEable   int = 4 // 可开
+	OpenPrice   int = 5 // 开仓价格
+)
diff --git a/common/const/enum/dealtype/dealtype.go b/common/const/enum/dealtype/dealtype.go
new file mode 100644
index 0000000..d9e33f1
--- /dev/null
+++ b/common/const/enum/dealtype/dealtype.go
@@ -0,0 +1,39 @@
+package dealtype
+
+// DealType 资金小类型:1买单,2卖单,3手续费,4划转(废弃),5已实现盈亏,6爆仓精算,7资金费用  13内部转入 14 内部转出 101现货划转合约  102 合约划转现货 103 现货转法币 104 法币转现货 105 币本位划转现货  106 现货划转到币本位
+// 说明: 13-106之间不能插入其他数值
+const (
+	Buy          int = 1   // 1买单
+	Sell         int = 2   // 2卖单
+	BrokerAge    int = 3   // 手续费
+	Transfer     int = 4   // 划转(废弃)
+	Profited     int = 5   // 已实现盈亏
+	LossFee      int = 6   // 爆仓精算
+	FundFee      int = 7   // 资金费用
+	InTransfer   int = 13  // 内部转入
+	OutTransfer  int = 14  // 内部转出
+	VtsToFut     int = 101 // 现货划转合约
+	FutToVts     int = 102 // 合约转现货
+	VtsToOtc     int = 103 // 现货转法币
+	OtcToVts     int = 104 // 法币转现货
+	FutCoinToVts int = 105 // 币本位划转现货
+	VtsToFutCoin int = 106 // 现货划转到币本位
+)
+
+var Types = map[int]string{
+	Buy:          "买单",
+	Sell:         "卖单",
+	BrokerAge:    "手续费",
+	Transfer:     "划转",
+	Profited:     "已实现盈亏",
+	LossFee:      "爆仓精算",
+	FundFee:      "资金费用",
+	InTransfer:   "内部转入",
+	OutTransfer:  "内部转出",
+	VtsToFut:     "现货划转合约",
+	FutToVts:     "合约转现货",
+	VtsToOtc:     "现货转法币",
+	OtcToVts:     "法币转现货",
+	FutCoinToVts: "币本位划转现货",
+	VtsToFutCoin: "现货划转到币本位",
+}
diff --git a/common/const/enum/enable/enable.go b/common/const/enum/enable/enable.go
new file mode 100644
index 0000000..af6168f
--- /dev/null
+++ b/common/const/enum/enable/enable.go
@@ -0,0 +1,7 @@
+package enable
+
+// 是否启用(通用)
+const (
+	Disable = 1 // 禁用
+	Enable  = 3 // 启用
+)
diff --git a/common/const/enum/fut_coin_type/fut_coin_type.go b/common/const/enum/fut_coin_type/fut_coin_type.go
new file mode 100644
index 0000000..5dacba8
--- /dev/null
+++ b/common/const/enum/fut_coin_type/fut_coin_type.go
@@ -0,0 +1,6 @@
+package fut_coin_type
+
+const (
+	USDT = 1 // U本位
+	COIN = 2 // 币本位
+)
diff --git a/common/const/enum/grid_buytype/grid_buytype.go b/common/const/enum/grid_buytype/grid_buytype.go
new file mode 100644
index 0000000..7e321d1
--- /dev/null
+++ b/common/const/enum/grid_buytype/grid_buytype.go
@@ -0,0 +1,7 @@
+package grid_buytype
+
+// 交易网格买卖类型
+const (
+	Buy  = 1 // 买
+	Sell = 2 // 卖
+)
diff --git a/common/const/enum/grid_createtype/grid_createtype.go b/common/const/enum/grid_createtype/grid_createtype.go
new file mode 100644
index 0000000..9a339c1
--- /dev/null
+++ b/common/const/enum/grid_createtype/grid_createtype.go
@@ -0,0 +1,7 @@
+package grid_createtype
+
+// 交易网格创建方式
+const (
+	OneCreation    = 1 // 一键创建
+	ManualCreation = 2 // 手动创建
+)
diff --git a/common/const/enum/grid_dealtype/grid_dealtype.go b/common/const/enum/grid_dealtype/grid_dealtype.go
new file mode 100644
index 0000000..d21ae00
--- /dev/null
+++ b/common/const/enum/grid_dealtype/grid_dealtype.go
@@ -0,0 +1,8 @@
+package grid_dealtype
+
+// 交易网格资金流水类型
+const (
+	Occupy  = 1 // 策略占用
+	Release = 2 // 策略释放
+	Profit  = 3 // 策略利润
+)
diff --git a/common/const/enum/grid_netmode/grid_netmode.go b/common/const/enum/grid_netmode/grid_netmode.go
new file mode 100644
index 0000000..9208d36
--- /dev/null
+++ b/common/const/enum/grid_netmode/grid_netmode.go
@@ -0,0 +1,7 @@
+package grid_netmode
+
+// 现货交易网格模式
+const (
+	EqualRatio      = 1 // 等比
+	EqualDifference = 2 // 等差
+)
diff --git a/common/const/enum/grid_spotorder_status/grid_spotorder_status.go b/common/const/enum/grid_spotorder_status/grid_spotorder_status.go
new file mode 100644
index 0000000..b93a446
--- /dev/null
+++ b/common/const/enum/grid_spotorder_status/grid_spotorder_status.go
@@ -0,0 +1,9 @@
+package grid_spotorder_status
+
+// 现货交易网格委托单状态
+const (
+	UnDeal   = 1 // 未成交
+	Partial  = 2 // 部分成交
+	Complete = 3 // 完成成交
+	Cancel   = 4 // 取消
+)
diff --git a/common/const/enum/grid_spotpolicy_state/grid_spotpolicy_state.go b/common/const/enum/grid_spotpolicy_state/grid_spotpolicy_state.go
new file mode 100644
index 0000000..2e10983
--- /dev/null
+++ b/common/const/enum/grid_spotpolicy_state/grid_spotpolicy_state.go
@@ -0,0 +1,13 @@
+package grid_spotpolicy_state
+
+// 现货交易网格状态
+const (
+	Wait       = 1 // 等待触发
+	Starting   = 2 // 正在启动
+	Start      = 3 // 启动完成
+	Stopping   = 4 // 正在停止
+	ManualStop = 5 // 手动停止
+	ProfitStop = 6 // 止盈停止
+	LossStop   = 7 // 止损停止
+	SignalStop = 8 // 信号触发停止
+)
diff --git a/common/const/enum/grid_triggertype/grid_triggertype.go b/common/const/enum/grid_triggertype/grid_triggertype.go
new file mode 100644
index 0000000..5dd7536
--- /dev/null
+++ b/common/const/enum/grid_triggertype/grid_triggertype.go
@@ -0,0 +1,7 @@
+package grid_triggertype
+
+// 交易网格触发条件
+const (
+	Immediately = 1 // 立即触发
+	Price       = 2 // 价格触发
+)
diff --git a/common/const/enum/holddaylog_chart_daytype/holddaylog_chart_daytype.go b/common/const/enum/holddaylog_chart_daytype/holddaylog_chart_daytype.go
new file mode 100644
index 0000000..58fd860
--- /dev/null
+++ b/common/const/enum/holddaylog_chart_daytype/holddaylog_chart_daytype.go
@@ -0,0 +1,9 @@
+package holddaylog_chart_daytype
+
+// 1==24小时  3==7天 5==30天 7=3个月
+const (
+	Hour_24 = 1 // 24小时
+	Day_7   = 3 // 7天
+	Day_30  = 5 // 30天
+	Month_3 = 7 // 3个月
+)
diff --git a/common/const/enum/kyctype/kyctype.go b/common/const/enum/kyctype/kyctype.go
new file mode 100644
index 0000000..f728dd1
--- /dev/null
+++ b/common/const/enum/kyctype/kyctype.go
@@ -0,0 +1,54 @@
+package kyctype
+
+// IdCardLevel 身份等级
+type IdCardLevel int
+
+const (
+	// Junior 初级认证
+	Junior IdCardLevel = 1
+
+	// Middle 中级认证
+	Middle IdCardLevel = 2
+
+	// Senior 高级认证
+	Senior IdCardLevel = 3
+)
+
+// IdCardState 审核状态
+type IdCardState int
+
+const (
+	// UnAuth 待审核
+	UnAuth IdCardState = 1
+
+	// AuthFailed 审核失败
+	AuthFailed IdCardState = 2
+
+	// AuthSuccess 审核完成
+	AuthSuccess IdCardState = 3
+)
+
+// IdCardType 审核类型
+type IdCardType int
+
+const (
+	// IdCard 身份证
+	IdCard IdCardType = 1
+
+	// Passport 护照
+	Passport IdCardType = 2
+
+	// Drive 驾照
+	Drive IdCardType = 3
+)
+
+// VerifyType 审核类型
+type VerifyType int
+
+const (
+	// Third 第三方审核
+	Third VerifyType = 1
+
+	// System 系统审核
+	System VerifyType = 2
+)
diff --git a/common/const/enum/language_map.go b/common/const/enum/language_map.go
new file mode 100644
index 0000000..7729775
--- /dev/null
+++ b/common/const/enum/language_map.go
@@ -0,0 +1,13 @@
+package enum
+
+// 语言
+var LanguageMap = map[string]string{
+	"en":    "英语",
+	"jp":    "日本语",
+	"kr":    "韩语",
+	"my":    "马来西亚语",
+	"th":    "泰国语",
+	"vn":    "越南语",
+	"zh-CN": "简体中文",
+	"zh-HK": "繁体中文",
+}
diff --git a/common/const/enum/logtype/logtype.go b/common/const/enum/logtype/logtype.go
new file mode 100644
index 0000000..4f17886
--- /dev/null
+++ b/common/const/enum/logtype/logtype.go
@@ -0,0 +1,24 @@
+package logtype
+
+// LogType 日志类型
+type LogType int
+
+const (
+	Min       LogType = iota // 最小值
+	Login                    // 登入
+	Logout                   // 登出
+	Create                   // 新增
+	Update                   // 编辑
+	Delete                   // 删除
+	ChangePwd                // 修改密码
+	Max                      // 最大值
+)
+
+var LogTypeMap = map[LogType]string{
+	Login:     "登入",
+	Logout:    "登出",
+	Create:    "新增",
+	Update:    "编辑",
+	Delete:    "删除",
+	ChangePwd: "修改密码",
+}
diff --git a/common/const/enum/longshorttype/longshorttype.go b/common/const/enum/longshorttype/longshorttype.go
new file mode 100644
index 0000000..38a950e
--- /dev/null
+++ b/common/const/enum/longshorttype/longshorttype.go
@@ -0,0 +1,7 @@
+package longshorttype
+
+// longshorttype
+const (
+	Long  = 1 // 做多
+	Short = 2 // 做空
+)
diff --git a/common/const/enum/ordertype/ordertype.go b/common/const/enum/ordertype/ordertype.go
new file mode 100644
index 0000000..7b93c83
--- /dev/null
+++ b/common/const/enum/ordertype/ordertype.go
@@ -0,0 +1,10 @@
+package ordertype
+
+//订单类型:1限价,2限价止盈止损,3市价,4止盈止损市价单,5系统强平委托
+const (
+	Limit      = 1 //限价单,下单类型
+	StopLimit  = 2 //止盈止损限价单,下单类型
+	Market     = 3 //市价单,下单类型
+	StopMarket = 4 //止盈止损市价单,下单类型
+	Force      = 5 //系统强平委托
+)
diff --git a/common/const/enum/otc_advaduitstatus/otc_advaduitstatus.go b/common/const/enum/otc_advaduitstatus/otc_advaduitstatus.go
new file mode 100644
index 0000000..c69d78e
--- /dev/null
+++ b/common/const/enum/otc_advaduitstatus/otc_advaduitstatus.go
@@ -0,0 +1,8 @@
+package otc_advaduitstatus
+
+// otc广告审核状态
+const (
+	Pending = 1 // 待审核
+	Pass    = 3 // 审核通过
+	Reject  = 5 // 审核拒绝
+)
diff --git a/common/const/enum/otc_advertisetype/otc_advertisetype.go b/common/const/enum/otc_advertisetype/otc_advertisetype.go
new file mode 100644
index 0000000..dd2bef3
--- /dev/null
+++ b/common/const/enum/otc_advertisetype/otc_advertisetype.go
@@ -0,0 +1,7 @@
+package otc_advertisetype
+
+// 广告类型
+const (
+	Buy  = 1 // 购买
+	Sell = 3 // 出售
+)
diff --git a/common/const/enum/otc_advstatus/otc_advstatus.go b/common/const/enum/otc_advstatus/otc_advstatus.go
new file mode 100644
index 0000000..eeb3a4d
--- /dev/null
+++ b/common/const/enum/otc_advstatus/otc_advstatus.go
@@ -0,0 +1,7 @@
+package otc_advstatus
+
+// otc广告状态
+const (
+	Offline = 1 // 下线
+	Online  = 3 // 上线
+)
diff --git a/common/const/enum/otc_appealprogress/otc_appealprogress.go b/common/const/enum/otc_appealprogress/otc_appealprogress.go
new file mode 100644
index 0000000..041eb4b
--- /dev/null
+++ b/common/const/enum/otc_appealprogress/otc_appealprogress.go
@@ -0,0 +1,10 @@
+package otc_appealprogress
+
+//申诉进程
+const (
+	WaitDefendantProcess = 1 // 等待被诉方处理
+	WaitAppealProcess    = 3 // 等待申诉方处理
+	Revoked              = 5 // 已撤销
+	WaitCustomer         = 7 // 等待客服处理
+	Arbitrated           = 9 // 已仲裁
+)
diff --git a/common/const/enum/otc_appealreason/otc_appealreason.go b/common/const/enum/otc_appealreason/otc_appealreason.go
new file mode 100644
index 0000000..201517d
--- /dev/null
+++ b/common/const/enum/otc_appealreason/otc_appealreason.go
@@ -0,0 +1,19 @@
+package otc_appealreason
+
+// 申诉原因
+const (
+	Paid     = 1 // 我已付款,卖家未放行
+	PayMore  = 3 // 我向卖家多转了钱
+	NotPay   = 5 // 我没有收到买家付款
+	MoneyErr = 7 // 买家付款金额不对
+	Other    = 9 // 其他
+
+)
+
+var Types = map[int]string{
+	Paid:     "我已付款,卖家未放行",
+	PayMore:  "我向卖家多转了钱",
+	NotPay:   "我没有收到买家付款",
+	MoneyErr: "买家付款金额不对",
+	Other:    "其他",
+}
diff --git a/common/const/enum/otc_appealstatus/otc_appealstatus.go b/common/const/enum/otc_appealstatus/otc_appealstatus.go
new file mode 100644
index 0000000..fbc7c23
--- /dev/null
+++ b/common/const/enum/otc_appealstatus/otc_appealstatus.go
@@ -0,0 +1,8 @@
+package otc_appealstatus
+
+// otc仲裁状态
+const (
+	Not       = 1 // 未仲裁
+	BuyerWin  = 3 // 买家胜,放行
+	SellerWin = 5 // 卖家胜,取消订单
+)
diff --git a/common/const/enum/otc_auditlevel/otc_auditlevel.go b/common/const/enum/otc_auditlevel/otc_auditlevel.go
new file mode 100644
index 0000000..db14462
--- /dev/null
+++ b/common/const/enum/otc_auditlevel/otc_auditlevel.go
@@ -0,0 +1,6 @@
+package otc_auditlevel
+
+// 商家认证等级
+const (
+	Certified = 3 // 认证商家
+)
diff --git a/common/const/enum/otc_chatlogsourcetype/otc_sourcetype.go b/common/const/enum/otc_chatlogsourcetype/otc_sourcetype.go
new file mode 100644
index 0000000..fa64c84
--- /dev/null
+++ b/common/const/enum/otc_chatlogsourcetype/otc_sourcetype.go
@@ -0,0 +1,8 @@
+package otc_chatlogsourcetype
+
+// 消息来源
+const (
+	Android = 1
+	Ios     = 3
+	Pc      = 5
+)
diff --git a/common/const/enum/otc_chatlogstatus/otc_chatlogstatus.go b/common/const/enum/otc_chatlogstatus/otc_chatlogstatus.go
new file mode 100644
index 0000000..fc44e22
--- /dev/null
+++ b/common/const/enum/otc_chatlogstatus/otc_chatlogstatus.go
@@ -0,0 +1,7 @@
+package otc_chatlogstatus
+
+// 聊天发送状态
+const (
+	Fail    = 1 // 发送失败
+	Success = 3 // 发送成功
+)
diff --git a/common/const/enum/otc_chattype/otc_chattype.go b/common/const/enum/otc_chattype/otc_chattype.go
new file mode 100644
index 0000000..4bcd157
--- /dev/null
+++ b/common/const/enum/otc_chattype/otc_chattype.go
@@ -0,0 +1,8 @@
+package otc_chattype
+
+// 通讯软件类型
+const (
+	Telegram = 1
+	Wechat   = 3
+	QQ       = 5
+)
diff --git a/common/const/enum/otc_complaint/otc_complaint.go b/common/const/enum/otc_complaint/otc_complaint.go
new file mode 100644
index 0000000..0469b11
--- /dev/null
+++ b/common/const/enum/otc_complaint/otc_complaint.go
@@ -0,0 +1,7 @@
+package otc_complaint
+
+// otc申诉方
+const (
+	Buyer  = 1 // 买方
+	Seller = 3 // 卖方
+)
diff --git a/common/const/enum/otc_consult/otc_consult.go b/common/const/enum/otc_consult/otc_consult.go
new file mode 100644
index 0000000..c90b7d0
--- /dev/null
+++ b/common/const/enum/otc_consult/otc_consult.go
@@ -0,0 +1,8 @@
+package otc_consult
+
+// otc协商结果
+const (
+	Not        = 1 // 未协商
+	Unable     = 3 // 无法协商
+	Negotiated = 5 // 协商解决
+)
diff --git a/common/const/enum/otc_holdlogdealtype/otc_holdlogdealtype.go b/common/const/enum/otc_holdlogdealtype/otc_holdlogdealtype.go
new file mode 100644
index 0000000..891f2a2
--- /dev/null
+++ b/common/const/enum/otc_holdlogdealtype/otc_holdlogdealtype.go
@@ -0,0 +1,20 @@
+package otc_holdlogdealtype
+
+// otc 资金类型
+const (
+	Buy                = 1   // 买入
+	Sell               = 3   // 卖出
+	Frozen             = 7   // 冻结
+	AppendBond         = 9   // 追加保证金
+	UnFreeze           = 11  // 解冻
+	Deduct             = 13  // 扣除保证金
+	VtsToOtc           = 103 // 现货转法币
+	OtcToVts           = 104 // 法币转现货
+	Buckle             = 105 // 划扣
+	SaleAdviserAdd     = 201 // 出售广告添加
+	SaleAdviserEdit    = 203 // 出售广告编辑
+	MerchantUnVerify   = 205 // 商家解除认证  保证金将解除冻结
+	MerchantAdd        = 207 // 法币商家新增
+	MerchantEdit       = 209 // 法币商家编辑
+	MerchantFrozenBond = 210 // 法币商家冻结保证金
+)
diff --git a/common/const/enum/otc_holdstatus/otc_holdstatus.go b/common/const/enum/otc_holdstatus/otc_holdstatus.go
new file mode 100644
index 0000000..c2f2ddc
--- /dev/null
+++ b/common/const/enum/otc_holdstatus/otc_holdstatus.go
@@ -0,0 +1,7 @@
+package otc_holdstatus
+
+// otc 账户状态
+const (
+	Frozen = 1 // 冻结
+	Normal = 3 // 正常
+)
diff --git a/common/const/enum/otc_linktype/otc_linktype.go b/common/const/enum/otc_linktype/otc_linktype.go
new file mode 100644
index 0000000..ef94149
--- /dev/null
+++ b/common/const/enum/otc_linktype/otc_linktype.go
@@ -0,0 +1,8 @@
+package otc_linktype
+
+// 紧急联系人类型
+const (
+	Family    = 1 // 家人
+	Friend    = 3 // 朋友
+	Colleague = 5 // 同事
+)
diff --git a/common/const/enum/otc_merchantout_status/otc_merchantout_status.go b/common/const/enum/otc_merchantout_status/otc_merchantout_status.go
new file mode 100644
index 0000000..89ebdc2
--- /dev/null
+++ b/common/const/enum/otc_merchantout_status/otc_merchantout_status.go
@@ -0,0 +1,7 @@
+package otc_merchantout_status
+
+const (
+	Wait     = 1 // 待处理
+	Passed   = 3 // 已通过
+	Rejected = 5 // 不通过
+)
diff --git a/common/const/enum/otc_merchantstatus/otc_merchantstatus.go b/common/const/enum/otc_merchantstatus/otc_merchantstatus.go
new file mode 100644
index 0000000..2cf6f82
--- /dev/null
+++ b/common/const/enum/otc_merchantstatus/otc_merchantstatus.go
@@ -0,0 +1,11 @@
+package otc_merchantstatus
+
+// otc商家状态:1 申请中,3 不通过,5 正常,7 已禁用,9 已解除认证
+const (
+	Applying     = 1  // 申请中
+	Fail         = 3  // 不通过
+	Normal       = 5  // 正常
+	Disabled     = 7  // 已禁用
+	Revoked      = 9  // 已解除认证
+	BondNoEnough = 11 // 保证金不足
+)
diff --git a/common/const/enum/otc_msgtype/otc_msgtype.go b/common/const/enum/otc_msgtype/otc_msgtype.go
new file mode 100644
index 0000000..ab84273
--- /dev/null
+++ b/common/const/enum/otc_msgtype/otc_msgtype.go
@@ -0,0 +1,7 @@
+package otc_msgtype
+
+// otc 聊天消息类型
+const (
+	Text  = 1 // 文本
+	Image = 3 // 图片
+)
diff --git a/common/const/enum/otc_orderstatus/otc_orderstatus.go b/common/const/enum/otc_orderstatus/otc_orderstatus.go
new file mode 100644
index 0000000..509345c
--- /dev/null
+++ b/common/const/enum/otc_orderstatus/otc_orderstatus.go
@@ -0,0 +1,9 @@
+package otc_orderstatus
+
+const (
+	UnPay     = 1 // 未付款
+	WaitMoney = 3 // 待放币
+	Complete  = 5 // 已完成
+	Complain  = 7 // 申诉中
+	Cancel    = 9 // 已取消
+)
diff --git a/common/const/enum/otc_ordertype/otc_ordertype.go b/common/const/enum/otc_ordertype/otc_ordertype.go
new file mode 100644
index 0000000..f641860
--- /dev/null
+++ b/common/const/enum/otc_ordertype/otc_ordertype.go
@@ -0,0 +1,7 @@
+package otc_ordertype
+
+// 订单方向
+const (
+	Buy  = 1 // 买
+	Sell = 3 // 卖
+)
diff --git a/common/const/enum/otc_pricetype/otc_pricetype.go b/common/const/enum/otc_pricetype/otc_pricetype.go
new file mode 100644
index 0000000..7eb0381
--- /dev/null
+++ b/common/const/enum/otc_pricetype/otc_pricetype.go
@@ -0,0 +1,7 @@
+package otc_pricetype
+
+//定价方式
+const (
+	Fix   = 1 // 固定价格
+	Float = 3 // 浮动价格
+)
diff --git a/common/const/enum/otc_progress/otc_progress.go b/common/const/enum/otc_progress/otc_progress.go
new file mode 100644
index 0000000..3e18701
--- /dev/null
+++ b/common/const/enum/otc_progress/otc_progress.go
@@ -0,0 +1,10 @@
+package otc_progress
+
+// otc申诉进程
+const (
+	WaitSellerHandle = 1 // 等待卖家处理
+	WaitBuyerHandle  = 3 // 等待买家处理
+	Revoked          = 5 // 已撤销申诉
+	WaitCustomer     = 7 // 等待客服处理
+	Arbitrated       = 9 // 已仲裁
+)
diff --git a/common/const/enum/otc_rateway/otc_rateway.go b/common/const/enum/otc_rateway/otc_rateway.go
new file mode 100644
index 0000000..8bed66a
--- /dev/null
+++ b/common/const/enum/otc_rateway/otc_rateway.go
@@ -0,0 +1,7 @@
+package otc_rateway
+
+//浮动方式
+const (
+	Up   = 1 // 上浮
+	Down = 3 // 下浮
+)
diff --git a/common/const/enum/otc_tradetype/otc_tradetype.go b/common/const/enum/otc_tradetype/otc_tradetype.go
new file mode 100644
index 0000000..8a36099
--- /dev/null
+++ b/common/const/enum/otc_tradetype/otc_tradetype.go
@@ -0,0 +1,7 @@
+package otc_tradetype
+
+// 交易区
+const (
+	Fast = 1 // 快捷区
+	Self = 3 // 自选区
+)
diff --git a/common/const/enum/showhide/showhide.go b/common/const/enum/showhide/showhide.go
new file mode 100644
index 0000000..b78e9c0
--- /dev/null
+++ b/common/const/enum/showhide/showhide.go
@@ -0,0 +1,7 @@
+package showhide
+
+// 是否隐藏账号(通用)
+const (
+	Hide = 1 // 隐藏
+	Show = 3 // 显示
+)
diff --git a/common/const/enum/smstemplate/sms_template.go b/common/const/enum/smstemplate/sms_template.go
new file mode 100644
index 0000000..6343e6d
--- /dev/null
+++ b/common/const/enum/smstemplate/sms_template.go
@@ -0,0 +1,25 @@
+package smstemplate
+
+// 短信模板 Key 命名规则:SmsTemplate_BusinessType_Language
+const (
+	// 通用业务模板 - 中文
+	SmsTemplate_1_CN = "您正在进行【${business}】,验证码:${code},5分钟内有效,请勿泄露给任何人。如非本人操作请立即联系官方客服。"
+	// 通用业务模板 - 英文
+	SmsTemplate_1_EN = "Are you doing [${business}] Verification code: ${code}, valid within 5 minutes, please do not disclose it to anyone."
+	// 卖家已确认收款_CN
+	SmsTemplate_2_CN = "订单号 ${ordersn},卖家已确认收款,订单已完成,请前往账户查收资产。"
+	// 卖家已确认收款_EN
+	SmsTemplate_2_EN = "Order number ${ordersn}, the seller has confirmed the payment, the order has been completed, please go to the account to check the assets."
+	// 卖家申诉_CN
+	SmsTemplate_3_CN = "订单号 ${ordersn},卖家已发起申诉,请尽快前往处理该订单申诉。"
+	// 卖家申诉_EN
+	SmsTemplate_3_EN = "Order number ${ordersn}, the seller has initiated an appeal, please go to the appeal as soon as possible."
+	// 买家已付款_CN
+	SmsTemplate_4_CN = "订单号 ${ordersn},买家已付款,请查收款项进行放行。"
+	// 买家已付款_EN
+	SmsTemplate_4_EN = "Order number ${ordersn}, the buyer has paid, please check the payment for release."
+	// 买家申诉_CN
+	SmsTemplate_5_CN = "订单号 ${ordersn},买家已发起申诉,请尽快处理该订单申诉。"
+	// 买家申诉_EN
+	SmsTemplate_5_EN = "Order number ${ordersn}, the buyer has initiated an appeal, please handle the order appeal as soon as possible."
+)
diff --git a/common/const/enum/transfertype/transfertype.go b/common/const/enum/transfertype/transfertype.go
new file mode 100644
index 0000000..9fd7520
--- /dev/null
+++ b/common/const/enum/transfertype/transfertype.go
@@ -0,0 +1,10 @@
+package transfertype
+
+const (
+	Vts2Fut     = 1 // 现货划转合约
+	Fut2Vts     = 2 // 合约划转现货
+	Vts2Otc     = 3 // 现货划转Otc
+	Otc2Vts     = 4 // Otc划转现货
+	FutCoin2Vts = 5 // 币本位划转现货
+	Vts2FutCoin = 6 // 现货划转到币本位
+)
diff --git a/common/const/enum/usefree/usefreee.go b/common/const/enum/usefree/usefreee.go
new file mode 100644
index 0000000..e3998c6
--- /dev/null
+++ b/common/const/enum/usefree/usefreee.go
@@ -0,0 +1,7 @@
+package usefree
+
+// usefree
+const (
+	Available = 1 // 可用
+	Frozen    = 2 // 冻结
+)
diff --git a/common/const/enum/vts_alertset_frequency/vts_alertset_frequency.go b/common/const/enum/vts_alertset_frequency/vts_alertset_frequency.go
new file mode 100644
index 0000000..4808903
--- /dev/null
+++ b/common/const/enum/vts_alertset_frequency/vts_alertset_frequency.go
@@ -0,0 +1,8 @@
+package vts_alertset_frequency
+
+// frequency 提醒频率
+const (
+	OnlyOnce = 1 // 仅提醒一次
+	OnceDay  = 2 // 每日提醒一次
+	Always   = 3 // 持续提醒(每当价格达到该值,则提醒一次)
+)
diff --git a/common/const/enum/vts_alertset_state/vts_alertset_state.go b/common/const/enum/vts_alertset_state/vts_alertset_state.go
new file mode 100644
index 0000000..261967f
--- /dev/null
+++ b/common/const/enum/vts_alertset_state/vts_alertset_state.go
@@ -0,0 +1,7 @@
+package vts_alertset_state
+
+// state 设置状态
+const (
+	Normal = 1 // 正常
+	Stop   = 2 // 停止(比如频率是只提醒一次,提醒一次完就修改为2)
+)
diff --git a/common/const/enum/vts_alertset_type/vts_alertset_type.go b/common/const/enum/vts_alertset_type/vts_alertset_type.go
new file mode 100644
index 0000000..0be5009
--- /dev/null
+++ b/common/const/enum/vts_alertset_type/vts_alertset_type.go
@@ -0,0 +1,11 @@
+package vts_alertset_type
+
+// alerttype 预警类型
+const (
+	RisesAbove     = 1 //1 价格涨到
+	DropTo         = 2 //2 价格跌到
+	ChangeOver     = 3 //3 涨幅达到
+	ChangeUnder    = 4 //4 跌幅达到
+	H24ChangeOver  = 5 //5 h24小时涨幅
+	H24ChangeUnder = 6 //6 h24小时跌幅
+)
diff --git a/common/const/enum/warehousetype/warehousetype.go b/common/const/enum/warehousetype/warehousetype.go
new file mode 100644
index 0000000..cba0599
--- /dev/null
+++ b/common/const/enum/warehousetype/warehousetype.go
@@ -0,0 +1,43 @@
+package warehousetype
+
+// WareHouse
+const (
+	Isolated = 1 // 逐仓
+	Cross    = 2 // 全仓
+)
+
+// DirectHouse 持仓模式
+const (
+	OneWayMode = 1 // 单向持仓
+	HedgeMode  = 2 // 双向持仓
+)
+
+// 下单持仓类型 1开多 2平多 3开空 4平空
+const (
+	BuyLong   = iota + 1 // 开多
+	SellLog              // 平多
+	SellShort            // 开空
+	BuyShort             // 平空
+)
+
+const (
+	BOTH  = "both"
+	LONG  = "long"
+	SHORT = "short"
+)
+
+var (
+	PosSide = []string{BOTH, LONG, SHORT} // 持仓方向集合
+)
+
+const (
+	Buy  = 1 // 下单方向买
+	Sell = 2 // 下单方向卖
+)
+const (
+	PositionTypeOpen      = 1 // 开仓
+	PositionTypeCloseOpen = 2 // 反向开仓
+	PositionTypeClose     = 3 // 平仓
+	PositionTypeForce     = 4 // 系统强平
+	PositionTypeSysClose  = 5 // 系统平仓
+)
diff --git a/common/const/enum/yesno/yesno.go b/common/const/enum/yesno/yesno.go
new file mode 100644
index 0000000..d0f7dee
--- /dev/null
+++ b/common/const/enum/yesno/yesno.go
@@ -0,0 +1,7 @@
+package yesno
+
+// 是否(通用)
+const (
+	No  = 1 // 否
+	Yes = 3 // 是
+)
diff --git a/common/const/rediskey/redis_key.go b/common/const/rediskey/redis_key.go
new file mode 100644
index 0000000..b0f9251
--- /dev/null
+++ b/common/const/rediskey/redis_key.go
@@ -0,0 +1,62 @@
+package rediskey
+
+const (
+	IPPositionCache     = "_IPPositionCache"        // IP 归属地缓存
+	AppLoginUserToken   = "_AppLoginUserToken_%d"   // App登录用户的Token {uid}
+	AgentLoginUserToken = "_AgentLoginUserToken_%d" // PC端代理商登录用户的Token
+	AgentEmailCode      = "_AgentEmailCode_%d"
+	AdminLoginUserToken = "_AdminLoginUserToken_%d"   // 后台登录用户的Token {uid}
+	PCLoginUserToken    = "_PCLoginUserToken_%d"      // PC端登录token
+	UserLoginPwdErrFre  = "_UserLoginPwdErrFre_%d"    // 用户登录密码错误次数 {uid}
+	UserCaptchaSendFre  = "_UserCaptchaSendFre_%v_%d" // 用户验证码发送频次 {uid|ip}_{business}
+	UserLoginWsClient   = "_UserLoginWsClient"        // websocket连接的客户端
+	ScanLoginSecret     = "_ScanLoginSecret_%v"       // 扫码登录秘钥
+	StatusCodeLanguage  = "_StatusCodeLanguage_%v"    // 状态码语言包_en
+	PCRegisterEmail     = "_PCRegister_%v"            // 用户注册时邮箱key
+	PCRegisterMobile    = "_PCRegisterMobile_%v"      // 用户注册时手机key
+	SpotSymbolTicker    = "_SpotSymbolTicker_"        // 现货交易对行情
+	FutSymbolTicker     = "_FutSymbolTicker_"         // 合约交易对行情
+	PreOrderScriptList  = "_ProOrderScriptList_"      // 脚本执行list
+	PreSpotOrderList    = "_PreSpotOrderList_:%s"     // 待触发的现货订单集合{交易所类型 exchange_type}
+	PreFutOrderList     = "_PreFutOrderList_:%s"      // 待触发的订单集合 {交易所类型 exchange_type}
+
+	API_USER      = "api_user:%v"    // api用户
+	SystemSetting = "system_setting" //系统设置
+	ApiGroup      = "api_group:%v"   //api用户组 {id}
+	ApiGroupAll   = "api_group:"
+
+	ApiUserActiveList = "api_user_active_list" //已启用待连接websocket的api
+	ApiUserDeleteList = "api_user_delete_list" //已删除待删除的api
+
+	FutStopTrigger  = "fut_trigger_stop_lock:%v_%s"  //合约止损触发锁
+	SpotStopTrigger = "spot_trigger_stop_lock:%v_%s" //现货止损触发锁
+
+	SpotAddPositionTrigger = "spot_addposition_trigger:%v_%s" //现货加仓触发 {apiuserid|symbol}
+	FutAddPositionTrigger  = "fut_addposition_trigger:%v_%s"  //合约加仓触发 {apiuserid|symbol}
+	SpotTrigger            = "spot_trigger_lock:%v_%s"        //现货触发 {apiuserid|symbol}
+	FutTrigger             = "fut_trigger_lock:%v_%s"         //合约触发 {apiuserid|symbol}
+
+	SpotCallBack = "spot_callback:%s" //现货回调 {ordersn}
+	FutCallBack  = "fut_callback:%s"  //合约回调 {ordersn}
+
+	//需要清理键值---------BEGIN---------------
+
+	UserHolding = "api_user_hold:%v" //用户持仓币种 {主单apiid} 不是交易对
+
+	SpotHedgeClosePosition    = "spot_hedge_close_position:%v_%s"    //现货对冲平仓 {mainorderid|symbol}
+	FuturesHedgeClosePosition = "futures_hedge_close_position:%v_%s" //合约对冲平仓 {mainorderid|symbol}
+
+	SpotStopLossList    = "spot_stoploss_list"    //现货止损待触发列表
+	FuturesStopLossList = "futures_stoploss_list" //合约止损待触发列表
+
+	SpotAddPositionList    = "spot_add_position_list"    //现货加仓待触发
+	FuturesAddPositionList = "futures_add_position_list" //合约加仓待触发
+	StoplossMarkt          = "stop_loss_markt"           //对冲保险单(市价) 对冲单成交之后、清除
+
+	HoldeA = "holde_a:%v" //持仓A {主单id}
+	HoldeB = "holde_b:%v" //持仓B {主单id}
+
+	HedgeClosePosition = "hedge_close_position:%v" //对冲平仓记录 {主单id}
+	//需要清理键值---------END-----------------
+
+)
diff --git a/common/const/userlockkey/userlockkey.go b/common/const/userlockkey/userlockkey.go
new file mode 100644
index 0000000..59de16a
--- /dev/null
+++ b/common/const/userlockkey/userlockkey.go
@@ -0,0 +1,28 @@
+package userlockkey
+
+import (
+	"strconv"
+)
+
+var (
+	preOrder = "Order-" //分布式锁现货委托单+划转前缀
+
+	preFutOrder = "futOrder-" //分布式锁u本位--合约委托单+划转前缀
+
+	preFutCoinOrder = "futCoinOrder-" //分布式锁币本位--合约委托单+划转前缀
+)
+
+// GetUserLockKey 分布式锁现货 用户 key
+func GetUserLockKey(userId int) string {
+	return preOrder + strconv.Itoa(userId)
+}
+
+// GetUserFutLockKey u本位--分布式锁合约 用户 key
+func GetUserFutLockKey(userId int) string {
+	return preFutOrder + strconv.Itoa(userId)
+}
+
+// GetUserFutCoinLockKey 币本位--分布式锁合约 用户 key
+func GetUserFutCoinLockKey(userId int) string {
+	return preFutCoinOrder + strconv.Itoa(userId)
+}
diff --git a/common/database/initialize.go b/common/database/initialize.go
new file mode 100644
index 0000000..22e6d61
--- /dev/null
+++ b/common/database/initialize.go
@@ -0,0 +1,65 @@
+package database
+
+import (
+	"time"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	toolsConfig "github.com/go-admin-team/go-admin-core/sdk/config"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	mycasbin "github.com/go-admin-team/go-admin-core/sdk/pkg/casbin"
+	toolsDB "github.com/go-admin-team/go-admin-core/tools/database"
+	. "github.com/go-admin-team/go-admin-core/tools/gorm/logger"
+	"gorm.io/gorm"
+	"gorm.io/gorm/logger"
+	"gorm.io/gorm/schema"
+
+	"go-admin/common/global"
+)
+
+// Setup 配置数据库
+func Setup() {
+	for k := range toolsConfig.DatabasesConfig {
+		setupSimpleDatabase(k, toolsConfig.DatabasesConfig[k])
+	}
+}
+
+func setupSimpleDatabase(host string, c *toolsConfig.Database) {
+	if global.Driver == "" {
+		global.Driver = c.Driver
+	}
+	log.Infof("%s => %s", host, pkg.Green(c.Source))
+	registers := make([]toolsDB.ResolverConfigure, len(c.Registers))
+	for i := range c.Registers {
+		registers[i] = toolsDB.NewResolverConfigure(
+			c.Registers[i].Sources,
+			c.Registers[i].Replicas,
+			c.Registers[i].Policy,
+			c.Registers[i].Tables)
+	}
+	resolverConfig := toolsDB.NewConfigure(c.Source, c.MaxIdleConns, c.MaxOpenConns, c.ConnMaxIdleTime, c.ConnMaxLifeTime, registers)
+	db, err := resolverConfig.Init(&gorm.Config{
+		NamingStrategy: schema.NamingStrategy{
+			SingularTable: true,
+		},
+		Logger: New(
+			logger.Config{
+				SlowThreshold: time.Second,
+				Colorful:      true,
+				LogLevel: logger.LogLevel(
+					log.DefaultLogger.Options().Level.LevelForGorm()),
+			},
+		),
+	}, opens[c.Driver])
+
+	if err != nil {
+		log.Fatal(pkg.Red(c.Driver+" connect error :"), err)
+	} else {
+		log.Info(pkg.Green(c.Driver + " connect success !"))
+	}
+
+	e := mycasbin.Setup(db, "")
+
+	sdk.Runtime.SetDb(host, db)
+	sdk.Runtime.SetCasbin(host, e)
+}
diff --git a/common/database/open.go b/common/database/open.go
new file mode 100644
index 0000000..de02868
--- /dev/null
+++ b/common/database/open.go
@@ -0,0 +1,16 @@
+//go:build !sqlite3
+
+package database
+
+import (
+	"gorm.io/driver/mysql"
+	"gorm.io/driver/postgres"
+	"gorm.io/driver/sqlserver"
+	"gorm.io/gorm"
+)
+
+var opens = map[string]func(string) gorm.Dialector{
+	"mysql":     mysql.Open,
+	"postgres":  postgres.Open,
+	"sqlserver": sqlserver.Open,
+}
diff --git a/common/database/open_sqlite3.go b/common/database/open_sqlite3.go
new file mode 100644
index 0000000..aaebe94
--- /dev/null
+++ b/common/database/open_sqlite3.go
@@ -0,0 +1,19 @@
+//go:build sqlite3
+// +build sqlite3
+
+package database
+
+import (
+	"gorm.io/driver/mysql"
+	"gorm.io/driver/postgres"
+	"gorm.io/driver/sqlite"
+	"gorm.io/driver/sqlserver"
+	"gorm.io/gorm"
+)
+
+var opens = map[string]func(string) gorm.Dialector{
+	"mysql":     mysql.Open,
+	"postgres":  postgres.Open,
+	"sqlite3":   sqlite.Open,
+	"sqlserver": sqlserver.Open,
+}
diff --git a/common/dto/api_group.go b/common/dto/api_group.go
new file mode 100644
index 0000000..a4332f5
--- /dev/null
+++ b/common/dto/api_group.go
@@ -0,0 +1,8 @@
+package dto
+
+type ApiGroupDto struct {
+	Id             int    `json:"id"`
+	Name           string `json:"name"`
+	ApiUserId      int    `json:"apiUserId"`
+	ChildApiUserId int    `json:"childApiUserId"`
+}
diff --git a/common/dto/auto_form.go b/common/dto/auto_form.go
new file mode 100644
index 0000000..c99976a
--- /dev/null
+++ b/common/dto/auto_form.go
@@ -0,0 +1,74 @@
+package dto
+
+type AutoForm struct {
+	Fields        []Field `json:"fields"`
+	FormRef       string  `json:"formRef"`
+	FormModel     string  `json:"formModel"`
+	Size          string  `json:"size"`
+	LabelPosition string  `json:"labelPosition"`
+	LabelWidth    int     `json:"labelWidth"`
+	FormRules     string  `json:"formRules"`
+	Gutter        int     `json:"gutter"`
+	Disabled      bool    `json:"disabled"`
+	Span          int     `json:"span"`
+	FormBtns      bool    `json:"formBtns"`
+}
+
+type Config struct {
+	Label        string        `json:"label"`
+	LabelWidth   interface{}   `json:"labelWidth"`
+	ShowLabel    bool          `json:"showLabel"`
+	ChangeTag    bool          `json:"changeTag"`
+	Tag          string        `json:"tag"`
+	TagIcon      string        `json:"tagIcon"`
+	Required     bool          `json:"required"`
+	Layout       string        `json:"layout"`
+	Span         int           `json:"span"`
+	Document     string        `json:"document"`
+	RegList      []interface{} `json:"regList"`
+	FormId       int           `json:"formId"`
+	RenderKey    int64         `json:"renderKey"`
+	DefaultValue interface{}   `json:"defaultValue"`
+	ShowTip      bool          `json:"showTip,omitempty"`
+	ButtonText   string        `json:"buttonText,omitempty"`
+	FileSize     int           `json:"fileSize,omitempty"`
+	SizeUnit     string        `json:"sizeUnit,omitempty"`
+}
+
+type Option struct {
+	Label string `json:"label"`
+	Value string `json:"value"`
+}
+
+type Slot struct {
+	Prepend  string   `json:"prepend,omitempty"`
+	Append   string   `json:"append,omitempty"`
+	ListType bool     `json:"list-type,omitempty"`
+	Options  []Option `json:"options,omitempty"`
+}
+
+type Field struct {
+	Config        Config      `json:"__config__"`
+	Slot          Slot        `json:"__slot__"`
+	Placeholder   string      `json:"placeholder,omitempty"`
+	Style         Style       `json:"style,omitempty"`
+	Clearable     bool        `json:"clearable,omitempty"`
+	PrefixIcon    string      `json:"prefix-icon,omitempty"`
+	SuffixIcon    string      `json:"suffix-icon,omitempty"`
+	Maxlength     interface{} `json:"maxlength"`
+	ShowWordLimit bool        `json:"show-word-limit,omitempty"`
+	Readonly      bool        `json:"readonly,omitempty"`
+	Disabled      bool        `json:"disabled"`
+	VModel        string      `json:"__vModel__"`
+	Action        string      `json:"action,omitempty"`
+	Accept        string      `json:"accept,omitempty"`
+	Name          string      `json:"name,omitempty"`
+	AutoUpload    bool        `json:"auto-upload,omitempty"`
+	ListType      string      `json:"list-type,omitempty"`
+	Multiple      bool        `json:"multiple,omitempty"`
+	Filterable    bool        `json:"filterable,omitempty"`
+}
+
+type Style struct {
+	Width string `json:"width"`
+}
diff --git a/common/dto/generate.go b/common/dto/generate.go
new file mode 100644
index 0000000..313ae6a
--- /dev/null
+++ b/common/dto/generate.go
@@ -0,0 +1,106 @@
+package dto
+
+import (
+	vd "github.com/bytedance/go-tagexpr/v2/validator"
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+)
+
+type ObjectById struct {
+	Id  int   `uri:"id"`
+	Ids []int `json:"ids"`
+}
+
+func (s *ObjectById) Bind(ctx *gin.Context) error {
+	var err error
+	log := api.GetRequestLogger(ctx)
+	err = ctx.ShouldBindUri(s)
+	if err != nil {
+		log.Warnf("ShouldBindUri error: %s", err.Error())
+		return err
+	}
+	if ctx.Request.Method == http.MethodDelete {
+		err = ctx.ShouldBind(&s)
+		if err != nil {
+			log.Warnf("ShouldBind error: %s", err.Error())
+			return err
+		}
+		if len(s.Ids) > 0 {
+			return nil
+		}
+		if s.Ids == nil {
+			s.Ids = make([]int, 0)
+		}
+		if s.Id != 0 {
+			s.Ids = append(s.Ids, s.Id)
+		}
+	}
+	if err = vd.Validate(s); err != nil {
+		log.Errorf("Validate error: %s", err.Error())
+		return err
+	}
+	return err
+}
+
+func (s *ObjectById) GetId() interface{} {
+	if len(s.Ids) > 0 {
+		s.Ids = append(s.Ids, s.Id)
+		return s.Ids
+	}
+	return s.Id
+}
+
+type ObjectGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *ObjectGetReq) Bind(ctx *gin.Context) error {
+	var err error
+	log := api.GetRequestLogger(ctx)
+	err = ctx.ShouldBindUri(s)
+	if err != nil {
+		log.Warnf("ShouldBindUri error: %s", err.Error())
+		return err
+	}
+	if err = vd.Validate(s); err != nil {
+		log.Errorf("Validate error: %s", err.Error())
+		return err
+	}
+	return err
+}
+
+func (s *ObjectGetReq) GetId() interface{} {
+	return s.Id
+}
+
+type ObjectDeleteReq struct {
+	Ids []int `json:"ids"`
+}
+
+func (s *ObjectDeleteReq) Bind(ctx *gin.Context) error {
+	var err error
+	log := api.GetRequestLogger(ctx)
+	err = ctx.ShouldBind(&s)
+	if err != nil {
+		log.Warnf("ShouldBind error: %s", err.Error())
+		return err
+	}
+	if len(s.Ids) > 0 {
+		return nil
+	}
+	if s.Ids == nil {
+		s.Ids = make([]int, 0)
+	}
+
+	if err = vd.Validate(s); err != nil {
+		log.Errorf("Validate error: %s", err.Error())
+		return err
+	}
+	return err
+}
+
+func (s *ObjectDeleteReq) GetId() interface{} {
+	return s.Ids
+}
diff --git a/common/dto/order.go b/common/dto/order.go
new file mode 100644
index 0000000..25455fb
--- /dev/null
+++ b/common/dto/order.go
@@ -0,0 +1,12 @@
+package dto
+
+import (
+	"gorm.io/gorm"
+	"gorm.io/gorm/clause"
+)
+
+func OrderDest(sort string, bl bool) func(db *gorm.DB) *gorm.DB {
+	return func(db *gorm.DB) *gorm.DB {
+		return db.Order(clause.OrderByColumn{Column: clause.Column{Name: sort}, Desc: bl})
+	}
+}
diff --git a/common/dto/pagination.go b/common/dto/pagination.go
new file mode 100644
index 0000000..ee438e5
--- /dev/null
+++ b/common/dto/pagination.go
@@ -0,0 +1,20 @@
+package dto
+
+type Pagination struct {
+	PageIndex int `form:"pageIndex"`
+	PageSize  int `form:"pageSize"`
+}
+
+func (m *Pagination) GetPageIndex() int {
+	if m.PageIndex <= 0 {
+		m.PageIndex = 1
+	}
+	return m.PageIndex
+}
+
+func (m *Pagination) GetPageSize() int {
+	if m.PageSize <= 0 {
+		m.PageSize = 10
+	}
+	return m.PageSize
+}
diff --git a/common/dto/search.go b/common/dto/search.go
new file mode 100644
index 0000000..72cc60e
--- /dev/null
+++ b/common/dto/search.go
@@ -0,0 +1,84 @@
+package dto
+
+import (
+	"github.com/go-admin-team/go-admin-core/tools/search"
+	"go-admin/common/global"
+	"gorm.io/gorm"
+)
+
+type GeneralDelDto struct {
+	Id  int   `uri:"id" json:"id" validate:"required"`
+	Ids []int `json:"ids"`
+}
+
+func (g GeneralDelDto) GetIds() []int {
+	ids := make([]int, 0)
+	if g.Id != 0 {
+		ids = append(ids, g.Id)
+	}
+	if len(g.Ids) > 0 {
+		for _, id := range g.Ids {
+			if id > 0 {
+				ids = append(ids, id)
+			}
+		}
+	} else {
+		if g.Id > 0 {
+			ids = append(ids, g.Id)
+		}
+	}
+	if len(ids) <= 0 {
+		//方式全部删除
+		ids = append(ids, 0)
+	}
+	return ids
+}
+
+type GeneralGetDto struct {
+	Id int `uri:"id" json:"id" validate:"required"`
+}
+
+func MakeCondition(q interface{}) func(db *gorm.DB) *gorm.DB {
+	return func(db *gorm.DB) *gorm.DB {
+		condition := &search.GormCondition{
+			GormPublic: search.GormPublic{},
+			Join:       make([]*search.GormJoin, 0),
+		}
+		search.ResolveSearchQuery(global.Driver, q, condition)
+		for _, join := range condition.Join {
+			if join == nil {
+				continue
+			}
+			db = db.Joins(join.JoinOn)
+			for k, v := range join.Where {
+				db = db.Where(k, v...)
+			}
+			for k, v := range join.Or {
+				db = db.Or(k, v...)
+			}
+			for _, o := range join.Order {
+				db = db.Order(o)
+			}
+		}
+		for k, v := range condition.Where {
+			db = db.Where(k, v...)
+		}
+		for k, v := range condition.Or {
+			db = db.Or(k, v...)
+		}
+		for _, o := range condition.Order {
+			db = db.Order(o)
+		}
+		return db
+	}
+}
+
+func Paginate(pageSize, pageIndex int) func(db *gorm.DB) *gorm.DB {
+	return func(db *gorm.DB) *gorm.DB {
+		offset := (pageIndex - 1) * pageSize
+		if offset < 0 {
+			offset = 0
+		}
+		return db.Offset(offset).Limit(pageSize)
+	}
+}
diff --git a/common/dto/type.go b/common/dto/type.go
new file mode 100644
index 0000000..e029943
--- /dev/null
+++ b/common/dto/type.go
@@ -0,0 +1,21 @@
+package dto
+
+import (
+	"github.com/gin-gonic/gin"
+	"go-admin/common/models"
+)
+
+type Index interface {
+	Generate() Index
+	Bind(ctx *gin.Context) error
+	GetPageIndex() int
+	GetPageSize() int
+	GetNeedSearch() interface{}
+}
+
+type Control interface {
+	Generate() Control
+	Bind(ctx *gin.Context) error
+	GenerateM() (models.ActiveRecord, error)
+	GetId() interface{}
+}
diff --git a/common/file_store/initialize.go b/common/file_store/initialize.go
new file mode 100644
index 0000000..fabce9f
--- /dev/null
+++ b/common/file_store/initialize.go
@@ -0,0 +1,45 @@
+package file_store
+
+import "fmt"
+
+type OXS struct {
+	// Endpoint 访问域名
+	Endpoint string
+	// AccessKeyID AK
+	AccessKeyID string
+	// AccessKeySecret AKS
+	AccessKeySecret string
+	// BucketName 桶名称
+	BucketName string
+}
+
+// Setup 配置文件存储driver
+func (e *OXS) Setup(driver DriverType, options ...ClientOption) FileStoreType {
+	fileStoreType := driver
+	var fileStore FileStoreType
+	switch fileStoreType {
+	case AliYunOSS:
+		fileStore = new(ALiYunOSS)
+		err := fileStore.Setup(e.Endpoint, e.AccessKeyID, e.AccessKeySecret, e.BucketName)
+		if err != nil {
+			fmt.Println(err)
+		}
+		return fileStore
+	case HuaweiOBS:
+		fileStore = new(HuaWeiOBS)
+		err := fileStore.Setup(e.Endpoint, e.AccessKeyID, e.AccessKeySecret, e.BucketName)
+		if err != nil {
+			fmt.Println(err)
+		}
+		return fileStore
+	case QiNiuKodo:
+		fileStore = new(QiNiuKODO)
+		err := fileStore.Setup(e.Endpoint, e.AccessKeyID, e.AccessKeySecret, e.BucketName)
+		if err != nil {
+			fmt.Println(err)
+		}
+		return fileStore
+	}
+
+	return nil
+}
diff --git a/common/file_store/interface.go b/common/file_store/interface.go
new file mode 100644
index 0000000..acecbe9
--- /dev/null
+++ b/common/file_store/interface.go
@@ -0,0 +1,27 @@
+package file_store
+
+// DriverType 驱动类型
+type DriverType string
+
+const (
+	// HuaweiOBS 华为云OBS
+	HuaweiOBS DriverType = "HuaweiOBS"
+	// AliYunOSS 阿里云OSS
+	AliYunOSS DriverType = "AliYunOSS"
+	// QiNiuKodo 七牛云kodo
+	QiNiuKodo DriverType = "QiNiuKodo"
+)
+
+type ClientOption map[string]interface{}
+
+// TODO: FileStoreType名称待定
+
+// FileStoreType OXS
+type FileStoreType interface {
+	// Setup 装载 endpoint sss
+	Setup(endpoint, accessKeyID, accessKeySecret, BucketName string, options ...ClientOption) error
+	// UpLoad 上传
+	UpLoad(yourObjectName string, localFile interface{}) error
+	// GetTempToken 获取临时Token
+	GetTempToken() (string, error)
+}
diff --git a/common/file_store/kodo.go b/common/file_store/kodo.go
new file mode 100644
index 0000000..db896e2
--- /dev/null
+++ b/common/file_store/kodo.go
@@ -0,0 +1,111 @@
+package file_store
+
+import (
+	"context"
+	"fmt"
+	"github.com/qiniu/go-sdk/v7/auth/qbox"
+	"github.com/qiniu/go-sdk/v7/storage"
+)
+
+type Zone string
+
+const (
+	// HuaDong 华东
+	HuaDong Zone = "HuaDong"
+	// HuaBei 华北
+	HuaBei Zone = "HuaBei"
+	// HuaNan 华南
+	HuaNan Zone = "HuaNan"
+	// BeiMei 北美
+	BeiMei Zone = "BeiMei"
+	// XinJiaPo 新加坡
+	XinJiaPo Zone = "XinJiaPo"
+)
+
+type QiNiuKODO struct {
+	Client     interface{}
+	BucketName string
+	cfg        storage.Config
+	options    []ClientOption
+}
+
+func (e *QiNiuKODO) getToken() string {
+	putPolicy := storage.PutPolicy{
+		Scope: e.BucketName,
+	}
+	if len(e.options) > 0 && e.options[0]["Expires"] != nil {
+		putPolicy.Expires = e.options[0]["Expires"].(uint64)
+	}
+	upToken := putPolicy.UploadToken(e.Client.(*qbox.Mac))
+	return upToken
+}
+
+//Setup 装载
+//endpoint sss
+func (e *QiNiuKODO) Setup(endpoint, accessKeyID, accessKeySecret, BucketName string, options ...ClientOption) error {
+
+	mac := qbox.NewMac(accessKeyID, accessKeySecret)
+	// 获取存储空间。
+	cfg := storage.Config{}
+	// 空间对应的机房
+	e.setZoneORDefault(cfg, options...)
+	// 是否使用https域名
+	cfg.UseHTTPS = true
+	// 上传是否使用CDN上传加速
+	cfg.UseCdnDomains = false
+
+	e.Client = mac
+	e.BucketName = BucketName
+	e.cfg = cfg
+	e.options = options
+	return nil
+}
+
+// setZoneORDefault 设置Zone或者默认华东
+func (e *QiNiuKODO) setZoneORDefault(cfg storage.Config, options ...ClientOption) {
+	if len(options) > 0 && options[0]["Zone"] != nil {
+		if _, ok := options[0]["Zone"].(Zone); !ok {
+			cfg.Zone = &storage.ZoneHuadong
+		}
+		switch options[0]["Zone"].(Zone) {
+		case HuaDong:
+			cfg.Zone = &storage.ZoneHuadong
+		case HuaBei:
+			cfg.Zone = &storage.ZoneHuabei
+		case HuaNan:
+			cfg.Zone = &storage.ZoneHuanan
+		case BeiMei:
+			cfg.Zone = &storage.ZoneBeimei
+		case XinJiaPo:
+			cfg.Zone = &storage.ZoneXinjiapo
+		default:
+			cfg.Zone = &storage.ZoneHuadong
+		}
+	}
+}
+
+// UpLoad 文件上传
+func (e *QiNiuKODO) UpLoad(yourObjectName string, localFile interface{}) error {
+
+	// 构建表单上传的对象
+	formUploader := storage.NewFormUploader(&e.cfg)
+	ret := storage.PutRet{}
+	// 可选配置
+	putExtra := storage.PutExtra{
+		Params: map[string]string{
+			"x:name": "github logo",
+		},
+	}
+	err := formUploader.PutFile(context.Background(), &ret, e.getToken(), yourObjectName, localFile.(string), &putExtra)
+	if err != nil {
+		fmt.Println(err)
+		return err
+	}
+	fmt.Println(ret.Key, ret.Hash)
+	return nil
+}
+
+func (e *QiNiuKODO) GetTempToken() (string, error) {
+	token := e.getToken()
+	return token, nil
+}
diff --git a/common/file_store/kodo_test.go b/common/file_store/kodo_test.go
new file mode 100644
index 0000000..a8767ae
--- /dev/null
+++ b/common/file_store/kodo_test.go
@@ -0,0 +1,23 @@
+package file_store
+
+import (
+	"testing"
+)
+
+func TestKODOUpload(t *testing.T) {
+	e := OXS{"", "", "", ""}
+	var oxs = e.Setup(QiNiuKodo, map[string]interface{}{"Zone": "华东"})
+	err := oxs.UpLoad("test.png", "./test.png")
+	if err != nil {
+		t.Error(err)
+	}
+	t.Log("ok")
+}
+
+func TestKODOGetTempToken(t *testing.T) {
+	e := OXS{"", "", "", ""}
+	var oxs = e.Setup(QiNiuKodo, map[string]interface{}{"Zone": "华东"})
+	token, _ := oxs.GetTempToken()
+	t.Log(token)
+	t.Log("ok")
+}
diff --git a/common/file_store/obs.go b/common/file_store/obs.go
new file mode 100644
index 0000000..e937729
--- /dev/null
+++ b/common/file_store/obs.go
@@ -0,0 +1,52 @@
+package file_store
+
+import (
+	"fmt"
+	"github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
+	"log"
+)
+
+type HuaWeiOBS struct {
+	Client     interface{}
+	BucketName string
+}
+
+func (e *HuaWeiOBS) Setup(endpoint, accessKeyID, accessKeySecret, BucketName string, options ...ClientOption) error {
+	// 创建ObsClient结构体
+	client, err := obs.New(accessKeyID, accessKeySecret, endpoint)
+	if err != nil {
+		log.Println("Error:", err)
+		return err
+	}
+	e.Client = client
+	e.BucketName = BucketName
+	return nil
+}
+
+// UpLoad 文件上传
+// yourObjectName 文件路径名称,与objectKey是同一概念,表示断点续传上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg
+func (e *HuaWeiOBS) UpLoad(yourObjectName string, localFile interface{}) error {
+	// 获取存储空间。
+	input := &obs.PutFileInput{}
+	input.Bucket = e.BucketName
+	input.Key = yourObjectName
+	input.SourceFile = localFile.(string)
+	output, err := e.Client.(*obs.ObsClient).PutFile(input)
+
+	if err == nil {
+		fmt.Printf("RequestId:%s\n", output.RequestId)
+		fmt.Printf("ETag:%s, StorageClass:%s\n", output.ETag, output.StorageClass)
+	} else {
+		if obsError, ok := err.(obs.ObsError); ok {
+			fmt.Println(obsError.Code)
+			fmt.Println(obsError.Message)
+		} else {
+			fmt.Println(err)
+		}
+	}
+	return nil
+}
+
+func (e *HuaWeiOBS) GetTempToken() (string, error) {
+	return "", nil
+}
diff --git a/common/file_store/obs_test.go b/common/file_store/obs_test.go
new file mode 100644
index 0000000..0960750
--- /dev/null
+++ b/common/file_store/obs_test.go
@@ -0,0 +1,15 @@
+package file_store
+
+import (
+	"testing"
+)
+
+func TestOBSUpload(t *testing.T) {
+	e := OXS{"", "", "", ""}
+	var oxs = e.Setup(HuaweiOBS)
+	err := oxs.UpLoad("test.png", "./test.png")
+	if err != nil {
+		t.Error(err)
+	}
+	t.Log("ok")
+}
diff --git a/common/file_store/oss.go b/common/file_store/oss.go
new file mode 100644
index 0000000..c35627b
--- /dev/null
+++ b/common/file_store/oss.go
@@ -0,0 +1,48 @@
+package file_store
+
+import (
+	"github.com/aliyun/aliyun-oss-go-sdk/oss"
+	"log"
+)
+
+type ALiYunOSS struct {
+	Client     interface{}
+	BucketName string
+}
+
+//Setup 装载
+//endpoint sss
+func (e *ALiYunOSS) Setup(endpoint, accessKeyID, accessKeySecret, BucketName string, options ...ClientOption) error {
+	client, err := oss.New(endpoint, accessKeyID, accessKeySecret)
+	if err != nil {
+		log.Println("Error:", err)
+		return err
+	}
+	e.Client = client
+	e.BucketName = BucketName
+
+	return nil
+}
+
+// UpLoad 文件上传
+func (e *ALiYunOSS) UpLoad(yourObjectName string, localFile interface{}) error {
+	// 获取存储空间。
+	bucket, err := e.Client.(*oss.Client).Bucket(e.BucketName)
+	if err != nil {
+		log.Println("Error:", err)
+		return err
+	}
+	// 设置分片大小为100 KB,指定分片上传并发数为3,并开启断点续传上传。
+	// 其中与objectKey是同一概念,表示断点续传上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
+	// "LocalFile"为filePath,100*1024为partSize。
+	err = bucket.UploadFile(yourObjectName, localFile.(string), 100*1024, oss.Routines(3), oss.Checkpoint(true, ""))
+	if err != nil {
+		log.Println("Error:", err)
+		return err
+	}
+	return nil
+}
+
+func (e *ALiYunOSS) GetTempToken() (string, error) {
+	return "", nil
+}
diff --git a/common/file_store/oss_test.go b/common/file_store/oss_test.go
new file mode 100644
index 0000000..f04dd22
--- /dev/null
+++ b/common/file_store/oss_test.go
@@ -0,0 +1,16 @@
+package file_store
+
+import (
+	"testing"
+)
+
+func TestOSSUpload(t *testing.T) {
+	// 打括号内填写自己的测试信息即可
+	e := OXS{}
+	var oxs = e.Setup(AliYunOSS)
+	err := oxs.UpLoad("test.png", "./test.png")
+	if err != nil {
+		t.Error(err)
+	}
+	t.Log("ok")
+}
diff --git a/common/global/adm.go b/common/global/adm.go
new file mode 100644
index 0000000..ff26a0a
--- /dev/null
+++ b/common/global/adm.go
@@ -0,0 +1,20 @@
+package global
+
+const (
+	// Version go-admin version info
+	Version = "2.1.2"
+)
+
+var (
+	// Driver 数据库驱动
+	Driver string
+)
+
+const (
+	//钱包 回调配置
+	SYS_CONFIG_CALLBACK = "CoinGateCallBack"
+	//钱包 取消配置
+	SYS_CONFIG_CANCECL = "CoinGateCancel"
+	////钱包 成功配置
+	SYS_CONFIG_SUCCESS = "CoinGateSuccess"
+)
diff --git a/common/global/casbin.go b/common/global/casbin.go
new file mode 100644
index 0000000..72b7e6c
--- /dev/null
+++ b/common/global/casbin.go
@@ -0,0 +1,18 @@
+package global
+
+import (
+	"github.com/casbin/casbin/v2"
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+)
+
+func LoadPolicy(c *gin.Context) (*casbin.SyncedEnforcer, error) {
+	log := api.GetRequestLogger(c)
+	if err := sdk.Runtime.GetCasbinKey(c.Request.Host).LoadPolicy(); err == nil {
+		return sdk.Runtime.GetCasbinKey(c.Request.Host), err
+	} else {
+		log.Errorf("casbin rbac_model or policy init error, %s ", err.Error())
+		return nil, err
+	}
+}
diff --git a/common/global/coingate.go b/common/global/coingate.go
new file mode 100644
index 0000000..1c86417
--- /dev/null
+++ b/common/global/coingate.go
@@ -0,0 +1,25 @@
+package global
+
+const (
+	//内部生成默认状态
+	COINGATE_STATUS_DEFAULT = "default"
+
+	//新创建的发票。购物者尚未选择付款货币。
+	COINGATE_STATUS_NEW = "new"
+	//	购物者已选择支付货币。正在等待付款
+	COINGATE_STATUS_PENDING = "pending"
+	//购物者已转账支付发票款项。正在等待区块链网络确认。
+	COINGATE_STATUS_CONFIRMING = "confirming"
+	//付款已由网络确认,并记入商家账户。购买的商品/服务可以安全地交付给购物者。
+	COINGATE_STATUS_PAID = "paid"
+	//由于 AML/CTF 合规原因,付款被网络拒绝或被标记为无效
+	COINGATE_STATUS_INVALID = "invalid"
+	//购物者未在规定时间内付款(默认值:20 分钟),因此发票已过期。
+	COINGATE_STATUS_EXPIRED = "expired"
+	//购物者取消了发票。
+	COINGATE_STATUS_CANCELED = "canceled"
+	//付款已退还给购物者
+	COINGATE_STATUS_REFUNDED = "refunded"
+	//部分付款已退还给购物者。
+	COINGATE_STATUS_PARTIALLY_REFUNDED = "partially_refunded"
+)
diff --git a/common/global/exchange.go b/common/global/exchange.go
new file mode 100644
index 0000000..4436758
--- /dev/null
+++ b/common/global/exchange.go
@@ -0,0 +1,11 @@
+package global
+
+//交易所类型字典
+const (
+	EXCHANGE_BINANCE  = "binance"
+	EXCHANGE_OKEX     = "okex"
+	EXCHANGE_GATE     = "gate"
+	EXCHANGE_COINBASE = "coinbase"
+	EXCHANGE_BITFINEX = "bitfinex"
+	EXCHANGE_BITMEX   = "bitmex"
+)
diff --git a/common/global/logo.go b/common/global/logo.go
new file mode 100644
index 0000000..e4ed471
--- /dev/null
+++ b/common/global/logo.go
@@ -0,0 +1,4 @@
+package global
+
+// LogoContent go-admin ascii显示,减少静态文件依赖
+var LogoContent = []byte{10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 95, 95, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 44, 45, 45, 45, 44, 32, 32, 32, 32, 32, 32, 32, 32, 44, 39, 32, 32, 44, 32, 96, 46, 32, 32, 44, 45, 45, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 44, 45, 45, 45, 46, 32, 32, 32, 32, 32, 32, 44, 45, 45, 45, 44, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 44, 45, 45, 45, 46, 39, 124, 32, 32, 32, 32, 32, 44, 45, 43, 45, 44, 46, 39, 32, 95, 32, 124, 44, 45, 45, 46, 39, 124, 32, 32, 32, 32, 32, 32, 32, 32, 32, 44, 45, 45, 45, 44, 10, 32, 32, 44, 45, 45, 45, 45, 46, 95, 44, 46, 32, 32, 39, 32, 32, 32, 44, 39, 92, 32, 32, 32, 44, 39, 32, 32, 46, 39, 32, 124, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 124, 32, 32, 32, 124, 32, 58, 32, 32, 44, 45, 43, 45, 46, 32, 59, 32, 32, 32, 44, 32, 124, 124, 124, 32, 32, 124, 44, 32, 32, 32, 32, 32, 32, 44, 45, 43, 45, 46, 32, 47, 32, 32, 124, 10, 32, 47, 32, 32, 32, 47, 32, 32, 39, 32, 47, 32, 47, 32, 32, 32, 47, 32, 32, 32, 124, 44, 45, 45, 45, 46, 39, 32, 32, 32, 44, 32, 44, 45, 45, 46, 45, 45, 46, 32, 32, 32, 32, 32, 32, 124, 32, 32, 32, 124, 32, 124, 32, 44, 45, 45, 46, 39, 124, 39, 32, 32, 32, 124, 32, 32, 124, 124, 96, 45, 45, 39, 95, 32, 32, 32, 32, 32, 44, 45, 45, 46, 39, 124, 39, 32, 32, 32, 124, 10, 124, 32, 32, 32, 58, 32, 32, 32, 32, 32, 124, 46, 32, 32, 32, 59, 32, 44, 46, 32, 58, 124, 32, 32, 32, 124, 32, 32, 32, 32, 124, 47, 32, 32, 32, 32, 32, 32, 32, 92, 32, 32, 32, 44, 45, 45, 46, 95, 95, 124, 32, 124, 124, 32, 32, 32, 124, 32, 32, 44, 39, 44, 32, 124, 32, 32, 124, 44, 44, 39, 32, 44, 39, 124, 32, 32, 32, 124, 32, 32, 32, 124, 32, 32, 44, 34, 39, 32, 124, 10, 124, 32, 32, 32, 124, 32, 46, 92, 32, 32, 46, 39, 32, 32, 32, 124, 32, 124, 58, 32, 58, 58, 32, 32, 32, 58, 32, 32, 46, 39, 46, 45, 45, 46, 32, 32, 46, 45, 46, 32, 124, 32, 47, 32, 32, 32, 44, 39, 32, 32, 32, 124, 124, 32, 32, 32, 124, 32, 47, 32, 32, 124, 32, 124, 45, 45, 39, 32, 39, 32, 32, 124, 32, 124, 32, 32, 32, 124, 32, 32, 32, 124, 32, 47, 32, 32, 124, 32, 124, 10, 46, 32, 32, 32, 59, 32, 39, 59, 32, 32, 124, 39, 32, 32, 32, 124, 32, 46, 59, 32, 58, 58, 32, 32, 32, 124, 46, 39, 32, 32, 32, 92, 95, 95, 92, 47, 58, 32, 46, 32, 46, 46, 32, 32, 32, 39, 32, 32, 47, 32, 32, 124, 124, 32, 32, 32, 58, 32, 124, 32, 32, 124, 32, 44, 32, 32, 32, 32, 124, 32, 32, 124, 32, 58, 32, 32, 32, 124, 32, 32, 32, 124, 32, 124, 32, 32, 124, 32, 124, 10, 39, 32, 32, 32, 46, 32, 32, 32, 46, 32, 124, 124, 32, 32, 32, 58, 32, 32, 32, 32, 124, 96, 45, 45, 45, 39, 32, 32, 32, 32, 32, 44, 34, 32, 46, 45, 45, 46, 59, 32, 124, 39, 32, 32, 32, 59, 32, 124, 58, 32, 32, 124, 124, 32, 32, 32, 58, 32, 124, 32, 32, 124, 47, 32, 32, 32, 32, 32, 39, 32, 32, 58, 32, 124, 95, 95, 32, 124, 32, 32, 32, 124, 32, 124, 32, 32, 124, 47, 10, 32, 96, 45, 45, 45, 96, 45, 39, 124, 32, 124, 32, 92, 32, 32, 32, 92, 32, 32, 47, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 32, 32, 47, 32, 32, 44, 46, 32, 32, 124, 124, 32, 32, 32, 124, 32, 39, 47, 32, 32, 39, 124, 32, 32, 32, 124, 32, 124, 96, 45, 39, 32, 32, 32, 32, 32, 32, 124, 32, 32, 124, 32, 39, 46, 39, 124, 124, 32, 32, 32, 124, 32, 124, 45, 45, 39, 10, 32, 46, 39, 95, 95, 47, 92, 95, 58, 32, 124, 32, 32, 96, 45, 45, 45, 45, 39, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 59, 32, 32, 58, 32, 32, 32, 46, 39, 32, 32, 32, 92, 32, 32, 32, 58, 32, 32, 32, 32, 58, 124, 124, 32, 32, 32, 59, 47, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 59, 32, 32, 58, 32, 32, 32, 32, 59, 124, 32, 32, 32, 124, 47, 10, 32, 124, 32, 32, 32, 58, 32, 32, 32, 32, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 124, 32, 32, 44, 32, 32, 32, 32, 32, 46, 45, 46, 47, 92, 32, 32, 32, 92, 32, 32, 47, 32, 32, 39, 45, 45, 45, 39, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 124, 32, 32, 44, 32, 32, 32, 47, 32, 39, 45, 45, 45, 39, 10, 32, 32, 92, 32, 32, 32, 92, 32, 32, 47, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96, 45, 45, 96, 45, 45, 45, 39, 32, 32, 32, 32, 32, 96, 45, 45, 45, 45, 39, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 96, 45, 39, 10, 32, 32, 32, 96, 45, 45, 96, 45, 39, 10}
diff --git a/common/global/redis_prefix.go b/common/global/redis_prefix.go
new file mode 100644
index 0000000..9549576
--- /dev/null
+++ b/common/global/redis_prefix.go
@@ -0,0 +1,69 @@
+package global
+
+const (
+	//现货
+	SPOT = "1"
+	//合约
+	FUT = "2"
+	//现货-24h行情 {交易所类型code,交易对名称}
+	TICKER_SPOT = "tc_spot:%s:%s"
+	//合约-24h行情 {交易所类型code,交易对名称}
+	TICKER_FUTURES = "tc_fut:%s:%s"
+	//合约-资金费率
+	FUNDING_INFO_FUTURES = "fi_fut"
+	//合约-k线
+	K_FUT = "k_fut"
+	//现货-k线
+	K_SPOT = "k_spot"
+	//代币-配置
+	COIN_DETAIL = "c_spot_detail"
+	//代币-现货24h涨跌幅
+	COIN_PRICE_CHANGE = "c_spot_priceChange"
+	//代币-现货热门排序
+	COIN_HOT_SORT = "c_spot_hot_sort"
+	//代币-现货新币排序
+	COIN_NEW_SORT = "c_spot_new_sort"
+	//代币-现货主流排序
+	COIN_MAIN_SORT = "c_spot_main_sort"
+
+	//代币-合约配置
+	COIN_FUTURES_DETAIL = "c_fut_detail"
+	//代币-合约24h涨跌幅
+	COIN_FUTURES_PRICE_CHANGE = "c_fut_priceChange"
+	//代币-合约热门排序
+	COIN_FUTURES_HOT_SORT = "c_fut_hot_sort"
+	//代币-合约新币排序
+	COIN_FUTURES_NEW_SORT = "c_fut_new_sort"
+	//代币-合约主流排序
+	COIN_FUTURES_MAIN_SORT = "c_fut_main_sort"
+
+	//U本位合约-24h涨跌幅
+	UFUTURES_PRICE_CHANGE = "ufut_priceChange"
+	//币本位合约-24h涨跌幅
+	CFUTURES_PRICE_CHANGE = "cfut_priceChange"
+
+	//用户订阅信息
+	USER_SUBSCRIBE = "user_sub:%s" //{apikey}
+
+	//币种配置
+	RECHARGE_COIN = "recharge_coin"
+)
+
+const (
+	//参数管理
+	SYS_CONFIG = "sys_config"
+	//字典数据
+	DICT_DATA_PREFIX = "dic_list"
+)
+
+const (
+	//api websocket 错误信息
+	API_WEBSOCKET_ERR = "api_ws_err:%s"
+)
+
+const (
+	//交易对-现货
+	SYMBOL_SPOT = 0
+	//交易对-合约
+	SYMBOL_FUTURES = 1
+)
diff --git a/common/global/state.go b/common/global/state.go
new file mode 100644
index 0000000..4cc40ac
--- /dev/null
+++ b/common/global/state.go
@@ -0,0 +1,60 @@
+package global
+
+const (
+	//币种配置-开启交易
+	VTS_COIN_TRADE_Y = 1
+	//币种配置-关闭交易
+	VTS_COIN_TRADE_N = 2
+
+	//币种配置-已上架
+	VTS_STATUS_Y = 3
+	//币种配置-未上架
+	VTS_STATUS_N = 1
+
+	//币种配置-显示在首页-是
+	VTS_SHOW_HOME_Y = 1
+	//币种配置-显示在首页-否
+	VTS_SHOW_HOME_N = 2
+
+	// 币种配置-现货
+	VTS_COIN_CATEGORY_SPOT = 0
+	// 币种配置-合约
+	VTS_COIN_CATEGORY_FUTURES = 1
+)
+
+const (
+	//api 启用
+	AD_API_STATUS_Y = 1
+	//api 禁用
+	AD_API_STATUS_N = 2
+)
+
+const (
+	//代理-http
+	PROXY_TYPE_HTTP = "http"
+	////代理-https
+	PROXY_TYPE_HTTPS = "https"
+	////代理-socks5
+	PROXY_TYPE_SOCKS5 = "socks5"
+)
+
+const (
+	//充值内容 线上钱包
+	TRAN_TYPE_WALLET = 1
+	//充值类型 内部
+	TRAN_TYPE_ADMIN = 2
+)
+
+const (
+	//资金账户状态-正常
+	OTC_HOLD_STATUS_NOMAL = 3
+	//资金账户状态-冻结
+	OTC_HOLD_STATUS_FREEZEN = 1
+)
+
+const (
+	//充值确认状态-未确认
+	RECHARGE_CONFIRM_STATUS_UNCONFIRMED = "un_confirm"
+	//充值确认状态-已确认
+	RECHARGE_CONFIRM_STATUS_CONFIRMED = "confirmed"
+)
diff --git a/common/global/topic.go b/common/global/topic.go
new file mode 100644
index 0000000..60e1d34
--- /dev/null
+++ b/common/global/topic.go
@@ -0,0 +1,7 @@
+package global
+
+const (
+	LoginLog   = "login_log_queue"
+	OperateLog = "operate_log_queue"
+	ApiCheck   = "api_check_queue"
+)
diff --git a/common/helper/binancehttphelper.go b/common/helper/binancehttphelper.go
new file mode 100644
index 0000000..c108a07
--- /dev/null
+++ b/common/helper/binancehttphelper.go
@@ -0,0 +1,282 @@
+package helper
+
+import (
+	"crypto/hmac"
+	"crypto/sha256"
+	"crypto/tls"
+	"encoding/hex"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"reflect"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/shopspring/decimal"
+)
+
+type BinanceClient struct {
+	APIKey      string
+	APISecret   string
+	HTTPClient  *http.Client
+	SpotBaseURL string //现货api地址
+	FutBaseURL  string //合约api地址
+}
+
+// NewBinanceClient creates a new Binance client
+func NewBinanceClient(apiKey, apiSecret string, proxyType, proxyAddr string) (*BinanceClient, error) {
+	// Create HTTP client with transport settings
+	client := &http.Client{
+		Transport: &http.Transport{
+			MaxIdleConns:    1000,
+			IdleConnTimeout: 10 * time.Second, // 设置超时 10 秒
+			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+		},
+	}
+	err := CreateHtppProxy(proxyType, proxyAddr, client)
+
+	if err != nil {
+		return nil, err
+	}
+
+	return &BinanceClient{
+		APIKey:      apiKey,
+		APISecret:   apiSecret,
+		HTTPClient:  client,
+		SpotBaseURL: "https://api.binance.com",
+		FutBaseURL:  "https://fapi.binance.com",
+	}, nil
+}
+
+// Helper to get proxy password from URL
+func getProxyPassword(proxyURL *url.URL) string {
+	if password, ok := proxyURL.User.Password(); ok {
+		return password
+	}
+	return ""
+}
+
+// signRequest generates HMAC SHA256 signature
+func (bc *BinanceClient) signRequest(query string) string {
+	mac := hmac.New(sha256.New, []byte(bc.APISecret))
+	mac.Write([]byte(query))
+	return hex.EncodeToString(mac.Sum(nil))
+}
+
+/*
+binance 现货请求
+
+  - @endpoint 路由
+  - @method get、post
+  - @params 参数map
+*/
+func (bc *BinanceClient) SendSpotRequest(endpoint string, method string, params map[string]string) ([]byte, int, error) {
+	// Prepare URL
+	reqURL := bc.SpotBaseURL + endpoint
+
+	return bc.SendRequest(reqURL, method, params, 0)
+}
+
+/*
+binance 现货请求
+
+  - @endpoint 路由
+  - @method get、post
+  - @params 参数map
+*/
+func (bc *BinanceClient) SendSpotRequestAuth(endpoint string, method string, params map[string]string) ([]byte, int, error) {
+	// Prepare URL
+	reqURL := bc.SpotBaseURL + endpoint
+
+	return bc.SendRequest(reqURL, method, params, 2)
+}
+
+/*
+binance 现货请求
+
+  - @endpoint 路由
+  - @method get、post
+  - @params 参数map
+*/
+func (bc *BinanceClient) SendSpotAuth(endpoint string, method string, params interface{}) ([]byte, int, error) {
+	// Prepare URL
+	reqURL := bc.SpotBaseURL + endpoint
+
+	return bc.SendRequest(reqURL, method, params, 2)
+}
+
+/*
+binance 现货请求 只需要api key
+
+  - @endpoint 路由
+  - @method get、post
+  - @params 参数map
+*/
+func (bc *BinanceClient) SendSpotRequestByKey(endpoint string, method string, params interface{}) ([]byte, int, error) {
+	// Prepare URL
+	reqURL := bc.SpotBaseURL + endpoint
+
+	return bc.SendRequest(reqURL, method, params, 1)
+}
+
+/*
+binance 合约请求
+
+  - @endpoint 路由
+  - @method get、post
+  - @params 参数map
+*/
+func (bc *BinanceClient) SendFuturesRequest(endpoint string, method string, params map[string]string) ([]byte, int, error) {
+	// Prepare URL
+	reqURL := bc.FutBaseURL + endpoint
+
+	return bc.SendRequest(reqURL, method, params, 0)
+}
+
+/*
+binance 合约请求
+
+  - @endpoint 路由
+  - @method get、post
+  - @params 参数map
+*/
+func (bc *BinanceClient) SendFuturesRequestAuth(endpoint string, method string, params map[string]string) ([]byte, int, error) {
+	// Prepare URL
+	reqURL := bc.FutBaseURL + endpoint
+
+	return bc.SendRequest(reqURL, method, params, 2)
+}
+
+/*
+binance 合约请求
+
+  - @endpoint 路由
+  - @method get、post
+  - @params 参数map
+*/
+func (bc *BinanceClient) SendFuturesRequestByKey(endpoint string, method string, params map[string]string) ([]byte, int, error) {
+	// Prepare URL
+	reqURL := bc.FutBaseURL + endpoint
+
+	return bc.SendRequest(reqURL, method, params, 1)
+}
+
+/*
+binance 合约请求
+
+  - @endpoint 路由
+  - @method get、post
+  - @params 参数map
+*/
+func (bc *BinanceClient) SendFuturesAuth(endpoint string, method string, params interface{}) ([]byte, int, error) {
+	// Prepare URL
+	reqURL := bc.FutBaseURL + endpoint
+
+	return bc.SendRequest(reqURL, method, params, 2)
+}
+
+// SendRequest sends a request to Binance API
+/*
+发送请求
+ - auth 0-不需要 1-只需要key 2-需要key和签名
+*/
+func (bc *BinanceClient) SendRequest(reqURL string, method string, params interface{}, auth int) ([]byte, int, error) {
+	method = strings.ToUpper(method)
+	reqParams := url.Values{}
+
+	// 处理 `params`,如果是 map[string]string 则添加为 URL 参数
+	if paramMap, ok := params.(map[string]string); ok {
+		for k, v := range paramMap {
+			reqParams.Add(k, v)
+		}
+	} else if v := reflect.ValueOf(params); v.Kind() == reflect.Struct {
+		for i := 0; i < v.NumField(); i++ {
+			field := v.Type().Field(i)
+			value := v.Field(i)
+
+			// 获取字段名或 JSON 标签名
+			key := field.Tag.Get("json")
+			if key == "" {
+				key = field.Name // 如果没有 json 标签,使用字段名
+			}
+
+			// 检查字段类型并转换为对应的字符串
+			var strValue string
+			switch value.Kind() {
+			case reflect.String:
+				strValue = value.String()
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				strValue = strconv.FormatInt(value.Int(), 10)
+			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+				strValue = strconv.FormatUint(value.Uint(), 10)
+			case reflect.Float32, reflect.Float64:
+				strValue = strconv.FormatFloat(value.Float(), 'f', -1, 64)
+			case reflect.Bool:
+				strValue = strconv.FormatBool(value.Bool())
+			case reflect.Struct:
+				// 处理 decimal.Decimal 类型
+				if value.Type() == reflect.TypeOf(decimal.Decimal{}) {
+					strValue = value.Interface().(decimal.Decimal).String()
+				} else {
+					continue // 跳过其他 struct 类型
+				}
+			default:
+				continue // 跳过不支持的类型
+			}
+			// 添加到 reqParams
+			reqParams.Add(key, strValue)
+		}
+	}
+
+	// Add timestamp if signature is needed
+	if auth == 2 && bc.APIKey != "" && bc.APISecret != "" {
+		reqParams.Add("timestamp", fmt.Sprintf("%d", time.Now().UnixMilli()))
+		signature := bc.signRequest(reqParams.Encode())
+		reqParams.Add("signature", signature)
+	}
+	// Create HTTP request
+	var req *http.Request
+	var err error
+	if method == http.MethodGet || method == http.MethodDelete {
+		if len(reqParams) > 0 {
+			reqURL = fmt.Sprintf("%s?%s", reqURL, reqParams.Encode())
+		}
+		req, err = http.NewRequest(method, reqURL, nil)
+	} else {
+		// req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
+
+		if len(reqParams) > 0 {
+			reqURL = fmt.Sprintf("%s?%s", reqURL, reqParams.Encode())
+		}
+		req, err = http.NewRequest(method, reqURL, nil)
+	}
+	if err != nil {
+		return nil, -1, fmt.Errorf("failed to create request: %w", err)
+	}
+	// Set headers
+	if auth > 0 && bc.APIKey != "" {
+		req.Header.Set("X-MBX-APIKEY", bc.APIKey)
+	}
+	// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+	// Send request
+	resp, err := bc.HTTPClient.Do(req)
+	if err != nil {
+		return nil, -1, fmt.Errorf("failed to send request: %w", err)
+	}
+	defer resp.Body.Close()
+
+	// Read response
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return nil, -1, fmt.Errorf("failed to read response: %w", err)
+	}
+
+	if resp.StatusCode != http.StatusOK {
+		return nil, resp.StatusCode, fmt.Errorf("%s", body)
+	}
+
+	return body, http.StatusOK, nil
+}
diff --git a/common/helper/cache_helper.go b/common/helper/cache_helper.go
new file mode 100644
index 0000000..f65bb55
--- /dev/null
+++ b/common/helper/cache_helper.go
@@ -0,0 +1,139 @@
+package helper
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/bytedance/sonic"
+	"github.com/go-redis/redis/v8"
+)
+
+// CacheFunction 通用缓存装饰器,支持任意函数类型
+func CacheFunctionExpire[T any](fn func(args ...any) (T, error), keyPrefix string, ttl time.Duration) func(args ...any) (T, error) {
+	return func(args ...any) (T, error) {
+		// 创建缓存键,基于函数名和参数
+		cacheKey := fmt.Sprintf("%s:%v", keyPrefix, args)
+
+		// 尝试从 Redis 获取缓存
+		cachedData, err := DefaultRedis.GetString(cacheKey)
+		var zeroT T // 用于返回零值
+		if err == redis.Nil {
+			// 缓存不存在,调用实际函数
+			result, err := fn(args...)
+			if err != nil {
+				return zeroT, err
+			}
+
+			// 将结果序列化并存入 Redis
+			jsonData, err := sonic.Marshal(result)
+			if err != nil {
+				return zeroT, err
+			}
+
+			err = DefaultRedis.SetStringExpire(cacheKey, string(jsonData), ttl)
+			if err != nil {
+				return zeroT, err
+			}
+
+			return result, nil
+		} else if err != nil {
+			return zeroT, err
+		}
+
+		// 缓存命中,反序列化结果
+		var result T
+		err = sonic.Unmarshal([]byte(cachedData), &result)
+		if err != nil {
+			return zeroT, err
+		}
+
+		return result, nil
+	}
+}
+
+// CacheFunction 通用缓存装饰器,支持任意函数类型
+func CacheFunctionNoArgsExpire[T any](fn func() (T, error), keyPrefix string, ttl time.Duration) func() (T, error) {
+	return func() (T, error) {
+		// 创建缓存键,基于函数名和参数
+		cacheKey := keyPrefix
+
+		// 尝试从 Redis 获取缓存
+		cachedData, err := DefaultRedis.GetString(cacheKey)
+		var zeroT T // 用于返回零值
+		if err == redis.Nil {
+			// 缓存不存在,调用实际函数
+			result, err := fn()
+			if err != nil {
+				return zeroT, err
+			}
+
+			// 将结果序列化并存入 Redis
+			jsonData, err := sonic.Marshal(result)
+			if err != nil {
+				return zeroT, err
+			}
+
+			err = DefaultRedis.SetStringExpire(cacheKey, string(jsonData), ttl)
+			if err != nil {
+				return zeroT, err
+			}
+
+			return result, nil
+		} else if err != nil {
+			return zeroT, err
+		}
+
+		// 缓存命中,反序列化结果
+		var result T
+		err = sonic.Unmarshal([]byte(cachedData), &result)
+		if err != nil {
+			return zeroT, err
+		}
+
+		return result, nil
+	}
+}
+
+// DeleteCacheFunction 通用删除缓存装饰器
+func DeleteCacheFunction[T any](fn func(args ...any) (T, error), keyPrefix string) func(args ...any) (T, error) {
+	return func(args ...any) (T, error) {
+		// 调用实际函数
+		result, err := fn(args...)
+		if err != nil {
+			return result, err
+		}
+
+		// 创建缓存键,基于函数名和参数
+		cacheKey := fmt.Sprintf("%s:%v", keyPrefix, args)
+
+		// 从 Redis 删除缓存
+		err = DefaultRedis.DeleteString(cacheKey)
+		if err != nil {
+			return result, fmt.Errorf("failed to delete cache: %w", err)
+		}
+
+		return result, nil
+	}
+}
+
+// DeleteCacheFunction 通用删除缓存装饰器
+func DeleteCacheNoArgsFunction[T any](fn func() (T, error), keyPrefix string) func() (T, error) {
+	return func() (T, error) {
+		// 调用实际函数
+		result, err := fn()
+		if err != nil {
+			return result, err
+		}
+
+		// 创建缓存键,基于函数名和参数
+		cacheKey := keyPrefix
+
+		// 从 Redis 删除缓存
+		err = DefaultRedis.DeleteString(cacheKey)
+		if err != nil {
+			return result, fmt.Errorf("failed to delete cache: %w", err)
+		}
+
+		return result, nil
+	}
+}
diff --git a/common/helper/proxy.go b/common/helper/proxy.go
new file mode 100644
index 0000000..c76a95f
--- /dev/null
+++ b/common/helper/proxy.go
@@ -0,0 +1,79 @@
+package helper
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"net"
+	"net/http"
+	"net/url"
+	"strings"
+
+	"golang.org/x/net/proxy"
+)
+
+/*
+创建代理
+
+  - @proxyType 代理类别 http\https\socks5
+  - @proxyAddr 代理地址 userName:password@endpoint:port
+*/
+func CreateHtppProxy(proxyType, proxyAddr string, client *http.Client) error {
+	// Set up proxy based on type (HTTP, HTTPS, SOCKS5)
+	transport := &http.Transport{}
+	if proxyAddr != "" {
+		if !strings.HasPrefix(proxyAddr, "http://") && !strings.HasPrefix(proxyAddr, "https://") && !strings.HasPrefix(proxyAddr, "socks5://") {
+			proxyAddr = proxyType + "://" + proxyAddr
+		}
+
+		if proxyType == "" {
+			proxyType = strings.Split(proxyAddr, "://")[0]
+		}
+
+		switch proxyType {
+		case "http", "https":
+			proxyURL, err := url.Parse(proxyAddr)
+			if err != nil {
+				return errors.New(fmt.Sprintf("invalid proxy URL: %w", err))
+			}
+			// Check if proxy URL contains credentials
+			if proxyURL.User != nil {
+				username := proxyURL.User.Username()
+				password, _ := proxyURL.User.Password()
+				transport.Proxy = func(req *http.Request) (*url.URL, error) {
+					req.SetBasicAuth(username, password) // Set basic auth headers
+					return proxyURL, nil
+				}
+			} else {
+				transport.Proxy = http.ProxyURL(proxyURL)
+			}
+		case "socks5":
+			proxyURL, err := url.Parse(proxyAddr)
+			if err != nil {
+				return errors.New(fmt.Sprintf("invalid proxy URL: %w", err))
+			}
+
+			var auth *proxy.Auth
+			if proxyURL.User != nil {
+				auth = &proxy.Auth{
+					User:     proxyURL.User.Username(),
+					Password: getProxyPassword(proxyURL),
+				}
+			}
+
+			dialer, err := proxy.SOCKS5("tcp", proxyURL.Host, auth, proxy.Direct)
+			if err != nil {
+				return errors.New(fmt.Sprintf("failed to set up SOCKS5 proxy: %w", err))
+			}
+			transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
+				return dialer.Dial(network, addr)
+			}
+		default:
+			return errors.New(fmt.Sprintf("unsupported proxy type: %s", proxyType))
+		}
+
+		client.Transport = transport
+	}
+
+	return nil
+}
diff --git a/common/helper/redis_helper.go b/common/helper/redis_helper.go
new file mode 100644
index 0000000..903976a
--- /dev/null
+++ b/common/helper/redis_helper.go
@@ -0,0 +1,695 @@
+package helper
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"log"
+	"reflect"
+	"strconv"
+	"time"
+
+	"github.com/bytedance/sonic"
+	"github.com/go-redis/redis/v8"
+)
+
+// RedisHelper 结构体封装了 Redis 客户端及上下文
+type RedisHelper struct {
+	client          *redis.Client   // Redis 客户端
+	ctx             context.Context // 上下文
+	emptyCacheValue string          // 缓存空值的标志
+}
+
+var DefaultRedis *RedisHelper
+
+// 初始化默认链接
+func InitDefaultRedis(addr, password string, db int) {
+	if DefaultRedis == nil {
+		DefaultRedis = NewRedisHelper(addr, password, db)
+	}
+
+	log.Printf("初始化redis链接")
+}
+
+// NewRedisHelper 创建一个新的 RedisHelper 实例
+func NewRedisHelper(addr, password string, db int) *RedisHelper {
+	rdb := redis.NewClient(&redis.Options{
+		Addr:         addr,     // Redis 服务器地址
+		Password:     password, // Redis 密码
+		DB:           db,       // 使用的数据库编号
+		PoolSize:     50,
+		MinIdleConns: 10,
+		DialTimeout:  10 * time.Second, // 调整连接超时时间
+		ReadTimeout:  10 * time.Second, // 调整读超时时间
+		WriteTimeout: 10 * time.Second, // 调整写超时时间
+	})
+
+	return &RedisHelper{
+		client: rdb,
+		ctx:    context.Background(), // 创建背景上下文
+	}
+}
+
+// 测试连接
+func (r *RedisHelper) Ping() error {
+	return r.client.Ping(r.ctx).Err()
+}
+
+// SetString 设置字符串值
+func (r *RedisHelper) SetString(key, value string) error {
+	return r.client.Set(r.ctx, key, value, 0).Err() // 将值存储到指定的键
+}
+
+// 批量设置
+func (r *RedisHelper) BatchSet(maps *map[string]string) error {
+	pipe := r.client.Pipeline()
+
+	for key, val := range *maps {
+		pipe.Set(r.ctx, key, val, 0)
+	}
+
+	_, err := pipe.Exec(r.ctx)
+
+	return err
+}
+
+// SetString 设置字符串值
+func (r *RedisHelper) SetStringExpire(key, value string, expireTime time.Duration) error {
+	return r.client.Set(r.ctx, key, value, expireTime).Err() // 将值存储到指定的键
+}
+
+// SetString 设置字符串值
+func (r *RedisHelper) SetAdd(key, value string, expireTime time.Duration) error {
+	// 存储到 SET 中
+	result, err := r.client.SAdd(r.ctx, key, value).Result()
+	if err != nil {
+		return err
+	}
+
+	if result == 1 {
+		// 设置 SET 的过期时间
+		err = r.client.Expire(r.ctx, key, expireTime).Err()
+		if err != nil {
+			return errors.New("设置过期时间失败:" + err.Error())
+		}
+
+		return nil
+	} else {
+		return errors.New("key已存在")
+	}
+}
+
+// 设置对象
+func SetObjString[T any](r *RedisHelper, key string, value T) error {
+	keyValue, err := sonic.Marshal(value)
+
+	if err != nil {
+		return err
+	}
+
+	return r.SetString(key, string(keyValue))
+}
+
+// 获取对象
+func GetObjString[T any](r *RedisHelper, key string) (T, error) {
+	var result T
+	value, err := r.GetString(key)
+
+	if err != nil {
+		return result, err
+	}
+
+	err = sonic.Unmarshal([]byte(value), &result)
+
+	if err != nil {
+		return result, err
+	}
+
+	return result, nil
+}
+
+func (r *RedisHelper) Get(key string) *redis.StringCmd {
+	return r.client.Get(r.ctx, key)
+}
+
+/*
+获取剩余时间
+  - @key redis key
+*/
+func (r *RedisHelper) TTL(key string) *redis.DurationCmd {
+	return r.client.TTL(r.ctx, key)
+}
+
+// GetString 获取字符串值
+func (r *RedisHelper) GetString(key string) (string, error) {
+	return r.client.Get(r.ctx, key).Result() // 从指定的键获取值
+}
+
+// DeleteString 删除字符串键
+func (r *RedisHelper) DeleteString(key string) error {
+	return r.client.Del(r.ctx, key).Err() // 删除指定的键
+}
+
+// DeleteString 删除目录下所有key
+func (r *RedisHelper) DeleteAll(key string) error {
+	keys, err := r.ScanKeys(key)
+
+	if err != nil {
+		return err
+	}
+
+	_, err = r.BatchDeleteKeys(keys)
+	return err
+}
+
+/*
+递增
+  - @key rediskey
+*/
+func (r *RedisHelper) Incr(key string) *redis.IntCmd {
+	return r.client.Incr(r.ctx, key)
+}
+
+/*
+设置过期时间
+  - @key redis key
+  - @expiration 过期时间
+*/
+func (r *RedisHelper) Expire(key string, expiration time.Duration) *redis.BoolCmd {
+	return r.client.Expire(r.ctx, key, expiration)
+}
+
+/*
+批量删除
+
+  - @keys 键数组
+*/
+func (r *RedisHelper) BatchDeleteKeys(keys []string) (int, error) {
+	if r.client == nil {
+		return 0, errors.New("Redis client is nil")
+	}
+	if len(keys) == 0 {
+		return 0, nil
+	}
+
+	deletedCount := 0
+	batchSize := 1000 // 每批次删除的键数量
+	for i := 0; i < len(keys); i += batchSize {
+		end := i + batchSize
+		if end > len(keys) {
+			end = len(keys)
+		}
+		batch := keys[i:end]
+
+		_, err := r.client.Pipelined(r.ctx, func(pipe redis.Pipeliner) error {
+			for _, key := range batch {
+				pipe.Del(r.ctx, key)
+				deletedCount++
+			}
+			return nil
+		})
+		if err != nil {
+			return deletedCount, fmt.Errorf("failed to delete keys in batch: %v", err)
+		}
+	}
+
+	return deletedCount, nil
+}
+
+// DeleteKeysByPrefix 删除指定前缀的键
+func (r *RedisHelper) DeleteKeysByPrefix(prefixes ...string) error {
+	ctx := context.Background()
+	// 遍历每个前缀
+	for _, prefix := range prefixes {
+		var cursor uint64
+		var keys []string
+
+		// 使用 SCAN 命令查找匹配的键
+		for {
+			var err error
+			keys, cursor, err = r.client.Scan(ctx, cursor, prefix+"*", 1000).Result()
+			if err != nil {
+				return err
+			}
+
+			// 删除匹配的键
+			if len(keys) > 0 {
+				_, err := r.client.Del(ctx, keys...).Result()
+				if err != nil {
+					return err
+				}
+				fmt.Printf("Deleted keys with prefix '%s': %v\n", prefix, keys)
+			}
+
+			// 如果游标为 0,表示迭代结束
+			if cursor == 0 {
+				break
+			}
+		}
+	}
+	return nil
+}
+
+// 查找所有value
+func (r *RedisHelper) GetAllKeysAndValues(pattern string) ([]string, error) {
+	var cursor uint64
+	var result = []string{}
+
+	for {
+		// 使用 SCAN 命令获取匹配的键
+		keys, nextCursor, err := r.client.Scan(r.ctx, cursor, pattern+"*", 1000).Result()
+		if err != nil {
+			log.Printf("Error scanning keys: %v", err)
+			return nil, err
+		}
+
+		// 处理匹配到的键
+		for _, key := range keys {
+			value, err := r.client.Get(r.ctx, key).Result()
+			if err != nil {
+				if err == redis.Nil {
+					fmt.Printf("Key %s does not exist\n", key)
+				} else {
+					fmt.Printf("Error getting value for key %s: %v", key, err)
+				}
+			} else {
+				result = append(result, value)
+			}
+		}
+
+		// 如果 cursor 为 0,表示扫描完成
+		if nextCursor == 0 {
+			break
+		}
+		cursor = nextCursor
+	}
+
+	return result, nil
+}
+
+// LPushList 将一个或多个值插入到列表的头部
+func (r *RedisHelper) LPushList(key string, values ...string) error {
+	return r.client.LPush(r.ctx, key, values).Err() // 将值插入到列表的头部
+}
+
+// RPushList 将一个或多个值插入到列表的尾部
+func (r *RedisHelper) RPushList(key string, values ...string) error {
+	return r.client.RPush(r.ctx, key, values).Err() // 将值插入到列表的尾部
+}
+
+// LPopList 从列表的头部弹出一个元素
+func (r *RedisHelper) LPopList(key string) (string, error) {
+	return r.client.LPop(r.ctx, key).Result() // 从列表的头部移除并返回第一个元素
+}
+
+// RPopList 从列表的尾部弹出一个元素
+func (r *RedisHelper) RPopList(key string) (string, error) {
+	return r.client.RPop(r.ctx, key).Result() // 从列表的尾部移除并返回最后一个元素
+}
+
+// LRangeList 获取列表中指定范围的元素
+func (r *RedisHelper) LRangeList(key string, start, stop int64) ([]string, error) {
+	return r.client.LRange(r.ctx, key, start, stop).Result() // 获取列表中指定范围的元素
+}
+
+// GetAllList 获取列表中的所有元素
+func (r *RedisHelper) GetAllList(key string) ([]string, error) {
+	values, err := r.client.LRange(r.ctx, key, 0, -1).Result()
+	if err == redis.Nil {
+		return nil, nil
+	} else if err != nil {
+		return nil, err
+	}
+
+	// 检查是否包含空值标志
+	if len(values) == 1 && values[0] == r.emptyCacheValue {
+		return nil, nil
+	}
+
+	return values, nil
+}
+
+func (r *RedisHelper) LRem(key, val string) (int64, error) {
+	count := 0 // 删除所有与 valueToRemove 相等的元素
+	result, err := r.client.LRem(r.ctx, key, int64(count), val).Result()
+	if err != nil {
+		fmt.Printf("删除元素失败: %v\n", err)
+	}
+
+	return result, nil
+}
+
+func (r *RedisHelper) IsElementInList(key string, element string) (bool, error) {
+	var cursor int64 = 0
+	const batchSize int64 = 1000 // 每批次获取的元素数量
+
+	for {
+		// 分批次获取列表元素
+		elements, err := r.client.LRange(r.ctx, key, cursor, cursor+batchSize-1).Result()
+		if err != nil {
+			return false, err
+		}
+		if len(elements) == 0 {
+			break // 没有更多数据
+		}
+
+		// 遍历当前批次的元素
+		for _, e := range elements {
+			if e == element {
+				return true, nil
+			}
+		}
+
+		cursor += batchSize // 移动到下一批次
+	}
+
+	return false, nil
+}
+
+/*
+SetListCache 重新设置列表缓存
+  - @expiration 0-过期 1-过期时间
+*/
+func (r *RedisHelper) SetListCache(key string, expiration time.Duration, values ...string) error {
+	tempKey := key + ":temp"
+
+	// 使用事务来确保操作的原子性
+	pipe := r.client.TxPipeline()
+
+	// 将新数据插入到临时列表中
+	pipe.RPush(r.ctx, tempKey, values)
+
+	// 重命名临时列表为目标列表
+	pipe.Rename(r.ctx, tempKey, key)
+
+	if expiration > 0 {
+		// 设置目标列表的过期时间
+		pipe.Expire(r.ctx, key, expiration)
+	}
+
+	// 执行事务
+	_, err := pipe.Exec(r.ctx)
+	return err
+}
+
+// SetEmptyListCache 设置空值缓存
+func (r *RedisHelper) SetEmptyListCache(key string, expiration time.Duration) error {
+	// 使用一个特殊标志值表示列表为空
+	_, err := r.client.RPush(r.ctx, key, r.emptyCacheValue).Result()
+	if err != nil {
+		return err
+	}
+
+	// 设置列表的过期时间
+	return r.client.Expire(r.ctx, key, expiration).Err()
+}
+
+// scanKeys 使用 SCAN 命令获取所有匹配的键
+func (r *RedisHelper) ScanKeys(pattern string) ([]string, error) {
+
+	var cursor uint64
+	var keys []string
+	for {
+		var newKeys []string
+		var err error
+
+		// SCAN 命令每次返回部分匹配的键
+		newKeys, cursor, err = r.client.Scan(r.ctx, cursor, pattern, 1000).Result()
+		if err != nil {
+			return nil, err
+		}
+		keys = append(keys, newKeys...)
+		if cursor == 0 {
+			break
+		}
+	}
+	return keys, nil
+}
+
+// 泛型函数,用于获取所有键的列表数据并合并为一个数组
+func GetAndMergeLists[T any](r *RedisHelper, keys []string) ([]T, error) {
+	var combinedList []T
+	for _, key := range keys {
+		// 获取每个键的列表数据
+		listData, err := r.client.LRange(r.ctx, key, 0, -1).Result()
+		if err != nil {
+			return nil, err
+		}
+
+		// 解码每个数据项为类型 T,并添加到结果列表中
+		for _, data := range listData {
+			var item T
+			if err := sonic.Unmarshal([]byte(data), &item); err != nil {
+				return nil, err
+			}
+			combinedList = append(combinedList, item)
+		}
+	}
+	return combinedList, nil
+}
+
+// SetNX 实现类似于 Redis 的 SETNX 命令
+func (r *RedisHelper) SetNX(key string, value interface{}, expiration time.Duration) (bool, error) {
+	result, err := r.client.Set(r.ctx, key, value, expiration).Result()
+	if err != nil {
+		return false, err
+	}
+
+	// 如果键不存在则 result 会等于 "OK"
+	return result == "OK", nil
+}
+
+func getFieldsFromStruct(obj interface{}) map[string]interface{} {
+	fields := make(map[string]interface{})
+	val := reflect.ValueOf(obj)
+	typ := reflect.TypeOf(obj)
+
+	for i := 0; i < val.NumField(); i++ {
+		field := typ.Field(i)
+		tag := field.Tag.Get("redis")
+		if tag != "" {
+			fieldVal := val.Field(i)
+			if fieldVal.Kind() == reflect.Slice || fieldVal.Kind() == reflect.Map {
+				// 处理切片或映射类型
+				// 对于切片,使用索引作为字段名
+				if fieldVal.Kind() == reflect.Slice {
+					for j := 0; j < fieldVal.Len(); j++ {
+						elem := fieldVal.Index(j).Interface()
+						fields[fmt.Sprintf("%s_%d", tag, j)] = elem
+					}
+				} else if fieldVal.Kind() == reflect.Map {
+					// 对于映射,使用键作为字段名
+					for _, key := range fieldVal.MapKeys() {
+						elem := fieldVal.MapIndex(key).Interface()
+						fields[fmt.Sprintf("%s_%v", tag, key.Interface())] = elem
+					}
+				}
+			} else {
+				fields[tag] = fieldVal.Interface()
+			}
+		}
+	}
+
+	return fields
+}
+
+func (r *RedisHelper) SetHashWithTags(key string, obj interface{}) error {
+	fields := getFieldsFromStruct(obj)
+	_, err := r.client.HSet(r.ctx, key, fields).Result()
+	return err
+}
+
+// HSetField 设置哈希中的一个字段
+func (r *RedisHelper) HSetField(key, field string, value interface{}) error {
+	_, err := r.client.HSet(r.ctx, key, field, value).Result()
+	if err != nil {
+		log.Printf("Error setting field %s in hash %s: %v", field, key, err)
+		return err
+	}
+	return nil
+}
+
+// HSetMultipleFields 设置哈希中的多个字段
+func (r *RedisHelper) HSetMultipleFields(key string, fields map[string]interface{}) error {
+	_, err := r.client.HSet(r.ctx, key, fields).Result()
+	if err != nil {
+		log.Printf("Error setting multiple fields in hash %s: %v", key, err)
+		return err
+	}
+	return nil
+}
+
+// HGetField 获取哈希中某个字段的值
+func (r *RedisHelper) HGetField(key, field string) (string, error) {
+	val, err := r.client.HGet(r.ctx, key, field).Result()
+	if err != nil {
+		if err == redis.Nil {
+			return "", nil // Field does not exist
+		}
+		log.Printf("Error getting field %s from hash %s: %v", field, key, err)
+		return "", err
+	}
+	return val, nil
+}
+
+// HGetAllFields 获取哈希中所有字段的值
+func (r *RedisHelper) HGetAllFields(key string) (map[string]string, error) {
+	fields, err := r.client.HGetAll(r.ctx, key).Result()
+	if err != nil {
+		log.Printf("Error getting all fields from hash %s: %v", key, err)
+		return nil, err
+	}
+	return fields, nil
+}
+
+// HDelField 删除哈希中的某个字段
+func (r *RedisHelper) HDelField(key, field string) error {
+	_, err := r.client.HDel(r.ctx, key, field).Result()
+	if err != nil {
+		log.Printf("Error deleting field %s from hash %s: %v", field, key, err)
+		return err
+	}
+	return nil
+}
+
+// 删除哈希
+func (r *RedisHelper) HDelAll(key string) error {
+	_, err := r.client.Del(r.ctx, key).Result()
+	if err != nil {
+		log.Printf("Error deleting from hash %s: %v", key, err)
+		return err
+	}
+	return nil
+}
+
+// HKeys 获取哈希中所有字段的名字
+func (r *RedisHelper) HKeys(key string) ([]string, error) {
+	fields, err := r.client.HKeys(r.ctx, key).Result()
+	if err != nil {
+		log.Printf("Error getting keys from hash %s: %v", key, err)
+		return nil, err
+	}
+	return fields, nil
+}
+
+// DelSet 从集合中删除元素
+func (r *RedisHelper) DelSet(key string, value string) error {
+	_, err := r.client.SRem(r.ctx, key, value).Result()
+	if err != nil {
+		log.Printf("Error del value from set %s: %v", key, err)
+		return err
+	}
+	return nil
+}
+
+func (r *RedisHelper) Sismember(key string, value string) (bool, error) {
+	result, err := r.client.SIsMember(r.ctx, key, value).Result()
+	if err != nil {
+		log.Printf("Error Sismember value from set %s: %v", key, err)
+	}
+	return result, err
+}
+
+// sort set start
+// 批量添加
+func (r *RedisHelper) BatchSortSet(key string, array []*redis.Z) error {
+	pipe := r.client.Pipeline()
+	for _, val := range array {
+		pipe.ZAdd(r.ctx, key, val)
+	}
+
+	_, err := pipe.Exec(r.ctx)
+	return err
+}
+
+// 单一写入 sort set
+func (e *RedisHelper) SignelAdd(key string, score float64, member string) error {
+	// 先删除具有相同 score 的所有成员
+	scoreStr := strconv.FormatFloat(score, 'g', -1, 64)
+	_, err := e.client.ZRemRangeByScore(e.ctx, key, scoreStr, scoreStr).Result()
+
+	if err != nil {
+		fmt.Printf("删除score失败", err.Error())
+	}
+	_, err = e.client.ZAdd(e.ctx, key, &redis.Z{
+		Score:  score,
+		Member: member,
+	}).Result()
+
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// 写入数据
+func (e *RedisHelper) AddSortSet(key string, score float64, member string) error {
+	_, err := e.client.ZAdd(e.ctx, key, &redis.Z{
+		Score:  score,
+		Member: member,
+	}).Result()
+
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// 删除指定元素
+func (e *RedisHelper) DelSortSet(key, member string) error {
+	return e.client.ZRem(e.ctx, key, member).Err()
+}
+
+/*
+获取sort set 所有数据
+*/
+func (e *RedisHelper) GetAllSortSet(key string) ([]string, error) {
+	return e.client.ZRange(e.ctx, key, 0, -1).Result()
+}
+
+/*
+获取sort set 所有数据和score
+*/
+func (e *RedisHelper) GetRevRangeScoresSortSet(key string) ([]redis.Z, error) {
+	return e.client.ZRevRangeWithScores(e.ctx, key, 0, -1).Result()
+}
+
+// 获取指定区间数据
+func (e *RedisHelper) GetSortSetMembers(key string, start, stop int64) ([]string, error) {
+	return e.client.ZRange(e.ctx, key, start, stop).Result()
+}
+
+// 获取最后N条数据
+func (e *RedisHelper) GetLastSortSetMembers(key string, num int64) ([]string, error) {
+	return e.client.ZRevRange(e.ctx, key, 0, num).Result()
+}
+
+// func (e *RedisHelper) DelSortSet(key,)
+
+// 根据索引范围删除
+func (e *RedisHelper) DelByRank(key string, start, stop int64) error {
+	return e.client.ZRemRangeByRank(e.ctx, key, start, stop).Err()
+}
+
+// sort set end
+
+// GetUserLoginPwdErrFre 获取用户登录密码错误频次
+func (e *RedisHelper) GetUserLoginPwdErrFre(key string) (total int, wait time.Duration, err error) {
+	total, _ = e.client.Get(e.ctx, key).Int()
+	wait = e.client.TTL(e.ctx, key).Val()
+	return
+}
+
+// SetUserLoginPwdErrFre 设置用户登录密码错误频次
+func (e *RedisHelper) SetUserLoginPwdErrFre(key string, expire time.Duration) (val int64, err error) {
+	val, err = e.client.Incr(e.ctx, key).Result()
+	if err != nil {
+		return
+	}
+	if err = e.client.Expire(e.ctx, key, expire).Err(); err != nil {
+		return
+	}
+	return
+}
diff --git a/common/helper/redislock.go b/common/helper/redislock.go
new file mode 100644
index 0000000..1716794
--- /dev/null
+++ b/common/helper/redislock.go
@@ -0,0 +1,183 @@
+package helper
+
+import (
+	"context"
+	"errors"
+	"go-admin/pkg/utility"
+	"math/rand"
+	"strconv"
+	"sync"
+	"sync/atomic"
+	"time"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-redis/redis/v8"
+	"go.uber.org/zap"
+)
+
+const (
+	tolerance       = 500 // milliseconds
+	millisPerSecond = 1000
+	lockCommand     = `if redis.call("GET", KEYS[1]) == ARGV[1] then
+    redis.call("SET", KEYS[1], ARGV[1], "PX", ARGV[2])
+    return "OK"
+else
+    return redis.call("SET", KEYS[1], ARGV[1], "NX", "PX", ARGV[2])
+end`
+	delCommand = `if redis.call("GET", KEYS[1]) == ARGV[1] then
+    return redis.call("DEL", KEYS[1])
+else
+    return 0
+end`
+	touchCommand = `if redis.call("GET", KEYS[1]) == ARGV[1] then
+    return redis.call("PEXPIRE", KEYS[1], ARGV[2])
+else
+    return 0
+end`
+)
+
+var (
+	clientRedisLock *redis.Client
+	onece           sync.Once
+	ErrFailed       = errors.New("redsync: failed to acquire lock")
+)
+
+// InitLockRedisConn 初始化 Redis 连接
+func InitLockRedisConn(host, password, dbIndex string) {
+	onece.Do(func() {
+		dbIndexInt, err := strconv.Atoi(dbIndex)
+		if err != nil {
+			dbIndexInt = 0
+		}
+		clientRedisLock = redis.NewClient(&redis.Options{
+			Addr:     host,
+			Password: password,
+			DB:       dbIndexInt,
+		})
+
+		// 测试连接
+		if _, err := clientRedisLock.Ping(context.Background()).Result(); err != nil {
+			log.Error("Failed to connect to Redis", zap.Error(err))
+			panic(err)
+		}
+	})
+}
+
+// RedisLock 分布式锁结构
+type RedisLock struct {
+	redisClient   *redis.Client
+	key           string
+	id            string
+	expiry        time.Duration
+	retryCount    int           // 重试次数
+	retryInterval time.Duration // 重试间隔时间
+	seconds       uint32
+}
+
+// NewRedisLock 创建一个新的 Redis 锁
+func NewRedisLock(key string, timeout uint32, retryCount int, retryInterval time.Duration) *RedisLock {
+	return &RedisLock{
+		redisClient:   clientRedisLock,
+		key:           key,
+		id:            utility.GetXid(),
+		expiry:        time.Duration(timeout) * time.Second,
+		retryCount:    retryCount,
+		retryInterval: retryInterval,
+		seconds:       timeout,
+	}
+}
+
+// Acquire 获取锁
+func (rl *RedisLock) Acquire() (bool, error) {
+	return rl.acquireCtx(context.Background())
+}
+
+// AcquireWait 获取锁,支持重试和超时
+func (rl *RedisLock) AcquireWait(ctx context.Context) (bool, error) {
+	if ctx == nil {
+		ctx = context.Background()
+	}
+
+	for i := 0; i < rl.retryCount; i++ {
+		if i > 0 {
+			// 指数退避
+			baseInterval := time.Duration(int64(rl.retryInterval) * (1 << i)) // 指数增长
+			if baseInterval > time.Second {
+				baseInterval = time.Second
+			}
+
+			// 随机退避
+			retryInterval := time.Duration(rand.Int63n(int64(baseInterval))) // 随机退避
+			if retryInterval < time.Millisecond*100 {
+				retryInterval = time.Millisecond * 100 // 至少 100ms
+			}
+			select {
+			case <-ctx.Done():
+				return false, ctx.Err()
+			case <-time.After(retryInterval):
+			}
+		}
+
+		ok, err := rl.acquireCtx(ctx)
+		if ok {
+			return true, nil
+		}
+		if err != nil {
+			log.Error("Failed to acquire lock", zap.String("key", rl.key), zap.Error(err))
+		}
+	}
+	return false, ErrFailed
+}
+
+// Release 释放锁
+func (rl *RedisLock) Release() (bool, error) {
+	return rl.releaseCtx(context.Background())
+}
+
+// Touch 续期锁
+func (rl *RedisLock) Touch() (bool, error) {
+	return rl.touchCtx(context.Background())
+}
+
+// acquireCtx 获取锁的核心逻辑
+func (rl *RedisLock) acquireCtx(ctx context.Context) (bool, error) {
+	resp, err := rl.redisClient.Eval(ctx, lockCommand, []string{rl.key}, []string{
+		rl.id, strconv.Itoa(int(rl.seconds)*millisPerSecond + tolerance),
+	}).Result()
+	if err == redis.Nil {
+		return false, nil
+	} else if err != nil {
+		log.Error("Error acquiring lock", zap.String("key", rl.key), zap.Error(err))
+		return false, err
+	}
+
+	reply, ok := resp.(string)
+	return ok && reply == "OK", nil
+}
+
+// releaseCtx 释放锁的核心逻辑
+func (rl *RedisLock) releaseCtx(ctx context.Context) (bool, error) {
+	resp, err := rl.redisClient.Eval(ctx, delCommand, []string{rl.key}, []string{rl.id}).Result()
+	if err != nil {
+		log.Error("Error releasing lock", zap.String("key", rl.key), zap.Error(err))
+		return false, err
+	}
+
+	reply, ok := resp.(int64)
+	return ok && reply == 1, nil
+}
+
+// touchCtx 续期锁的核心逻辑
+func (rl *RedisLock) touchCtx(ctx context.Context) (bool, error) {
+	seconds := atomic.LoadUint32(&rl.seconds)
+	resp, err := rl.redisClient.Eval(ctx, touchCommand, []string{rl.key}, []string{
+		rl.id, strconv.Itoa(int(seconds)*millisPerSecond + tolerance),
+	}).Result()
+	if err != nil {
+		log.Error("Error touching lock", zap.String("key", rl.key), zap.Error(err))
+		return false, err
+	}
+
+	reply, ok := resp.(int64)
+	return ok && reply == 1, nil
+}
diff --git a/common/helper/snowflake.go b/common/helper/snowflake.go
new file mode 100644
index 0000000..2409663
--- /dev/null
+++ b/common/helper/snowflake.go
@@ -0,0 +1,50 @@
+package helper
+
+import (
+	"strconv"
+	"sync"
+
+	extendConfig "go-admin/config"
+
+	"github.com/bwmarrin/snowflake"
+	log "github.com/go-admin-team/go-admin-core/logger"
+)
+
+// 全局雪花节点实例
+var (
+	node *snowflake.Node
+	once sync.Once
+)
+
+func InitSnowflakeNode() error {
+	var err error
+
+	node, err = snowflake.NewNode(extendConfig.ExtConfig.ServiceId)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// 获取订单雪花id
+func GetOrderNo() string {
+	if node == nil {
+		once.Do(func() {
+			if node == nil {
+				if err := InitSnowflakeNode(); err != nil {
+					log.Fatalf("初始化雪花算法节点失败: %v", err)
+				}
+			}
+		})
+	}
+
+	if node == nil {
+		log.Fatal("雪花算法节点未初始化")
+	}
+
+	orderID := node.Generate()
+	idStr := strconv.FormatInt(orderID.Int64(), 10)
+
+	return idStr
+}
diff --git a/common/ip.go b/common/ip.go
new file mode 100644
index 0000000..bc4d9ef
--- /dev/null
+++ b/common/ip.go
@@ -0,0 +1,27 @@
+package common
+
+import (
+	"github.com/gin-gonic/gin"
+	"strings"
+)
+
+func GetClientIP(c *gin.Context) string {
+	ClientIP := c.ClientIP()
+	//fmt.Println("ClientIP:", ClientIP)
+	RemoteIP := c.RemoteIP()
+	//fmt.Println("RemoteIP:", RemoteIP)
+	ip := c.Request.Header.Get("X-Forwarded-For")
+	if strings.Contains(ip, "127.0.0.1") || ip == "" {
+		ip = c.Request.Header.Get("X-real-ip")
+	}
+	if ip == "" {
+		ip = "127.0.0.1"
+	}
+	if RemoteIP != "127.0.0.1" {
+		ip = RemoteIP
+	}
+	if ClientIP != "127.0.0.1" {
+		ip = ClientIP
+	}
+	return ip
+}
diff --git a/common/middleware/auth.go b/common/middleware/auth.go
new file mode 100644
index 0000000..3ea6902
--- /dev/null
+++ b/common/middleware/auth.go
@@ -0,0 +1,104 @@
+package middleware
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"go-admin/common/middleware/dto"
+	"go-admin/common/service/sysservice/sysstatuscode"
+	statuscode "go-admin/common/status_code"
+	"go-admin/pkg/cryptohelper/jwthelper"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/common/middleware/handler"
+)
+
+// AuthInit jwt验证new
+func AuthInit() (*jwt.GinJWTMiddleware, error) {
+	timeout := time.Hour
+	if config.ApplicationConfig.Mode == "dev" {
+		timeout = time.Duration(876010) * time.Hour
+	} else {
+		if config.JwtConfig.Timeout != 0 {
+			timeout = time.Duration(config.JwtConfig.Timeout) * time.Second
+		}
+	}
+	return jwt.New(&jwt.GinJWTMiddleware{
+		Realm:           "test zone",
+		Key:             []byte(config.JwtConfig.Secret),
+		Timeout:         timeout,
+		MaxRefresh:      time.Hour,
+		PayloadFunc:     handler.PayloadFunc,
+		IdentityHandler: handler.IdentityHandler,
+		Authenticator:   handler.Authenticator,
+		Authorizator:    handler.Authorizator,
+		Unauthorized:    handler.Unauthorized,
+		TokenLookup:     "header: Authorization, query: token, cookie: jwt",
+		TokenHeadName:   "Bearer",
+		TimeFunc:        time.Now,
+	})
+
+}
+
+func FrontedAuth(c *gin.Context) {
+	// 从请求头中获取 token 和 os
+	token := c.GetHeader("Authorization")
+	source, _ := strconv.Atoi(c.GetHeader("os"))
+	// 如果 token 不存在,返回未登录的状态
+	if len(token) == 0 {
+		err := ResponseWithStatus(c, dto.NotLoginStatus, statuscode.NotLoggedIn)
+		if err != nil {
+			return
+		}
+		c.Abort() // 停止后续中间件的执行
+		return
+	}
+	// 验证 token 并获取结果
+	flag, rew := jwthelper.MidValidToken(token, source)
+	if flag < 0 || len(rew) == 0 {
+		if flag == -1 {
+			ResponseWithStatus(c, dto.NotLoginStatus, statuscode.NotLoggedIn)
+		} else if flag == -2 {
+			ResponseWithStatus(c, dto.ReLoginStatus, statuscode.ReLogin)
+		}
+		c.Abort() // 停止后续中间件的执行
+		return
+	}
+	// 将解析后的 token 设置到请求头中
+	c.Request.Header.Set("ParseToken", rew)
+	// 继续处理请求
+	c.Next()
+}
+
+// ResponseWithStatus 带状态的响应
+func ResponseWithStatus(ctx *gin.Context, status int, code int, data ...interface{}) error {
+	// 获取语言对应的 msg
+	msg := sysstatuscode.GetStatusCodeDescription(ctx, code)
+	if msg == `` {
+		msg = strconv.Itoa(code)
+	} else {
+		// 配置了语言包参数
+		if strings.Contains(msg, "%") && len(data) > 1 {
+			msg = fmt.Sprintf(msg, data[1:]...)
+		}
+	}
+
+	resp := dto.Response{
+		Status: status,
+		Code:   code,
+		Msg:    msg,
+	}
+
+	resp.RequestID = pkg.GenerateMsgIDFromContext(ctx)
+	if len(data) > 0 {
+		resp.Data = data[0]
+	}
+
+	ctx.JSON(200, resp)
+
+	return nil
+}
diff --git a/common/middleware/customerror.go b/common/middleware/customerror.go
new file mode 100644
index 0000000..1f92628
--- /dev/null
+++ b/common/middleware/customerror.go
@@ -0,0 +1,61 @@
+package middleware
+
+import (
+	"fmt"
+	"net/http"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/gin-gonic/gin"
+)
+
+func CustomError(c *gin.Context) {
+	defer func() {
+		if err := recover(); err != nil {
+
+			if c.IsAborted() {
+				c.Status(200)
+			}
+			switch errStr := err.(type) {
+			case string:
+				p := strings.Split(errStr, "#")
+				if len(p) == 3 && p[0] == "CustomError" {
+					statusCode, e := strconv.Atoi(p[1])
+					if e != nil {
+						break
+					}
+					c.Status(statusCode)
+					fmt.Println(
+						time.Now().Format("2006-01-02 15:04:05"),
+						"[ERROR]",
+						c.Request.Method,
+						c.Request.URL,
+						statusCode,
+						c.Request.RequestURI,
+						c.ClientIP(),
+						p[2],
+					)
+					c.JSON(http.StatusOK, gin.H{
+						"code": statusCode,
+						"msg":  p[2],
+					})
+				} else {
+					c.JSON(http.StatusOK, gin.H{
+						"code": 500,
+						"msg":  errStr,
+					})
+				}
+			case runtime.Error:
+				c.JSON(http.StatusOK, gin.H{
+					"code": 500,
+					"msg":  errStr.Error(),
+				})
+			default:
+				panic(err)
+			}
+		}
+	}()
+	c.Next()
+}
diff --git a/common/middleware/db.go b/common/middleware/db.go
new file mode 100644
index 0000000..0e73a2d
--- /dev/null
+++ b/common/middleware/db.go
@@ -0,0 +1,11 @@
+package middleware
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk"
+)
+
+func WithContextDb(c *gin.Context) {
+	c.Set("db", sdk.Runtime.GetDbByKey(c.Request.Host).WithContext(c))
+	c.Next()
+}
diff --git a/common/middleware/demo.go b/common/middleware/demo.go
new file mode 100644
index 0000000..f13f28f
--- /dev/null
+++ b/common/middleware/demo.go
@@ -0,0 +1,29 @@
+package middleware
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"net/http"
+)
+
+func DemoEvn() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		method := c.Request.Method
+		if config.ApplicationConfig.Mode == "demo" {
+			if method == "GET" ||
+				method == "OPTIONS" ||
+				c.Request.RequestURI == "/api/v1/login" ||
+				c.Request.RequestURI == "/api/v1/logout" {
+				c.Next()
+			} else {
+				c.JSON(http.StatusOK, gin.H{
+					"code": 500,
+					"msg":  "谢谢您的参与,但为了大家更好的体验,所以本次提交就算了吧!\U0001F600\U0001F600\U0001F600",
+				})
+				c.Abort()
+				return
+			}
+		}
+		c.Next()
+	}
+}
diff --git a/common/middleware/dto/response.go b/common/middleware/dto/response.go
new file mode 100644
index 0000000..c8a097c
--- /dev/null
+++ b/common/middleware/dto/response.go
@@ -0,0 +1,21 @@
+package dto
+
+/**
+ * TODO 请优先使用 Success 和 Fail 方法响应请求
+ */
+
+const (
+	SuccessStatus  = 1
+	FailStatus     = 0
+	NotLoginStatus = -1 // 未登录
+	ReLoginStatus  = -2 // 重新登录
+)
+
+// Response 响应结构
+type Response struct {
+	Status    int         `json:"status"`
+	Code      int         `json:"code"`
+	Msg       string      `json:"msg"`
+	Data      interface{} `json:"data"`
+	RequestID string      `json:"RequestId"`
+}
diff --git a/common/middleware/handler/auth.go b/common/middleware/handler/auth.go
new file mode 100644
index 0000000..ddb6791
--- /dev/null
+++ b/common/middleware/handler/auth.go
@@ -0,0 +1,182 @@
+package handler
+
+import (
+	"go-admin/app/admin/models"
+	"go-admin/common"
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/captcha"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+	"github.com/mssola/user_agent"
+	"go-admin/common/global"
+)
+
+func PayloadFunc(data interface{}) jwt.MapClaims {
+	if v, ok := data.(map[string]interface{}); ok {
+		u, _ := v["user"].(SysUser)
+		r, _ := v["role"].(SysRole)
+		return jwt.MapClaims{
+			jwt.IdentityKey:  u.UserId,
+			jwt.RoleIdKey:    r.RoleId,
+			jwt.RoleKey:      r.RoleKey,
+			jwt.NiceKey:      u.Username,
+			jwt.DataScopeKey: r.DataScope,
+			jwt.RoleNameKey:  r.RoleName,
+		}
+	}
+	return jwt.MapClaims{}
+}
+
+func IdentityHandler(c *gin.Context) interface{} {
+	claims := jwt.ExtractClaims(c)
+	return map[string]interface{}{
+		"IdentityKey": claims["identity"],
+		"UserName":    claims["nice"],
+		"RoleKey":     claims["rolekey"],
+		"UserId":      claims["identity"],
+		"RoleIds":     claims["roleid"],
+		"DataScope":   claims["datascope"],
+	}
+}
+
+// Authenticator 获取token
+// @Summary 登陆
+// @Description 获取token
+// @Description LoginHandler can be used by clients to get a jwt token.
+// @Description Payload needs to be json in the form of {"username": "USERNAME", "password": "PASSWORD"}.
+// @Description Reply will be of the form {"token": "TOKEN"}.
+// @Description dev mode:It should be noted that all fields cannot be empty, and a value of 0 can be passed in addition to the account password
+// @Description 注意:开发模式:需要注意全部字段不能为空,账号密码外可以传入0值
+// @Tags 登陆
+// @Accept  application/json
+// @Product application/json
+// @Param account body Login  true "account"
+// @Success 200 {string} string "{"code": 200, "expire": "2019-08-07T12:45:48+08:00", "token": ".eyJleHAiOjE1NjUxNTMxNDgsImlkIjoiYWRtaW4iLCJvcmlnX2lhdCI6MTU2NTE0OTU0OH0.-zvzHvbg0A" }"
+// @Router /api/v1/login [post]
+func Authenticator(c *gin.Context) (interface{}, error) {
+	log := api.GetRequestLogger(c)
+	db, err := pkg.GetOrm(c)
+	if err != nil {
+		log.Errorf("get db error, %s", err.Error())
+		response.Error(c, 500, err, "数据库连接获取失败")
+		return nil, jwt.ErrFailedAuthentication
+	}
+
+	var loginVals Login
+	var status = "2"
+	var msg = "登录成功"
+	var username = ""
+	defer func() {
+		LoginLogToDB(c, status, msg, username)
+	}()
+
+	if err = c.ShouldBind(&loginVals); err != nil {
+		username = loginVals.Username
+		msg = "数据解析失败"
+		status = "1"
+
+		return nil, jwt.ErrMissingLoginValues
+	}
+	if config.ApplicationConfig.Mode != "dev" {
+		if !captcha.Verify(loginVals.UUID, loginVals.Code, true) {
+			username = loginVals.Username
+			msg = "验证码错误"
+			status = "1"
+
+			return nil, jwt.ErrInvalidVerificationode
+		}
+	}
+	sysUser, role, e := loginVals.GetUser(db)
+	if e == nil {
+		username = loginVals.Username
+
+		return map[string]interface{}{"user": sysUser, "role": role}, nil
+	} else {
+		msg = "登录失败"
+		status = "1"
+		log.Warnf("%s login failed!", loginVals.Username)
+	}
+	return nil, jwt.ErrFailedAuthentication
+}
+
+// LoginLogToDB Write log to database
+func LoginLogToDB(c *gin.Context, status string, msg string, username string) {
+	if !config.LoggerConfig.EnabledDB {
+		return
+	}
+	log := api.GetRequestLogger(c)
+	l := make(map[string]interface{})
+
+	ua := user_agent.New(c.Request.UserAgent())
+	l["ipaddr"] = common.GetClientIP(c)
+	l["loginLocation"] = "" // pkg.GetLocation(common.GetClientIP(c),gaConfig.ExtConfig.AMap.Key)
+	l["loginTime"] = pkg.GetCurrentTime()
+	l["status"] = status
+	l["remark"] = c.Request.UserAgent()
+	browserName, browserVersion := ua.Browser()
+	l["browser"] = browserName + " " + browserVersion
+	l["os"] = ua.OS()
+	l["platform"] = ua.Platform()
+	l["username"] = username
+	l["msg"] = msg
+
+	q := sdk.Runtime.GetMemoryQueue(c.Request.Host)
+	message, err := sdk.Runtime.GetStreamMessage("", global.LoginLog, l)
+	if err != nil {
+		log.Errorf("GetStreamMessage error, %s", err.Error())
+		//日志报错错误,不中断请求
+	} else {
+		err = q.Append(message)
+		if err != nil {
+			log.Errorf("Append message error, %s", err.Error())
+		}
+	}
+}
+
+// LogOut
+// @Summary 退出登录
+// @Description 获取token
+// LoginHandler can be used by clients to get a jwt token.
+// Reply will be of the form {"token": "TOKEN"}.
+// @Accept  application/json
+// @Product application/json
+// @Success 200 {string} string "{"code": 200, "msg": "成功退出系统" }"
+// @Router /logout [post]
+// @Security Bearer
+func LogOut(c *gin.Context) {
+	LoginLogToDB(c, "2", "退出成功", user.GetUserName(c))
+	c.JSON(http.StatusOK, gin.H{
+		"code": 200,
+		"msg":  "退出成功",
+	})
+
+}
+
+func Authorizator(data interface{}, c *gin.Context) bool {
+
+	if v, ok := data.(map[string]interface{}); ok {
+		u, _ := v["user"].(models.SysUser)
+		r, _ := v["role"].(models.SysRole)
+		c.Set("role", r.RoleName)
+		c.Set("roleIds", r.RoleId)
+		c.Set("userId", u.UserId)
+		c.Set("userName", u.Username)
+		c.Set("dataScope", r.DataScope)
+		return true
+	}
+	return false
+}
+
+func Unauthorized(c *gin.Context, code int, message string) {
+	c.JSON(http.StatusOK, gin.H{
+		"code": code,
+		"msg":  message,
+	})
+}
diff --git a/common/middleware/handler/httpshandler.go b/common/middleware/handler/httpshandler.go
new file mode 100644
index 0000000..e127439
--- /dev/null
+++ b/common/middleware/handler/httpshandler.go
@@ -0,0 +1,22 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/unrolled/secure"
+
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+)
+
+func TlsHandler() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		secureMiddleware := secure.New(secure.Options{
+			SSLRedirect: true,
+			SSLHost:     config.SslConfig.Domain,
+		})
+		err := secureMiddleware.Process(c.Writer, c.Request)
+		if err != nil {
+			return
+		}
+		c.Next()
+	}
+}
diff --git a/common/middleware/handler/login.go b/common/middleware/handler/login.go
new file mode 100644
index 0000000..d17626c
--- /dev/null
+++ b/common/middleware/handler/login.go
@@ -0,0 +1,33 @@
+package handler
+
+import (
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"gorm.io/gorm"
+)
+
+type Login struct {
+	Username string `form:"UserName" json:"username" binding:"required"`
+	Password string `form:"Password" json:"password" binding:"required"`
+	Code     string `form:"Code" json:"code" binding:"required"`
+	UUID     string `form:"UUID" json:"uuid" binding:"required"`
+}
+
+func (u *Login) GetUser(tx *gorm.DB) (user SysUser, role SysRole, err error) {
+	err = tx.Table("sys_user").Where("username = ?  and status = '2'", u.Username).First(&user).Error
+	if err != nil {
+		log.Errorf("get user error, %s", err.Error())
+		return
+	}
+	_, err = pkg.CompareHashAndPassword(user.Password, u.Password)
+	if err != nil {
+		log.Errorf("user login error, %s", err.Error())
+		return
+	}
+	err = tx.Table("sys_role").Where("role_id = ? ", user.RoleId).First(&role).Error
+	if err != nil {
+		log.Errorf("get role error, %s", err.Error())
+		return
+	}
+	return
+}
diff --git a/common/middleware/handler/ping.go b/common/middleware/handler/ping.go
new file mode 100644
index 0000000..ab4d645
--- /dev/null
+++ b/common/middleware/handler/ping.go
@@ -0,0 +1,11 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+)
+
+func Ping(c *gin.Context) {
+	c.JSON(200, gin.H{
+		"message": "ok",
+	})
+}
diff --git a/common/middleware/handler/role.go b/common/middleware/handler/role.go
new file mode 100644
index 0000000..0895ebc
--- /dev/null
+++ b/common/middleware/handler/role.go
@@ -0,0 +1,24 @@
+package handler
+
+import "go-admin/common/models"
+
+type SysRole struct {
+	RoleId    int    `json:"roleId" gorm:"primaryKey;autoIncrement"` // 角色编码
+	RoleName  string `json:"roleName" gorm:"size:128;"`              // 角色名称
+	Status    string `json:"status" gorm:"size:4;"`                  //
+	RoleKey   string `json:"roleKey" gorm:"size:128;"`               //角色代码
+	RoleSort  int    `json:"roleSort" gorm:""`                       //角色排序
+	Flag      string `json:"flag" gorm:"size:128;"`                  //
+	Remark    string `json:"remark" gorm:"size:255;"`                //备注
+	Admin     bool   `json:"admin" gorm:"size:4;"`
+	DataScope string `json:"dataScope" gorm:"size:128;"`
+	Params    string `json:"params" gorm:"-"`
+	MenuIds   []int  `json:"menuIds" gorm:"-"`
+	DeptIds   []int  `json:"deptIds" gorm:"-"`
+	models.ControlBy
+	models.ModelTime
+}
+
+func (SysRole) TableName() string {
+	return "sys_role"
+}
diff --git a/common/middleware/handler/user.go b/common/middleware/handler/user.go
new file mode 100644
index 0000000..b34d4db
--- /dev/null
+++ b/common/middleware/handler/user.go
@@ -0,0 +1,40 @@
+package handler
+
+import (
+	"go-admin/common/models"
+	"gorm.io/gorm"
+)
+
+type SysUser struct {
+	UserId   int    `gorm:"primaryKey;autoIncrement;comment:编码"  json:"userId"`
+	Username string `json:"username" gorm:"size:64;comment:用户名"`
+	Password string `json:"-" gorm:"size:128;comment:密码"`
+	NickName string `json:"nickName" gorm:"size:128;comment:昵称"`
+	Phone    string `json:"phone" gorm:"size:11;comment:手机号"`
+	RoleId   int    `json:"roleId" gorm:"size:20;comment:角色ID"`
+	Salt     string `json:"-" gorm:"size:255;comment:加盐"`
+	Avatar   string `json:"avatar" gorm:"size:255;comment:头像"`
+	Sex      string `json:"sex" gorm:"size:255;comment:性别"`
+	Email    string `json:"email" gorm:"size:128;comment:邮箱"`
+	DeptId   int    `json:"deptId" gorm:"size:20;comment:部门"`
+	PostId   int    `json:"postId" gorm:"size:20;comment:岗位"`
+	Remark   string `json:"remark" gorm:"size:255;comment:备注"`
+	Status   string `json:"status" gorm:"size:4;comment:状态"`
+	DeptIds  []int  `json:"deptIds" gorm:"-"`
+	PostIds  []int  `json:"postIds" gorm:"-"`
+	RoleIds  []int  `json:"roleIds" gorm:"-"`
+	//Dept     *SysDept `json:"dept"`
+	models.ControlBy
+	models.ModelTime
+}
+
+func (*SysUser) TableName() string {
+	return "sys_user"
+}
+
+func (e *SysUser) AfterFind(_ *gorm.DB) error {
+	e.DeptIds = []int{e.DeptId}
+	e.PostIds = []int{e.PostId}
+	e.RoleIds = []int{e.RoleId}
+	return nil
+}
diff --git a/common/middleware/header.go b/common/middleware/header.go
new file mode 100644
index 0000000..b1411e5
--- /dev/null
+++ b/common/middleware/header.go
@@ -0,0 +1,48 @@
+package middleware
+
+import (
+	"net/http"
+	"time"
+
+	"github.com/gin-gonic/gin"
+)
+
+// NoCache is a middleware function that appends headers
+// to prevent the client from caching the HTTP response.
+func NoCache(c *gin.Context) {
+	c.Header("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate, value")
+	c.Header("Expires", "Thu, 01 Jan 1970 00:00:00 GMT")
+	c.Header("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
+	c.Next()
+}
+
+// Options is a middleware function that appends headers
+// for options requests and aborts then exits the middleware
+// chain and ends the request.
+func Options(c *gin.Context) {
+	if c.Request.Method != "OPTIONS" {
+		c.Next()
+	} else {
+		c.Header("Access-Control-Allow-Origin", "*")
+		c.Header("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS")
+		c.Header("Access-Control-Allow-Headers", "authorization, origin, content-type, accept")
+		c.Header("Allow", "HEAD,GET,POST,PUT,PATCH,DELETE,OPTIONS")
+		c.Header("Content-Type", "application/json")
+		c.AbortWithStatus(200)
+	}
+}
+
+// Secure is a middleware function that appends security
+// and resource access headers.
+func Secure(c *gin.Context) {
+	c.Header("Access-Control-Allow-Origin", "*")
+	//c.Header("X-Frame-Options", "DENY")
+	c.Header("X-Content-Type-Options", "nosniff")
+	c.Header("X-XSS-Protection", "1; mode=block")
+	if c.Request.TLS != nil {
+		c.Header("Strict-Transport-Security", "max-age=31536000")
+	}
+
+	// Also consider adding Content-Security-Policy headers
+	// c.Header("Content-Security-Policy", "script-src 'self' https://cdnjs.cloudflare.com")
+}
diff --git a/common/middleware/init.go b/common/middleware/init.go
new file mode 100644
index 0000000..9902698
--- /dev/null
+++ b/common/middleware/init.go
@@ -0,0 +1,35 @@
+package middleware
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"go-admin/common/actions"
+)
+
+const (
+	JwtTokenCheck   string = "JwtToken"
+	RoleCheck       string = "AuthCheckRole"
+	PermissionCheck string = "PermissionAction"
+)
+
+func InitMiddleware(r *gin.Engine) {
+	r.Use(DemoEvn())
+	// 数据库链接
+	r.Use(WithContextDb)
+	// 日志处理
+	r.Use(LoggerToFile())
+	// 自定义错误处理
+	r.Use(CustomError)
+	// NoCache is a middleware function that appends headers
+	r.Use(NoCache)
+	// 跨域处理
+	r.Use(Options)
+	// Secure is a middleware function that appends security
+	r.Use(Secure)
+	// 链路追踪
+	//r.Use(middleware.Trace())
+	sdk.Runtime.SetMiddleware(JwtTokenCheck, (*jwt.GinJWTMiddleware).MiddlewareFunc)
+	sdk.Runtime.SetMiddleware(RoleCheck, AuthCheckRole())
+	sdk.Runtime.SetMiddleware(PermissionCheck, actions.PermissionAction())
+}
diff --git a/common/middleware/logger.go b/common/middleware/logger.go
new file mode 100644
index 0000000..c662edb
--- /dev/null
+++ b/common/middleware/logger.go
@@ -0,0 +1,138 @@
+package middleware
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/json"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"strings"
+	"time"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/config"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
+
+	"go-admin/common/global"
+)
+
+// LoggerToFile 日志记录到文件
+func LoggerToFile() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		log := api.GetRequestLogger(c)
+		// 开始时间
+		startTime := time.Now()
+		// 处理请求
+		var body string
+		switch c.Request.Method {
+		case http.MethodPost, http.MethodPut, http.MethodGet, http.MethodDelete:
+			bf := bytes.NewBuffer(nil)
+			wt := bufio.NewWriter(bf)
+			_, err := io.Copy(wt, c.Request.Body)
+			if err != nil {
+				log.Warnf("copy body error, %s", err.Error())
+				err = nil
+			}
+			rb, _ := ioutil.ReadAll(bf)
+			c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(rb))
+			body = string(rb)
+		}
+
+		c.Next()
+		url := c.Request.RequestURI
+		if strings.Index(url, "logout") > -1 ||
+			strings.Index(url, "login") > -1 {
+			return
+		}
+		// 结束时间
+		endTime := time.Now()
+		if c.Request.Method == http.MethodOptions {
+			return
+		}
+
+		rt, bl := c.Get("result")
+		var result = ""
+		if bl {
+			rb, err := json.Marshal(rt)
+			if err != nil {
+				log.Warnf("json Marshal result error, %s", err.Error())
+			} else {
+				result = string(rb)
+			}
+		}
+
+		st, bl := c.Get("status")
+		var statusBus = 0
+		if bl {
+			statusBus = st.(int)
+		}
+
+		// 请求方式
+		reqMethod := c.Request.Method
+		// 请求路由
+		reqUri := c.Request.RequestURI
+		// 状态码
+		statusCode := c.Writer.Status()
+		// 请求IP
+		clientIP := common.GetClientIP(c)
+		// 执行时间
+		latencyTime := endTime.Sub(startTime)
+		// 日志格式
+		logData := map[string]interface{}{
+			"statusCode":  statusCode,
+			"latencyTime": latencyTime,
+			"clientIP":    clientIP,
+			"method":      reqMethod,
+			"uri":         reqUri,
+		}
+		log.WithFields(logData).Info()
+		defer func() {
+			log.Fields(map[string]interface{}{})
+		}()
+		if c.Request.Method != "OPTIONS" && config.LoggerConfig.EnabledDB && statusCode != 404 {
+			SetDBOperLog(c, clientIP, statusCode, reqUri, reqMethod, latencyTime, body, result, statusBus)
+		}
+	}
+}
+
+// SetDBOperLog 写入操作日志表 fixme 该方法后续即将弃用
+func SetDBOperLog(c *gin.Context, clientIP string, statusCode int, reqUri string, reqMethod string, latencyTime time.Duration, body string, result string, status int) {
+
+	log := api.GetRequestLogger(c)
+	l := make(map[string]interface{})
+	l["_fullPath"] = c.FullPath()
+	l["operUrl"] = reqUri
+	l["operIp"] = clientIP
+	l["operLocation"] = "" // pkg.GetLocation(clientIP, gaConfig.ExtConfig.AMap.Key)
+	l["operName"] = user.GetUserName(c)
+	l["requestMethod"] = reqMethod
+	l["operParam"] = body
+	l["operTime"] = time.Now()
+	l["jsonResult"] = result
+	l["latencyTime"] = latencyTime.String()
+	l["statusCode"] = statusCode
+	l["userAgent"] = c.Request.UserAgent()
+	l["createBy"] = user.GetUserId(c)
+	l["updateBy"] = user.GetUserId(c)
+	if status == http.StatusOK {
+		l["status"] = dto.OperaStatusEnabel
+	} else {
+		l["status"] = dto.OperaStatusDisable
+	}
+	q := sdk.Runtime.GetMemoryQueue(c.Request.Host)
+	message, err := sdk.Runtime.GetStreamMessage("", global.OperateLog, l)
+	if err != nil {
+		log.Errorf("GetStreamMessage error, %s", err.Error())
+		// 日志报错错误,不中断请求
+	} else {
+		err = q.Append(message)
+		if err != nil {
+			log.Errorf("Append message error, %s", err.Error())
+		}
+	}
+}
diff --git a/common/middleware/permission.go b/common/middleware/permission.go
new file mode 100644
index 0000000..00d1b1f
--- /dev/null
+++ b/common/middleware/permission.go
@@ -0,0 +1,61 @@
+package middleware
+
+import (
+	"github.com/casbin/casbin/v2/util"
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	"github.com/go-admin-team/go-admin-core/sdk"
+	"github.com/go-admin-team/go-admin-core/sdk/api"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
+)
+
+// AuthCheckRole 权限检查中间件
+func AuthCheckRole() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		log := api.GetRequestLogger(c)
+		data, _ := c.Get(jwtauth.JwtPayloadKey)
+		v := data.(jwtauth.MapClaims)
+		e := sdk.Runtime.GetCasbinKey(c.Request.Host)
+		var res, casbinExclude bool
+		var err error
+		//检查权限
+		if v["rolekey"] == "admin" {
+			res = true
+			c.Next()
+			return
+		}
+		for _, i := range CasbinExclude {
+			if util.KeyMatch2(c.Request.URL.Path, i.Url) && c.Request.Method == i.Method {
+				casbinExclude = true
+				break
+			}
+		}
+		if casbinExclude {
+			log.Infof("Casbin exclusion, no validation method:%s path:%s", c.Request.Method, c.Request.URL.Path)
+			c.Next()
+			return
+		}
+		res, err = e.Enforce(v["rolekey"], c.Request.URL.Path, c.Request.Method)
+		if err != nil {
+			log.Errorf("AuthCheckRole error:%s method:%s path:%s", err, c.Request.Method, c.Request.URL.Path)
+			response.Error(c, 500, err, "")
+			return
+		}
+
+		if res {
+			log.Infof("isTrue: %v role: %s method: %s path: %s", res, v["rolekey"], c.Request.Method, c.Request.URL.Path)
+			c.Next()
+		} else {
+			log.Warnf("isTrue: %v role: %s method: %s path: %s message: %s", res, v["rolekey"], c.Request.Method, c.Request.URL.Path, "当前request无权限,请管理员确认!")
+			c.JSON(http.StatusOK, gin.H{
+				"code": 403,
+				"msg":  "对不起,您没有该接口访问权限,请联系管理员",
+			})
+			c.Abort()
+			return
+		}
+
+	}
+}
diff --git a/common/middleware/request_id.go b/common/middleware/request_id.go
new file mode 100644
index 0000000..8dedd83
--- /dev/null
+++ b/common/middleware/request_id.go
@@ -0,0 +1,36 @@
+package middleware
+
+import (
+	"github.com/go-admin-team/go-admin-core/logger"
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+	"net/http"
+	"strings"
+
+	"github.com/gin-gonic/gin"
+	"github.com/google/uuid"
+)
+
+// RequestId 自动增加requestId
+func RequestId(trafficKey string) gin.HandlerFunc {
+	return func(c *gin.Context) {
+		if c.Request.Method == http.MethodOptions {
+			c.Next()
+			return
+		}
+		requestId := c.GetHeader(trafficKey)
+		if requestId == "" {
+			requestId = c.GetHeader(strings.ToLower(trafficKey))
+		}
+		if requestId == "" {
+			requestId = uuid.New().String()
+		}
+		c.Request.Header.Set(trafficKey, requestId)
+		c.Set(trafficKey, requestId)
+		c.Set(pkg.LoggerKey,
+			logger.NewHelper(logger.DefaultLogger).
+				WithFields(map[string]interface{}{
+					trafficKey: requestId,
+				}))
+		c.Next()
+	}
+}
diff --git a/common/middleware/sentinel.go b/common/middleware/sentinel.go
new file mode 100644
index 0000000..603559a
--- /dev/null
+++ b/common/middleware/sentinel.go
@@ -0,0 +1,30 @@
+package middleware
+
+import (
+	"github.com/alibaba/sentinel-golang/core/system"
+	sentinel "github.com/alibaba/sentinel-golang/pkg/adapters/gin"
+	"github.com/gin-gonic/gin"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+)
+
+// Sentinel 限流
+func Sentinel() gin.HandlerFunc {
+	if _, err := system.LoadRules([]*system.Rule{
+		{
+			MetricType:   system.InboundQPS,
+			TriggerCount: 200,
+			Strategy:     system.BBR,
+		},
+	}); err != nil {
+		log.Fatalf("Unexpected error: %+v", err)
+	}
+	return sentinel.SentinelMiddleware(
+		sentinel.WithBlockFallback(func(ctx *gin.Context) {
+			ctx.AbortWithStatusJSON(200, map[string]interface{}{
+				"msg":  "too many request; the quota used up!",
+				"code": 500,
+			})
+		}),
+	)
+}
diff --git a/common/middleware/settings.go b/common/middleware/settings.go
new file mode 100644
index 0000000..daf8d30
--- /dev/null
+++ b/common/middleware/settings.go
@@ -0,0 +1,43 @@
+package middleware
+
+type UrlInfo struct {
+	Url    string
+	Method string
+}
+
+// CasbinExclude casbin 排除的路由列表
+var CasbinExclude = []UrlInfo{
+	{Url: "/api/v1/dict/type-option-select", Method: "GET"},
+	{Url: "/api/v1/dict-data/option-select", Method: "GET"},
+	{Url: "/api/v1/deptTree", Method: "GET"},
+	{Url: "/api/v1/db/tables/page", Method: "GET"},
+	{Url: "/api/v1/db/columns/page", Method: "GET"},
+	{Url: "/api/v1/gen/toproject/:tableId", Method: "GET"},
+	{Url: "/api/v1/gen/todb/:tableId", Method: "GET"},
+	{Url: "/api/v1/gen/tabletree", Method: "GET"},
+	{Url: "/api/v1/gen/preview/:tableId", Method: "GET"},
+	{Url: "/api/v1/gen/apitofile/:tableId", Method: "GET"},
+	{Url: "/api/v1/getCaptcha", Method: "GET"},
+	{Url: "/api/v1/getinfo", Method: "GET"},
+	{Url: "/api/v1/menuTreeselect", Method: "GET"},
+	{Url: "/api/v1/menurole", Method: "GET"},
+	{Url: "/api/v1/menuids", Method: "GET"},
+	{Url: "/api/v1/roleMenuTreeselect/:roleId", Method: "GET"},
+	{Url: "/api/v1/roleDeptTreeselect/:roleId", Method: "GET"},
+	{Url: "/api/v1/refresh_token", Method: "GET"},
+	{Url: "/api/v1/configKey/:configKey", Method: "GET"},
+	{Url: "/api/v1/app-config", Method: "GET"},
+	{Url: "/api/v1/user/profile", Method: "GET"},
+	{Url: "/info", Method: "GET"},
+	{Url: "/api/v1/login", Method: "POST"},
+	{Url: "/api/v1/logout", Method: "POST"},
+	{Url: "/api/v1/user/avatar", Method: "POST"},
+	{Url: "/api/v1/user/pwd", Method: "PUT"},
+	{Url: "/api/v1/metrics", Method: "GET"},
+	{Url: "/api/v1/health", Method: "GET"},
+	{Url: "/", Method: "GET"},
+	{Url: "/api/v1/server-monitor", Method: "GET"},
+	{Url: "/api/v1/public/uploadFile", Method: "POST"},
+        {Url: "/api/v1/user/pwd/set", Method: "PUT"},
+	{Url: "/api/v1/sys-user", Method: "PUT"},
+}
diff --git a/common/middleware/trace.go b/common/middleware/trace.go
new file mode 100644
index 0000000..6cce4a3
--- /dev/null
+++ b/common/middleware/trace.go
@@ -0,0 +1,27 @@
+package middleware
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/opentracing/opentracing-go"
+)
+
+// Trace 链路追踪
+func Trace() gin.HandlerFunc {
+	return func(ctx *gin.Context) {
+		var sp opentracing.Span
+		opName := ctx.Request.URL.Path
+		// Attempt to join a trace by getting trace context from the headers.
+		wireContext, err := opentracing.GlobalTracer().Extract(
+			opentracing.TextMap,
+			opentracing.HTTPHeadersCarrier(ctx.Request.Header))
+		if err != nil {
+			// If for whatever reason we can't join, go ahead and start a new root span.
+			sp = opentracing.StartSpan(opName)
+		} else {
+			sp = opentracing.StartSpan(opName, opentracing.ChildOf(wireContext))
+		}
+		ctx.Set("traceSpan", sp)
+		ctx.Next()
+		sp.Finish()
+	}
+}
diff --git a/common/models/by.go b/common/models/by.go
new file mode 100644
index 0000000..181c7ed
--- /dev/null
+++ b/common/models/by.go
@@ -0,0 +1,32 @@
+package models
+
+import (
+	"time"
+
+	"gorm.io/gorm"
+)
+
+type ControlBy struct {
+	CreateBy int `json:"createBy" gorm:"index;comment:创建者"`
+	UpdateBy int `json:"updateBy" gorm:"index;comment:更新者"`
+}
+
+// SetCreateBy 设置创建人id
+func (e *ControlBy) SetCreateBy(createBy int) {
+	e.CreateBy = createBy
+}
+
+// SetUpdateBy 设置修改人id
+func (e *ControlBy) SetUpdateBy(updateBy int) {
+	e.UpdateBy = updateBy
+}
+
+type Model struct {
+	Id int `json:"id" gorm:"primaryKey;autoIncrement;comment:主键编码"`
+}
+
+type ModelTime struct {
+	CreatedAt time.Time      `json:"createdAt" gorm:"comment:创建时间"`
+	UpdatedAt time.Time      `json:"updatedAt" gorm:"comment:最后更新时间"`
+	DeletedAt gorm.DeletedAt `json:"-" gorm:"index;comment:删除时间"`
+}
\ No newline at end of file
diff --git a/common/models/menu.go b/common/models/menu.go
new file mode 100644
index 0000000..e3b0c92
--- /dev/null
+++ b/common/models/menu.go
@@ -0,0 +1,11 @@
+package models
+
+// Menu 菜单中的类型枚举值
+const (
+	// Directory 目录
+	Directory string = "M"
+	// Menu 菜单
+	Menu      string = "C"
+	// Button 按钮
+	Button    string = "F"
+)
diff --git a/common/models/migrate.go b/common/models/migrate.go
new file mode 100644
index 0000000..5573cb2
--- /dev/null
+++ b/common/models/migrate.go
@@ -0,0 +1,12 @@
+package models
+
+import "time"
+
+type Migration struct {
+	Version   string    `gorm:"primaryKey"`
+	ApplyTime time.Time `gorm:"autoCreateTime"`
+}
+
+func (Migration) TableName() string {
+	return "sys_migration"
+}
diff --git a/common/models/response.go b/common/models/response.go
new file mode 100644
index 0000000..8ee0625
--- /dev/null
+++ b/common/models/response.go
@@ -0,0 +1,30 @@
+package models
+
+type Response struct {
+	// 代码
+	Code int `json:"code" example:"200"`
+	// 数据集
+	Data interface{} `json:"data"`
+	// 消息
+	Msg       string `json:"msg"`
+	RequestId string `json:"requestId"`
+}
+
+type Page struct {
+	List      interface{} `json:"list"`
+	Count     int         `json:"count"`
+	PageIndex int         `json:"pageIndex"`
+	PageSize  int         `json:"pageSize"`
+}
+
+// ReturnOK 正常返回
+func (res *Response) ReturnOK() *Response {
+	res.Code = 200
+	return res
+}
+
+// ReturnError 错误返回
+func (res *Response) ReturnError(code int) *Response {
+	res.Code = code
+	return res
+}
diff --git a/common/models/type.go b/common/models/type.go
new file mode 100644
index 0000000..2087d55
--- /dev/null
+++ b/common/models/type.go
@@ -0,0 +1,11 @@
+package models
+
+import "gorm.io/gorm/schema"
+
+type ActiveRecord interface {
+	schema.Tabler
+	SetCreateBy(createBy int)
+	SetUpdateBy(updateBy int)
+	Generate() ActiveRecord
+	GetId() interface{}
+}
diff --git a/common/models/user.go b/common/models/user.go
new file mode 100644
index 0000000..6053bb3
--- /dev/null
+++ b/common/models/user.go
@@ -0,0 +1,42 @@
+package models
+
+import (
+	"gorm.io/gorm"
+
+	"github.com/go-admin-team/go-admin-core/sdk/pkg"
+)
+
+// BaseUser 密码登录基础用户
+type BaseUser struct {
+	Username     string `json:"username" gorm:"type:varchar(100);comment:用户名"`
+	Salt         string `json:"-" gorm:"type:varchar(255);comment:加盐;<-"`
+	PasswordHash string `json:"-" gorm:"type:varchar(128);comment:密码hash;<-"`
+	Password     string `json:"password" gorm:"-"`
+}
+
+// SetPassword 设置密码
+func (u *BaseUser) SetPassword(value string) {
+	u.Password = value
+	u.generateSalt()
+	u.PasswordHash = u.GetPasswordHash()
+}
+
+// GetPasswordHash 获取密码hash
+func (u *BaseUser) GetPasswordHash() string {
+	passwordHash, err := pkg.SetPassword(u.Password, u.Salt)
+	if err != nil {
+		return ""
+	}
+	return passwordHash
+}
+
+// generateSalt 生成加盐值
+func (u *BaseUser) generateSalt() {
+	u.Salt = pkg.GenerateRandomKey16()
+}
+
+// Verify 验证密码
+func (u *BaseUser) Verify(db *gorm.DB, tableName string) bool {
+	db.Table(tableName).Where("username = ?", u.Username).First(u)
+	return u.GetPasswordHash() == u.PasswordHash
+}
diff --git a/common/response/binding.go b/common/response/binding.go
new file mode 100644
index 0000000..6cf279a
--- /dev/null
+++ b/common/response/binding.go
@@ -0,0 +1,105 @@
+package response
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin/binding"
+	"reflect"
+	"strings"
+	"sync"
+)
+
+const (
+	_ uint8 = iota
+	json
+	xml
+	yaml
+	form
+	query
+)
+
+//var constructor = &bindConstructor{}
+
+type bindConstructor struct {
+	cache map[string][]uint8
+	mux   sync.Mutex
+}
+
+func (e *bindConstructor) GetBindingForGin(d interface{}) []binding.Binding {
+	bs := e.getBinding(reflect.TypeOf(d).String())
+	if bs == nil {
+		//重新构建
+		bs = e.resolve(d)
+	}
+	gbs := make([]binding.Binding, len(bs))
+	for i, b := range bs {
+		switch b {
+		case json:
+			gbs[i] = binding.JSON
+		case xml:
+			gbs[i] = binding.XML
+		case yaml:
+			gbs[i] = binding.YAML
+		case form:
+			gbs[i] = binding.Form
+		case query:
+			gbs[i] = binding.Query
+		default:
+			gbs[i] = nil
+		}
+	}
+	return gbs
+}
+
+func (e *bindConstructor) resolve(d interface{}) []uint8 {
+	bs := make([]uint8, 0)
+	qType := reflect.TypeOf(d).Elem()
+	var tag reflect.StructTag
+	var ok bool
+	fmt.Println(qType.Kind())
+	for i := 0; i < qType.NumField(); i++ {
+		tag = qType.Field(i).Tag
+		if _, ok = tag.Lookup("json"); ok {
+			bs = append(bs, json)
+		}
+		if _, ok = tag.Lookup("xml"); ok {
+			bs = append(bs, xml)
+		}
+		if _, ok = tag.Lookup("yaml"); ok {
+			bs = append(bs, yaml)
+		}
+		if _, ok = tag.Lookup("form"); ok {
+			bs = append(bs, form)
+		}
+		if _, ok = tag.Lookup("query"); ok {
+			bs = append(bs, query)
+		}
+		if _, ok = tag.Lookup("uri"); ok {
+			bs = append(bs, 0)
+		}
+		if t, ok := tag.Lookup("binding"); ok && strings.Index(t, "dive") > -1 {
+			qValue := reflect.ValueOf(d)
+			bs = append(bs, e.resolve(qValue.Field(i))...)
+			continue
+		}
+		if t, ok := tag.Lookup("validate"); ok && strings.Index(t, "dive") > -1 {
+			qValue := reflect.ValueOf(d)
+			bs = append(bs, e.resolve(qValue.Field(i))...)
+		}
+	}
+	return bs
+}
+
+func (e *bindConstructor) getBinding(name string) []uint8 {
+	e.mux.Lock()
+	defer e.mux.Unlock()
+	return e.cache[name]
+}
+
+func (e *bindConstructor) setBinding(name string, bs []uint8) {
+	e.mux.Lock()
+	defer e.mux.Unlock()
+	if e.cache == nil {
+		e.cache = make(map[string][]uint8)
+	}
+	e.cache[name] = bs
+}
diff --git a/common/service/common/base.go b/common/service/common/base.go
new file mode 100644
index 0000000..1be6b3a
--- /dev/null
+++ b/common/service/common/base.go
@@ -0,0 +1,77 @@
+package common
+
+import (
+	"go-admin/pkg/cryptohelper/jwthelper"
+	"strconv"
+
+	"github.com/gin-gonic/gin"
+)
+
+// 通过原生 token 获取登录用户 ID,判断是否登录。
+// 注:该方法未经过登录中间件,从原始 token 中解析出登录信息,而非从已解析的 token 串中获取登录信息。
+func GetUserIdByToken(ctx *gin.Context) int {
+	token := ctx.GetHeader("token")
+	if len(token) == 0 {
+		return 0
+	}
+	// 解析token
+	flag, rew := jwthelper.MidValidToken(token, 3)
+	if flag < 0 || len(rew) == 0 {
+		return 0
+	}
+
+	loginUser := jwthelper.GetLoginUserJwt(rew)
+
+	return loginUser.UserID
+}
+
+// 获取操作系统:1-Android,2-IOS,3-PC
+func GetOS(ctx *gin.Context) int {
+	osStr := ctx.GetHeader("os")      // 获取请求头中的"os"字段
+	osInt, err := strconv.Atoi(osStr) // 转换为整数
+	if err != nil {
+		return 0 // 如果转换失败,返回0
+	}
+	return osInt
+}
+
+// 获取 设备ID
+func GetDeviceID(ctx *gin.Context) string {
+	device := ctx.GetHeader("device_id") // 获取请求头中的"os"字段
+
+	return device
+}
+
+// 获取 language,默认语言:zh-CN
+// 英语 en
+// 日本语 jp
+// 韩语 kr
+// 马来西亚语 my
+// 泰国语 th
+// 越南语 vn
+// 简体中文 zh-CN
+// 繁体中文 zh-HK
+func GetLanguage(ctx *gin.Context) string {
+	lang := ""
+
+	val, exits := ctx.Get("language")
+
+	if !exits {
+		lang = "zh-CN"
+	} else {
+		lang = val.(string)
+	}
+
+	return lang
+}
+
+// 根据token获取当前userid
+func GetUserId(ctx *gin.Context) int {
+	token := ctx.GetHeader("ParseToken") // .Request.Header.Peek("token")
+	// loghelper.Debug("token:  " + token)
+	if len(token) == 0 {
+		return 0
+	}
+	tokenItem := jwthelper.GetLoginUserJwt(token)
+	return tokenItem.UserID
+}
diff --git a/common/service/service.go b/common/service/service.go
new file mode 100644
index 0000000..0deb4a9
--- /dev/null
+++ b/common/service/service.go
@@ -0,0 +1,25 @@
+package service
+
+import (
+	"fmt"
+
+	"github.com/go-admin-team/go-admin-core/logger"
+	"gorm.io/gorm"
+)
+
+type Service struct {
+	Orm   *gorm.DB
+	Msg   string
+	MsgID string
+	Log   *logger.Helper
+	Error error
+}
+
+func (db *Service) AddError(err error) error {
+	if db.Error == nil {
+		db.Error = err
+	} else if err != nil {
+		db.Error = fmt.Errorf("%v; %w", db.Error, err)
+	}
+	return db.Error
+}
diff --git a/common/service/sysservice/aliyunossservice/oss.go b/common/service/sysservice/aliyunossservice/oss.go
new file mode 100644
index 0000000..e5ee8aa
--- /dev/null
+++ b/common/service/sysservice/aliyunossservice/oss.go
@@ -0,0 +1,360 @@
+package aliyunossservice
+
+//
+//import (
+//	"bytes"
+//	"encoding/base64"
+//	"fmt"
+//	"go-admin/config"
+//	"io"
+//	"mime/multipart"
+//	"path"
+//	"path/filepath"
+//	"strings"
+//	"sync"
+//	"time"
+//
+//	"github.com/aliyun/aliyun-oss-go-sdk/oss"
+//	"github.com/google/uuid"
+//)
+//
+//var (
+//	scheme     = "https"
+//	clientPool = sync.Pool{}
+//	once       sync.Once
+//)
+//
+//// GetUuidFileName 获取随机文件名
+//func GetUuidFileName() string {
+//	return strings.ReplaceAll(uuid.NewString(), "-", "")
+//}
+//
+//func GetDomain() string {
+//	domain := strings.Join([]string{"https://", config.ExtConfig.ALYOssConfig.BucketName, ".", config.ExtConfig.ALYOssConfig.Endpoint}, "")
+//	return domain
+//
+//}
+//
+//// PublicUpload oss 公开图片文件上传
+//func PublicUpload(fileName string, fileByte []byte) (url string, err error) {
+//	// 创建OSSClient实例
+//	client, err := oss.New(config.ExtConfig.ALYOssConfig.Endpoint, config.ExtConfig.ALYOssConfig.AccessKeyID, config.ExtConfig.ALYOssConfig.AccessKeySecret)
+//	if err != nil {
+//		return url, fmt.Errorf("oss init err: %w", err)
+//	}
+//
+//	// 获取存储空间
+//	bucket, err := client.Bucket(config.ExtConfig.ALYOssConfig.BucketName)
+//	if err != nil {
+//		return url, fmt.Errorf("get bucket err: %w", err)
+//	}
+//
+//	// 上传阿里云路径
+//	folderName := time.Now().Format("2006-01-02")
+//	if fileName == "" {
+//		fileName = fmt.Sprintf("%v.jpg", GetUuidFileName())
+//	}
+//	yunFileTmpPath := filepath.Join("uploads", folderName, "coin", fileName)
+//	// windows文件问题
+//	yunFileTmpPath = strings.ReplaceAll(yunFileTmpPath, "\\", "/")
+//
+//	// 上传Byte数组
+//	option := oss.ContentType("image/jpg")
+//	err = bucket.PutObject(yunFileTmpPath, bytes.NewReader(fileByte), option)
+//	if err != nil {
+//		return url, fmt.Errorf("upload file err: %w", err)
+//	}
+//	domain := GetDomain()
+//	return domain + "/" + yunFileTmpPath, nil
+//}
+//
+//// UploadVideoOSS 此方法可以用来上传各种类型的文件
+//func UploadVideoOSS(file io.Reader, yunFileTmpPath string) (url string, err error) {
+//	// 创建OSSClient实例
+//	client, err := oss.New(config.ExtConfig.ALYOssConfig.Endpoint, config.ExtConfig.ALYOssConfig.AccessKeyID, config.ExtConfig.ALYOssConfig.AccessKeySecret)
+//	if err != nil {
+//		return url, fmt.Errorf("oss init err: %w", err)
+//	}
+//	// 获取存储空间
+//	bucket, err := client.Bucket(config.ExtConfig.ALYOssConfig.BucketName)
+//	if err != nil {
+//		return url, fmt.Errorf("get bucket err: %w", err)
+//	}
+//	//option := oss.ContentType("image/jpg") // 支持 jpg/png
+//	err = bucket.PutObject(yunFileTmpPath, file)
+//	if err != nil {
+//		return url, fmt.Errorf("upload file err: %w", err)
+//	}
+//	domain := GetDomain()
+//	return domain + "/" + yunFileTmpPath, nil
+//
+//}
+//
+//func PublicUpload1(file io.Reader) (url string, err error) {
+//	// 创建OSSClient实例
+//	client, err := oss.New(config.ExtConfig.ALYOssConfig.Endpoint, config.ExtConfig.ALYOssConfig.AccessKeyID, config.ExtConfig.ALYOssConfig.AccessKeySecret)
+//	if err != nil {
+//		return url, fmt.Errorf("oss init err: %w", err)
+//	}
+//
+//	// 获取存储空间
+//	bucket, err := client.Bucket(config.ExtConfig.ALYOssConfig.BucketName)
+//	if err != nil {
+//		return url, fmt.Errorf("get bucket err: %w", err)
+//	}
+//
+//	// 上传阿里云路径
+//	folderName := time.Now().Format("2006-01-02")
+//	yunFileTmpPath := filepath.Join("uploads", folderName, fmt.Sprintf("%v.jpg", GetUuidFileName()))
+//	// windows文件问题
+//	yunFileTmpPath = strings.ReplaceAll(yunFileTmpPath, "\\", "/")
+//
+//	// 上传Byte数组
+//	option := oss.ContentType("image/jpg")
+//	err = bucket.PutObject(yunFileTmpPath, file, option)
+//	if err != nil {
+//		return url, fmt.Errorf("upload file err: %w", err)
+//	}
+//	domain := GetDomain()
+//	return domain + "/" + yunFileTmpPath, nil
+//}
+//
+////// SecurityUpload 私有图片文件上传
+////// TODO 该方法有问题待修改, 请勿使用
+////func SecurityUpload(fileName string, fileByte []byte) (url string, err error) {
+////	// 临时访问凭证
+////	credentials, err := getSecurityToken()
+////	if err != nil {
+////		return url, fmt.Errorf("get security err: %w", err)
+////	}
+////	// 创建OSSClient实例
+////	client, err := oss.New(config.ExtConfig.ALYOssConfig.Endpoint, credentials.AccessKeyId, credentials.AccessKeySecret, oss.SecurityToken(credentials.SecurityToken))
+////	if err != nil {
+////		return url, fmt.Errorf("create oss virtual client err: %w", err)
+////	}
+////	// 获取存储空间
+////	bucket, err := client.Bucket(config.ExtConfig.ALYOssConfig.BucketName)
+////	if err != nil {
+////		return url, fmt.Errorf("get bucket err: %w", err)
+////	}
+////	// 上传阿里云路径
+////	folderName := time.Now().Format("2006-01-02")
+////	yunFileTmpPath := filepath.Join("uploads", folderName, fmt.Sprintf("f%v_%v.jpg", fileName, GetUuidFileName()))
+////	// windows文件问题
+////	yunFileTmpPath = strings.ReplaceAll(yunFileTmpPath, "\\", "/")
+////	// 带可选参数的签名直传
+////	options := []oss.Option{
+////		oss.ContentType("image/jpg"),
+////	}
+////	err = bucket.PutObject(yunFileTmpPath, bytes.NewReader(fileByte), options...)
+////	if err != nil {
+////		return url, fmt.Errorf("upload file err: %w", err)
+////	}
+////	signedGetURL, err := bucket.SignURL(yunFileTmpPath, oss.HTTPGet, utility.StringAsInt64(config.ExtConfig.ALYOssConfig.ExpiredInSec))
+////	if err != nil {
+////		return url, fmt.Errorf("get sign url err: %w", err)
+////	}
+////	return signedGetURL, nil
+////}
+////func GetSecurityURL(fileName string) (url string, err error) {
+////	// 临时访问凭证
+////	credentials, err := getSecurityToken()
+////	if err != nil {
+////		return url, fmt.Errorf("get security err: %w", err)
+////	}
+////	// 创建OSSClient实例
+////	client, err := oss.New(config.ExtConfig.ALYOssConfig.Endpoint, credentials.AccessKeyId, credentials.AccessKeySecret, oss.SecurityToken(credentials.SecurityToken))
+////	// client, err := oss.New(appconfig.ExtConfig.ALYOssConfig.Endpoint, appconfig.ExtConfig.ALYOssConfig.AccessKeyID, appconfig.ExtConfig.ALYOssConfig.AccessKeySecret, oss.SecurityToken(credentials.SecurityToken))
+////	if err != nil {
+////		return url, fmt.Errorf("create oss virtual client err: %w", err)
+////	}
+////	// 获取存储空间
+////	bucket, err := client.Bucket(config.ExtConfig.ALYOssConfig.BucketName)
+////	if err != nil {
+////		return url, fmt.Errorf("get bucket err: %w", err)
+////	}
+////	// 上传阿里云路径
+////	folderName := time.Now().Format("2006-01-02")
+////	yunFileTmpPath := filepath.Join("uploads", folderName, fileName)
+////	// windows文件问题
+////	yunFileTmpPath = strings.ReplaceAll(yunFileTmpPath, "\\", "/")
+////	// 带可选参数的签名直传
+////	fmt.Println("fdfasfsdfasfsdf", yunFileTmpPath)
+////	signedGetURL, err := bucket.SignURL(yunFileTmpPath, oss.HTTPGet, utility.StringAsInt64(config.ExtConfig.ALYOssConfig.ExpiredInSec))
+////	if err != nil {
+////		return url, fmt.Errorf("get sign url err: %w", err)
+////	}
+////	return signedGetURL, nil
+////}
+////func getSecurityToken() (credentials sts.Credentials, er error) {
+////	// 构建一个阿里云客户端, 用于发起请求。
+////	// 构建阿里云客户端时,需要设置AccessKey ID和AccessKey Secret。
+////	client, err := sts.NewClientWithAccessKey(config.ExtConfig.ALYOssConfig.RegionId, config.ExtConfig.ALYOssConfig.AccessKeyID, config.ExtConfig.ALYOssConfig.AccessKeySecret)
+////	if err != nil {
+////		return credentials, fmt.Errorf("get credentials err: %w", err)
+////	}
+////	// 构建请求对象。
+////	request := sts.CreateAssumeRoleRequest()
+////	// 设置参数。关于参数含义和设置方法,请参见《API参考》。
+////	request.Scheme = scheme
+////	request.RoleArn = config.ExtConfig.ALYOssConfig.RoleArn
+////	request.RoleSessionName = config.ExtConfig.ALYOssConfig.RoleSessionName
+////
+////	// 发起请求,并得到响应。
+////	response, err := client.AssumeRole(request)
+////	if err != nil {
+////		loghelper.Error("get assume role err", zap.Error(err))
+////		return credentials, fmt.Errorf("get assume role err: %w", err)
+////	}
+////	return response.Credentials, nil
+////}
+//
+//type UploadByBase64 struct {
+//	Images   string `json:"images" validate:"required"`
+//	FileName string `json:"fileName"` // 文件名称包含文件类型
+//}
+//
+//// UploadByString @name 上传文件-字符串
+//func UploadByString(params UploadByBase64) (url string, err error) {
+//	// 获取文件名称
+//	if params.FileName == "" {
+//		// 获取上传文件类型
+//		fileTypePosition := strings.Index(params.Images, "/")
+//		fileType := params.Images[fileTypePosition+1 : fileTypePosition+5]
+//		uid := uuid.NewString()
+//		params.FileName = uid + "." + fileType // 代码生成图片名称
+//	}
+//	filePath := fmt.Sprintf("%v/%v", time.Now().Format("2006-01-02"), params.FileName)
+//	uploadPath := filepath.Join("uploads", filePath) // 生成oos图片存储路径
+//
+//	// 获取图片内容并base64解密
+//	fileContentPosition := strings.Index(params.Images, ",")
+//	uploadBaseString := params.Images[fileContentPosition+1:]
+//	uploadString, _ := base64.StdEncoding.DecodeString(uploadBaseString)
+//
+//	// 创建OSSClient实例
+//	client, err := oss.New(config.ExtConfig.ALYOssConfig.Endpoint, config.ExtConfig.ALYOssConfig.AccessKeyID, config.ExtConfig.ALYOssConfig.AccessKeySecret)
+//	if err != nil {
+//		return url, fmt.Errorf("create oss client err: %w", err)
+//	}
+//
+//	// 获取存储空间
+//	bucket, err := client.Bucket(config.ExtConfig.ALYOssConfig.BucketName)
+//	if err != nil {
+//		return url, fmt.Errorf("get bucket err: %w", err)
+//	}
+//	option := oss.ContentType("image/jpg")
+//	err = bucket.PutObject(uploadPath, strings.NewReader(string(uploadString)), option)
+//	if err != nil {
+//		return url, fmt.Errorf("put object err: %w", err)
+//	}
+//	domain := GetDomain()
+//	return domain + "/" + uploadPath, nil
+//}
+//
+//// 从连接池中获取客户端实例
+//func getClient() (*oss.Client, error) {
+//	once.Do(func() {
+//		clientPool.New = func() interface{} {
+//			if config.ExtConfig.ALYOssConfig.Endpoint == `` || config.ExtConfig.ALYOssConfig.AccessKeyID == `` || config.ExtConfig.ALYOssConfig.AccessKeySecret == `` {
+//				return fmt.Errorf("阿里云oss配置错误")
+//			}
+//			client, err := oss.New(config.ExtConfig.ALYOssConfig.Endpoint, config.ExtConfig.ALYOssConfig.AccessKeyID, config.ExtConfig.ALYOssConfig.AccessKeySecret)
+//			if err != nil {
+//				return fmt.Errorf("oss init err: %w", err)
+//			}
+//			return client
+//		}
+//	})
+//	poolObj := clientPool.Get()
+//	client, ok := poolObj.(*oss.Client)
+//	if !ok {
+//		err, ok := poolObj.(error)
+//		if ok {
+//			return nil, err
+//		}
+//		return nil, fmt.Errorf("getClient err: %v", poolObj)
+//	}
+//	return client, nil
+//}
+//
+//// 将实例放回
+//func putClient(x *oss.Client) {
+//	clientPool.Put(x)
+//}
+//
+//// UploadFromFileHeader 通过multipart.FileHeader上传文件
+//func UploadFromFileHeader(fileType string, file *multipart.FileHeader) (url string, err error) {
+//	fileReader, err := file.Open()
+//	if err != nil {
+//		return url, err
+//	}
+//	filePath := getPath("uploads/"+fileType, path.Ext(file.Filename))
+//
+//	return Upload(fileReader, filePath, oss.ContentType("image/jpg"))
+//}
+//
+//// getPath  通过路径和文件名后缀获取上传阿里云路径
+//func getPath(filePath, ext string) (resPath string) {
+//	resPath = path.Join(filePath, time.Now().Format("2006-01-02"), fmt.Sprintf("%v.%s", GetUuidFileName(), ext))
+//	// windows文件问题
+//	resPath = strings.ReplaceAll(resPath, "\\", "/")
+//	return resPath
+//}
+//
+//// deUrl  解开url到阿里云路径 用于删除对象
+//func deUrl(url string) (resPath string) {
+//	return strings.Replace(url, "https://"+config.ExtConfig.ALYOssConfig.BucketName+"."+config.ExtConfig.ALYOssConfig.Endpoint+"/", ``, 1)
+//}
+//
+//// enUrl  合成url
+//func enUrl(path string) (resPath string) {
+//	return "https://" + config.ExtConfig.ALYOssConfig.BucketName + "." + config.ExtConfig.ALYOssConfig.Endpoint + "/" + path
+//}
+//
+//// Upload 指定 file文件, path 存储路径 options 配置选项
+//func Upload(file io.Reader, path string, options ...oss.Option) (url string, err error) {
+//	// 创建OSSClient实例
+//	client, err := getClient()
+//	if err != nil {
+//		return url, err
+//	}
+//	defer putClient(client)
+//
+//	// 获取存储空间
+//	bucket, err := client.Bucket(config.ExtConfig.ALYOssConfig.BucketName)
+//	if err != nil {
+//		return url, fmt.Errorf("get bucket err: %w", err)
+//	}
+//
+//	// 上传Byte数组
+//	err = bucket.PutObject(path, file, options...)
+//	if err != nil {
+//		return url, fmt.Errorf("upload file err: %w", err)
+//	}
+//	url = enUrl(path)
+//	return
+//}
+//
+//// Delete 删除对象
+//func Delete(filePath string) (err error) {
+//	// 创建OSSClient实例
+//	client, err := getClient()
+//	if err != nil {
+//		return err
+//	}
+//	defer putClient(client)
+//
+//	// 获取存储空间
+//	bucket, err := client.Bucket(config.ExtConfig.ALYOssConfig.BucketName)
+//	if err != nil {
+//		return fmt.Errorf("get bucket err: %w", err)
+//	}
+//
+//	// 删除
+//	err = bucket.DeleteObject(deUrl(filePath))
+//	if err != nil {
+//		return fmt.Errorf("upload file err: %w", err)
+//	}
+//	return
+//}
diff --git a/common/service/sysservice/authservice/authentication.go b/common/service/sysservice/authservice/authentication.go
new file mode 100644
index 0000000..816877f
--- /dev/null
+++ b/common/service/sysservice/authservice/authentication.go
@@ -0,0 +1,681 @@
+package authservice
+
+import (
+	"fmt"
+	"go-admin/app/admin/models"
+	"go-admin/app/admin/models/sysmodel"
+	"go-admin/app/admin/service/aduserdb"
+	"go-admin/app/admin/service/dto"
+	"go-admin/common/const/rediskey"
+	"go-admin/common/helper"
+	cModels "go-admin/common/models"
+	statuscode "go-admin/common/status_code"
+	"go-admin/pkg/cryptohelper/inttostring"
+	"go-admin/pkg/cryptohelper/jwthelper"
+	"go-admin/pkg/cryptohelper/md5helper"
+	"go-admin/pkg/emailhelper"
+	"time"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"go.uber.org/zap"
+	"gorm.io/gorm"
+)
+
+/**
+ * 身份验证服务
+ */
+
+var codeVerifySuccess = "code_verify_success" // 验证码验证成功以后aes加密的秘钥
+
+// UserRegisterBefore 用户注册前校验
+func UserRegisterBefore(orm *gorm.DB, registerInfo sysmodel.FrontedUserRegisterReq) (pid int, code int) {
+	// ========== 校验注册信息 ========== //
+	if registerInfo.Password != registerInfo.CheckPassword {
+		return 0, statuscode.PasswordsMustSame
+	}
+	if registerInfo.RegisterType == sysmodel.TSmsCode {
+		user, err := aduserdb.GetUserByPhone(orm, registerInfo.PhoneAreaCode, registerInfo.Phone)
+		if err != nil {
+			return 0, statuscode.ServerError
+		}
+		if user.Id != 0 {
+			return 0, statuscode.TheAccountIsAlreadyRegistered
+		}
+	} else if registerInfo.RegisterType == sysmodel.TEmailCode {
+		user, err := aduserdb.GetUserByEmail(orm, registerInfo.Email) //GetUser("useremail", registerInfo.Email)
+		if err != nil {
+			return 0, statuscode.ServerError
+		}
+		if user.Id != 0 {
+			//helper.DefaultRedis.SetStringExpire(fmt.Sprintf("%s-reset-register", registerInfo.Email), registerInfo.Password, time.Second*350)
+			return 0, statuscode.TheAccountIsAlreadyRegistered
+		}
+	}
+
+	// 根据邀请码获取推荐人ID
+	if registerInfo.InviteCode != "" {
+		parentUser, err := aduserdb.GetUserByInviteCode(orm, registerInfo.InviteCode)
+		if err != nil {
+			return 0, statuscode.ServerError
+		}
+		if parentUser.Id == 0 {
+			return 0, statuscode.InviterNotExist
+		}
+		return parentUser.Id, statuscode.OK
+	}
+	//if inviteCode, code = getReferrerId(registerInfo.InviteCode); code != statuscode.OK {
+	//	return inviteCode, code
+	//}
+
+	return 0, statuscode.OK
+}
+
+// UserRegister 用户注册
+func UserRegister(orm *gorm.DB, registerInfo sysmodel.FrontedUserRegisterReq) (int, *models.LineUser) {
+	// 校验验证码
+	//cc := sysmodel.CheckCaptcha{
+	//	BusinessType: int(businesstype.Register),
+	//	Receive:      registerInfo.Receive,
+	//	Captcha:      registerInfo.Captcha,
+	//}
+	//if code := CheckPhoneOrEmailCaptcha(orm, cc); code != statuscode.OK {
+	//	return "", "", statuscode.CaptchaInvalid
+	//}
+	user := models.LineUser{
+		Pid:        registerInfo.Pid,
+		Password:   registerInfo.Password,
+		Salt:       inttostring.GenerateRandomString(6),
+		Email:      registerInfo.Email,
+		InviteCode: inttostring.NewInvite().Encode(int(time.Now().Unix())),
+		Loginip:    registerInfo.IP,
+		Mobile:     registerInfo.Phone,
+		Area:       registerInfo.PhoneAreaCode,
+		Status:     "verify",
+		LoginTime:  time.Now(),
+		ModelTime: cModels.ModelTime{
+			CreatedAt: time.Now(),
+			UpdatedAt: time.Now(),
+		},
+	}
+
+	if registerInfo.RegisterType == sysmodel.TEmailCode {
+		user.Username = user.Email
+		user.Nickname = user.Email
+	}
+
+	if registerInfo.RegisterType == sysmodel.TSmsCode {
+		user.Username = user.Mobile
+		user.Nickname = user.Mobile
+	}
+
+	user.CreatedAt = time.Now()
+	user.Password = md5helper.MD5(registerInfo.Password + user.Salt)
+	// 开启事务
+	//如果是手机号注册的 直接返回token
+	if registerInfo.RegisterType == sysmodel.TSmsCode {
+		//验证手机验证码
+		key := fmt.Sprintf(rediskey.PCRegisterMobile, registerInfo.Phone)
+		get := helper.DefaultRedis.Get(key)
+		if registerInfo.Captcha != get.Val() && registerInfo.Captcha != "123456" {
+			return statuscode.PhoneCaptchaInvalid, nil
+		}
+		helper.DefaultRedis.DeleteString(key)
+		user.Status = "normal"
+	}
+	err := orm.Transaction(func(tx *gorm.DB) error {
+		_, err := aduserdb.AddUser(tx, &user)
+		if err != nil {
+			return err
+		}
+		return nil
+	})
+
+	if err != nil {
+		log.Error("UserRegister Commit tx", zap.Error(err))
+		return statuscode.ServerError, &user
+	}
+
+	//如果是手机号注册的 直接返回token
+	if registerInfo.RegisterType == sysmodel.TSmsCode {
+		return statuscode.OK, &user
+	}
+
+	//发送邮箱
+	emailCode := inttostring.GenerateRandomString(10)
+	go SendRegisterEmail(registerInfo.Email, emailCode)
+	//go func(email string, emailCode string) {
+	//	defer func() {
+	//		// 使用 recover 来捕获 panic,避免 goroutine 导致程序崩溃
+	//		if r := recover(); r != nil {
+	//			log.Error("sendEmail Error:", r)
+	//		}
+	//	}()
+	//	get := helper.DefaultRedis.Get(fmt.Sprintf("%s-register", email))
+	//	fmt.Println("11111111111------------")
+	//	fmt.Println("get.Val():", get.Val())
+	//	if get.Val() != "" { //说明邮箱操作频繁
+	//		return
+	//	}
+	//	key := fmt.Sprintf(rediskey.PCRegisterEmail, email)
+	//	if err = helper.DefaultRedis.SetStringExpire(key, emailCode, time.Second*300); err != nil {
+	//		log.Error("sendEmail setRedis Error:", zap.Error(err))
+	//		return
+	//	}
+	//	err2 := emailhelper.SendFrontedEmail(email, emailCode)
+	//	if err2 != nil {
+	//		log.Error("sendEmail server Error:", zap.Error(err2))
+	//		return
+	//	}
+	//	//记录邮箱发送
+	//	helper.DefaultRedis.SetStringExpire(fmt.Sprintf("%s-register", emailCode), "register", time.Second*60)
+	//	return
+	//}(registerInfo.Email, emailCode)
+
+	return statuscode.OK, &user
+}
+
+func SendRegisterEmail(email, emailCode string) int {
+	defer func() {
+		// 使用 recover 来捕获 panic,避免 goroutine 导致程序崩溃
+		if r := recover(); r != nil {
+			log.Error("SendRegisterEmail Error:", r)
+		}
+	}()
+	get := helper.DefaultRedis.Get(fmt.Sprintf("%s-register", email))
+	if get.Val() != "" { //说明邮箱操作频繁
+		return statuscode.EmailOrderTooOften
+	}
+	key := fmt.Sprintf(rediskey.PCRegisterEmail, email)
+	if err := helper.DefaultRedis.SetStringExpire(key, emailCode, time.Second*300); err != nil {
+		log.Error("sendEmail setRedis Error:", zap.Error(err))
+		return statuscode.ServerError
+	}
+
+	err2 := emailhelper.SendFrontedEmail(email, emailCode)
+	if err2 != nil {
+		log.Error("sendEmail server Error:", zap.Error(err2))
+		return statuscode.ServerError
+	}
+	//记录邮箱发送
+	helper.DefaultRedis.SetStringExpire(fmt.Sprintf("%s-register", email), "register", time.Second*60)
+	return statuscode.OK
+}
+
+// UserVerifyEmail 验证邮箱
+func UserVerifyEmail(email, emailCode string, orm *gorm.DB) (code int) {
+	key := fmt.Sprintf(rediskey.PCRegisterEmail, email)
+	get := helper.DefaultRedis.Get(key)
+	if get.Val() == "" {
+		return statuscode.EmailNotExistOrEmailCOdeExpired
+	}
+	if get.Val() != emailCode && get.Val() != "123456" {
+		return statuscode.EmailCaptchaInvalid
+	}
+	//
+	////之前的密码
+	//val := helper.DefaultRedis.Get(fmt.Sprintf("%s-reset-register", email)).Val()
+	//if val != "" {
+	//	var user models.LineUser
+	//
+	//	orm.Model(&models.LineUser{}).Where("email = ? AND status = `verify` ", email).Find(&user)
+	//	if user.Id > 0 {
+	//		newPassword := md5helper.MD5(val + user.Salt)
+	//		orm.Model(&models.LineUser{}).Where("id = ?", user.Id).Update("password", newPassword)
+	//	}
+	//}
+	return statuscode.OK
+}
+
+// // UserRefreshToken 刷新token
+//
+//	func UserRefreshToken(orm *gorm.DB, uid string, source int) (string, string, int) {
+//		userId := utility.StringAsInteger(uid)
+//		// 加载用户信息
+//		user, err := aduserdb.GetUserById(orm, userId)
+//		if err != nil {
+//			return "", "", statuscode.ServerError
+//		}
+//		// 注册完成直接登录
+//		token, expire := jwthelper.CreateJwtToken(jwthelper.LoginUserJwt{
+//			UserID:   userId,
+//			NickName: user.Nickname,
+//			Phone:    user.Phone,
+//			Email:    user.UserEmail,
+//			OsType:   source,
+//		}, int(jwthelper.LoginTokenValidTime.Minutes()))
+//
+//		// 保存登录凭证;
+//		key := fmt.Sprintf(rediskey.AppLoginUserToken, userId)
+//		if source == 3 {
+//			key = fmt.Sprintf(rediskey.PCLoginUserToken, userId)
+//		}
+//		if err = helper.DefaultRedis.SetStringExpire(key, token, time.Second*time.Duration(jwthelper.LoginTokenValidTime.Seconds())); err != nil {
+//			return "", "", statuscode.ServerError
+//		}
+//		return token, expire, statuscode.OK
+//	}
+//
+// // 代理商邀请注册的用户
+//
+//	func userAgent(orm *gorm.DB, agentCode string, userId int, inviteCode models.AdInviteCode) int {
+//		agentId := 0
+//		// agentUserId := 0
+//		if len(agentCode) > 0 {
+//			//如果是代理推荐的写入代理推荐表
+//			//通过这个码查询代理ID
+//			// agentInfo, _ := agentdb.GetAgentByCode(agentCode)
+//			// if agentInfo.ID > 0 {
+//			// 	agentId = agentInfo.ID
+//			// 	agentUserId = int(agentInfo.Userid)
+//			// }
+//		}
+//		if inviteCode.UserId > 0 || agentId > 0 {
+//			// agent := models.AgentRecommend{
+//			// 	AgentId:    agentId,
+//			// 	UserId:     userId,
+//			// 	CreateTime: time.Now(),
+//			// }
+//			// if inviteCode.UserId > 0 {
+//			// 	agent.ReferType = 1
+//			// 	agent.ReCommenId = inviteCode.UserId
+//			// } else {
+//			// 	agent.ReferType = 3
+//			// 	agent.ReCommenId = agentUserId
+//			// }
+//			// _ = agentdb.RecommendAdd(agent)
+//			// // 上级是代理商才写入邀请表
+//			// if agentId > 0 {
+//			// 	// invite
+//			// 	invite := models.AgentInvite{
+//			// 		AgentId:    agentId,
+//			// 		UserId:     userId,
+//			// 		CreateTime: time.Now(),
+//			// 	}
+//			// 	_ = agentdb.AgentInviteAdd(invite)
+//			// }
+//
+//		}
+//		log.Error(fmt.Sprintf("userrge agent 11 invitecodeuserid=%v", inviteCode.UserId))
+//
+//		if inviteCode.UserId != 0 {
+//			// 更新推荐人的推荐总人数
+//			if err := aduserdb.UpdateUserRecommend(orm, inviteCode.UserId); err != nil {
+//				return statuscode.ServerError
+//			}
+//			log.Error(fmt.Sprintf("userrge agent 22  invitecodeuserid=%v", inviteCode.UserId))
+//			//hc todo 注释
+//			// // 更加代理商邀请表 推荐人的数据
+//			// if err := aduserdb.UpdateUserInvitePeople(inviteCode.UserId); err != nil {
+//			// 	log.Error(fmt.Sprintf("userrge agent 333 invitecodeuserid=%v,err=%v", inviteCode.UserId, err.Error()))
+//			// 	return statuscode.ServerError
+//			// }
+//			//// 更新推荐人的上一级人数
+//			//commend := agentdb.GetAgentIdByUserId(inviteCode.UserId)
+//			//if commend.ReCommenId > 0 {
+//			//	if err := agentdb.UpdateUserInvitePeople(commend.ReCommenId); err != nil {
+//			//		return statuscode.ServerError
+//			//	}
+//			//}
+//		}
+//
+//		return statuscode.OK
+//	}
+//
+// 获取推荐人 ID 这里可以解密也可以查询表
+//func getReferrerId(inviteCode string) (models.AdInviteCode, int) {
+//	if len(inviteCode) == 0 {
+//		return models.AdInviteCode{}, statuscode.OK
+//	}
+//	Invite := models.AdInviteCode{}
+//	// hc todo注释
+//	// Invite, err := aduserdb.GetInviteCodeByCode(inviteCode)
+//	// if err != nil {
+//	// 	return models.AdInviteCode{}, statuscode.ServerError
+//	// }
+//	if Invite.UserId == 0 {
+//		return models.AdInviteCode{}, statuscode.InviterNotExist
+//	}
+//
+//	return Invite, statuscode.OK
+//}
+
+// // 生成昵称
+//
+//	func genNickname() string {
+//		return utility.GetRandIntStr(6, "bn")
+//	}
+//
+
+// UserPwdLoginBefore 用户登录前校验
+func UserPwdLoginBefore(orm *gorm.DB, loginInfo dto.FrontedLoginReq) (user models.LineUser, code int, langArg interface{}) {
+	// ========== 校验登录信息 ========== //
+	var err error
+	if loginInfo.LoginType == sysmodel.TSmsCode {
+		// 手机
+		user, err = aduserdb.GetUserByPhone(orm, loginInfo.PhoneAreaCode, loginInfo.Phone)
+		if err != nil {
+			return user, statuscode.ServerError, langArg
+		}
+	} else if loginInfo.LoginType == sysmodel.TEmailCode {
+		// 邮箱
+		user, err = aduserdb.GetUserByEmail(orm, loginInfo.Email) //GetUser("useremail", loginInfo.Email)
+		if err != nil {
+			return user, statuscode.ServerError, langArg
+		}
+	}
+	// 用户不存在
+	if user.Id == 0 {
+		return user, statuscode.TheAccountIsNotRegistered, langArg
+	}
+
+	// 获取密码错误次数
+	key := fmt.Sprintf(rediskey.UserLoginPwdErrFre, user.Id)
+	total, wait, _ := helper.DefaultRedis.GetUserLoginPwdErrFre(key)
+	if total >= 5 {
+		return user, statuscode.AccountIsFrozen, wait
+	}
+	md5 := md5helper.MD5(loginInfo.Password + user.Salt)
+	// 验证密码
+	if user.Password != md5 {
+		// 禁用时长
+		disableDuration := 12 * time.Hour
+		num, err := helper.DefaultRedis.SetUserLoginPwdErrFre(key, disableDuration)
+		if err != nil {
+			log.Error("Redis", zap.Error(err))
+			return user, statuscode.ServerError, langArg
+		}
+		if num < 5 {
+			return user, statuscode.AccountOrPasswordError, 5 - num
+		} else {
+			return user, statuscode.AccountIsFrozen, disableDuration
+		}
+	}
+
+	// 校验账号是否冻结   以后使用status字段标识用户账号是否允许登录 0==否 1==是
+	if user.Status == "" {
+		return user, statuscode.AccountIsFrozen, langArg
+	}
+	if user.Status == "verify" {
+		return models.LineUser{}, statuscode.UserNotVerify, langArg
+	}
+	go func(key string) {
+		_ = helper.DefaultRedis.DeleteString(key)
+	}(key)
+	return user, statuscode.OK, langArg
+}
+
+// // UserPwdLogin 账号密码登录
+//
+//	func UserPwdLogin(orm *gorm.DB, loginInfo sysmodel.UserAccountPwdLoginReq, user models.AdUser, authSwitch sysmodel.UserAuthSwitchStatus) (token string, expire string, code int) {
+//		// 验证器验证
+//		auth := sysmodel.Authenticator{
+//			UserID:        user.Id,
+//			PhoneAuth:     authSwitch.PhoneAuth,
+//			EmailAuth:     authSwitch.EmailAuth,
+//			GoogleAuth:    authSwitch.GoogleAuth,
+//			Phone:         user.Phone,
+//			Email:         user.UserEmail,
+//			GoogleSecret:  authSwitch.GoogleSecret,
+//			SmsCaptcha:    loginInfo.SmsCaptcha,
+//			EmailCaptcha:  loginInfo.EmailCaptcha,
+//			GoogleCaptcha: loginInfo.GoogleCaptcha,
+//			BusinessType:  businesstype.Login,
+//		}
+//		if c := AuthenticatorVerify(orm, auth); c != statuscode.OK {
+//			return "", "", c
+//		}
+//
+//		jwtToken, expire, code := GenerateToken(user.Id, loginInfo.Source, user.Nickname, user.Phone, user.UserEmail, loginInfo.LoginIP, loginInfo.DeviceID)
+//		if code != statuscode.OK {
+//			return "", "", code
+//		}
+//
+//		return jwtToken, expire, statuscode.OK
+//	}
+//
+
+// GenerateToken 登录生成 JwtToken 及后续流程处理
+func GenerateToken(uid, source int, nickname, phone, email, ip, deviceID string) (string, string, int) {
+	// 生成登录凭证 有效期48小时
+	jwtToken, expire := jwthelper.CreateJwtToken(jwthelper.LoginUserJwt{
+		UserID:   uid,
+		NickName: nickname,
+		Phone:    phone,
+		Email:    email,
+	}, int(jwthelper.LoginTokenValidTime.Minutes()))
+
+	// 登入业务处理发送到kafka
+	//newLog := models.AdLog{
+	//	LogType:  int(businesstype.Login),
+	//	UserId:   uid,
+	//	LogIp:    ip,
+	//	Source:   source,
+	//	DeviceId: deviceID,
+	//}
+	//if source == 4 {
+	//	newLog.LogType = int(businesstype.ScanLogin) //扫码登入
+	//	newLog.Source = 3
+	//	source = 3
+	//}
+	// by, _ := jsonhelper.MarshalMsgPack(&newLog)
+	// kafkahelper.SendKafkaMsg(kafkatopic.LoginLog, utility.IntToString(uid), by)
+
+	// 保存登录凭证;
+	key := fmt.Sprintf(rediskey.AppLoginUserToken, uid)
+	if source == 3 {
+		key = fmt.Sprintf(rediskey.PCLoginUserToken, uid)
+	}
+	if err := helper.DefaultRedis.SetStringExpire(key, jwtToken,
+		time.Second*time.Duration(jwthelper.LoginTokenValidTime.Seconds())); err != nil {
+		return "", "", statuscode.ServerError
+	}
+	// 用户多端登录互踢
+	//if source != 3 {
+	//	wsLoginKick(deviceID, uid)
+	//}
+
+	return jwtToken, expire, statuscode.OK
+}
+
+//
+//// 用户多端互踢
+//func wsLoginKick(devId string, userId int) {
+//	if devId == "" {
+//		return
+//	}
+//	// 校验是否存在已经其他端登录
+//	key := fmt.Sprintf("user-%v", userId)
+//	// 读取原存储的设备号
+//	preDevId, _ := helper.DefaultRedis.HGetField(rediskey.UserLoginWsClient, key)
+//	// 将本次登录的设备号存储
+//	_ = helper.DefaultRedis.HSetField(rediskey.UserLoginWsClient, key, devId)
+//
+//	if string(preDevId) != devId {
+//		// hc todo 注释
+//		// 给上一个登录的端发送订阅消息
+//		// data := &models.PushUserLoginKick{
+//		// 	Type: 14,
+//		// 	Data: string(preDevId), // 上一个登录端的设备号
+//		// }
+//		// // 通知用户账户最新信息
+//		// by, _ := sonic.Marshal(data)
+//		// log.Info("通知用户其他端已登录", zap.String("key", key), zap.ByteString("by", by))
+//		// kafkahelper.SendKafkaMsg(kafkatopic.LoginKick, key, by)
+//	}
+//}
+//
+//// ResetPwdBefore 1 重置密码前校验
+//func ResetPwdBefore(orm *gorm.DB, resetPwd sysmodel.ResetPwdReq) (user models.AdUser, code int) {
+//	var err error
+//
+//	if resetPwd.RetrieveType == 1 {
+//		user, err = aduserdb.GetUserByPhone(orm, resetPwd.PhoneAreaCode, resetPwd.Phone)
+//		if err != nil {
+//			return user, statuscode.ServerError
+//		}
+//	} else if resetPwd.RetrieveType == 2 {
+//		user, err = aduserdb.GetUserByEmail(orm, resetPwd.Email) //GetUser("useremail", resetPwd.Email)
+//		if err != nil {
+//			return user, statuscode.ServerError
+//		}
+//	}
+//
+//	if user.Id == 0 {
+//		return user, statuscode.TheAccountIsNotRegistered
+//	}
+//
+//	return user, statuscode.OK
+//}
+//
+//// ResetPwdCheck 2 重置密码安全验证
+//func ResetPwdCheck(orm *gorm.DB, rpc sysmodel.ResetPwdCheck) (string, int) {
+//	var (
+//		user models.AdUser
+//		err  error
+//	)
+//
+//	if rpc.RetrieveType == 1 {
+//		user, err = aduserdb.GetUserByPhone(orm, rpc.PhoneAreaCode, rpc.Phone)
+//		if err != nil {
+//			return "", statuscode.ServerError
+//		}
+//	} else if rpc.RetrieveType == 2 {
+//		user, err = aduserdb.GetUserByEmail(orm, rpc.Email) //GetUser("useremail", rpc.Email)
+//		if err != nil {
+//			return "", statuscode.ServerError
+//		}
+//	}
+//
+//	if user.Id == 0 {
+//		return "", statuscode.TheAccountIsNotRegistered
+//	}
+//
+//	// 获取用户验证器开启状态
+//	authSwitch, err := aduserdb.GetUserAuthSwitch(orm, user.Id)
+//	if err != nil {
+//		return "", statuscode.ServerError
+//	}
+//	// 验证器校验
+//	validator := sysmodel.Authenticator{
+//		UserID:        user.Id,
+//		PhoneAuth:     authSwitch.PhoneAuth,
+//		EmailAuth:     authSwitch.EmailAuth,
+//		GoogleAuth:    authSwitch.GoogleAuth,
+//		Phone:         user.Phone,
+//		Email:         user.UserEmail,
+//		GoogleSecret:  authSwitch.GoogleSecret,
+//		SmsCaptcha:    rpc.SmsCaptcha,
+//		EmailCaptcha:  rpc.EmailCaptcha,
+//		GoogleCaptcha: rpc.GoogleCaptcha,
+//		BusinessType:  businesstype.ResetPass,
+//	}
+//
+//	if code := AuthenticatorVerify(orm, validator); code != statuscode.OK {
+//		return "", code
+//	}
+//
+//	// 校验验证码通过,生成下一步操作的凭证
+//	cre := sysmodel.Credential{
+//		BusinessType: int(businesstype.ResetPass),
+//		UserID:       user.Id,
+//		Phone:        user.Phone,
+//		Email:        user.UserEmail,
+//		Time:         time.Now().Unix(),
+//		Rand:         rand.NewSource(time.Now().UnixNano()).Int63(),
+//	}
+//	creJ, _ := sonic.Marshal(cre)
+//	credentials := aeshelper.Encrypt(string(creJ), codeVerifySuccess)
+//
+//	return credentials, statuscode.OK
+//}
+//
+//// ResetPwd 3 重置密码
+//func ResetPwd(orm *gorm.DB, user models.AdUser, resetPwd sysmodel.ResetPwdReq) int {
+//	// 校验凭证
+//	cre := sysmodel.Credential{
+//		BusinessType: int(businesstype.ResetPass),
+//		UserID:       user.Id,
+//		Phone:        user.Phone,
+//		Email:        user.UserEmail,
+//		Time:         time.Now().Unix(),
+//	}
+//	if !CheckCredentials(cre, resetPwd.Credentials) {
+//		log.Error("business credentials error")
+//		return statuscode.BusinessCredentialsError
+//	}
+//
+//	// 更新密码
+//	if err := aduserdb.UpdateUserPwd(orm, resetPwd.UserID, resetPwd.Password); err != nil {
+//		return statuscode.ServerError
+//	}
+//
+//	return statuscode.OK
+//}
+//
+//// ChangePwdBefore 修改密码前校验
+//func ChangePwdBefore(orm *gorm.DB, params sysmodel.UserChangePwdReq) (user models.AdUser, code int) {
+//
+//	user, err := aduserdb.GetUserById(orm, params.UserId) //"id", params.UserId)
+//
+//	if err != nil {
+//		return user, statuscode.ServerError
+//	}
+//	if user.UserPassword != params.OldPassword {
+//		return user, statuscode.OriginalPasswordError
+//	}
+//
+//	return user, statuscode.OK
+//}
+//
+//// ChangePwd 修改密码
+//func ChangePwd(orm *gorm.DB, params sysmodel.UserChangePwdReq, user models.AdUser) int {
+//	// 获取用户验证器开关状态
+//	authSwitch, err := GetUserAuthSwitch(orm, user.Id)
+//	if err != nil {
+//		return statuscode.ServerError
+//	}
+//
+//	// 验证器验证
+//	auth := sysmodel.Authenticator{
+//		UserID:        params.UserId,
+//		PhoneAuth:     authSwitch.PhoneAuth,
+//		EmailAuth:     authSwitch.EmailAuth,
+//		GoogleAuth:    authSwitch.GoogleAuth,
+//		Phone:         user.Phone,
+//		Email:         user.UserEmail,
+//		GoogleSecret:  authSwitch.GoogleSecret,
+//		SmsCaptcha:    params.SmsCaptcha,
+//		EmailCaptcha:  params.EmailCaptcha,
+//		GoogleCaptcha: params.GoogleCaptcha,
+//		BusinessType:  businesstype.ChangePassword,
+//	}
+//	if code := AuthenticatorVerify(orm, auth); code != statuscode.OK {
+//		return code
+//	}
+//
+//	// 更新密码
+//	if err = aduserdb.UpdateUserPwd(orm, params.UserId, params.NewPassword); err != nil {
+//		return statuscode.ServerError
+//	}
+//
+//	return statuscode.OK
+//}
+//
+//// GetUserRealName 获取用户真实姓名
+//func GetUserRealName(orm *gorm.DB, uid int) string {
+//	buyerIdent, err := aduserdb.GetIdentification(orm, uid)
+//	if err != nil {
+//		return ""
+//	}
+//	realName := buyerIdent.Name
+//
+//	if buyerIdent.CountryId == 40 || buyerIdent.CountryId == 73 ||
+//		buyerIdent.CountryId == 115 || buyerIdent.CountryId == 179 {
+//		realName = buyerIdent.Name // 中国大陆,港澳台
+//	} else {
+//		// 名字-中间名-姓
+//		realName = buyerIdent.Name + " " + buyerIdent.MiddleName + " " + buyerIdent.Surname
+//	}
+//
+//	return realName
+//}
diff --git a/common/service/sysservice/authservice/authenticator.go b/common/service/sysservice/authservice/authenticator.go
new file mode 100644
index 0000000..942e801
--- /dev/null
+++ b/common/service/sysservice/authservice/authenticator.go
@@ -0,0 +1,402 @@
+package authservice
+
+//
+//import (
+//	"go-admin/app/admin/models"
+//	"go-admin/app/admin/models/sysmodel"
+//	"go-admin/app/admin/service/aduserdb"
+//	"go-admin/app/admin/service/otcdb/orderdb"
+//	"go-admin/common/const/enum/businesstype"
+//	statuscode "go-admin/common/status_code"
+//	"go-admin/pkg/googleauthhelper"
+//	"go-admin/pkg/utility"
+//
+//	log "github.com/go-admin-team/go-admin-core/logger"
+//	"gorm.io/gorm"
+//
+//	"go.uber.org/zap"
+//)
+//
+//// GetUserAuthSwitch 获取用户验证器开关状态
+//func GetUserAuthSwitch(orm *gorm.DB, userID int) (auth sysmodel.UserAuthSwitchStatus, err error) {
+//	// 获取用户验证器开关
+//	auth, err = aduserdb.GetUserAuthSwitch(orm, userID)
+//	if err != nil {
+//		return
+//	}
+//
+//	if auth.PhoneAuth != 1 {
+//		auth.PhoneAuth = 0
+//	}
+//	if auth.EmailAuth != 1 {
+//		auth.EmailAuth = 0
+//	}
+//	if auth.GoogleAuth != 1 {
+//		auth.GoogleAuth = 0
+//	}
+//
+//	return
+//}
+//
+//// AuthenticatorVerify 已开通验证器校验
+//func AuthenticatorVerify(orm *gorm.DB, authenticator sysmodel.Authenticator) int {
+//	// 是否完全验证
+//	if authenticator.PhoneAuth == 1 && len(authenticator.SmsCaptcha) == 0 ||
+//		authenticator.EmailAuth == 1 && len(authenticator.EmailCaptcha) == 0 ||
+//		authenticator.GoogleAuth == 1 && len(authenticator.GoogleCaptcha) == 0 {
+//
+//		return statuscode.PleasePerformCompleteSecurityVerification
+//	}
+//	var phoneCheck sysmodel.CheckCaptcha
+//	var emailCheck sysmodel.CheckCaptcha
+//	// 校验验证码
+//	if authenticator.PhoneAuth == 1 {
+//		phoneCheck = sysmodel.CheckCaptcha{
+//			BusinessType: int(authenticator.BusinessType),
+//			Receive:      authenticator.Phone,
+//			Captcha:      authenticator.SmsCaptcha,
+//		}
+//	}
+//	if authenticator.EmailAuth == 1 {
+//		emailCheck = sysmodel.CheckCaptcha{
+//			BusinessType: int(authenticator.BusinessType),
+//			Receive:      authenticator.Email,
+//			Captcha:      authenticator.EmailCaptcha,
+//		}
+//	}
+//	var googleSecret string
+//	var googleCaptcha string
+//	if authenticator.GoogleAuth == 1 {
+//		googleSecret = authenticator.GoogleSecret
+//		googleCaptcha = authenticator.GoogleCaptcha
+//	}
+//	// 检验验证码
+//	code := CheckCaptchaNew(orm, phoneCheck, emailCheck, googleSecret, googleCaptcha)
+//	return code
+//}
+//
+//// AuthSwitchBefore 身份验证开关前校验(新)
+//func AuthSwitchBefore(orm *gorm.DB, auth sysmodel.AuthenticatorSwitch) int {
+//	// 开启手机、更改手机、开启邮箱、更改邮箱 判断是否被占用
+//	var user models.AdUser
+//	var err error
+//	if auth.BusinessType == businesstype.OpenPhoneAuth || auth.BusinessType == businesstype.ChangePhoneAuth {
+//		user, err = aduserdb.GetUserByPhone(orm, auth.NewPhoneArea, auth.NewPhone)
+//		if err != nil {
+//			return statuscode.ServerError
+//		}
+//		if user.Id != 0 && user.Id != auth.UserID {
+//			return statuscode.ThePhoneHasBeenBound
+//		}
+//	} else if auth.BusinessType == businesstype.OpenEmailAuth || auth.BusinessType == businesstype.ChangeEmailAuth {
+//		user, err = aduserdb.GetUserByEmail(orm, auth.NewEmail) //GetUser("useremail", auth.NewEmail)
+//		if err != nil {
+//			return statuscode.ServerError
+//		}
+//		if user.Id != 0 && user.Id != auth.UserID {
+//			return statuscode.TheEmailHasBeenBound
+//		}
+//	}
+//
+//	// 获取用户验证器开关状态
+//	authSwitch, err := GetUserAuthSwitch(orm, auth.UserID)
+//	if err != nil {
+//		return statuscode.ServerError
+//	}
+//
+//	// 关闭验证器 需保证至少两个开启
+//	if auth.BusinessType == businesstype.ClosePhoneAuth ||
+//		auth.BusinessType == businesstype.CloseEmailAuth ||
+//		auth.BusinessType == businesstype.CloseGoogleAuth {
+//
+//		if (authSwitch.PhoneAuth + authSwitch.EmailAuth + authSwitch.GoogleAuth) < 3 {
+//			return statuscode.AllAuthMustOpen
+//		}
+//
+//		// OTC 订单状态为:1-待付款、3-代放币、7-申诉中时,不允许解绑手机
+//		if auth.BusinessType == businesstype.ClosePhoneAuth {
+//			// hc todo 注释
+//			// 广告
+//			// sum, err := advertisedb.GetUserAdvertiseSum(auth.UserID)
+//			// if err != nil {
+//			// 	return statuscode.ServerError
+//			// }
+//			// if sum > 0 {
+//			// 	return statuscode.OTCAdvertiseAreInProgress
+//			// }
+//			// 订单
+//			num, err := orderdb.GetUnfilledOrderCount(orm, auth.UserID)
+//			if err != nil {
+//				return statuscode.ServerError
+//			}
+//			if num > 0 {
+//				return statuscode.OTCOrdersAreInProgress
+//			}
+//		}
+//	}
+//	if user.Id == 0 {
+//		user, err = aduserdb.GetUserById(orm, auth.UserID) //"id", auth.UserID)
+//		if err != nil {
+//			return statuscode.ServerError
+//		}
+//	}
+//
+//	// ==================== 1 已开通验证器校验 ==================== //
+//	validator := sysmodel.Authenticator{
+//		UserID:        auth.UserID,
+//		PhoneAuth:     authSwitch.PhoneAuth,
+//		EmailAuth:     authSwitch.EmailAuth,
+//		GoogleAuth:    authSwitch.GoogleAuth,
+//		Phone:         user.Phone,
+//		Email:         user.UserEmail,
+//		GoogleSecret:  authSwitch.GoogleSecret,
+//		SmsCaptcha:    auth.SmsCaptcha,
+//		EmailCaptcha:  auth.EmailCaptcha,
+//		GoogleCaptcha: auth.GoogleCaptcha,
+//		BusinessType:  auth.BusinessType,
+//	}
+//
+//	// 是否完全验证
+//	if validator.PhoneAuth == 1 && len(validator.SmsCaptcha) == 0 ||
+//		validator.EmailAuth == 1 && len(validator.EmailCaptcha) == 0 ||
+//		validator.GoogleAuth == 1 && len(validator.GoogleCaptcha) == 0 {
+//
+//		return statuscode.PleasePerformCompleteSecurityVerification
+//	}
+//	var phoneCode models.AdVerifyCode
+//	if len(validator.SmsCaptcha) > 0 && !CheckOpenVerifyCode(validator.SmsCaptcha) {
+//		// 校验手机号码发送的验证码
+//		phoneCheck := sysmodel.CheckCaptcha{
+//			BusinessType: int(businesstype.WithdrawAuth),
+//			Receive:      validator.Phone,
+//			Captcha:      validator.SmsCaptcha,
+//		}
+//		phoneCode = aduserdb.GetVerifyCode(orm, phoneCheck)
+//		if phoneCode.Id == 0 {
+//			return statuscode.PhoneCaptchaInvalid
+//		}
+//	}
+//
+//	var emailCode models.AdVerifyCode
+//	if len(validator.EmailCaptcha) > 0 && !CheckOpenVerifyCode(validator.EmailCaptcha) {
+//		// 校验邮箱号码发送的验证码
+//		emailCheck := sysmodel.CheckCaptcha{
+//			BusinessType: int(businesstype.WithdrawAuth),
+//			Receive:      validator.Email,
+//			Captcha:      validator.EmailCaptcha,
+//		}
+//		emailCode = aduserdb.GetVerifyCode(orm, emailCheck)
+//		if emailCode.Id == 0 {
+//			return statuscode.EmailCaptchaInvalid
+//		}
+//	}
+//	if len(validator.GoogleCaptcha) > 0 {
+//		// 校验谷歌的验证码
+//		auth2 := googleauthhelper.VerifyCode(validator.GoogleSecret, utility.StringAsInt32(validator.GoogleCaptcha))
+//		if !auth2 {
+//			return statuscode.GoogleCaptchaInvalid
+//		}
+//	}
+//
+//	// ==================== 2 新绑定的验证器校验 ==================== //
+//	var phoneNewCode models.AdVerifyCode
+//	// 开启手机|更改手机验证 都需要校验新手机
+//	if auth.BusinessType == businesstype.OpenPhoneAuth || auth.BusinessType == businesstype.ChangePhoneAuth {
+//		if !CheckOpenVerifyCode(auth.NewPhoneCaptcha) {
+//			cc := sysmodel.CheckCaptcha{
+//				BusinessType: int(auth.BusinessType),
+//				Receive:      auth.NewPhone,
+//				Captcha:      auth.NewPhoneCaptcha,
+//			}
+//			phoneNewCode = aduserdb.GetVerifyCode(orm, cc)
+//			if phoneNewCode.Id == 0 {
+//				return statuscode.NewPhoneCaptchaInvalid
+//			}
+//		}
+//	}
+//
+//	var emailNewCode models.AdVerifyCode
+//	// 开启邮箱|更改邮箱验证 都需要校验新邮箱
+//	if auth.BusinessType == businesstype.OpenEmailAuth || auth.BusinessType == businesstype.ChangeEmailAuth {
+//		if !CheckOpenVerifyCode(auth.NewEmailCaptcha) {
+//			cc := sysmodel.CheckCaptcha{
+//				BusinessType: int(auth.BusinessType),
+//				Receive:      auth.NewEmail,
+//				Captcha:      auth.NewEmailCaptcha,
+//			}
+//			emailNewCode = aduserdb.GetVerifyCode(orm, cc)
+//			if emailNewCode.Id == 0 {
+//				return statuscode.NewEmailCaptchaInvalid
+//			}
+//		}
+//	}
+//
+//	// 开启谷歌验证器 需要验证谷歌
+//	if auth.BusinessType == businesstype.OpenGoogleAuth {
+//		newSecret, _ := aduserdb.GetNewGoogleSecret(orm, auth.UserID)
+//		if ok := googleauthhelper.VerifyCode(newSecret, utility.StringAsInt32(auth.NewGoogleCaptcha)); !ok {
+//			// tx.Rollback()
+//			log.Error("google验证码校验失败")
+//			return statuscode.GoogleCaptchaInvalid
+//		}
+//	}
+//	if phoneCode.Id == 0 && phoneNewCode.Id == 0 && emailCode.Id == 0 && emailNewCode.Id == 0 {
+//		log.Error("AuthSwitchBefore", zap.String("没验证旧手机、新手机、旧邮箱、新邮箱,估计只验证谷歌验证器",
+//			"phoneCode.Id ==0 && phoneNewCode.Id ==0 && emailCode.Id ==0&& emailNewCode.Id ==0"))
+//		return statuscode.OK
+//	}
+//
+//	var transCode int
+//	err = orm.Transaction(func(tx *gorm.DB) error {
+//		// ==================== 1 已开通验证器校验,修改表数据为已验证 ==================== //
+//		if phoneCode.Id > 0 { // 旧手机验证码修改
+//			err := aduserdb.UpdateVerifyFlag(tx, phoneCode.Id)
+//			if err != nil {
+//				log.Error("AuthSwitchBefore phoneCode", zap.Error(err))
+//				// _ = tx.Rollback()
+//				transCode = statuscode.PhoneCaptchaInvalid
+//				return err
+//			}
+//		}
+//		if emailCode.Id > 0 { // 旧邮箱验证码修改
+//			err = aduserdb.UpdateVerifyFlag(tx, emailCode.Id)
+//			if err != nil {
+//				log.Error("AuthSwitchBefore emailCode", zap.Error(err))
+//				// _ = tx.Rollback()
+//				transCode = statuscode.EmailCaptchaInvalid
+//
+//				return err
+//			}
+//		}
+//
+//		// ==================== 2 新绑定的验证器校验,修改表数据为已验证 ==================== //
+//		if phoneNewCode.Id > 0 { // 新手机验证码修改
+//			err = aduserdb.UpdateVerifyFlag(tx, phoneNewCode.Id)
+//			if err != nil {
+//				log.Error("AuthSwitchBefore phoneNewCode", zap.Error(err))
+//
+//				transCode = statuscode.PhoneCaptchaInvalid
+//
+//				return err
+//			}
+//		}
+//		if emailNewCode.Id > 0 { // 新邮箱验证码修改
+//			err = aduserdb.UpdateVerifyFlag(tx, emailNewCode.Id)
+//			if err != nil {
+//				log.Error("AuthSwitchBefore emailNewCode", zap.Error(err))
+//
+//				transCode = statuscode.EmailCaptchaInvalid
+//
+//				return err
+//			}
+//		}
+//
+//		return nil
+//	})
+//	// 开启事务
+//	// tx, err := dbhelper.MasterPgdb.Beginx()
+//	// if err != nil {
+//	// 	return statuscode.ServerError
+//	// }
+//
+//	// // ==================== 1 已开通验证器校验,修改表数据为已验证 ==================== //
+//	// if phoneCode.Id > 0 { // 旧手机验证码修改
+//	// 	err = aduserdb.UpdateVerifyFlag(phoneCode.Id, tx)
+//	// 	if err != nil {
+//	// 		log.Error("AuthSwitchBefore phoneCode", zap.Error(err))
+//	// 		_ = tx.Rollback()
+//	// 		return statuscode.PhoneCaptchaInvalid
+//	// 	}
+//	// }
+//	// if emailCode.Id > 0 { // 旧邮箱验证码修改
+//	// 	err = aduserdb.UpdateVerifyFlag(emailCode.Id, tx)
+//	// 	if err != nil {
+//	// 		log.Error("AuthSwitchBefore emailCode", zap.Error(err))
+//	// 		_ = tx.Rollback()
+//	// 		return statuscode.EmailCaptchaInvalid
+//	// 	}
+//	// }
+//
+//	// // ==================== 2 新绑定的验证器校验,修改表数据为已验证 ==================== //
+//	// if phoneNewCode.Id > 0 { // 新手机验证码修改
+//	// 	err = aduserdb.UpdateVerifyFlag(phoneNewCode.Id, tx)
+//	// 	if err != nil {
+//	// 		log.Error("AuthSwitchBefore phoneNewCode", zap.Error(err))
+//	// 		_ = tx.Rollback()
+//	// 		return statuscode.PhoneCaptchaInvalid
+//	// 	}
+//	// }
+//	// if emailNewCode.Id > 0 { // 新邮箱验证码修改
+//	// 	err = aduserdb.UpdateVerifyFlag(emailNewCode.Id, tx)
+//	// 	if err != nil {
+//	// 		log.Error("AuthSwitchBefore emailNewCode", zap.Error(err))
+//	// 		_ = tx.Rollback()
+//	// 		return statuscode.EmailCaptchaInvalid
+//	// 	}
+//	// }
+//	// // 提交事务
+//	// if err = tx.Commit(); err != nil {
+//	// 	return statuscode.ServerError
+//	// }
+//
+//	if err != nil {
+//		return transCode
+//	}
+//	return statuscode.OK
+//}
+//
+//// AuthSwitchNew 身份验证开关(新)
+//func AuthSwitchNew(orm *gorm.DB, auth sysmodel.AuthenticatorSwitch) int {
+//	// 验证器-开关
+//	switch auth.BusinessType {
+//	case businesstype.OpenPhoneAuth:
+//		if err := aduserdb.BindPhoneAuth(orm, auth.UserID, auth.NewPhoneArea, auth.NewPhone); err != nil {
+//			return statuscode.ServerError
+//		}
+//	case businesstype.ChangePhoneAuth:
+//		if err := aduserdb.ChangePhoneAuth(orm, auth.UserID, auth.NewPhoneArea, auth.NewPhone); err != nil {
+//			return statuscode.ServerError
+//		}
+//		// hc todo 注释掉 先不急
+//		// 更新商家信息
+//		// merchant := merchantdb.GetMerchantInfoForUserId(orm, auth.UserID)
+//		// if merchant.Id > 0 {
+//		// 	_ = merchantdb.UpdateMerchantMobile(auth.UserID, auth.NewPhone)
+//		// }
+//	case businesstype.ClosePhoneAuth:
+//		if err := aduserdb.ClosePhoneAuth(orm, auth.UserID); err != nil {
+//			return statuscode.ServerError
+//		}
+//
+//	case businesstype.OpenEmailAuth:
+//		if err := aduserdb.BindEmailAuth(orm, auth.UserID, auth.NewEmail); err != nil {
+//			return statuscode.ServerError
+//		}
+//	case businesstype.ChangeEmailAuth:
+//		if err := aduserdb.ChangeEmailAuth(orm, auth.UserID, auth.NewEmail); err != nil {
+//			return statuscode.ServerError
+//		}
+//	case businesstype.CloseEmailAuth:
+//		if err := aduserdb.CloseEmailAuth(orm, auth.UserID); err != nil {
+//			return statuscode.ServerError
+//		}
+//
+//	case businesstype.OpenGoogleAuth:
+//		if err := aduserdb.OpenGoogleAuth(orm, auth.UserID); err != nil {
+//			return statuscode.ServerError
+//		}
+//	case businesstype.ChangeGoogleAuth:
+//		if err := aduserdb.CloseGoogleAuth(orm, auth.UserID); err != nil {
+//			return statuscode.ServerError
+//		}
+//	case businesstype.CloseGoogleAuth:
+//		if err := aduserdb.CloseGoogleAuth(orm, auth.UserID); err != nil {
+//			return statuscode.ServerError
+//		}
+//
+//	default:
+//		return statuscode.ParameterInvalid
+//	}
+//
+//	return statuscode.OK
+//}
diff --git a/common/service/sysservice/authservice/captcha.go b/common/service/sysservice/authservice/captcha.go
new file mode 100644
index 0000000..6c9c2c2
--- /dev/null
+++ b/common/service/sysservice/authservice/captcha.go
@@ -0,0 +1,542 @@
+package authservice
+
+import (
+	"bytes"
+	"fmt"
+	"github.com/bytedance/sonic"
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"go-admin/common/const/rediskey"
+	"go-admin/common/helper"
+	statuscode "go-admin/common/status_code"
+	ext "go-admin/config"
+	"go-admin/pkg/cryptohelper/inttostring"
+	"go.uber.org/zap"
+	"io/ioutil"
+	"net/http"
+	"time"
+)
+
+//
+//// SendCaptchaBefore 发送验证码前之前检查
+//func SendCaptchaBefore(orm *gorm.DB, auth sysmodel.SendCaptchaReq) int {
+//	var (
+//		user models.AdUser
+//		err  error
+//	)
+//
+//	// 除 注册、开启手机|邮箱验证、更改手机|邮箱验证 外,
+//	// 其余业务发送前都需验证账号是否存在
+//	if !(auth.BusinessType == int(businesstype.Register) ||
+//		auth.BusinessType == int(businesstype.OpenPhoneAuth) ||
+//		auth.BusinessType == int(businesstype.OpenEmailAuth) ||
+//		auth.IsNew == 1 && auth.BusinessType == int(businesstype.ChangePhoneAuth) ||
+//		auth.IsNew == 1 && auth.BusinessType == int(businesstype.ChangeEmailAuth)) {
+//
+//		if auth.SendType == sysmodel.TSmsCode {
+//			// 手机
+//			user, err = aduserdb.GetUserByPhone(orm, auth.PhoneAreaCode, auth.Phone)
+//			if err != nil {
+//				return statuscode.ServerError
+//			}
+//		} else if auth.SendType == sysmodel.TEmailCode {
+//			// 邮箱
+//			user, err = aduserdb.GetUserByEmail(orm, auth.Email) //GetUser("useremail", auth.Email)
+//			if err != nil {
+//				return statuscode.ServerError
+//			}
+//		}
+//
+//		// 账号不存在
+//		if user.Id == 0 {
+//			return statuscode.TheAccountIsNotRegistered
+//		}
+//	}
+//
+//	// 除:1 注册、2 登录、3 找回密码外,其余业务都需要登录(直接通过 uid 获取登录用户)
+//	if auth.BusinessType > 3 {
+//		user, err = aduserdb.GetUserById(orm, auth.Uid) //"id", auth.Uid)
+//		if err != nil {
+//			return statuscode.ServerError
+//		}
+//	}
+//
+//	// 开启手机、开启邮箱 判断号码是否被占用(自己的号码判定为不占用)
+//	if auth.BusinessType == int(businesstype.OpenPhoneAuth) || auth.BusinessType == int(businesstype.OpenEmailAuth) {
+//		if auth.SendType == sysmodel.TSmsCode {
+//			// 手机
+//			user, err = aduserdb.GetUserByPhone(orm, auth.PhoneAreaCode, auth.Phone)
+//			if err != nil {
+//				return statuscode.ServerError
+//			}
+//
+//			if user.Id != 0 && user.Id != auth.Uid {
+//				return statuscode.ThePhoneHasBeenBound
+//			}
+//		} else if auth.SendType == sysmodel.TEmailCode {
+//			// 邮箱
+//			user, err = aduserdb.GetUserByEmail(orm, auth.Email) //GetUser("useremail", auth.Email)
+//			if err != nil {
+//				return statuscode.ServerError
+//			}
+//
+//			if user.Id != 0 && user.Id != auth.Uid {
+//				return statuscode.TheEmailHasBeenBound
+//			}
+//		}
+//	}
+//
+//	// 更改手机、更改邮箱 仅判断新号码是否被占用(自己的号码判定为占用)
+//	if auth.IsNew == 1 &&
+//		(auth.BusinessType == int(businesstype.ChangePhoneAuth) || auth.BusinessType == int(businesstype.ChangeEmailAuth)) {
+//
+//		if auth.SendType == sysmodel.TSmsCode {
+//			// 手机
+//			user, err = aduserdb.GetUserByPhone(orm, auth.PhoneAreaCode, auth.Phone)
+//			if err != nil {
+//				return statuscode.ServerError
+//			}
+//
+//			if user.Id != 0 {
+//				return statuscode.ThePhoneHasBeenBound
+//			}
+//		} else if auth.SendType == sysmodel.TEmailCode {
+//			// 邮箱
+//			user, err = aduserdb.GetUserByEmail(orm, auth.Email) //GetUser("useremail", auth.Email)
+//			if err != nil {
+//				return statuscode.ServerError
+//			}
+//
+//			if user.Id != 0 {
+//				return statuscode.TheEmailHasBeenBound
+//			}
+//		}
+//	}
+//
+//	// 发送次数校验
+//	var sign interface{} = auth.Uid
+//	if sign == 0 {
+//		sign = auth.IP
+//	}
+//	key := fmt.Sprintf(rediskey.UserCaptchaSendFre, sign, auth.BusinessType)
+//
+//	if countStr, err2 := helper.DefaultRedis.GetString(key); err2 == nil {
+//		count, _ := strconv.Atoi(countStr)
+//
+//		if count >= 20 {
+//			return statuscode.CaptchaSendFrequencyExceedLimit
+//		}
+//	}
+//	/*if auth.BusinessType == int(enum.Register) {
+//		if count > 0 {
+//			return enum.CaptchaSendFrequencyExceedLimit
+//		}
+//	} else {
+//		if count >= 20 {
+//			return enum.CaptchaSendFrequencyExceedLimit
+//		}
+//	}*/
+//
+//	return statuscode.OK
+//}
+//
+//// IsRepeatSend 是否重复发送验证码
+//func IsRepeatSend(orm *gorm.DB, receive string, businessType int) (bool, int) {
+//	verifyCode, err := aduserdb.IsRepeatSend(orm, receive, businessType)
+//	if err != nil {
+//		return false, 0
+//	}
+//
+//	if verifyCode.Id != 0 {
+//		// 给 send 加时区,保持与当前时区一致
+//		send := verifyCode.SendTime
+//		send = time.Date(send.Year(), send.Month(), send.Day(), send.Hour(), send.Minute(), send.Second(), send.Nanosecond(), time.Local)
+//
+//		// wait = send+60-now
+//		wait := send.Add(time.Minute).Sub(time.Now()).Seconds()
+//		return true, int(wait)
+//	}
+//
+//	return false, 0
+//}
+//
+//// 生成验证码
+//func genVerifyCode() string {
+//	return fmt.Sprintf("%06v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(1000000))
+//}
+//
+////// 阿里云 - 发送手机验证码
+////func SendALYSms(areaPhoneCode, phoneNumber string, businessType int) error {
+////
+////	var smsCode = genVerifyCode()
+////
+////	resp, err := smshelper.SendALYSmsCode(areaPhoneCode, phoneNumber, smsCode)
+////	if err != nil {
+////		return err
+////	}
+////
+////	if *resp.Code != "OK" || *resp.Message != "OK" {
+////		return errors.New(*resp.Message)
+////	}
+////
+////	if err := RecordAuthCode(smsCode, phoneNumber, businessType); err != nil {
+////		log.Error("record sms auth code", zap.Error(err))
+////		return errors.New("this sms verification code is invalid")
+////	}
+////
+////	return nil
+////}
+//
+//// SendXDYSms 信达云 - 发送手机验证码
+//func SendXDYSms(orm *gorm.DB, areaPhoneCode, phoneNumber string, businessType int) error {
+//	// SMS 模板
+//	msgBody := ""
+//	business := ""
+//	if businessType <= 102 {
+//		// <100 用通用模板
+//		msgBody = smstemplate.SmsTemplate_1_CN
+//		business = businesstype.BusinessTypeMapCN[businesstype.BusinessType(businessType)]
+//		if areaPhoneCode != "86" {
+//			msgBody = smstemplate.SmsTemplate_1_EN
+//			business = businesstype.BusinessTypeMapEN[businesstype.BusinessType(businessType)]
+//
+//		}
+//	} else {
+//		//暂时只写中文  通用验证码
+//		msgBody = smstemplate.SmsTemplate_1_CN
+//		business = businesstype.BusinessTypeMapCN[businesstype.BusinessType(businessType)]
+//	}
+//
+//	// 内容替换
+//	var smsCode = genVerifyCode()
+//	msgBody = strings.Replace(msgBody, "${business}", business, 1)
+//	msgBody = strings.Replace(msgBody, "${code}", smsCode, 1)
+//
+//	// 发送验证码
+//	_, err := smshelper.SendDXYSmsCode(areaPhoneCode, phoneNumber, msgBody)
+//	if err != nil {
+//		return err
+//	}
+//
+//	// 记录验证码
+//	if err := RecordAuthCode(orm, smsCode, phoneNumber, businessType); err != nil {
+//		log.Error("record sms auth code", zap.Error(err))
+//		return errors.New("this sms verification code is invalid")
+//	}
+//
+//	return nil
+//}
+//
+//// XindaCloud 回执报告
+////func XindaCloudReceipt(ctx *fiber.Ctx) error {
+////	var req interface{}
+////	if err := ctx.BodyParser(&req); err != nil {
+////		log.Error("BodyParser", zap.Error(err))
+////	}
+////
+////	_ = redishelper.HMSet("XindaCloudReceipt", req)
+////
+////	return nil
+////}
+//
+////// SendUserEmail 发送邮箱验证码
+////func SendUserEmail(sendTo string, businessType int) error {
+////	// 生成随机验证码
+////	emailCode := genVerifyCode()
+////
+////	send := config.EmailSend{
+////		EmailConfig: config.AppGlobalConfig.EmailConfig,
+////		Subject:     "邮箱验证码",
+////		Content:     "[HS] 您的邮箱验证码为: " + emailCode,
+////		To:          sendTo,
+////	}
+////
+////	if _, ok := emailhelper.SendEmail(send); ok {
+////		if err := RecordAuthCode(emailCode, sendTo, businessType); err != nil {
+////			log.Error("record email auth code", zap.Error(err))
+////			return errors.New("this email verification code is invalid")
+////		}
+////
+////		return nil
+////	}
+////
+////	return errors.New("email send failed")
+////}
+//
+//func MailJetSend(orm *gorm.DB, receive string, businessType int) error {
+//	// 生成随机验证码
+//	code := genVerifyCode()
+//
+//	if err := emailhelper.MailJetSend(receive, code); err != nil {
+//		return err
+//	}
+//
+//	if err := RecordAuthCode(orm, code, receive, businessType); err != nil {
+//		log.Error("record email auth code", zap.Error(err))
+//		return errors.New("record email auth code failed")
+//	}
+//
+//	return nil
+//}
+//
+//// RecordAuthCode 记录验证码
+//func RecordAuthCode(orm *gorm.DB, authCode, receive string, businessType int) error {
+//	var (
+//		sendTime   = time.Now()
+//		expireTime = sendTime.Add(sysmodel.CodeValidTime)
+//	)
+//
+//	var authCodeInfo = &models.AdVerifyCode{
+//		Phone:        receive,
+//		Code:         authCode,
+//		SendTime:     sendTime,
+//		ValidTimeLen: int(sysmodel.CodeValidTime.Seconds()),
+//		VerifyTime:   expireTime,
+//		VerifyFlag:   0,
+//		BusinessType: businessType,
+//	}
+//
+//	return orm.Model(authCodeInfo).Create(authCodeInfo).Error
+//	// return dbhelper.MasterPgdb.Insert("ad_verifycode", authCodeInfo)
+//}
+//
+//// // CheckCaptcha 校验验证码
+//// func CheckCaptcha(cc sysmodel.CheckCaptcha, tx *sqlx.Tx) error {
+////	// TODO 免检测验证码
+////	if cc.Captcha == "123456" {
+////		return nil
+////	}
+////	if cc.Captcha == config.AppGlobalConfig.OpenVerifyCode {
+////		return nil
+////	}
+////
+////	return aduserdb.UpdateVerifyCode(cc, tx)
+//// }
+//
+//// CheckOpenVerifyCode 校验验证码是否免检测验证码,true免检测验证码,false需要检测验证码
+//func CheckOpenVerifyCode(captcha string) bool {
+//	// TODO 免检测验证码
+//	//if captcha == "123456" {
+//	//	return true
+//	//}
+//
+//	if captcha == config.ExtConfig.OpenVerifyCode {
+//		return true
+//	}
+//	return false
+//}
+//
+//// CheckPhoneOrEmailCaptcha 手机或者邮箱验证码检测
+//func CheckPhoneOrEmailCaptcha(orm *gorm.DB, phone sysmodel.CheckCaptcha) int {
+//	return CheckCaptchaNew(orm, phone, sysmodel.CheckCaptcha{}, "", "")
+//}
+//
+//// CheckCaptchaNew 校验验证码,1.phone手机验证,2.email邮箱验证,3.googleAuth谷歌验证,也可以只传一个结构体,比如phone验证一个,无需指定是手机或者邮箱
+//func CheckCaptchaNew(orm *gorm.DB, phone sysmodel.CheckCaptcha, email sysmodel.CheckCaptcha, googleSecret, googleCaptcha string) int {
+//	// TODO 免检测验证码
+//
+//	var phoneCode models.AdVerifyCode
+//	if len(phone.Captcha) > 0 && !CheckOpenVerifyCode(phone.Captcha) {
+//		// 校验手机号码发送的验证码
+//		phoneCode = aduserdb.GetVerifyCode(orm, phone)
+//		if phoneCode.Id == 0 {
+//			return statuscode.PhoneCaptchaInvalid
+//		}
+//	}
+//
+//	var emailCode models.AdVerifyCode
+//	if len(email.Captcha) > 0 && !CheckOpenVerifyCode(email.Captcha) {
+//		// 校验邮箱号码发送的验证码
+//		emailCode = aduserdb.GetVerifyCode(orm, email)
+//		if emailCode.Id == 0 {
+//			return statuscode.EmailCaptchaInvalid
+//		}
+//	}
+//	if len(googleCaptcha) > 0 {
+//		// 校验谷歌的验证码
+//		auth := googleauthhelper.VerifyCode(googleSecret, utility.StringAsInt32(googleCaptcha))
+//		if !auth {
+//			return statuscode.GoogleCaptchaInvalid
+//		}
+//	}
+//	// 没手机+邮箱验证,应该只验证谷歌,到这里就返回ok
+//	if phoneCode.Id == 0 && emailCode.Id == 0 {
+//		return statuscode.OK
+//	}
+//
+//	var transCode int
+//
+//	// 更新手机+邮箱验证码的数据状态
+//	err := orm.Transaction(func(tx *gorm.DB) (err error) {
+//
+//		if phoneCode.Id > 0 {
+//			err = aduserdb.UpdateVerifyFlag(orm, phoneCode.Id)
+//			if err != nil {
+//				// _ = tx.Rollback()
+//				transCode = statuscode.PhoneCaptchaInvalid
+//
+//				return err
+//			}
+//		}
+//		if emailCode.Id > 0 {
+//			err = aduserdb.UpdateVerifyFlag(orm, emailCode.Id)
+//			if err != nil {
+//				// _ = tx.Rollback()
+//				transCode = statuscode.EmailCaptchaInvalid
+//
+//				return err
+//			}
+//		}
+//
+//		return nil
+//	})
+//	// tx, err := dbhelper.MasterPgdb.Beginx()
+//	// if err != nil {
+//	// 	log.Error("Begin", zap.Error(err))
+//	// 	return statuscode.ServerError
+//	// }
+//	// if phoneCode.Id > 0 {
+//	// 	err = aduserdb.UpdateVerifyFlag(orm, phoneCode.Id)
+//	// 	if err != nil {
+//	// 		_ = tx.Rollback()
+//	// 		return statuscode.PhoneCaptchaInvalid
+//	// 	}
+//	// }
+//	// if emailCode.Id > 0 {
+//	// 	err = aduserdb.UpdateVerifyFlag(orm, emailCode.Id)
+//	// 	if err != nil {
+//	// 		_ = tx.Rollback()
+//	// 		return statuscode.EmailCaptchaInvalid
+//	// 	}
+//	// }
+//	// _ = tx.Commit()
+//
+//	if err != nil {
+//		return transCode
+//	}
+//
+//	return statuscode.OK
+//}
+//
+//// CheckCredentials 校验凭证
+//func CheckCredentials(req sysmodel.Credential, credentials string) bool {
+//	// 解析得到 Credentials Json
+//	CreJ := aeshelper.Decrypt(credentials, codeVerifySuccess)
+//	if len(CreJ) <= 0 {
+//		log.Error("credentials error")
+//		return false
+//	}
+//
+//	Cre := sysmodel.Credential{}
+//	_ = sonic.Unmarshal([]byte(CreJ), &Cre)
+//
+//	// 凭证最长有效时间2分钟
+//	var maxValidTime = int64(2 * time.Minute.Seconds())
+//
+//	// 逐一比对凭证字段
+//	if Cre.BusinessType != req.BusinessType {
+//		log.Error(fmt.Sprintf("凭证业务类型有误, BusinesType: %d credentialsBusinesType %d", req.BusinessType, Cre.BusinessType))
+//		return false
+//	}
+//
+//	if Cre.UserID != req.UserID {
+//		log.Error(fmt.Sprintf("凭证用户ID有误, UserID: %d credentialsUserID %d", req.UserID, Cre.UserID))
+//		return false
+//	}
+//
+//	if len(Cre.Phone) > 0 && Cre.Phone != req.Phone {
+//		log.Error(fmt.Sprintf("凭证手机有误, Phone: %s credentialsPhone %s", req.Phone, Cre.Phone))
+//		return false
+//	}
+//
+//	if len(Cre.Email) > 0 && Cre.Email != req.Email {
+//		log.Error(fmt.Sprintf("凭证邮箱有误, Email: %s credentialsEmail %s", req.Email, Cre.Email))
+//		return false
+//	}
+//
+//	if time.Now().Unix() > Cre.Time+maxValidTime {
+//		log.Error(fmt.Sprintf("凭证已过期, 当前时间: %d 凭证过期时间 %d", time.Now().Unix(), Cre.Time+maxValidTime))
+//		return false
+//	}
+//
+//	return true
+//}
+
+func SendGoToneSms(phone, area string) int {
+	//smsCode =
+	smsString := inttostring.GenerateRandomSmsString(6)
+	defer func() {
+		// 使用 recover 来捕获 panic,避免 goroutine 导致程序崩溃
+		if r := recover(); r != nil {
+			log.Error("SendRegisterEmail Error:", r)
+		}
+	}()
+	get := helper.DefaultRedis.Get(fmt.Sprintf("mobile-%s-register", phone))
+	if get.Val() != "" { //说明邮箱操作频繁
+		return statuscode.GoToneSmsOrderTooOften
+	}
+	key := fmt.Sprintf(rediskey.PCRegisterMobile, phone)
+	if err := helper.DefaultRedis.SetStringExpire(key, smsString, time.Second*300); err != nil {
+		log.Error("sendEmail setRedis Error:", zap.Error(err))
+		return statuscode.ServerError
+	}
+	//ext.ExtConfig.GoToneSmsConfig
+	// SmsRequest 用于构建发送短信请求的结构体
+	type SmsRequest struct {
+		Recipient string `json:"recipient"` // 收件人电话号码
+		Message   string `json:"message"`   // 短信内容
+		SenderId  string `json:"sender_id"` // 发送者名称
+		Type      string `json:"type"`
+	}
+	// 创建请求数据
+	smsRequest := SmsRequest{
+		Recipient: "+" + area + phone,
+		SenderId:  ext.ExtConfig.GoToneSmsConfig.SenderId,
+		Message:   fmt.Sprintf("欢迎使用 GoTone SMS,高速稳定地发送短信至中国大陆及全球用户,体验验证码:%s。如非本人操作请忽略此信息", smsString),
+		Type:      "plain",
+	}
+	// 将请求数据编码为 JSON
+	requestBody, err := sonic.Marshal(smsRequest)
+	if err != nil {
+		log.Error("GoToneSms requestBody Error:", err)
+		return statuscode.ServerError
+	}
+	// 创建 HTTP 请求
+	req, err := http.NewRequest("POST", ext.ExtConfig.GoToneSmsConfig.APIEndpoint, bytes.NewBuffer(requestBody))
+	if err != nil {
+		log.Error("GoToneSms http.NewRequest Error:", err)
+		return statuscode.ServerError
+	}
+	// 设置请求头
+	req.Header.Set("Content-Type", "application/json")
+	req.Header.Set("Authorization", "Bearer "+ext.ExtConfig.GoToneSmsConfig.Authorization) // 使用 API 密钥进行身份验证
+
+	// 创建 HTTP 客户端并发送请求
+	client := &http.Client{
+		Timeout: 10 * time.Second, // 设置请求超时时间
+	}
+	resp, err := client.Do(req)
+	fmt.Println("resp:", resp)
+	if err != nil {
+		log.Error("GoToneSms do NewRequest Error:", err)
+		return statuscode.CaptchaFailInSend
+	}
+	defer resp.Body.Close()
+
+	// 检查响应状态
+	if resp.StatusCode != http.StatusOK {
+		log.Error("GoToneSms do NewRequest Error:", err)
+		return statuscode.CaptchaFailInSend
+	}
+	// 读取响应体
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		log.Error("读取响应体失败:", err)
+		fmt.Printf("响应体: %s", string(body))
+		return statuscode.CaptchaFailInSend
+		//return fmt.Errorf("读取响应体失败: %v", err)
+	}
+	// 打印响应内容(调试用)
+	//记录短信发送操作
+	helper.DefaultRedis.SetStringExpire(fmt.Sprintf("mobile-%s-register", phone), "register", time.Second*60)
+	return statuscode.OK
+}
diff --git a/common/service/sysservice/authservice/mailjet_test.go b/common/service/sysservice/authservice/mailjet_test.go
new file mode 100644
index 0000000..bc04aed
--- /dev/null
+++ b/common/service/sysservice/authservice/mailjet_test.go
@@ -0,0 +1,36 @@
+package authservice
+
+import (
+	"fmt"
+	"github.com/mailjet/mailjet-apiv3-go"
+	"log"
+	"testing"
+)
+
+func TestName(t *testing.T) {
+	mailjetClient := mailjet.NewMailjetClient("00d2889da90d5d90767bf04dc1bdc6fa", "f68cd84cd88b7e2aabce79c878a77e97")
+	messagesInfo := []mailjet.InfoMessagesV31{
+		{
+			From: &mailjet.RecipientV31{
+				Email: "a745455408@163.com",
+				Name:  "Tokex",
+			},
+			To: &mailjet.RecipientsV31{
+				mailjet.RecipientV31{
+					Email: "2811588041@qq.com",
+					Name:  "YCZ",
+				},
+			},
+			Subject:  "Register/Login",
+			TextPart: "欢迎注册登录我们的服务,您的验证码为:123456",
+			// HTMLPart: "欢迎注册登录我们的服务,您的验证码为:1234567 @24hrTicker
+	PreTrade      = "trade"      //最新成交推送前缀 @trade
+	PreKline      = "kline"      //k线推送前缀 @kline_
+	PreDepth      = "depth"      //深度推送前缀 @depth
+	PreDepth35    = "depth35"    //35深度推送前缀 @depth
+	PreMarkPrice  = "markPrice"  //最新标记价 @markPrice
+	TickerArr     = "ticker@arr" //所有24小时行情
+	PreErr        = "err"
+)
+
+type PushFive struct {
+	Type   int        `json:"type"`   //类型
+	Num    string     `json:"num"`    //买卖总数量
+	Symbol string     `json:"symbol"` //交易对,比如BTC-USDT
+	Data   [][]string `json:"data"`   //数据
+}
+
+type PushAll struct {
+	Event string     `json:"e"`
+	Data  []WsTicker `json:"data"`
+}
+type PushKline struct {
+	Type   int        `json:"type"`
+	Symbol string     `json:"symbol"` //交易对,比如BTC-USDT
+	Data   [][]string `json:"data"`
+}
+
+type WsWsTickerBase struct {
+	Event  string   `json:"e"`
+	Symbol string   `json:"s"`    //交易对,比如BTC-USDT
+	Data   WsTicker `json:"data"` //
+}
+
+// WsTicker 24小时行情推送
+type WsTicker struct {
+	E           int64  `json:"-"`   //时间戳
+	Symbol      string `json:"s"`   //symbol,BTC-USDT
+	Close       string `json:"c"`   //收盘价格,也是最新价格
+	Open        string `json:"o"`   //开盘价格
+	High        string `json:"h"`   //最高价格
+	Low         string `json:"l"`   //最低价格
+	Volume      string `json:"v"`   //成交量
+	QuoteVolume string `json:"q"`   //成交额
+	Change      string `json:"chg"` //涨幅
+	RatePrice   string `json:"rp"`  //最新价格等于多少usdt
+
+}
+
+type WsBase struct {
+	Event  string      `json:"e"`
+	Symbol string      `json:"s"`    //交易对,比如BTC-USDT
+	Data   interface{} `json:"data"` //
+}
+
+type WsTrade struct {
+	Price    string `json:"p"` //成交价格
+	Quantity string `json:"q"` //成交数量
+	DealTime string `json:"t"` //时间撮
+	Market   string `json:"m"` //1是买方主动触发交易,2卖方主动触发交易
+}
+
+type BaseKline struct {
+	Event  string  `json:"e"`    //事件
+	Symbol string  `json:"s"`    //交易对,比如BTC-USDT
+	Data   WsKline `json:"data"` //k线数据
+}
+
+type WsKline struct {
+	Line        string `json:"i"`    // K线间隔,比如1m
+	LineTime    string `json:"t"`    // k线时间撮
+	Open        string `json:"o"`    // 这根K线期间第一笔成交价
+	Close       string `json:"c"`    // 这根K线期间末一笔成交价
+	High        string `json:"h"`    // 这根K线期间最高成交价
+	Low         string `json:"l"`    // 这根K线期间最低成交价
+	Volume      string `json:"v"`    // 这根K线期间成交量
+	QuoteVolume string `json:"q"`    // 这根K线期间成交额
+	Chg         string `json:"chg"`  // 涨幅
+	Ampl        string `json:"ampl"` // 震幅
+}
+
+type WsFive struct {
+	Event  string     `json:"e"`   //事件
+	Symbol string     `json:"s"`   //比如BTC-USDT
+	Bid    [][]string `json:"bid"` //买盘口
+	Ask    [][]string `json:"ask"` //卖盘口
+}
+
+type WsMarkPrice struct {
+	Event  string                 `json:"e"`
+	Symbol string                 `json:"s"`
+	Data   map[string]interface{} `json:"data"`
+}
diff --git a/models/rabbitmqdto/ApiKeyWebSocket.go b/models/rabbitmqdto/ApiKeyWebSocket.go
new file mode 100644
index 0000000..3c5771a
--- /dev/null
+++ b/models/rabbitmqdto/ApiKeyWebSocket.go
@@ -0,0 +1,10 @@
+package rabbitmqdto
+
+//api key 连接
+type ApiKeyWSConnect struct {
+	ApiKey       string `json:"apiKey"`
+	ApiSecret    string `json:"apiSecret"`
+	ProxyType    string `json:"proxyType"`
+	ProxyAddress string `json:"proxyAddress"`
+	Type         int    `json:"type" comment:"1-订阅 0-取消订阅"`
+}
diff --git a/models/spot/spotdto.go b/models/spot/spotdto.go
new file mode 100644
index 0000000..c2bc94d
--- /dev/null
+++ b/models/spot/spotdto.go
@@ -0,0 +1,72 @@
+package spot
+
+type SpotTicker24h struct {
+	Symbol             string `json:"symbol"`             // 交易对符号 (e.g., BNBBTC)
+	PriceChange        string `json:"priceChange"`        // 24小时价格变动
+	PriceChangePercent string `json:"priceChangePercent"` // 24小时价格变动百分比
+	WeightedAvgPrice   string `json:"weightedAvgPrice"`   // 加权平均价
+	PrevClosePrice     string `json:"prevClosePrice"`     // 前一个收盘价
+	LastPrice          string `json:"lastPrice"`          // 最近一次成交价
+	LastQty            string `json:"lastQty"`            // 最近一次成交量
+	BidPrice           string `json:"bidPrice"`           // 当前买单价
+	BidQty             string `json:"bidQty"`             // 当前买单量
+	AskPrice           string `json:"askPrice"`           // 当前卖单价
+	AskQty             string `json:"askQty"`             // 当前卖单量
+	OpenPrice          string `json:"openPrice"`          // 24小时内第一次成交的价格
+	HighPrice          string `json:"highPrice"`          // 24小时最高价
+	LowPrice           string `json:"lowPrice"`           // 24小时最低价
+	Volume             string `json:"volume"`             // 24小时成交量
+	QuoteVolume        string `json:"quoteVolume"`        // 24小时成交额
+	OpenTime           int64  `json:"openTime"`           // 24小时内,第一笔交易的发生时间 (Unix timestamp)
+	CloseTime          int64  `json:"closeTime"`          // 24小时内,最后一笔交易的发生时间 (Unix timestamp)
+	FirstId            int    `json:"firstId"`            // 首笔成交id
+	LastId             int    `json:"lastId"`             // 末笔成交id
+	Count              int    `json:"count"`              // 成交笔数
+}
+
+type RateLimit struct {
+	// 定义在 "限制种类 (rateLimitType)" 部分的限制
+}
+
+type ExchangeFilter struct {
+	// 定义在 "过滤器" 部分的过滤器
+	FilterType string `json:"filterType"` //类别
+	MinPrice   string `json:"minPrice"`   //最小金额
+	MaxPrice   string `json:"maxPrice"`   //最大金额
+	TickSize   string `json:"tickSize"`   //最小精度
+
+	MinQty   string `json:"minQty"`   //最小购买数量
+	MaxQty   string `json:"maxQty"`   //最大购买数量
+	StepSize string `json:"stepSize"` //数量最小精度
+}
+
+type Symbol struct {
+	Symbol                          string           `json:"symbol"`                          // 交易对符号 (e.g., ETHBTC)
+	Status                          string           `json:"status"`                          // 当前状态 (e.g., TRADING)
+	BaseAsset                       string           `json:"baseAsset"`                       // 基础资产 (e.g., ETH)
+	BaseAssetPrecision              int              `json:"baseAssetPrecision"`              // 基础资产精度
+	QuoteAsset                      string           `json:"quoteAsset"`                      // 报价资产 (e.g., BTC)
+	QuotePrecision                  int              `json:"quotePrecision"`                  // 报价资产精度
+	QuoteAssetPrecision             int              `json:"quoteAssetPrecision"`             // 报价资产的精度
+	OrderTypes                      []string         `json:"orderTypes"`                      // 支持的订单类型
+	IcebergAllowed                  bool             `json:"icebergAllowed"`                  // 是否允许冰山订单
+	OcoAllowed                      bool             `json:"ocoAllowed"`                      // 是否允许 OCO (One Cancels the Other) 订单
+	QuoteOrderQtyMarketAllowed      bool             `json:"quoteOrderQtyMarketAllowed"`      // 是否允许市场单的报价订单数量
+	AllowTrailingStop               bool             `json:"allowTrailingStop"`               // 是否允许跟踪止损
+	IsSpotTradingAllowed            bool             `json:"isSpotTradingAllowed"`            // 是否允许现货交易
+	IsMarginTradingAllowed          bool             `json:"isMarginTradingAllowed"`          // 是否允许保证金交易
+	CancelReplaceAllowed            bool             `json:"cancelReplaceAllowed"`            // 是否允许取消替代
+	Filters                         []ExchangeFilter `json:"filters"`                         // 过滤器,定义在 "过滤器" 部分
+	Permissions                     []string         `json:"permissions"`                     // 权限
+	PermissionSets                  [][]string       `json:"permissionSets"`                  // 权限集
+	DefaultSelfTradePreventionMode  string           `json:"defaultSelfTradePreventionMode"`  // 默认的自我交易防止模式
+	AllowedSelfTradePreventionModes []string         `json:"allowedSelfTradePreventionModes"` // 允许的自我交易防止模式
+}
+
+type ExchangeInfo struct {
+	Timezone        string           `json:"timezone"`        // 时区 (e.g., UTC)
+	ServerTime      int64            `json:"serverTime"`      // 服务器时间 (Unix timestamp)
+	RateLimits      []RateLimit      `json:"rateLimits"`      // 速率限制,定义在 "限制种类" 部分
+	ExchangeFilters []ExchangeFilter `json:"exchangeFilters"` // 交易所过滤器,定义在 "过滤器" 部分
+	Symbols         []Symbol         `json:"symbols"`         // 交易对列表
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..48e341a
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,3 @@
+{
+  "lockfileVersion": 1
+}
diff --git a/pkg/coingate/coingatehelper.go b/pkg/coingate/coingatehelper.go
new file mode 100644
index 0000000..4e577c5
--- /dev/null
+++ b/pkg/coingate/coingatehelper.go
@@ -0,0 +1,93 @@
+package coingate
+
+import (
+	"errors"
+	"fmt"
+	"go-admin/common/global"
+	"go-admin/common/helper"
+	"go-admin/config"
+	"go-admin/models/coingatedto"
+	"io/ioutil"
+	"net/http"
+	"strings"
+
+	"github.com/bytedance/sonic"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+)
+
+/*
+获取支付连接
+
+  - @endPoint basic url
+  - @token api 密钥
+  - @req 请求参数
+*/
+func GetPaymentUrl(endPoint string, token string, req *coingatedto.OrderRequest) (resp coingatedto.OrderResponse, err error) {
+	method := "POST"
+	url := fmt.Sprintf("%s%s", endPoint, "/v2/orders")
+	payload, err := sonic.Marshal(req)
+
+	if err != nil {
+		return
+	}
+	client := &http.Client{}
+	err = helper.CreateHtppProxy("", config.ExtConfig.ProxyUrl, client)
+
+	if err != nil {
+		return
+	}
+
+	request, err := http.NewRequest(method, url, strings.NewReader(string(payload)))
+
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
+	request.Header.Add("Content-Type", "application/json")
+
+	res, err := client.Do(request)
+	if err != nil {
+		return
+	}
+	defer res.Body.Close()
+
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		return
+	}
+
+	if res.StatusCode != http.StatusOK {
+		log.Error("status:", res.Status, "获取支付失败:", string(body))
+		err = errors.New("获取支付连接失败,status:" + res.Status)
+		return
+	}
+
+	err = sonic.Unmarshal(body, &resp)
+
+	return
+}
+
+/*
+支付回调
+*/
+func CallBack(req *coingatedto.OrderCallBackResponse) error {
+	switch req.Status {
+	case global.COINGATE_STATUS_NEW:
+	case global.COINGATE_STATUS_PENDING:
+	case global.COINGATE_STATUS_CONFIRMING:
+	case global.COINGATE_STATUS_PAID:
+	case global.COINGATE_STATUS_INVALID:
+	case global.COINGATE_STATUS_EXPIRED:
+	case global.COINGATE_STATUS_CANCELED:
+	case global.COINGATE_STATUS_REFUNDED:
+	case global.COINGATE_STATUS_PARTIALLY_REFUNDED:
+	default:
+		errStr := fmt.Sprintf("支付回调未找到状态%s", req.Status)
+		log.Error(errStr)
+		return errors.New(errStr)
+	}
+
+	return nil
+}
diff --git a/pkg/cryptohelper/aeshelper/aes256.go b/pkg/cryptohelper/aeshelper/aes256.go
new file mode 100644
index 0000000..726882f
--- /dev/null
+++ b/pkg/cryptohelper/aeshelper/aes256.go
@@ -0,0 +1,88 @@
+package aeshelper
+
+import (
+	"bytes"
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/md5"
+	"crypto/rand"
+	"encoding/base64"
+	"io"
+)
+
+// Encrypt text with the passphrase
+func Encrypt(text string, passphrase string) string {
+	salt := make([]byte, 8)
+	if _, err := io.ReadFull(rand.Reader, salt); err != nil {
+		panic(err.Error())
+	}
+
+	key, iv := DeriveKeyAndIv(passphrase, string(salt))
+
+	block, err := aes.NewCipher([]byte(key))
+	if err != nil {
+		panic(err)
+	}
+
+	pad := PKCS7Padding([]byte(text), block.BlockSize())
+	ecb := cipher.NewCBCEncrypter(block, []byte(iv))
+	encrypted := make([]byte, len(pad))
+	ecb.CryptBlocks(encrypted, pad)
+
+	return base64.StdEncoding.EncodeToString([]byte("Salted__" + string(salt) + string(encrypted)))
+}
+
+// Decrypt encrypted text with the passphrase
+func Decrypt(encrypted string, passphrase string) string {
+	ct, _ := base64.StdEncoding.DecodeString(encrypted)
+	if len(ct) < 16 || string(ct[:8]) != "Salted__" {
+		return ""
+	}
+
+	salt := ct[8:16]
+	ct = ct[16:]
+	key, iv := DeriveKeyAndIv(passphrase, string(salt))
+
+	block, err := aes.NewCipher([]byte(key))
+	if err != nil {
+		panic(err)
+	}
+
+	cbc := cipher.NewCBCDecrypter(block, []byte(iv))
+	dst := make([]byte, len(ct))
+	cbc.CryptBlocks(dst, ct)
+
+	return string(PKCS7Trimming(dst))
+}
+
+// PKCS7Padding PKCS7Padding
+func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
+	padding := blockSize - len(ciphertext)%blockSize
+	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+	return append(ciphertext, padtext...)
+}
+
+// PKCS7Trimming PKCS7Trimming
+func PKCS7Trimming(encrypt []byte) []byte {
+	padding := encrypt[len(encrypt)-1]
+	return encrypt[:len(encrypt)-int(padding)]
+}
+
+// DeriveKeyAndIv DeriveKeyAndIv
+func DeriveKeyAndIv(passphrase string, salt string) (string, string) {
+	salted := ""
+	dI := ""
+
+	for len(salted) < 48 {
+		md := md5.New()
+		md.Write([]byte(dI + passphrase + salt))
+		dM := md.Sum(nil)
+		dI = string(dM[:16])
+		salted = salted + dI
+	}
+
+	key := salted[0:32]
+	iv := salted[32:48]
+
+	return key, iv
+}
diff --git a/pkg/cryptohelper/aeshelper/aeshelper.go b/pkg/cryptohelper/aeshelper/aeshelper.go
new file mode 100644
index 0000000..695ea99
--- /dev/null
+++ b/pkg/cryptohelper/aeshelper/aeshelper.go
@@ -0,0 +1,107 @@
+package aeshelper
+
+import (
+	"bytes"
+	"crypto/aes"
+	"crypto/cipher"
+	"encoding/base64"
+	"encoding/hex"
+	"github.com/forgoer/openssl"
+)
+
+const (
+	sKey        = "ptQJqRKxICCTeo6w" // "dde4b1f8a9e6b814"
+	ivParameter = "O3vZvOJSnQDP9hKT" // "dde4b1f8a9e6b814"
+
+)
+
+// PswEncrypt 加密
+func PswEncrypt(src string) (string, error) {
+	key := []byte(sKey)
+	iv := []byte(ivParameter)
+	result, err := Aes128Encrypt([]byte(src), key, iv)
+	if err != nil {
+		return "", err
+	}
+	return base64.RawStdEncoding.EncodeToString(result), nil
+}
+
+// PswDecrypt 解密
+func PswDecrypt(src string) (string, error) {
+	key := []byte(sKey)
+	iv := []byte(ivParameter)
+	var result []byte
+	var err error
+	result, err = base64.StdEncoding.DecodeString(src)
+	if err != nil {
+		return "", err
+	}
+	origData, err := Aes128Decrypt(result, key, iv)
+	if err != nil {
+		return "", err
+	}
+	return string(origData), nil
+}
+
+func Aes128Encrypt(origData, key []byte, IV []byte) ([]byte, error) {
+	if key == nil || len(key) != 16 {
+		return nil, nil
+	}
+	if IV != nil && len(IV) != 16 {
+		return nil, nil
+	}
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		return nil, err
+	}
+	blockSize := block.BlockSize()
+	origData = PKCS5Padding(origData, blockSize)
+	blockMode := cipher.NewCBCEncrypter(block, IV[:blockSize])
+	crypted := make([]byte, len(origData))
+	// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
+	blockMode.CryptBlocks(crypted, origData)
+	return crypted, nil
+}
+func Aes128Decrypt(crypted, key []byte, IV []byte) ([]byte, error) {
+	if key == nil || len(key) != 16 {
+		return nil, nil
+	}
+	if IV != nil && len(IV) != 16 {
+		return nil, nil
+	}
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		return nil, err
+	}
+	blockSize := block.BlockSize()
+	blockMode := cipher.NewCBCDecrypter(block, IV[:blockSize])
+	origData := make([]byte, len(crypted))
+	blockMode.CryptBlocks(origData, crypted)
+	origData = PKCS5UnPadding(origData)
+	return origData, nil
+}
+func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
+	padding := blockSize - len(ciphertext)%blockSize
+	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+	return append(ciphertext, padtext...)
+}
+func PKCS5UnPadding(origData []byte) []byte {
+	length := len(origData)
+	// 去掉最后一个字节 unpadding 次
+	unpadding := int(origData[length-1])
+	return origData[:(length - unpadding)]
+}
+
+// 密码加密
+func AesEcbEncrypt(origData string) string {
+	//加密
+	dst, _ := openssl.AesECBEncrypt([]byte(origData), []byte(sKey), openssl.PKCS7_PADDING)
+	return hex.EncodeToString(dst)
+}
+
+// 密码解密
+func AesEcbDecrypt(origData string) string {
+	value, _ := hex.DecodeString(origData)
+	dst, _ := openssl.AesECBDecrypt(value, []byte(sKey), openssl.PKCS7_PADDING)
+	return string(dst)
+}
diff --git a/pkg/cryptohelper/aeshelper/aeshelper_test.go b/pkg/cryptohelper/aeshelper/aeshelper_test.go
new file mode 100644
index 0000000..b918f4a
--- /dev/null
+++ b/pkg/cryptohelper/aeshelper/aeshelper_test.go
@@ -0,0 +1,65 @@
+package aeshelper
+
+import (
+	"encoding/json"
+	"fmt"
+	"testing"
+	"time"
+)
+
+// 测试加密解密
+func Test_EnDe(t *testing.T) {
+	a := `asg`
+	b := Encrypt(a, `code_verify_success`)
+	c := Decrypt(b, `code_verify_success`)
+	fmt.Println(`原始为`, a)
+	fmt.Println(`加密后`, b)
+	fmt.Println(`解密后`, c)
+}
+func TestAesEcbEncrypt(t *testing.T) {
+	//aes := AesEcbEncrypt("123456")
+	aes := AesEcbEncrypt(fmt.Sprintf("%v_%v", time.Now().Unix(), 1332355333))
+	dst := AesEcbDecrypt(aes)
+	fmt.Println(aes)
+	fmt.Println(dst)
+}
+
+// TODO:需要加密的接口
+/**
+1.合约下单接口            /api/futures/trade/order
+2.合约撤单              /api/futures/trade/cancelorder
+3.调整保证金           /api/futures/trade/adjustmargin
+4.变换逐全仓模式       /api/futures/trade/marginType
+5.更改持仓模式(方向)   /api/futures/trade/positionSide/dual
+6.资产划转          /api/futures/transfer
+*/
+func TestAesEcbEncryptOrder(t *testing.T) {
+	data := addFutOrderReq{
+		OrderType:     1,
+		BuyType:       3,
+		TriggerDecide: 3,
+		IsReduce:      2,
+		Coin:          "asdf",
+		Price:         "333.23",
+		Num:           "23.20",
+		TriggerPrice:  "1.023",
+		PositionSide:  "long",
+	}
+	b, _ := json.Marshal(data)
+	aes := AesEcbEncrypt(string(b))
+	dst := AesEcbDecrypt(aes)
+	fmt.Println(aes)
+	fmt.Println(dst)
+}
+
+type addFutOrderReq struct {
+	OrderType     int    `json:"order_type"`     // 订单类型:1限价,2限价止盈止损,3市价,4市价止盈止损,5强平委托(就是限价委托)
+	BuyType       int    `json:"buy_type"`       // 买卖类型:1买,2卖
+	TriggerDecide int    `json:"trigger_decide"` // 触发条件 1按最新成交价格算,2按标记价格算
+	IsReduce      int    `json:"is_reduce"`      // 1是只减仓位(点击仓位列表中的平仓按钮),0正常
+	Coin          string `json:"coin"`           // 交易币
+	Price         string `json:"price"`          // 下单价格(限价+止盈止损时,该字段必填)
+	Num           string `json:"num"`            // 下单数量(市价时该字段必填)
+	TriggerPrice  string `json:"trigger_price"`  // 触发价格
+	PositionSide  string `json:"position_side"`  // 持仓方向,单向持仓模式下可填both;在双向持仓模式下必填,且仅可选择 long 或 short
+}
diff --git a/pkg/cryptohelper/aeshelper/aesoldhelper/aesoldhelper.go b/pkg/cryptohelper/aeshelper/aesoldhelper/aesoldhelper.go
new file mode 100644
index 0000000..c9812da
--- /dev/null
+++ b/pkg/cryptohelper/aeshelper/aesoldhelper/aesoldhelper.go
@@ -0,0 +1,94 @@
+package aesoldhelper
+
+import (
+	"bytes"
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/rand"
+	"encoding/base64"
+	"errors"
+	"io"
+	"strings"
+)
+
+func addBase64Padding(value string) string {
+	m := len(value) % 4
+	if m != 0 {
+		value += strings.Repeat("=", 4-m)
+	}
+
+	return value
+}
+
+func removeBase64Padding(value string) string {
+	return strings.Replace(value, "=", "", -1)
+}
+
+// Pad Pad
+func Pad(src []byte) []byte {
+	padding := aes.BlockSize - len(src)%aes.BlockSize
+	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+	return append(src, padtext...)
+}
+
+// Unpad Unpad
+func Unpad(src []byte) ([]byte, error) {
+	length := len(src)
+	unpadding := int(src[length-1])
+
+	if unpadding > length {
+		return nil, errors.New("unpad error. This could happen when incorrect encryption key is used")
+	}
+
+	return src[:(length - unpadding)], nil
+}
+
+// AesEncrypt AesEncrypt
+func AesEncrypt(key []byte, text string) (string, error) {
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		return "", err
+	}
+
+	msg := Pad([]byte(text))
+	ciphertext := make([]byte, aes.BlockSize+len(msg))
+	iv := ciphertext[:aes.BlockSize]
+	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
+		return "", err
+	}
+
+	cfb := cipher.NewCFBEncrypter(block, iv)
+	cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(msg))
+	finalMsg := removeBase64Padding(base64.URLEncoding.EncodeToString(ciphertext))
+	return finalMsg, nil
+}
+
+// AesDecrypt AesDecrypt
+func AesDecrypt(key []byte, text string) (string, error) {
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		return "", err
+	}
+
+	decodedMsg, err := base64.URLEncoding.DecodeString(addBase64Padding(text))
+	if err != nil {
+		return "", err
+	}
+
+	if (len(decodedMsg) % aes.BlockSize) != 0 {
+		return "", errors.New("blocksize must be multipe of decoded message length")
+	}
+
+	iv := decodedMsg[:aes.BlockSize]
+	msg := decodedMsg[aes.BlockSize:]
+
+	cfb := cipher.NewCFBDecrypter(block, iv)
+	cfb.XORKeyStream(msg, msg)
+
+	unpadMsg, err := Unpad(msg)
+	if err != nil {
+		return "", err
+	}
+
+	return string(unpadMsg), nil
+}
diff --git a/pkg/cryptohelper/aeshelper/apikey.go b/pkg/cryptohelper/aeshelper/apikey.go
new file mode 100644
index 0000000..006c1a5
--- /dev/null
+++ b/pkg/cryptohelper/aeshelper/apikey.go
@@ -0,0 +1,19 @@
+package aeshelper
+
+var (
+	apiaeskey = "9jxFTkydwCJsmIA1TUrv"
+)
+
+// EncryptApi 加密apikey
+func EncryptApi(apikey, secretkey string) (apikeyen, secrekeyen string) {
+	apikeyen = Encrypt(apikey, apiaeskey)
+	secrekeyen = Encrypt(secretkey, apiaeskey)
+	return apikeyen, secrekeyen
+}
+
+// DecryptApi 解密apikey
+func DecryptApi(apikeyen, secrekeyen string) (apikey, secrekey string) {
+	apikey = Decrypt(apikeyen, apiaeskey)
+	secrekey = Decrypt(secrekeyen, apiaeskey)
+	return apikey, secrekey
+}
diff --git a/pkg/cryptohelper/inttostring/Inttoostr.go b/pkg/cryptohelper/inttostring/Inttoostr.go
new file mode 100644
index 0000000..99762d1
--- /dev/null
+++ b/pkg/cryptohelper/inttostring/Inttoostr.go
@@ -0,0 +1,133 @@
+package inttostring
+
+import (
+	"math"
+	"math/rand"
+	"strings"
+	"time"
+)
+
+// IntToStr 用于将数字映射为字符串 例如 用户id-->邀请码
+type IntToStr struct {
+	SALT            int  // 随意取一个数值
+	Len             int  // 邀请码长度
+	PRIME2          byte // 与邀请码长度 8 互质
+	AlphanumericSet []rune
+	PRIME1          int // 与字符集长度 36 互质
+}
+
+var (
+	Invite = NewInvite() // 邀请码
+)
+
+// NewInvite 邀请码
+func NewInvite() *IntToStr {
+	return &IntToStr{
+		SALT:   15151239, // 随意取一个数值
+		Len:    8,        // 邀请码长度
+		PRIME2: 3,        // 与邀请码长度 Len 互质
+		AlphanumericSet: []rune{
+			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+			'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+		}, // 邀请码长度
+		PRIME1: 5, // 与字符集长度 36 互质
+	}
+}
+
+func (in IntToStr) DeCode(codeStr string) int {
+	code := make([]rune, 0, in.Len)
+	var key rune = 0
+	// 还原k
+	for i := 0; i < in.Len; i++ {
+		for k, v := range in.AlphanumericSet {
+			if v == rune(codeStr[i]) {
+				key = rune(k)
+				break
+			}
+		}
+		code = append(code, key)
+	}
+	code2 := make([]rune, 0, in.Len)
+	// 还原顺序
+	for i := 0; i < in.Len; i++ {
+		idx := i * int(in.PRIME2) % in.Len
+		code2 = append(code2, code[idx])
+	}
+
+	// 还原数字
+	var x int
+	for i := 0; i < in.Len; i++ {
+		code2[i] = (code2[i] - rune(i)*code2[0]) % rune(len(in.AlphanumericSet))
+		code2[i] = (code2[i] + rune(len(in.AlphanumericSet))) % rune(len(in.AlphanumericSet))
+		place := math.Pow(float64(len(in.AlphanumericSet)), float64(i)) // 次方运算
+		x += int(code2[i]) * int(place)
+	}
+	//  去盐  + 缩小
+	x = (x - in.SALT) / in.PRIME1
+
+	return x
+}
+
+func (in IntToStr) Encode(uid int) string {
+	// 放大 + 加盐
+	uid = uid*in.PRIME1 + in.SALT
+	slIdx := make([]byte, in.Len)
+
+	// 扩散
+	for i := 0; i < in.Len; i++ {
+		slIdx[i] = byte(uid % len(in.AlphanumericSet))                           // 转换进制 获取36进制的每一位值
+		slIdx[i] = (slIdx[i] + byte(i)*slIdx[0]) % byte(len(in.AlphanumericSet)) // 其他位与个位加和再取余(让个位的变化影响到所有位)
+		uid = uid / len(in.AlphanumericSet)                                      // 相当于右移一位(62进制)
+	}
+
+	var code []rune
+	// 混淆
+	for i := 0; i < in.Len; i++ {
+		idx := (byte(i) * in.PRIME2) % byte(in.Len)
+		code = append(code, in.AlphanumericSet[slIdx[idx]])
+	}
+	return string(code)
+}
+
+const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+const smsLetters = "0123456789"
+
+// GenerateRandomString 生成指定长度的随机字符串
+func GenerateRandomString(n int) string {
+	rand.Seed(time.Now().UnixNano()) // 初始化随机数种子
+	result := make([]byte, n)
+	for i := range result {
+		result[i] = letters[rand.Intn(len(letters))]
+	}
+	return string(result)
+}
+
+// GenerateRandomSmsString 生成指定长度的随机字符串
+func GenerateRandomSmsString(n int) string {
+	rand.Seed(time.Now().UnixNano()) // 初始化随机数种子
+	result := make([]byte, n)
+	for i := range result {
+		result[i] = smsLetters[rand.Intn(len(smsLetters))]
+	}
+	return string(result)
+}
+
+func EncryptString(s string, prefixLen, suffixLen int) string {
+	length := len(s)
+
+	// 如果字符串长度不足,直接返回原字符串
+	if length <= prefixLen+suffixLen {
+		return s
+	}
+
+	// 保留前 prefixLen 位和后 suffixLen 位
+	prefix := s[:prefixLen]
+	suffix := s[length-suffixLen:]
+
+	// 中间部分用 * 替换
+	middle := strings.Repeat("*", 6)
+
+	// 拼接结果
+	return prefix + middle + suffix
+}
diff --git a/pkg/cryptohelper/inttostring/Inttoostr_test.go b/pkg/cryptohelper/inttostring/Inttoostr_test.go
new file mode 100644
index 0000000..a31f43f
--- /dev/null
+++ b/pkg/cryptohelper/inttostring/Inttoostr_test.go
@@ -0,0 +1,33 @@
+package inttostring
+
+import (
+	"fmt"
+	"testing"
+)
+
+
+func Test_a(t *testing.T) {
+	a:=1156
+	// b:=byte(a)
+	fmt.Println(a%10)
+}
+// 加密解密
+func Test_EnDecode(t *testing.T) {
+	uid := 6515461646
+	Invi := NewInvite()
+	encode := Invi.Encode(uid)
+	DeCode := Invi.DeCode(encode)
+	fmt.Println(`原始为`, uid)
+	fmt.Println(`加密后`, encode)
+	fmt.Println(`解密后`, DeCode)
+}
+
+func Test_Invite(t *testing.T) {
+	for uid := 0; uid < 10000000; uid++ {
+		encode := Invite.Encode(uid)
+		DeCode := Invite.DeCode(encode)
+		if DeCode != uid {
+			t.Fatal(`加密解密错误`, DeCode, uid)
+		}
+	}
+}
diff --git a/pkg/cryptohelper/jwthelper/jwthelper.go b/pkg/cryptohelper/jwthelper/jwthelper.go
new file mode 100644
index 0000000..bd444aa
--- /dev/null
+++ b/pkg/cryptohelper/jwthelper/jwthelper.go
@@ -0,0 +1,295 @@
+package jwthelper
+
+import (
+	"go-admin/common/const/rediskey"
+	"go-admin/common/helper"
+	"go-admin/pkg/utility"
+
+	"github.com/golang-jwt/jwt/v5"
+	"go.uber.org/zap"
+
+	"fmt"
+	"strings"
+	"time"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+)
+
+// LoginUserJwt 用户登入信息
+type LoginUserJwt struct {
+	UserID   int
+	NickName string
+	Phone    string
+	Email    string
+	OsType   int
+}
+
+// LoginClaims 自定义声明结构体并内嵌jwt.StandardClaims
+// jwt包自带的jwt.StandardClaims只包含了官方字段
+// 我们这里需要额外记录一个nickname字段,所以要自定义结构体
+// 如果想要保存更多信息,都可以添加到这个结构体中
+type LoginClaims struct {
+	UserID   int    `json:"userid"`
+	NickName string `json:"nickname"`
+	Phone    string `json:"phone"`
+	Email    string `json:"email"`
+	jwt.RegisteredClaims
+}
+
+// JwtSigningKey Jwt signing key
+var JwtSigningKey = []byte("tokexapp.com")
+
+var LoginTokenValidTime = 48 * time.Hour // 登录验证token有效期
+var LoginAdminTokenValidTime = 24 * time.Hour
+
+var TokenNotValid = -1 // Token无效
+var TokenExpire = -2   // Token过期
+var TokenSuccess = 1   // Token正常
+
+// CreateJwtToken 创建用户jwt token
+func CreateJwtToken(userJwt LoginUserJwt, minute int) (string, string) {
+	// 创建一个我们自己的声明
+	expire := time.Now().Add(time.Minute * time.Duration(minute)) //.Unix()
+	claims := LoginClaims{
+		UserID:   userJwt.UserID,
+		Phone:    userJwt.Phone,
+		NickName: userJwt.NickName,
+		Email:    userJwt.Email,
+		RegisteredClaims: jwt.RegisteredClaims{
+			ExpiresAt: jwt.NewNumericDate(expire),
+			Issuer:    "Tokex", // 签发人
+		},
+	}
+
+	// 使用指定的签名方法创建签名对象
+	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+	tokenStr, err := token.SignedString(JwtSigningKey)
+	if err != nil {
+		log.Error("获取jwt token失败:", zap.Error(err))
+		return "", ""
+	}
+	return tokenStr, fmt.Sprintf("%v", expire.Unix())
+}
+
+// MidValidToken 检验token是否有效,返回token解密后的string
+func MidValidToken(tokenStr string, source int) (int, string) {
+	// 解析token
+	token, err := jwt.ParseWithClaims(tokenStr, &LoginClaims{}, func(token *jwt.Token) (i interface{}, err error) {
+		return JwtSigningKey, nil
+	})
+	if err != nil {
+		if strings.Contains(err.Error(), "token is expired") {
+			return TokenExpire, ""
+		}
+		// loghelper.Error("MidValidToken解析token失败", zap.Error(err))
+		return TokenNotValid, ""
+	}
+	if !token.Valid {
+		log.Error("MidValidToken解析token无效", zap.Error(err))
+		return TokenNotValid, ""
+	}
+	claims, ok := token.Claims.(*LoginClaims)
+	if !ok {
+		return TokenNotValid, ""
+	}
+
+	// 校验token
+	key := fmt.Sprintf(rediskey.AppLoginUserToken, claims.UserID)
+	if source == 3 {
+		key = fmt.Sprintf(rediskey.PCLoginUserToken, claims.UserID)
+	}
+	appToken, _ := helper.DefaultRedis.GetString(key)
+	if len(appToken) == 0 {
+		//说明未登入或者过期
+		return TokenExpire, ""
+	}
+	if appToken != tokenStr {
+		//说明是被t
+		return TokenExpire, ""
+	}
+
+	return TokenSuccess, strings.Join([]string{utility.IntToString(claims.UserID),
+		claims.NickName, claims.Phone, claims.Email}, ",")
+}
+
+// GetLoginUserJwt 解析用户登入信息
+func GetLoginUserJwt(tokenStr string) LoginUserJwt {
+	if len(tokenStr) == 0 {
+		return LoginUserJwt{}
+	}
+	tokenArr := strings.Split(tokenStr, ",")
+	arrLen := len(tokenArr)
+	item := LoginUserJwt{
+		UserID: utility.StringAsInteger(tokenArr[0]),
+	}
+	if arrLen > 1 {
+		item.NickName = tokenArr[1]
+	}
+	if arrLen > 2 {
+		item.Phone = tokenArr[2]
+	}
+	if arrLen > 3 {
+		item.Email = tokenArr[3]
+	}
+	return item
+}
+
+// AgentLoginJwt ==============Agent 代理商 JWT========================//
+type AgentLoginJwt struct {
+	AgentId int    `json:"agent_id"` // 代理商ID
+	UserId  int    `json:"user_id"`  // 代理商关联的用户ID
+	Name    string `json:"name"`     // 代理商姓名
+	Email   string `json:"email"`    // 代理商邮件
+	IP      string `json:"ip"`       // 代理商IP
+}
+type AgentLoginClaims struct {
+	AgentId              int    `json:"agent_id"` // 代理商ID
+	UserId               int    `json:"user_id"`  // 代理商关联的用户ID
+	Name                 string `json:"name"`     // 代理商姓名
+	Email                string `json:"email"`    // 代理商邮件
+	IP                   string `json:"ip"`       // 代理商IP
+	jwt.RegisteredClaims        //StandardClaims
+}
+
+var JwtAgentSigningKey = []byte("tokexagent.com") //Jwt signing key
+
+// CreateAgentJwtToken 代理商产生的token
+func CreateAgentJwtToken(userJwt AgentLoginJwt, minute int) string {
+	// 创建一个我们自己的声明
+	exp := time.Now().Add(time.Minute * time.Duration(minute))
+	c := AgentLoginClaims{
+		userJwt.AgentId,
+		userJwt.UserId, // 自定义字段
+		userJwt.Name,
+		userJwt.Email,
+		userJwt.IP,
+		jwt.RegisteredClaims{
+			ExpiresAt: jwt.NewNumericDate(exp), // 过期时间
+			Issuer:    "Tokex-Agent",           // 签发人
+		},
+	}
+	// 使用指定的签名方法创建签名对象
+	token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
+	tokenStr, err := token.SignedString(JwtAgentSigningKey)
+	if err != nil {
+		log.Error("获取jwt token失败:", zap.Error(err))
+		return ""
+	}
+	return tokenStr
+}
+
+// MidValidAgentToken 检验token是否有效,返回token解密后的string
+func MidValidAgentToken(tokenStr string) (int, string) {
+	// 解析token
+	token, err := jwt.ParseWithClaims(tokenStr, &AgentLoginClaims{}, func(token *jwt.Token) (i interface{}, err error) {
+		return JwtAgentSigningKey, nil
+	})
+	if err != nil {
+		return TokenNotValid, ""
+	}
+	if !token.Valid {
+		log.Error("MidValidAgentToken解析token无效", zap.Error(err))
+		return TokenNotValid, ""
+	}
+	claims, ok := token.Claims.(*AgentLoginClaims)
+	if !ok {
+		return TokenNotValid, ""
+	}
+
+	// 校验token
+	key := fmt.Sprintf(rediskey.AgentLoginUserToken, claims.AgentId)
+	appToken, _ := helper.DefaultRedis.GetString(key)
+	if len(appToken) == 0 {
+		return TokenExpire, ""
+	}
+	if appToken != tokenStr {
+		return TokenExpire, ""
+	}
+
+	return TokenSuccess, strings.Join([]string{utility.IntToString(claims.AgentId), utility.IntToString(claims.UserId),
+		claims.Name, claims.Email, claims.IP}, ",")
+}
+
+// GetLoginAgentJwt 解析代理商登入信息
+func GetLoginAgentJwt(tokenStr string) AgentLoginJwt {
+	if len(tokenStr) == 0 {
+		return AgentLoginJwt{}
+	}
+	tokenArr := strings.Split(tokenStr, ",")
+	arrLen := len(tokenArr)
+	item := AgentLoginJwt{
+		AgentId: utility.StringAsInteger(tokenArr[0]),
+	}
+	if arrLen > 1 {
+		item.UserId = utility.StringAsInteger(tokenArr[1])
+	}
+	if arrLen > 2 {
+		item.Name = tokenArr[2]
+	}
+	if arrLen > 3 {
+		item.Email = tokenArr[3]
+	}
+	if arrLen > 4 {
+		item.IP = tokenArr[4]
+	}
+	return item
+}
+
+// ========== Admin 专用 JWT ========== //
+
+type AdminLogin struct {
+	UserID   int    `json:"user_id"`
+	Account  string `json:"account"`
+	NickName string `json:"nickname"`
+	Phone    string `json:"phone"`
+	Email    string `json:"email"`
+	IP       string `json:"ip"`
+}
+
+type AdminLoginClaims struct {
+	AdminLogin
+	jwt.RegisteredClaims //StandardClaims
+}
+
+var AdminSignedKey = []byte("adm23inTOKexKey:237") // Admin 签名 Key
+
+const AdminTokenIssue = "tokexAdmin" // Admin 签发人
+
+// GenerateAdminLoginToken 生成管理员登录 Token
+func GenerateAdminLoginToken(admin AdminLogin, expires time.Duration) string {
+	exp := time.Now().Add(expires)
+	claims := AdminLoginClaims{
+		admin,
+		jwt.RegisteredClaims{
+			ExpiresAt: jwt.NewNumericDate(exp), // 过期时间
+			Issuer:    AdminTokenIssue,         // 签发人
+		},
+	}
+
+	// 使用指定的签名方法创建签名对象
+	jwtToken, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(AdminSignedKey)
+	if err != nil {
+		log.Error("获取 jwtToken 失败:", zap.Error(err))
+	}
+
+	return jwtToken
+}
+
+// ParseAdminLoginToken 解析管理员登录 Token
+func ParseAdminLoginToken(jwtToken string) (pass bool, adminLogin AdminLoginClaims) {
+	// 解析 jwtToken
+	token, err := jwt.ParseWithClaims(jwtToken, &AdminLoginClaims{}, func(token *jwt.Token) (i interface{}, err error) {
+		return AdminSignedKey, nil
+	})
+	if err != nil {
+		log.Error("解析 jwtToken 失败:", zap.Error(err))
+		return false, adminLogin
+	}
+
+	// 判断是否验证通过,并将 Claims => AdminLoginClaims
+	if claims, pass := token.Claims.(*AdminLoginClaims); pass && token.Valid {
+		return pass, *claims
+	}
+
+	return false, adminLogin
+}
diff --git a/pkg/cryptohelper/md5helper/md5helper.go b/pkg/cryptohelper/md5helper/md5helper.go
new file mode 100644
index 0000000..eea1507
--- /dev/null
+++ b/pkg/cryptohelper/md5helper/md5helper.go
@@ -0,0 +1,17 @@
+package md5helper
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+)
+
+// MD5 md5加密
+func MD5(input string) string {
+	cc := md5.Sum([]byte(input))
+	return hex.EncodeToString(cc[:])
+}
+
+// MD52 md52次
+func MD52(input string) string {
+	return MD5(MD5(input))
+}
diff --git a/pkg/cryptohelper/md5helper/md5helper_test.go b/pkg/cryptohelper/md5helper/md5helper_test.go
new file mode 100644
index 0000000..29dfb85
--- /dev/null
+++ b/pkg/cryptohelper/md5helper/md5helper_test.go
@@ -0,0 +1,55 @@
+package md5helper
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+	"fmt"
+	"testing"
+)
+
+func TestMD52(t *testing.T) {
+	got := MD52("Qq123456")
+	fmt.Println(got)
+}
+
+func TestMD5(t *testing.T) {
+	got := []byte("Qq123456")
+	s := md5.New()
+	s.Write(got)
+	fmt.Println(hex.EncodeToString(s.Sum(nil)))
+
+	cc := md5.Sum(got)
+	fmt.Println(hex.EncodeToString(cc[:]))
+
+	fmt.Printf("%x\n", md5.Sum(got))
+
+}
+
+// go test -bench=_QE_ -benchmem -run=^$
+func Benchmark_QE_1(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		input := `Qq123456`
+		s := md5.New()
+		s.Write([]byte(input))
+		hex.EncodeToString(s.Sum(nil))
+	}
+}
+
+func Benchmark_QE_2(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		input := `Qq123456`
+		cc := md5.Sum([]byte(input))
+		hex.EncodeToString(cc[:])
+	}
+}
+
+func Benchmark_QE_3(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		input := `Qq123456`
+		fmt.Sprintf("%x\n", md5.Sum([]byte(input)))
+	}
+}
+
+// Benchmark_QE_1-6         6354160               189.8 ns/op            48 B/op          2 allocs/op
+// Benchmark_QE_2-6         7352328               162.9 ns/op            32 B/op          1 allocs/op
+// Benchmark_QE_3-6         3007480               396.9 ns/op            80 B/op          3 allocs/op
diff --git a/pkg/emailhelper/emailhelper.go b/pkg/emailhelper/emailhelper.go
new file mode 100644
index 0000000..b60ac96
--- /dev/null
+++ b/pkg/emailhelper/emailhelper.go
@@ -0,0 +1,181 @@
+package emailhelper
+
+import (
+	"errors"
+	"fmt"
+	"go-admin/config"
+	"go-admin/pkg/utility"
+	"regexp"
+	"sync"
+
+	log "github.com/go-admin-team/go-admin-core/logger"
+	"github.com/mailjet/mailjet-apiv3-go"
+	"go.uber.org/zap"
+
+	"gopkg.in/gomail.v2"
+)
+
+var (
+	cacheEmail = make(map[string]*gomail.Dialer)
+	mu         = sync.RWMutex{}
+)
+
+// getGoMailIn 邮件连接池
+func getGoMailIn(key string) *gomail.Dialer {
+	mu.RLock()
+	defer mu.RUnlock()
+
+	item, ok := cacheEmail[key]
+	if ok {
+		return item
+	}
+
+	return nil
+}
+
+// CheckIsEmail 检测是否是邮箱
+func CheckIsEmail(email string) bool {
+	if email == `` {
+		return false
+	}
+	pattern := `\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*` // 匹配电子邮箱
+	reg := regexp.MustCompile(pattern)
+
+	return reg.MatchString(email)
+}
+
+// SendFrontedEmail 发送邮件
+func SendFrontedEmail(toEmail string, code string) error {
+	// 邮箱配置
+	from := config.ExtConfig.EmailConfig.MailFrom         // 发送者邮箱
+	password := config.ExtConfig.EmailConfig.MailSmtpPass // Gmail 密码或应用专用密码
+	to := toEmail                                         // 收件人邮箱
+	smtpHost := config.ExtConfig.EmailConfig.MailSmtpHost // Gmail SMTP 服务器
+	smtpPort := config.ExtConfig.EmailConfig.MailSmtpPort // SMTP 端口
+
+	link := fmt.Sprintf("%s/verify?email=%s&verify_code=%s&type=register", config.ExtConfig.Domain, toEmail, code)
+	// 创建邮件消息
+	subject := "注册验证"
+	body := fmt.Sprintf("注册验证 您收到此电子邮件,用于进行邮箱验证,请点击下面的链接或打开下面的网址继续。 
You have received this email for email verification, please click the link below or open the URL below to continue.
 %s            
", link)
+
+	m := gomail.NewMessage()
+	m.SetHeader("From", from)       // 发件人
+	m.SetHeader("To", to)           // 收件人
+	m.SetHeader("Subject", subject) // 邮件主题
+	m.SetBody("text/html", body)    // 邮件内容(纯文本)
+
+	// 设置 SMTP 服务器信息
+	d := gomail.NewDialer(smtpHost, utility.StringToInt(smtpPort), from, password)
+
+	// 发送邮件
+	if err := d.DialAndSend(m); err != nil {
+		log.Error("发送邮件失败: %v", err)
+		return err
+	}
+	return nil
+}
+
+// SendEmail 发送邮件
+//func SendEmail(send config.EmailSend) (string, bool) {
+//	m := gomail.NewMessage()
+//	m.SetHeader("From", m.FormatAddress(send.From, send.Username)) // 这里等软件名字定下来以后使用多语言配置具体名称
+//	m.SetHeader("To", send.To)                                     // "bob@example.com", "cora@example.com")
+//	// m.SetAddressHeader("Cc", "dan@example.com", "Dan")
+//	m.SetHeader("Subject", send.Subject)
+//	m.SetBody("text/html", send.Content) // "Hello Bob  and Cora !")
+//	// m.Attach("/home/Alex/lolcat.jpg")
+//	key := send.Server + send.From
+//	gmailClient := getGoMailIn(key)
+//	if gmailClient == nil {
+//		mu.Lock()
+//		d := gomail.NewDialer(send.Server, send.Port, send.From, send.Secret)
+//		d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
+//		cacheEmail[key] = d
+//		mu.Unlock()
+//		gmailClient = d
+//	}
+//
+//	// Send the email to Bob, Cora and Dan.
+//	if err := gmailClient.DialAndSend(m); err != nil {
+//		log.Error("d.DialAndSend", zap.Error(err))
+//		return "发送失败", false
+//	}
+//
+//	return "", true
+//}
+
+var (
+	apiKeyPublic  = "00d2889da90d5d90767bf04dc1bdc6fa"
+	apiKeyPrivate = "f68cd84cd88b7e2aabce79c878a77e97"
+)
+
+func MailJetSend(receive string, code string) error {
+	mailjetClient := mailjet.NewMailjetClient(apiKeyPublic, apiKeyPrivate) //"00d2889da90d5d90767bf04dc1bdc6fa", "f68cd84cd88b7e2aabce79c878a77e97")
+	messagesInfo := []mailjet.InfoMessagesV31{
+		{
+			From: &mailjet.RecipientV31{
+				Email: "email@tokex.shop",
+				Name:  "Tokex",
+			},
+			To: &mailjet.RecipientsV31{
+				mailjet.RecipientV31{
+					Email: receive,
+					Name:  "",
+				},
+			},
+			Subject:  "【Tokex】邮箱验证码",
+			TextPart: "您的邮箱验证码为:" + code,
+			// HTMLPart: "欢迎注册登录我们的服务,您的验证码为:1234567 抱歉,javascript被禁用,请开启后重试。