remove admin,focus go-zero
This commit is contained in:
parent
c6fd906d96
commit
7c3107bf0d
27
README-cn.md
27
README-cn.md
|
@ -35,8 +35,6 @@
|
|||
- docker-compose
|
||||
- mysql
|
||||
- redis
|
||||
- gin-vue-admin
|
||||
- air
|
||||
- modd
|
||||
- jenkins
|
||||
- gitlab
|
||||
|
@ -79,9 +77,6 @@
|
|||
|
||||
项目目录结构如下:
|
||||
|
||||
- admin:后台代码(整合了gin-vue-admin,充当一个后台大网关),使用grpc与app下的rpc业务交互,后台gin-vue-admin与go-zero的代码交互在banner功能上有个例子可以查看,如果不想要后台,直接删除admin整个文件夹,在执行一次 go mod tidy即可
|
||||
- admin/web : 后台web端代码,gin-vue-admin的
|
||||
|
||||
|
||||
- app:所有业务代码包含api、rpc以及mq(消息队列、延迟队列、定时任务)
|
||||
- common:通用组件 error、middleware、interceptor、tool、ctxdata等
|
||||
|
@ -114,9 +109,7 @@
|
|||
|
||||
## 网关
|
||||
|
||||
nginx做网关,使用nginx的auth模块,调用后端的identity服务统一鉴权,业务内部不鉴权,如果涉及到业务资金比较多也可以在业务中进行二次鉴权,为了安全嘛。
|
||||
|
||||
另外,很多同学觉得nginx做网关不太好,这块原理基本一样,可以自行替换成apisix、kong等
|
||||
nginx做对外网关,网关前面是slb,另外,很多同学觉得nginx做网关不太好,这块原理基本一样,可以自行替换成apisix、kong等
|
||||
|
||||
|
||||
|
||||
|
@ -146,21 +139,19 @@ go-zero默认jaeger、zipkin支持,只需要配置就可以了,可以看配
|
|||
|
||||
|
||||
|
||||
## 消息队列
|
||||
## 发布订阅
|
||||
|
||||
消息队列使用的是go-zero开发团队开发的go-queue,链接:https://github.com/zeromicro/go-queue
|
||||
kafka , 发布订阅使用的是go-zero开发团队开发的go-queue,链接:https://github.com/zeromicro/go-queue
|
||||
|
||||
这里使用可kq,kq是基于kafka做的高性能消息队列
|
||||
|
||||
通用go-queue中也有dq,是延迟队列,不过当前项目没有使用dq
|
||||
这里使用可kq,kq是基于kafka做的高性能发布订阅
|
||||
|
||||
|
||||
|
||||
## 延迟队列、定时任务
|
||||
## 消息队列、延迟队列、定时任务
|
||||
|
||||
延迟队列、定时任务本项目使用的是asynq , google团队给予redis开发的简单中间件,
|
||||
消息队列、延迟队列、定时任务本项目使用的是asynq ,基于redis开发的简单中间件,
|
||||
|
||||
当然了asynq也支持消息队列,你也可也把kq消息队列替换成这个,毕竟只需要redis不需要在去维护一个kafka也是不错的
|
||||
当然,消息队列你也可以使用go-queue
|
||||
|
||||
链接:https://github.com/hibiken/asynq
|
||||
|
||||
|
@ -182,7 +173,7 @@ go-zero默认jaeger、zipkin支持,只需要配置就可以了,可以看配
|
|||
|
||||
gitlab + jenkins + harbor + k8s
|
||||
|
||||
在jenkins中点击部署对应的服务,会去gitlab拉取代码-->再去拉取线上配置(线上配置单独一个git库,为什么不用配置中心,部署文档中有介绍)---->自动构建镜像-->推送到harbor镜像仓库--->使用kubectl自动发布到k8s中---->前面要挂一个nignx做网关统一入口、鉴权、限流等
|
||||
在jenkins中点击部署对应的服务,会去gitlab拉取代码-->再去拉取线上配置(线上配置单独一个git库,为什么不用配置中心,部署文档中有介绍)---->自动构建镜像-->推送到harbor镜像仓库--->使用kubectl自动发布到k8s中---->前面要挂一个nignx做网关统一入口
|
||||
|
||||
|
||||
|
||||
|
@ -192,8 +183,6 @@ go-zero 微服务: https://github.com/zeromicro/go-zero
|
|||
|
||||
dtm分布式事务:https://github.com/dtm-labs/dtm
|
||||
|
||||
gin-vue-admin后台:https://github.com/flipped-aurora/gin-vue-admin
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
| travel | 1003 | 2003 | |
|
||||
| usercenter | 1004 | 2004 | |
|
||||
| mqueue | - | - | job-3002、schedule-3003 |
|
||||
| banner | - | 2005 | |
|
||||
|
||||
|
||||
|
||||
|
@ -32,6 +31,4 @@
|
|||
| usercenter-rpc | 4009 |
|
||||
| mqueue-job | 4010 |
|
||||
| mqueue-scheduler | 4011 |
|
||||
| banner-rpc | 4012 |
|
||||
| admin-api | 4013 |
|
||||
|
26
README.md
26
README.md
|
@ -34,8 +34,6 @@ I may have contacted go zero earlier. I have been using go zero since about 1000
|
|||
- docker-compose
|
||||
- mysql
|
||||
- redis
|
||||
- gin-vue-admin
|
||||
- air
|
||||
- modd
|
||||
- jenkins
|
||||
- gitlab
|
||||
|
@ -106,9 +104,7 @@ The project directory structure is as follows:
|
|||
|
||||
## Gateway
|
||||
|
||||
Nginx acts as a gateway and uses the auth module of nginx to call the identity service of the back-end for unified authentication. There is no authentication within the business. If there are a lot of business funds involved, you can also carry out secondary authentication in the business for security.
|
||||
|
||||
In addition, many students think nginx is not very good as a gateway. The principle is basically the same. They can replace it with apisik, Kong ..
|
||||
nginx do external gateway, gateway in front of the slb, in addition, many students feel that nginx do not do gateway is not very good, this piece of principle is basically the same, you can replace it with apisix, kong, etc.
|
||||
|
||||
|
||||
|
||||
|
@ -138,23 +134,21 @@ Go zero supports Jaeger and Zipkin by default. You only need to configure it. Yo
|
|||
|
||||
|
||||
|
||||
## Message queue
|
||||
## Pub\Sub
|
||||
|
||||
The message queue uses the go queue developed by the go zero development team. The link is: https://github.com/zeromicro/go-queue
|
||||
kafka ,Publish subscription using go-zero development team developed by go-queue, link: https://github.com/zeromicro/go-queue
|
||||
|
||||
KQ can be used here. KQ is a high-performance message queue based on Kafka
|
||||
|
||||
DQ queue is used in the current project, but there is no delay in DQ queue
|
||||
Here we use kq, kq is based on kafka to do high-performance publish subscriptions
|
||||
|
||||
|
||||
|
||||
## Delay queue, Scheduled task
|
||||
## Message queues, delayed queues, timed tasks
|
||||
|
||||
Delay queue and scheduled tasks this project uses asynq, a simple middleware developed based on redis,
|
||||
Message queues, delay queues, timed tasks This project uses asynq, a simple middleware developed based on redis.
|
||||
|
||||
Of course, asynq also supports message queues. You can also replace KQ message queues with this one. After all, it's good to only need redis without maintaining a Kafka
|
||||
Of course, the message queue you can also use go-queue
|
||||
|
||||
Link:https://github.com/hibiken/asynq
|
||||
Link: https://github.com/hibiken/asynq
|
||||
|
||||
|
||||
|
||||
|
@ -176,7 +170,7 @@ project doc :https://github.com/Mikaelemmmm/go-zero-looklook/tree/main/doc
|
|||
|
||||
gitlab + jenkins + harbor + k8s
|
||||
|
||||
Click deploy the corresponding service in Jenkins, and you will go to gitlab to pull the code -- > and then pull the online configuration (a separate git library is configured online, why not use the configuration center, which is described in the deployment document) - -- > automatically build the image -- > push it to the harbor image warehouse -- > automatically publish it to k8s using kubectl -- > a nignx should be hung in front as the gateway for unified entry, authentication, current restriction ....
|
||||
Click in jenkins to deploy the corresponding service, will go to gitlab to pull the code --> then go to pull the online configuration (online configuration of a separate git repository, why not use the configuration center, the deployment documentation has an introduction) ----> automatically build the image --> push to harbor mirror repository --> use kubectl to automatically publish to k8s ----> in front to hang a nignx do gateway unified portal
|
||||
|
||||
|
||||
|
||||
|
@ -186,7 +180,5 @@ go-zero : https://github.com/zeromicro/go-zero
|
|||
|
||||
dtm:https://github.com/dtm-labs/dtm
|
||||
|
||||
gin-vue-admin:https://github.com/flipped-aurora/gin-vue-admin
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
# Config file for [Air](https://github.com/cosmtrek/air) in TOML format
|
||||
|
||||
# Working directory
|
||||
# . or absolute path, please note that the directories following must be under root.
|
||||
root = "."
|
||||
tmp_dir = "tmp"
|
||||
|
||||
[build]
|
||||
# Just plain old shell command. You could use `make` as well.
|
||||
cmd = "go build -o ./tmp/main ."
|
||||
# Binary file yields from `cmd`.
|
||||
bin = "tmp/main"
|
||||
# Customize binary.
|
||||
full_bin = "APP_ENV=dev APP_USER=air ./tmp/main"
|
||||
# Watch these filename extensions.
|
||||
include_ext = ["go", "tpl", "tmpl", "html"]
|
||||
# Ignore these filename extensions or directories.
|
||||
exclude_dir = ["assets", "tmp", "vendor", "web/node_modules"]
|
||||
# Watch these directories if you specified.
|
||||
include_dir = []
|
||||
# Exclude files.
|
||||
exclude_file = []
|
||||
# Exclude specific regular expressions.
|
||||
exclude_regex = ["_test.go"]
|
||||
# Exclude unchanged files.
|
||||
exclude_unchanged = true
|
||||
# Follow symlink for directories
|
||||
follow_symlink = true
|
||||
# This log file places in your tmp_dir.
|
||||
log = "air.log"
|
||||
# It's not necessary to trigger build each time file changes if it's too frequent.
|
||||
delay = 1000 # ms
|
||||
# Stop running old binary when build errors occur.
|
||||
stop_on_error = true
|
||||
# Send Interrupt signal before killing process (windows does not support this feature)
|
||||
send_interrupt = false
|
||||
# Delay after sending Interrupt signal
|
||||
kill_delay = 500 # ms
|
||||
|
||||
[log]
|
||||
# Show log time
|
||||
time = false
|
||||
|
||||
[color]
|
||||
# Customize each part's color. If no color found, use the raw app log.
|
||||
main = "magenta"
|
||||
watcher = "cyan"
|
||||
build = "yellow"
|
||||
runner = "green"
|
||||
|
||||
[misc]
|
||||
# Delete tmp directory on exit
|
||||
clean_on_exit = true
|
|
@ -1,6 +0,0 @@
|
|||
#tmp
|
||||
tmp
|
||||
tmp/*
|
||||
#log
|
||||
log/*
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
FROM golang:alpine as builder
|
||||
|
||||
WORKDIR /go/src/looklook/admin
|
||||
COPY . .
|
||||
|
||||
RUN go env -w GO111MODULE=on \
|
||||
&& go env -w GOPROXY=https://goproxy.cn,direct \
|
||||
&& go env -w CGO_ENABLED=0 \
|
||||
&& go env \
|
||||
&& go mod tidy \
|
||||
&& go build -o server .
|
||||
|
||||
FROM alpine:latest
|
||||
|
||||
LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com"
|
||||
|
||||
WORKDIR /go/src/looklook/admin
|
||||
|
||||
COPY --from=0 /go/src/looklook/admin/server ./
|
||||
COPY --from=0 /go/src/looklook/admin/resource ./resource/
|
||||
COPY --from=0 /go/src/looklook/admin/config.docker.yaml ./
|
||||
|
||||
EXPOSE 8888
|
||||
ENTRYPOINT ./server -c config.docker.yaml
|
|
@ -1,57 +0,0 @@
|
|||
## admin项目结构
|
||||
本模块是将gin-vue-admin集成到go-zero-looklook,使gin-vue-admin使用go-zero的zrpc与go-zero交互
|
||||
后台前端代码在go-zero-looklook/admin/web中
|
||||
|
||||
|
||||
```shell
|
||||
├── api
|
||||
│ └── v1
|
||||
├── config
|
||||
├── core
|
||||
├── docs
|
||||
├── global
|
||||
├── initialize
|
||||
│ └── internal
|
||||
├── middleware
|
||||
├── model
|
||||
│ ├── request
|
||||
│ └── response
|
||||
├── packfile
|
||||
├── resource
|
||||
│ ├── excel
|
||||
│ ├── page
|
||||
│ └── template
|
||||
├── router
|
||||
├── service
|
||||
├── source
|
||||
└── utils
|
||||
├── timer
|
||||
└── upload
|
||||
```
|
||||
|
||||
| 文件夹 | 说明 | 描述 |
|
||||
| ------------ | ----------------------- | --------------------------- |
|
||||
| `api` | api层 | api层 |
|
||||
| `--v1` | v1版本接口 | v1版本接口 |
|
||||
| `config` | 配置包 | config.yaml对应的配置结构体 |
|
||||
| `core` | 核心文件 | 核心组件(zap, viper, server)的初始化 |
|
||||
| `docs` | swagger文档目录 | swagger文档目录 |
|
||||
| `global` | 全局对象 | 全局对象 |
|
||||
| `initialize` | 初始化 | router,redis,gorm,validator, timer的初始化 |
|
||||
| `--internal` | 初始化内部函数 | gorm 的 longger 自定义,在此文件夹的函数只能由 `initialize` 层进行调用 |
|
||||
| `middleware` | 中间件层 | 用于存放 `gin` 中间件代码 |
|
||||
| `model` | 模型层 | 模型对应数据表 |
|
||||
| `--request` | 入参结构体 | 接收前端发送到后端的数据。 |
|
||||
| `--response` | 出参结构体 | 返回给前端的数据结构体 |
|
||||
| `packfile` | 静态文件打包 | 静态文件打包 |
|
||||
| `resource` | 静态资源文件夹 | 负责存放静态文件 |
|
||||
| `--excel` | excel导入导出默认路径 | excel导入导出默认路径 |
|
||||
| `--page` | 表单生成器 | 表单生成器 打包后的dist |
|
||||
| `--template` | 模板 | 模板文件夹,存放的是代码生成器的模板 |
|
||||
| `router` | 路由层 | 路由层 |
|
||||
| `service` | service层 | 存放业务逻辑问题 |
|
||||
| `source` | source层 | 存放初始化数据的函数 |
|
||||
| `utils` | 工具包 | 工具函数封装 |
|
||||
| `--timer` | timer | 定时器接口封装 |
|
||||
| `--upload` | oss | oss接口封装 |
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
package autocode
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/autocode"
|
||||
autocodeReq "looklook/admin/model/autocode/request"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/service"
|
||||
"looklook/admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type AutoCodeExampleApi struct{}
|
||||
|
||||
var autoCodeExampleService = service.ServiceGroupApp.AutoCodeServiceGroup.AutoCodeExampleService
|
||||
|
||||
// @Tags AutoCodeExample
|
||||
// @Summary 创建AutoCodeExample
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body autocode.AutoCodeExample true "AutoCodeExample模型"
|
||||
// @Success 200 {object} response.Response{msg=string} "创建AutoCodeExample"
|
||||
// @Router /autoCodeExample/createAutoCodeExample [post]
|
||||
func (autoCodeExampleApi *AutoCodeExampleApi) CreateAutoCodeExample(c *gin.Context) {
|
||||
var autoCodeExample autocode.AutoCodeExample
|
||||
_ = c.ShouldBindJSON(&autoCodeExample)
|
||||
if err := autoCodeExampleService.CreateAutoCodeExample(autoCodeExample); err != nil {
|
||||
global.GVA_LOG.Error("创建失败!", zap.Error(err))
|
||||
response.FailWithMessage("创建失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("创建成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags AutoCodeExample
|
||||
// @Summary 删除AutoCodeExample
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body autocode.AutoCodeExample true "AutoCodeExample模型"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除AutoCodeExample"
|
||||
// @Router /autoCodeExample/deleteAutoCodeExample [delete]
|
||||
func (autoCodeExampleApi *AutoCodeExampleApi) DeleteAutoCodeExample(c *gin.Context) {
|
||||
var autoCodeExample autocode.AutoCodeExample
|
||||
_ = c.ShouldBindJSON(&autoCodeExample)
|
||||
if err := autoCodeExampleService.DeleteAutoCodeExample(autoCodeExample); err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags AutoCodeExample
|
||||
// @Summary 更新AutoCodeExample
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body autocode.AutoCodeExample true "更新AutoCodeExample"
|
||||
// @Success 200 {object} response.Response{msg=string} "更新AutoCodeExample"
|
||||
// @Router /autoCodeExample/updateAutoCodeExample [put]
|
||||
func (autoCodeExampleApi *AutoCodeExampleApi) UpdateAutoCodeExample(c *gin.Context) {
|
||||
var autoCodeExample autocode.AutoCodeExample
|
||||
_ = c.ShouldBindJSON(&autoCodeExample)
|
||||
if err := autoCodeExampleService.UpdateAutoCodeExample(&autoCodeExample); err != nil {
|
||||
global.GVA_LOG.Error("更新失败!", zap.Error(err))
|
||||
response.FailWithMessage("更新失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("更新成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags AutoCodeExample
|
||||
// @Summary 用id查询AutoCodeExample
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query autocode.AutoCodeExample true "用id查询AutoCodeExample"
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "用id查询AutoCodeExample"
|
||||
// @Router /autoCodeExample/findAutoCodeExample [get]
|
||||
func (autoCodeExampleApi *AutoCodeExampleApi) FindAutoCodeExample(c *gin.Context) {
|
||||
var autoCodeExample autocode.AutoCodeExample
|
||||
_ = c.ShouldBindQuery(&autoCodeExample)
|
||||
if err := utils.Verify(autoCodeExample, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, reAutoCodeExample := autoCodeExampleService.GetAutoCodeExample(autoCodeExample.ID); err != nil {
|
||||
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||
response.FailWithMessage("查询失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"reAutoCodeExample": reAutoCodeExample}, "查询成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags AutoCodeExample
|
||||
// @Summary 分页获取AutoCodeExample列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query autocodeReq.AutoCodeExampleSearch true "页码, 每页大小, 搜索条件"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取AutoCodeExample列表,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /autoCodeExample/getAutoCodeExampleList [get]
|
||||
func (autoCodeExampleApi *AutoCodeExampleApi) GetAutoCodeExampleList(c *gin.Context) {
|
||||
var pageInfo autocodeReq.AutoCodeExampleSearch
|
||||
_ = c.ShouldBindQuery(&pageInfo)
|
||||
if err, list, total := autoCodeExampleService.GetAutoCodeExampleInfoList(pageInfo); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: pageInfo.Page,
|
||||
PageSize: pageInfo.PageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package autocode
|
||||
|
||||
type ApiGroup struct {
|
||||
// Code generated by looklook/admin Begin; DO NOT EDIT.
|
||||
AutoCodeExampleApi
|
||||
// Code generated by looklook/admin End; DO NOT EDIT.
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package banner
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"looklook/admin/model/banner/request"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/service"
|
||||
)
|
||||
|
||||
|
||||
type BannerApi struct {
|
||||
}
|
||||
|
||||
var bannerService = service.ServiceGroupApp.BannerServiceGroup.BannerService
|
||||
|
||||
|
||||
|
||||
// FindBanner 用id查询Banner
|
||||
// @Tags Banner
|
||||
// @Summary 用id查询Banner
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query autocode.Banner true "用id查询Banner"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
||||
// @Router /banner/findBanner [get]
|
||||
func (bannerApi *BannerApi) FindBanner(c *gin.Context) {
|
||||
|
||||
var banner request.GetBanner
|
||||
_ = c.ShouldBindJSON(&banner)
|
||||
|
||||
if err ,resp := bannerService.GetBanner(banner.Id);err!= nil {
|
||||
response.FailWithMessage("创建失败", c)
|
||||
} else {
|
||||
response.OkWithData(resp, c)
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package banner
|
||||
|
||||
type ApiGroup struct {
|
||||
// Code generated by looklook/admin Begin; DO NOT EDIT.
|
||||
BannerApi
|
||||
// Code generated by looklook/admin End; DO NOT EDIT.
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"looklook/admin/api/v1/autocode"
|
||||
"looklook/admin/api/v1/banner"
|
||||
"looklook/admin/api/v1/example"
|
||||
"looklook/admin/api/v1/system"
|
||||
)
|
||||
|
||||
type ApiGroup struct {
|
||||
SystemApiGroup system.ApiGroup
|
||||
ExampleApiGroup example.ApiGroup
|
||||
AutoCodeApiGroup autocode.ApiGroup
|
||||
BannerApiGroup banner.ApiGroup
|
||||
}
|
||||
|
||||
var ApiGroupApp = new(ApiGroup)
|
|
@ -1,15 +0,0 @@
|
|||
package example
|
||||
|
||||
import "looklook/admin/service"
|
||||
|
||||
type ApiGroup struct {
|
||||
ExcelApi
|
||||
CustomerApi
|
||||
FileUploadAndDownloadApi
|
||||
}
|
||||
|
||||
var (
|
||||
excelService = service.ServiceGroupApp.ExampleServiceGroup.ExcelService
|
||||
customerService = service.ServiceGroupApp.ExampleServiceGroup.CustomerService
|
||||
fileUploadAndDownloadService = service.ServiceGroupApp.ExampleServiceGroup.FileUploadAndDownloadService
|
||||
)
|
|
@ -1,142 +0,0 @@
|
|||
package example
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"strconv"
|
||||
|
||||
"looklook/admin/model/example"
|
||||
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
exampleRes "looklook/admin/model/example/response"
|
||||
"looklook/admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 断点续传到服务器
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file formData file true "an example for breakpoint resume, 断点续传示例"
|
||||
// @Success 200 {object} response.Response{msg=string} "断点续传到服务器"
|
||||
// @Router /fileUploadAndDownload/breakpointContinue [post]
|
||||
func (u *FileUploadAndDownloadApi) BreakpointContinue(c *gin.Context) {
|
||||
fileMd5 := c.Request.FormValue("fileMd5")
|
||||
fileName := c.Request.FormValue("fileName")
|
||||
chunkMd5 := c.Request.FormValue("chunkMd5")
|
||||
chunkNumber, _ := strconv.Atoi(c.Request.FormValue("chunkNumber"))
|
||||
chunkTotal, _ := strconv.Atoi(c.Request.FormValue("chunkTotal"))
|
||||
_, FileHeader, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("接收文件失败!", zap.Error(err))
|
||||
response.FailWithMessage("接收文件失败", c)
|
||||
return
|
||||
}
|
||||
f, err := FileHeader.Open()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("文件读取失败!", zap.Error(err))
|
||||
response.FailWithMessage("文件读取失败", c)
|
||||
return
|
||||
}
|
||||
defer func(f multipart.File) {
|
||||
err := f.Close()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}(f)
|
||||
cen, _ := ioutil.ReadAll(f)
|
||||
if !utils.CheckMd5(cen, chunkMd5) {
|
||||
global.GVA_LOG.Error("检查md5失败!", zap.Error(err))
|
||||
response.FailWithMessage("检查md5失败", c)
|
||||
return
|
||||
}
|
||||
err, file := fileUploadAndDownloadService.FindOrCreateFile(fileMd5, fileName, chunkTotal)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查找或创建记录失败!", zap.Error(err))
|
||||
response.FailWithMessage("查找或创建记录失败", c)
|
||||
return
|
||||
}
|
||||
err, pathc := utils.BreakPointContinue(cen, fileName, chunkNumber, chunkTotal, fileMd5)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("断点续传失败!", zap.Error(err))
|
||||
response.FailWithMessage("断点续传失败", c)
|
||||
return
|
||||
}
|
||||
|
||||
if err = fileUploadAndDownloadService.CreateFileChunk(file.ID, pathc, chunkNumber); err != nil {
|
||||
global.GVA_LOG.Error("创建文件记录失败!", zap.Error(err))
|
||||
response.FailWithMessage("创建文件记录失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithMessage("切片创建成功", c)
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 查找文件
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file formData file true "Find the file, 查找文件"
|
||||
// @Success 200 {object} response.Response{data=exampleRes.FileResponse,msg=string} "查找文件,返回包括文件详情"
|
||||
// @Router /fileUploadAndDownload/findFile [post]
|
||||
func (u *FileUploadAndDownloadApi) FindFile(c *gin.Context) {
|
||||
fileMd5 := c.Query("fileMd5")
|
||||
fileName := c.Query("fileName")
|
||||
chunkTotal, _ := strconv.Atoi(c.Query("chunkTotal"))
|
||||
err, file := fileUploadAndDownloadService.FindOrCreateFile(fileMd5, fileName, chunkTotal)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查找失败!", zap.Error(err))
|
||||
response.FailWithMessage("查找失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(exampleRes.FileResponse{File: file}, "查找成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 创建文件
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file formData file true "上传文件完成"
|
||||
// @Success 200 {object} response.Response{data=exampleRes.FilePathResponse,msg=string} "创建文件,返回包括文件路径"
|
||||
// @Router /fileUploadAndDownload/findFile [post]
|
||||
func (b *FileUploadAndDownloadApi) BreakpointContinueFinish(c *gin.Context) {
|
||||
fileMd5 := c.Query("fileMd5")
|
||||
fileName := c.Query("fileName")
|
||||
err, filePath := utils.MakeFile(fileName, fileMd5)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("文件创建失败!", zap.Error(err))
|
||||
response.FailWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "文件创建失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "文件创建成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 删除切片
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file formData file true "删除缓存切片"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除切片"
|
||||
// @Router /fileUploadAndDownload/removeChunk [post]
|
||||
func (u *FileUploadAndDownloadApi) RemoveChunk(c *gin.Context) {
|
||||
var file example.ExaFile
|
||||
c.ShouldBindJSON(&file)
|
||||
err := utils.RemoveChunk(file.FileMd5)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("缓存切片删除失败!", zap.Error(err))
|
||||
return
|
||||
}
|
||||
err = fileUploadAndDownloadService.DeleteFileChunk(file.FileMd5, file.FileName, file.FilePath)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error(err.Error(), zap.Error(err))
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
} else {
|
||||
response.OkWithMessage("缓存切片删除成功", c)
|
||||
}
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
package example
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/request"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/example"
|
||||
exampleRes "looklook/admin/model/example/response"
|
||||
"looklook/admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type CustomerApi struct{}
|
||||
|
||||
// @Tags ExaCustomer
|
||||
// @Summary 创建客户
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body example.ExaCustomer true "客户用户名, 客户手机号码"
|
||||
// @Success 200 {object} response.Response{msg=string} "创建客户"
|
||||
// @Router /customer/customer [post]
|
||||
func (e *CustomerApi) CreateExaCustomer(c *gin.Context) {
|
||||
var customer example.ExaCustomer
|
||||
_ = c.ShouldBindJSON(&customer)
|
||||
if err := utils.Verify(customer, utils.CustomerVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
customer.SysUserID = utils.GetUserID(c)
|
||||
customer.SysUserAuthorityID = utils.GetUserAuthorityId(c)
|
||||
if err := customerService.CreateExaCustomer(customer); err != nil {
|
||||
global.GVA_LOG.Error("创建失败!", zap.Error(err))
|
||||
response.FailWithMessage("创建失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("创建成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags ExaCustomer
|
||||
// @Summary 删除客户
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body example.ExaCustomer true "客户ID"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除客户"
|
||||
// @Router /customer/customer [delete]
|
||||
func (e *CustomerApi) DeleteExaCustomer(c *gin.Context) {
|
||||
var customer example.ExaCustomer
|
||||
_ = c.ShouldBindJSON(&customer)
|
||||
if err := utils.Verify(customer.GVA_MODEL, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := customerService.DeleteExaCustomer(customer); err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags ExaCustomer
|
||||
// @Summary 更新客户信息
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body example.ExaCustomer true "客户ID, 客户信息"
|
||||
// @Success 200 {object} response.Response{msg=string} "更新客户信息"
|
||||
// @Router /customer/customer [put]
|
||||
func (e *CustomerApi) UpdateExaCustomer(c *gin.Context) {
|
||||
var customer example.ExaCustomer
|
||||
_ = c.ShouldBindJSON(&customer)
|
||||
if err := utils.Verify(customer.GVA_MODEL, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := utils.Verify(customer, utils.CustomerVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := customerService.UpdateExaCustomer(&customer); err != nil {
|
||||
global.GVA_LOG.Error("更新失败!", zap.Error(err))
|
||||
response.FailWithMessage("更新失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("更新成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags ExaCustomer
|
||||
// @Summary 获取单一客户信息
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query example.ExaCustomer true "客户ID"
|
||||
// @Success 200 {object} response.Response{data=exampleRes.ExaCustomerResponse,msg=string} "获取单一客户信息,返回包括客户详情"
|
||||
// @Router /customer/customer [get]
|
||||
func (e *CustomerApi) GetExaCustomer(c *gin.Context) {
|
||||
var customer example.ExaCustomer
|
||||
_ = c.ShouldBindQuery(&customer)
|
||||
if err := utils.Verify(customer.GVA_MODEL, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
err, data := customerService.GetExaCustomer(customer.ID)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(exampleRes.ExaCustomerResponse{Customer: data}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags ExaCustomer
|
||||
// @Summary 分页获取权限客户列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query request.PageInfo true "页码, 每页大小"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取权限客户列表,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /customer/customerList [get]
|
||||
func (e *CustomerApi) GetExaCustomerList(c *gin.Context) {
|
||||
var pageInfo request.PageInfo
|
||||
_ = c.ShouldBindQuery(&pageInfo)
|
||||
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
err, customerList, total := customerService.GetCustomerInfoList(utils.GetUserAuthorityId(c), pageInfo)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败"+err.Error(), c)
|
||||
} else {
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: customerList,
|
||||
Total: total,
|
||||
Page: pageInfo.Page,
|
||||
PageSize: pageInfo.PageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
package example
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/example"
|
||||
"looklook/admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type ExcelApi struct{}
|
||||
|
||||
// /excel/importExcel 接口,与upload接口作用类似,只是把文件存到resource/excel目录下,用于导入Excel时存放Excel文件(ExcelImport.xlsx)
|
||||
// /excel/loadExcel接口,用于读取resource/excel目录下的文件((ExcelImport.xlsx)并加载为[]model.SysBaseMenu类型的示例数据
|
||||
// /excel/exportExcel 接口,用于读取前端传来的tableData,生成Excel文件并返回
|
||||
// /excel/downloadTemplate 接口,用于下载resource/excel目录下的 ExcelTemplate.xlsx 文件,作为导入的模板
|
||||
|
||||
// @Tags excel
|
||||
// @Summary 导出Excel
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/octet-stream
|
||||
// @Param data body example.ExcelInfo true "导出Excel文件信息"
|
||||
// @Success 200
|
||||
// @Router /excel/exportExcel [post]
|
||||
func (e *ExcelApi) ExportExcel(c *gin.Context) {
|
||||
var excelInfo example.ExcelInfo
|
||||
_ = c.ShouldBindJSON(&excelInfo)
|
||||
filePath := global.GVA_CONFIG.Excel.Dir + excelInfo.FileName
|
||||
err := excelService.ParseInfoList2Excel(excelInfo.InfoList, filePath)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("转换Excel失败!", zap.Error(err))
|
||||
response.FailWithMessage("转换Excel失败", c)
|
||||
return
|
||||
}
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
// @Tags excel
|
||||
// @Summary 导入Excel文件
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file formData file true "导入Excel文件"
|
||||
// @Success 200 {object} response.Response{msg=string} "导入Excel文件"
|
||||
// @Router /excel/importExcel [post]
|
||||
func (e *ExcelApi) ImportExcel(c *gin.Context) {
|
||||
_, header, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("接收文件失败!", zap.Error(err))
|
||||
response.FailWithMessage("接收文件失败", c)
|
||||
return
|
||||
}
|
||||
_ = c.SaveUploadedFile(header, global.GVA_CONFIG.Excel.Dir+"ExcelImport.xlsx")
|
||||
response.OkWithMessage("导入成功", c)
|
||||
}
|
||||
|
||||
// @Tags excel
|
||||
// @Summary 加载Excel数据
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "加载Excel数据,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /excel/loadExcel [get]
|
||||
func (e *ExcelApi) LoadExcel(c *gin.Context) {
|
||||
menus, err := excelService.ParseExcel2InfoList()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("加载数据失败!", zap.Error(err))
|
||||
response.FailWithMessage("加载数据失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: menus,
|
||||
Total: int64(len(menus)),
|
||||
Page: 1,
|
||||
PageSize: 999,
|
||||
}, "加载数据成功", c)
|
||||
}
|
||||
|
||||
// @Tags excel
|
||||
// @Summary 下载模板
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param fileName query string true "模板名称"
|
||||
// @Success 200
|
||||
// @Router /excel/downloadTemplate [get]
|
||||
func (e *ExcelApi) DownloadTemplate(c *gin.Context) {
|
||||
fileName := c.Query("fileName")
|
||||
filePath := global.GVA_CONFIG.Excel.Dir + fileName
|
||||
ok, err := utils.PathExists(filePath)
|
||||
if !ok || err != nil {
|
||||
global.GVA_LOG.Error("文件不存在!", zap.Error(err))
|
||||
response.FailWithMessage("文件不存在", c)
|
||||
return
|
||||
}
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.File(filePath)
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
package example
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/request"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/example"
|
||||
exampleRes "looklook/admin/model/example/response"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type FileUploadAndDownloadApi struct{}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 上传文件示例
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file formData file true "上传文件示例"
|
||||
// @Success 200 {object} response.Response{data=exampleRes.ExaFileResponse,msg=string} "上传文件示例,返回包括文件详情"
|
||||
// @Router /fileUploadAndDownload/upload [post]
|
||||
func (u *FileUploadAndDownloadApi) UploadFile(c *gin.Context) {
|
||||
var file example.ExaFileUploadAndDownload
|
||||
noSave := c.DefaultQuery("noSave", "0")
|
||||
_, header, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("接收文件失败!", zap.Error(err))
|
||||
response.FailWithMessage("接收文件失败", c)
|
||||
return
|
||||
}
|
||||
err, file = fileUploadAndDownloadService.UploadFile(header, noSave) // 文件上传后拿到文件路径
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("修改数据库链接失败!", zap.Error(err))
|
||||
response.FailWithMessage("修改数据库链接失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(exampleRes.ExaFileResponse{File: file}, "上传成功", c)
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 删除文件
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Param data body example.ExaFileUploadAndDownload true "传入文件里面id即可"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除文件"
|
||||
// @Router /fileUploadAndDownload/deleteFile [post]
|
||||
func (u *FileUploadAndDownloadApi) DeleteFile(c *gin.Context) {
|
||||
var file example.ExaFileUploadAndDownload
|
||||
_ = c.ShouldBindJSON(&file)
|
||||
if err := fileUploadAndDownloadService.DeleteFile(file); err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 分页文件列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.PageInfo true "页码, 每页大小"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页文件列表,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /fileUploadAndDownload/getFileList [post]
|
||||
func (u *FileUploadAndDownloadApi) GetFileList(c *gin.Context) {
|
||||
var pageInfo request.PageInfo
|
||||
_ = c.ShouldBindJSON(&pageInfo)
|
||||
err, list, total := fileUploadAndDownloadService.GetFileRecordInfoList(pageInfo)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: pageInfo.Page,
|
||||
PageSize: pageInfo.PageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package system
|
||||
|
||||
import "looklook/admin/service"
|
||||
|
||||
type ApiGroup struct {
|
||||
DBApi
|
||||
JwtApi
|
||||
BaseApi
|
||||
SystemApi
|
||||
CasbinApi
|
||||
AutoCodeApi
|
||||
SystemApiApi
|
||||
AuthorityApi
|
||||
DictionaryApi
|
||||
AuthorityMenuApi
|
||||
OperationRecordApi
|
||||
AutoCodeHistoryApi
|
||||
DictionaryDetailApi
|
||||
}
|
||||
|
||||
var (
|
||||
apiService = service.ServiceGroupApp.SystemServiceGroup.ApiService
|
||||
jwtService = service.ServiceGroupApp.SystemServiceGroup.JwtService
|
||||
menuService = service.ServiceGroupApp.SystemServiceGroup.MenuService
|
||||
userService = service.ServiceGroupApp.SystemServiceGroup.UserService
|
||||
initDBService = service.ServiceGroupApp.SystemServiceGroup.InitDBService
|
||||
casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService
|
||||
autoCodeService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeService
|
||||
baseMenuService = service.ServiceGroupApp.SystemServiceGroup.BaseMenuService
|
||||
authorityService = service.ServiceGroupApp.SystemServiceGroup.AuthorityService
|
||||
dictionaryService = service.ServiceGroupApp.SystemServiceGroup.DictionaryService
|
||||
systemConfigService = service.ServiceGroupApp.SystemServiceGroup.SystemConfigService
|
||||
operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService
|
||||
autoCodeHistoryService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeHistoryService
|
||||
dictionaryDetailService = service.ServiceGroupApp.SystemServiceGroup.DictionaryDetailService
|
||||
)
|
|
@ -1,173 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/request"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system"
|
||||
systemReq "looklook/admin/model/system/request"
|
||||
systemRes "looklook/admin/model/system/response"
|
||||
"looklook/admin/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type SystemApiApi struct{}
|
||||
|
||||
// @Tags SysApi
|
||||
// @Summary 创建基础api
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysApi true "api路径, api中文描述, api组, 方法"
|
||||
// @Success 200 {object} response.Response{msg=string} "创建基础api"
|
||||
// @Router /api/createApi [post]
|
||||
func (s *SystemApiApi) CreateApi(c *gin.Context) {
|
||||
var api system.SysApi
|
||||
_ = c.ShouldBindJSON(&api)
|
||||
if err := utils.Verify(api, utils.ApiVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := apiService.CreateApi(api); err != nil {
|
||||
global.GVA_LOG.Error("创建失败!", zap.Error(err))
|
||||
response.FailWithMessage("创建失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("创建成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysApi
|
||||
// @Summary 删除api
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysApi true "ID"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除api"
|
||||
// @Router /api/deleteApi [post]
|
||||
func (s *SystemApiApi) DeleteApi(c *gin.Context) {
|
||||
var api system.SysApi
|
||||
_ = c.ShouldBindJSON(&api)
|
||||
if err := utils.Verify(api.GVA_MODEL, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := apiService.DeleteApi(api); err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysApi
|
||||
// @Summary 分页获取API列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body systemReq.SearchApiParams true "分页获取API列表"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取API列表,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /api/getApiList [post]
|
||||
func (s *SystemApiApi) GetApiList(c *gin.Context) {
|
||||
var pageInfo systemReq.SearchApiParams
|
||||
_ = c.ShouldBindJSON(&pageInfo)
|
||||
if err := utils.Verify(pageInfo.PageInfo, utils.PageInfoVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, list, total := apiService.GetAPIInfoList(pageInfo.SysApi, pageInfo.PageInfo, pageInfo.OrderKey, pageInfo.Desc); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: pageInfo.Page,
|
||||
PageSize: pageInfo.PageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// todo
|
||||
// @Tags SysApi
|
||||
// @Summary 根据id获取api
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.GetById true "根据id获取api"
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysAPIResponse} "根据id获取api,返回包括api详情"
|
||||
// @Router /api/getApiById [post]
|
||||
func (s *SystemApiApi) GetApiById(c *gin.Context) {
|
||||
var idInfo request.GetById
|
||||
_ = c.ShouldBindJSON(&idInfo)
|
||||
if err := utils.Verify(idInfo, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
err, api := apiService.GetApiById(idInfo.ID)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithData(systemRes.SysAPIResponse{Api: api}, c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysApi
|
||||
// @Summary 修改基础api
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysApi true "api路径, api中文描述, api组, 方法"
|
||||
// @Success 200 {object} response.Response{msg=string} "修改基础api"
|
||||
// @Router /api/updateApi [post]
|
||||
func (s *SystemApiApi) UpdateApi(c *gin.Context) {
|
||||
var api system.SysApi
|
||||
_ = c.ShouldBindJSON(&api)
|
||||
if err := utils.Verify(api, utils.ApiVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := apiService.UpdateApi(api); err != nil {
|
||||
global.GVA_LOG.Error("修改失败!", zap.Error(err))
|
||||
response.FailWithMessage("修改失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("修改成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysApi
|
||||
// @Summary 获取所有的Api 不分页
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysAPIListResponse,msg=string} "获取所有的Api 不分页,返回包括api列表"
|
||||
// @Router /api/getAllApis [post]
|
||||
func (s *SystemApiApi) GetAllApis(c *gin.Context) {
|
||||
if err, apis := apiService.GetAllApis(); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(systemRes.SysAPIListResponse{Apis: apis}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysApi
|
||||
// @Summary 删除选中Api
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.IdsReq true "ID"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除选中Api"
|
||||
// @Router /api/deleteApisByIds [delete]
|
||||
func (s *SystemApiApi) DeleteApisByIds(c *gin.Context) {
|
||||
var ids request.IdsReq
|
||||
_ = c.ShouldBindJSON(&ids)
|
||||
if err := apiService.DeleteApisByIds(ids); err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/request"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system"
|
||||
systemReq "looklook/admin/model/system/request"
|
||||
systemRes "looklook/admin/model/system/response"
|
||||
"looklook/admin/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type AuthorityApi struct{}
|
||||
|
||||
// @Tags Authority
|
||||
// @Summary 创建角色
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysAuthority true "权限id, 权限名, 父角色id"
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysAuthorityResponse,msg=string} "创建角色,返回包括系统角色详情"
|
||||
// @Router /authority/createAuthority [post]
|
||||
func (a *AuthorityApi) CreateAuthority(c *gin.Context) {
|
||||
var authority system.SysAuthority
|
||||
_ = c.ShouldBindJSON(&authority)
|
||||
if err := utils.Verify(authority, utils.AuthorityVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, authBack := authorityService.CreateAuthority(authority); err != nil {
|
||||
global.GVA_LOG.Error("创建失败!", zap.Error(err))
|
||||
response.FailWithMessage("创建失败"+err.Error(), c)
|
||||
} else {
|
||||
_ = menuService.AddMenuAuthority(systemReq.DefaultMenu(), authority.AuthorityId)
|
||||
_ = casbinService.UpdateCasbin(authority.AuthorityId, systemReq.DefaultCasbin())
|
||||
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authBack}, "创建成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags Authority
|
||||
// @Summary 拷贝角色
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body response.SysAuthorityCopyResponse true "旧角色id, 新权限id, 新权限名, 新父角色id"
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysAuthorityResponse,msg=string} "拷贝角色,返回包括系统角色详情"
|
||||
// @Router /authority/copyAuthority [post]
|
||||
func (a *AuthorityApi) CopyAuthority(c *gin.Context) {
|
||||
var copyInfo systemRes.SysAuthorityCopyResponse
|
||||
_ = c.ShouldBindJSON(©Info)
|
||||
if err := utils.Verify(copyInfo, utils.OldAuthorityVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := utils.Verify(copyInfo.Authority, utils.AuthorityVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, authBack := authorityService.CopyAuthority(copyInfo); err != nil {
|
||||
global.GVA_LOG.Error("拷贝失败!", zap.Error(err))
|
||||
response.FailWithMessage("拷贝失败"+err.Error(), c)
|
||||
} else {
|
||||
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authBack}, "拷贝成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags Authority
|
||||
// @Summary 删除角色
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysAuthority true "删除角色"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除角色"
|
||||
// @Router /authority/deleteAuthority [post]
|
||||
func (a *AuthorityApi) DeleteAuthority(c *gin.Context) {
|
||||
var authority system.SysAuthority
|
||||
_ = c.ShouldBindJSON(&authority)
|
||||
if err := utils.Verify(authority, utils.AuthorityIdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := authorityService.DeleteAuthority(&authority); err != nil { // 删除角色之前需要判断是否有用户正在使用此角色
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败"+err.Error(), c)
|
||||
} else {
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags Authority
|
||||
// @Summary 更新角色信息
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysAuthority true "权限id, 权限名, 父角色id"
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysAuthorityResponse,msg=string} "更新角色信息,返回包括系统角色详情"
|
||||
// @Router /authority/updateAuthority [post]
|
||||
func (a *AuthorityApi) UpdateAuthority(c *gin.Context) {
|
||||
var auth system.SysAuthority
|
||||
_ = c.ShouldBindJSON(&auth)
|
||||
if err := utils.Verify(auth, utils.AuthorityVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, authority := authorityService.UpdateAuthority(auth); err != nil {
|
||||
global.GVA_LOG.Error("更新失败!", zap.Error(err))
|
||||
response.FailWithMessage("更新失败"+err.Error(), c)
|
||||
} else {
|
||||
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authority}, "更新成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags Authority
|
||||
// @Summary 分页获取角色列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.PageInfo true "页码, 每页大小"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取角色列表,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /authority/getAuthorityList [post]
|
||||
func (a *AuthorityApi) GetAuthorityList(c *gin.Context) {
|
||||
var pageInfo request.PageInfo
|
||||
_ = c.ShouldBindJSON(&pageInfo)
|
||||
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, list, total := authorityService.GetAuthorityInfoList(pageInfo); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败"+err.Error(), c)
|
||||
} else {
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: pageInfo.Page,
|
||||
PageSize: pageInfo.PageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags Authority
|
||||
// @Summary 设置角色资源权限
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysAuthority true "设置角色资源权限"
|
||||
// @Success 200 {object} response.Response{msg=string} "设置角色资源权限"
|
||||
// @Router /authority/setDataAuthority [post]
|
||||
func (a *AuthorityApi) SetDataAuthority(c *gin.Context) {
|
||||
var auth system.SysAuthority
|
||||
_ = c.ShouldBindJSON(&auth)
|
||||
if err := utils.Verify(auth, utils.AuthorityIdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := authorityService.SetDataAuthority(auth); err != nil {
|
||||
global.GVA_LOG.Error("设置失败!", zap.Error(err))
|
||||
response.FailWithMessage("设置失败"+err.Error(), c)
|
||||
} else {
|
||||
response.OkWithMessage("设置成功", c)
|
||||
}
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system"
|
||||
"looklook/admin/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type AutoCodeApi struct{}
|
||||
|
||||
// PreviewTemp
|
||||
// @Tags AutoCode
|
||||
// @Summary 预览创建后的代码
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.AutoCodeStruct true "预览创建代码"
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "预览创建后的代码"
|
||||
// @Router /autoCode/preview [post]
|
||||
func (autoApi *AutoCodeApi) PreviewTemp(c *gin.Context) {
|
||||
var a system.AutoCodeStruct
|
||||
_ = c.ShouldBindJSON(&a)
|
||||
if err := utils.Verify(a, utils.AutoCodeVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
autoCode, err := autoCodeService.PreviewTemp(a)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("预览失败!", zap.Error(err))
|
||||
response.FailWithMessage("预览失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"autoCode": autoCode}, "预览成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// CreateTemp
|
||||
// @Tags AutoCode
|
||||
// @Summary 自动代码模板
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.AutoCodeStruct true "创建自动代码"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
||||
// @Router /autoCode/createTemp [post]
|
||||
func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) {
|
||||
var a system.AutoCodeStruct
|
||||
_ = c.ShouldBindJSON(&a)
|
||||
if err := utils.Verify(a, utils.AutoCodeVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
var apiIds []uint
|
||||
if a.AutoCreateApiToSql {
|
||||
if ids, err := autoCodeService.AutoCreateApi(&a); err != nil {
|
||||
global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Error(err))
|
||||
c.Writer.Header().Add("success", "false")
|
||||
c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!"))
|
||||
return
|
||||
} else {
|
||||
apiIds = ids
|
||||
}
|
||||
}
|
||||
err := autoCodeService.CreateTemp(a, apiIds...)
|
||||
if err != nil {
|
||||
if errors.Is(err, system.AutoMoveErr) {
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.Writer.Header().Add("msg", url.QueryEscape(err.Error()))
|
||||
} else {
|
||||
c.Writer.Header().Add("success", "false")
|
||||
c.Writer.Header().Add("msg", url.QueryEscape(err.Error()))
|
||||
_ = os.Remove("./ginvueadmin.zip")
|
||||
}
|
||||
} else {
|
||||
c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", "ginvueadmin.zip")) // fmt.Sprintf("attachment; filename=%s", filename)对下载的文件重命名
|
||||
c.Writer.Header().Add("Content-Type", "application/json")
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.File("./ginvueadmin.zip")
|
||||
_ = os.Remove("./ginvueadmin.zip")
|
||||
}
|
||||
}
|
||||
|
||||
// GetDB
|
||||
// @Tags AutoCode
|
||||
// @Summary 获取当前所有数据库
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前所有数据库"
|
||||
// @Router /autoCode/getDatabase [get]
|
||||
func (autoApi *AutoCodeApi) GetDB(c *gin.Context) {
|
||||
dbs, err := autoCodeService.Database().GetDB()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
}
|
||||
response.OkWithDetailed(gin.H{"dbs": dbs}, "获取成功", c)
|
||||
}
|
||||
|
||||
// GetTables
|
||||
// @Tags AutoCode
|
||||
// @Summary 获取当前数据库所有表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前数据库所有表"
|
||||
// @Router /autoCode/getTables [get]
|
||||
func (autoApi *AutoCodeApi) GetTables(c *gin.Context) {
|
||||
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
|
||||
tables, err := autoCodeService.Database().GetTables(dbName)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询table失败!", zap.Error(err))
|
||||
response.FailWithMessage("查询table失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"tables": tables}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// GetColumn
|
||||
// @Tags AutoCode
|
||||
// @Summary 获取当前表所有字段
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前表所有字段"
|
||||
// @Router /autoCode/getColumn [get]
|
||||
func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) {
|
||||
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
|
||||
tableName := c.Query("tableName")
|
||||
columns, err := autoCodeService.Database().GetColumn(tableName, dbName)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
}
|
||||
response.OkWithDetailed(gin.H{"columns": columns}, "获取成功", c)
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/request"
|
||||
"looklook/admin/model/common/response"
|
||||
systemReq "looklook/admin/model/system/request"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type AutoCodeHistoryApi struct{}
|
||||
|
||||
// First
|
||||
// @Tags AutoCode
|
||||
// @Summary 获取meta信息
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.GetById true "请求参数"
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取meta信息"
|
||||
// @Router /autoCode/getMeta [post]
|
||||
func (a *AutoCodeHistoryApi) First(c *gin.Context) {
|
||||
var info request.GetById
|
||||
_ = c.ShouldBindJSON(&info)
|
||||
data, err := autoCodeHistoryService.First(&info)
|
||||
if err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(gin.H{"meta": data}, "获取成功", c)
|
||||
}
|
||||
|
||||
// Delete
|
||||
// @Tags AutoCode
|
||||
// @Summary 删除回滚记录
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.GetById true "请求参数"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除回滚记录"
|
||||
// @Router /autoCode/delSysHistory [post]
|
||||
func (a *AutoCodeHistoryApi) Delete(c *gin.Context) {
|
||||
var info request.GetById
|
||||
_ = c.ShouldBindJSON(&info)
|
||||
err := autoCodeHistoryService.Delete(&info)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
|
||||
// RollBack
|
||||
// @Tags AutoCode
|
||||
// @Summary 回滚自动生成代码
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.GetById true "请求参数"
|
||||
// @Success 200 {object} response.Response{msg=string} "回滚自动生成代码"
|
||||
// @Router /autoCode/rollback [post]
|
||||
func (a *AutoCodeHistoryApi) RollBack(c *gin.Context) {
|
||||
var info request.GetById
|
||||
_ = c.ShouldBindJSON(&info)
|
||||
if err := autoCodeHistoryService.RollBack(&info); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
response.OkWithMessage("回滚成功", c)
|
||||
}
|
||||
|
||||
// GetList
|
||||
// @Tags AutoCode
|
||||
// @Summary 查询回滚记录
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body systemReq.SysAutoHistory true "请求参数"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "查询回滚记录,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /autoCode/getSysHistory [post]
|
||||
func (a *AutoCodeHistoryApi) GetList(c *gin.Context) {
|
||||
var search systemReq.SysAutoHistory
|
||||
_ = c.ShouldBindJSON(&search)
|
||||
list, total, err := autoCodeHistoryService.GetList(search.PageInfo)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: search.Page,
|
||||
PageSize: search.PageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
systemRes "looklook/admin/model/system/response"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/mojocn/base64Captcha"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// 当开启多服务器部署时,替换下面的配置,使用redis共享存储验证码
|
||||
// var store = captcha.NewDefaultRedisStore()
|
||||
var store = base64Captcha.DefaultMemStore
|
||||
|
||||
type BaseApi struct{}
|
||||
|
||||
// Captcha
|
||||
// @Tags Base
|
||||
// @Summary 生成验证码
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysCaptchaResponse,msg=string} "生成验证码,返回包括随机数id,base64,验证码长度"
|
||||
// @Router /base/captcha [post]
|
||||
func (b *BaseApi) Captcha(c *gin.Context) {
|
||||
// 字符,公式,验证码配置
|
||||
// 生成默认数字的driver
|
||||
driver := base64Captcha.NewDriverDigit(global.GVA_CONFIG.Captcha.ImgHeight, global.GVA_CONFIG.Captcha.ImgWidth, global.GVA_CONFIG.Captcha.KeyLong, 0.7, 80)
|
||||
// cp := base64Captcha.NewCaptcha(driver, store.UseWithCtx(c)) // v8下使用redis
|
||||
cp := base64Captcha.NewCaptcha(driver, store)
|
||||
if id, b64s, err := cp.Generate(); err != nil {
|
||||
global.GVA_LOG.Error("验证码获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("验证码获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(systemRes.SysCaptchaResponse{
|
||||
CaptchaId: id,
|
||||
PicPath: b64s,
|
||||
CaptchaLength: global.GVA_CONFIG.Captcha.KeyLong,
|
||||
}, "验证码获取成功", c)
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system/request"
|
||||
systemRes "looklook/admin/model/system/response"
|
||||
"looklook/admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type CasbinApi struct{}
|
||||
|
||||
// @Tags Casbin
|
||||
// @Summary 更新角色api权限
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.CasbinInReceive true "权限id, 权限模型列表"
|
||||
// @Success 200 {object} response.Response{msg=string} "更新角色api权限"
|
||||
// @Router /casbin/UpdateCasbin [post]
|
||||
func (cas *CasbinApi) UpdateCasbin(c *gin.Context) {
|
||||
var cmr request.CasbinInReceive
|
||||
_ = c.ShouldBindJSON(&cmr)
|
||||
if err := utils.Verify(cmr, utils.AuthorityIdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := casbinService.UpdateCasbin(cmr.AuthorityId, cmr.CasbinInfos); err != nil {
|
||||
global.GVA_LOG.Error("更新失败!", zap.Error(err))
|
||||
response.FailWithMessage("更新失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("更新成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags Casbin
|
||||
// @Summary 获取权限列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.CasbinInReceive true "权限id, 权限模型列表"
|
||||
// @Success 200 {object} response.Response{data=systemRes.PolicyPathResponse,msg=string} "获取权限列表,返回包括casbin详情列表"
|
||||
// @Router /casbin/getPolicyPathByAuthorityId [post]
|
||||
func (cas *CasbinApi) GetPolicyPathByAuthorityId(c *gin.Context) {
|
||||
var casbin request.CasbinInReceive
|
||||
_ = c.ShouldBindJSON(&casbin)
|
||||
if err := utils.Verify(casbin, utils.AuthorityIdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
paths := casbinService.GetPolicyPathByAuthorityId(casbin.AuthorityId)
|
||||
response.OkWithDetailed(systemRes.PolicyPathResponse{Paths: paths}, "获取成功", c)
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system"
|
||||
"looklook/admin/model/system/request"
|
||||
"looklook/admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type DictionaryApi struct{}
|
||||
|
||||
// @Tags SysDictionary
|
||||
// @Summary 创建SysDictionary
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysDictionary true "SysDictionary模型"
|
||||
// @Success 200 {object} response.Response{msg=string} "创建SysDictionary"
|
||||
// @Router /sysDictionary/createSysDictionary [post]
|
||||
func (s *DictionaryApi) CreateSysDictionary(c *gin.Context) {
|
||||
var dictionary system.SysDictionary
|
||||
_ = c.ShouldBindJSON(&dictionary)
|
||||
if err := dictionaryService.CreateSysDictionary(dictionary); err != nil {
|
||||
global.GVA_LOG.Error("创建失败!", zap.Error(err))
|
||||
response.FailWithMessage("创建失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("创建成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysDictionary
|
||||
// @Summary 删除SysDictionary
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysDictionary true "SysDictionary模型"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除SysDictionary"
|
||||
// @Router /sysDictionary/deleteSysDictionary [delete]
|
||||
func (s *DictionaryApi) DeleteSysDictionary(c *gin.Context) {
|
||||
var dictionary system.SysDictionary
|
||||
_ = c.ShouldBindJSON(&dictionary)
|
||||
if err := dictionaryService.DeleteSysDictionary(dictionary); err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysDictionary
|
||||
// @Summary 更新SysDictionary
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysDictionary true "SysDictionary模型"
|
||||
// @Success 200 {object} response.Response{msg=string} "更新SysDictionary"
|
||||
// @Router /sysDictionary/updateSysDictionary [put]
|
||||
func (s *DictionaryApi) UpdateSysDictionary(c *gin.Context) {
|
||||
var dictionary system.SysDictionary
|
||||
_ = c.ShouldBindJSON(&dictionary)
|
||||
if err := dictionaryService.UpdateSysDictionary(&dictionary); err != nil {
|
||||
global.GVA_LOG.Error("更新失败!", zap.Error(err))
|
||||
response.FailWithMessage("更新失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("更新成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysDictionary
|
||||
// @Summary 用id查询SysDictionary
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query system.SysDictionary true "ID或字典英名"
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "用id查询SysDictionary"
|
||||
// @Router /sysDictionary/findSysDictionary [get]
|
||||
func (s *DictionaryApi) FindSysDictionary(c *gin.Context) {
|
||||
var dictionary system.SysDictionary
|
||||
_ = c.ShouldBindQuery(&dictionary)
|
||||
if err, sysDictionary := dictionaryService.GetSysDictionary(dictionary.Type, dictionary.ID); err != nil {
|
||||
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||
response.FailWithMessage("查询失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"resysDictionary": sysDictionary}, "查询成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysDictionary
|
||||
// @Summary 分页获取SysDictionary列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query request.SysDictionarySearch true "页码, 每页大小, 搜索条件"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取SysDictionary列表,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /sysDictionary/getSysDictionaryList [get]
|
||||
func (s *DictionaryApi) GetSysDictionaryList(c *gin.Context) {
|
||||
var pageInfo request.SysDictionarySearch
|
||||
_ = c.ShouldBindQuery(&pageInfo)
|
||||
if err := utils.Verify(pageInfo.PageInfo, utils.PageInfoVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, list, total := dictionaryService.GetSysDictionaryInfoList(pageInfo); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: pageInfo.Page,
|
||||
PageSize: pageInfo.PageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system"
|
||||
"looklook/admin/model/system/request"
|
||||
"looklook/admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type DictionaryDetailApi struct{}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 创建SysDictionaryDetail
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysDictionaryDetail true "SysDictionaryDetail模型"
|
||||
// @Success 200 {object} response.Response{msg=string} "创建SysDictionaryDetail"
|
||||
// @Router /sysDictionaryDetail/createSysDictionaryDetail [post]
|
||||
func (s *DictionaryDetailApi) CreateSysDictionaryDetail(c *gin.Context) {
|
||||
var detail system.SysDictionaryDetail
|
||||
_ = c.ShouldBindJSON(&detail)
|
||||
if err := dictionaryDetailService.CreateSysDictionaryDetail(detail); err != nil {
|
||||
global.GVA_LOG.Error("创建失败!", zap.Error(err))
|
||||
response.FailWithMessage("创建失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("创建成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 删除SysDictionaryDetail
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysDictionaryDetail true "SysDictionaryDetail模型"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除SysDictionaryDetail"
|
||||
// @Router /sysDictionaryDetail/deleteSysDictionaryDetail [delete]
|
||||
func (s *DictionaryDetailApi) DeleteSysDictionaryDetail(c *gin.Context) {
|
||||
var detail system.SysDictionaryDetail
|
||||
_ = c.ShouldBindJSON(&detail)
|
||||
if err := dictionaryDetailService.DeleteSysDictionaryDetail(detail); err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 更新SysDictionaryDetail
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysDictionaryDetail true "更新SysDictionaryDetail"
|
||||
// @Success 200 {object} response.Response{msg=string} "更新SysDictionaryDetail"
|
||||
// @Router /sysDictionaryDetail/updateSysDictionaryDetail [put]
|
||||
func (s *DictionaryDetailApi) UpdateSysDictionaryDetail(c *gin.Context) {
|
||||
var detail system.SysDictionaryDetail
|
||||
_ = c.ShouldBindJSON(&detail)
|
||||
if err := dictionaryDetailService.UpdateSysDictionaryDetail(&detail); err != nil {
|
||||
global.GVA_LOG.Error("更新失败!", zap.Error(err))
|
||||
response.FailWithMessage("更新失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("更新成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 用id查询SysDictionaryDetail
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query system.SysDictionaryDetail true "用id查询SysDictionaryDetail"
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "用id查询SysDictionaryDetail"
|
||||
// @Router /sysDictionaryDetail/findSysDictionaryDetail [get]
|
||||
func (s *DictionaryDetailApi) FindSysDictionaryDetail(c *gin.Context) {
|
||||
var detail system.SysDictionaryDetail
|
||||
_ = c.ShouldBindQuery(&detail)
|
||||
if err := utils.Verify(detail, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, resysDictionaryDetail := dictionaryDetailService.GetSysDictionaryDetail(detail.ID); err != nil {
|
||||
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||
response.FailWithMessage("查询失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"resysDictionaryDetail": resysDictionaryDetail}, "查询成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 分页获取SysDictionaryDetail列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query request.SysDictionaryDetailSearch true "页码, 每页大小, 搜索条件"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取SysDictionaryDetail列表,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /sysDictionaryDetail/getSysDictionaryDetailList [get]
|
||||
func (s *DictionaryDetailApi) GetSysDictionaryDetailList(c *gin.Context) {
|
||||
var pageInfo request.SysDictionaryDetailSearch
|
||||
_ = c.ShouldBindQuery(&pageInfo)
|
||||
if err, list, total := dictionaryDetailService.GetSysDictionaryDetailInfoList(pageInfo); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: pageInfo.Page,
|
||||
PageSize: pageInfo.PageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system/request"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type DBApi struct{}
|
||||
|
||||
// InitDB
|
||||
// @Tags InitDB
|
||||
// @Summary 初始化用户数据库
|
||||
// @Produce application/json
|
||||
// @Param data body request.InitDB true "初始化数据库参数"
|
||||
// @Success 200 {object} response.Response{data=string} "初始化用户数据库"
|
||||
// @Router /init/initdb [post]
|
||||
func (i *DBApi) InitDB(c *gin.Context) {
|
||||
if global.GVA_DB != nil {
|
||||
global.GVA_LOG.Error("已存在数据库配置!")
|
||||
response.FailWithMessage("已存在数据库配置", c)
|
||||
return
|
||||
}
|
||||
var dbInfo request.InitDB
|
||||
if err := c.ShouldBindJSON(&dbInfo); err != nil {
|
||||
global.GVA_LOG.Error("参数校验不通过!", zap.Error(err))
|
||||
response.FailWithMessage("参数校验不通过", c)
|
||||
return
|
||||
}
|
||||
if err := initDBService.InitDB(dbInfo); err != nil {
|
||||
global.GVA_LOG.Error("自动创建数据库失败!", zap.Error(err))
|
||||
response.FailWithMessage("自动创建数据库失败,请查看后台日志,检查后在进行初始化", c)
|
||||
return
|
||||
}
|
||||
response.OkWithData("自动创建数据库成功", c)
|
||||
}
|
||||
|
||||
// CheckDB
|
||||
// @Tags CheckDB
|
||||
// @Summary 初始化用户数据库
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "初始化用户数据库"
|
||||
// @Router /init/checkdb [post]
|
||||
func (i *DBApi) CheckDB(c *gin.Context) {
|
||||
var (
|
||||
message = "前往初始化数据库"
|
||||
needInit = true
|
||||
)
|
||||
|
||||
if global.GVA_DB != nil {
|
||||
message = "数据库无需初始化"
|
||||
needInit = false
|
||||
}
|
||||
global.GVA_LOG.Info(message)
|
||||
response.OkWithDetailed(gin.H{"needInit": needInit}, message, c)
|
||||
return
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type JwtApi struct{}
|
||||
|
||||
// @Tags Jwt
|
||||
// @Summary jwt加入黑名单
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{msg=string} "jwt加入黑名单"
|
||||
// @Router /jwt/jsonInBlacklist [post]
|
||||
func (j *JwtApi) JsonInBlacklist(c *gin.Context) {
|
||||
token := c.Request.Header.Get("x-token")
|
||||
jwt := system.JwtBlacklist{Jwt: token}
|
||||
if err := jwtService.JsonInBlacklist(jwt); err != nil {
|
||||
global.GVA_LOG.Error("jwt作废失败!", zap.Error(err))
|
||||
response.FailWithMessage("jwt作废失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("jwt作废成功", c)
|
||||
}
|
||||
}
|
|
@ -1,226 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/request"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system"
|
||||
systemReq "looklook/admin/model/system/request"
|
||||
systemRes "looklook/admin/model/system/response"
|
||||
"looklook/admin/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type AuthorityMenuApi struct{}
|
||||
|
||||
// @Tags AuthorityMenu
|
||||
// @Summary 获取用户动态路由
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Param data body request.Empty true "空"
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysMenusResponse,msg=string} "获取用户动态路由,返回包括系统菜单详情列表"
|
||||
// @Router /menu/getMenu [post]
|
||||
func (a *AuthorityMenuApi) GetMenu(c *gin.Context) {
|
||||
if err, menus := menuService.GetMenuTree(utils.GetUserAuthorityId(c)); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
if menus == nil {
|
||||
menus = []system.SysMenu{}
|
||||
}
|
||||
response.OkWithDetailed(systemRes.SysMenusResponse{Menus: menus}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags AuthorityMenu
|
||||
// @Summary 获取用户动态路由
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Param data body request.Empty true "空"
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysBaseMenusResponse,msg=string} "获取用户动态路由,返回包括系统菜单列表"
|
||||
// @Router /menu/getBaseMenuTree [post]
|
||||
func (a *AuthorityMenuApi) GetBaseMenuTree(c *gin.Context) {
|
||||
if err, menus := menuService.GetBaseMenuTree(); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(systemRes.SysBaseMenusResponse{Menus: menus}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags AuthorityMenu
|
||||
// @Summary 增加menu和角色关联关系
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body systemReq.AddMenuAuthorityInfo true "角色ID"
|
||||
// @Success 200 {object} response.Response{msg=string} "增加menu和角色关联关系"
|
||||
// @Router /menu/addMenuAuthority [post]
|
||||
func (a *AuthorityMenuApi) AddMenuAuthority(c *gin.Context) {
|
||||
var authorityMenu systemReq.AddMenuAuthorityInfo
|
||||
_ = c.ShouldBindJSON(&authorityMenu)
|
||||
if err := utils.Verify(authorityMenu, utils.AuthorityIdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := menuService.AddMenuAuthority(authorityMenu.Menus, authorityMenu.AuthorityId); err != nil {
|
||||
global.GVA_LOG.Error("添加失败!", zap.Error(err))
|
||||
response.FailWithMessage("添加失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("添加成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags AuthorityMenu
|
||||
// @Summary 获取指定角色menu
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.GetAuthorityId true "角色ID"
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取指定角色menu"
|
||||
// @Router /menu/getMenuAuthority [post]
|
||||
func (a *AuthorityMenuApi) GetMenuAuthority(c *gin.Context) {
|
||||
var param request.GetAuthorityId
|
||||
_ = c.ShouldBindJSON(¶m)
|
||||
if err := utils.Verify(param, utils.AuthorityIdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, menus := menuService.GetMenuAuthority(¶m); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithDetailed(systemRes.SysMenusResponse{Menus: menus}, "获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"menus": menus}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags Menu
|
||||
// @Summary 新增菜单
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysBaseMenu true "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
|
||||
// @Success 200 {object} response.Response{msg=string} "新增菜单"
|
||||
// @Router /menu/addBaseMenu [post]
|
||||
func (a *AuthorityMenuApi) AddBaseMenu(c *gin.Context) {
|
||||
var menu system.SysBaseMenu
|
||||
_ = c.ShouldBindJSON(&menu)
|
||||
if err := utils.Verify(menu, utils.MenuVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := utils.Verify(menu.Meta, utils.MenuMetaVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := menuService.AddBaseMenu(menu); err != nil {
|
||||
global.GVA_LOG.Error("添加失败!", zap.Error(err))
|
||||
|
||||
response.FailWithMessage("添加失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("添加成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags Menu
|
||||
// @Summary 删除菜单
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.GetById true "菜单id"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除菜单"
|
||||
// @Router /menu/deleteBaseMenu [post]
|
||||
func (a *AuthorityMenuApi) DeleteBaseMenu(c *gin.Context) {
|
||||
var menu request.GetById
|
||||
_ = c.ShouldBindJSON(&menu)
|
||||
if err := utils.Verify(menu, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := baseMenuService.DeleteBaseMenu(menu.ID); err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags Menu
|
||||
// @Summary 更新菜单
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysBaseMenu true "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
|
||||
// @Success 200 {object} response.Response{msg=string} "更新菜单"
|
||||
// @Router /menu/updateBaseMenu [post]
|
||||
func (a *AuthorityMenuApi) UpdateBaseMenu(c *gin.Context) {
|
||||
var menu system.SysBaseMenu
|
||||
_ = c.ShouldBindJSON(&menu)
|
||||
if err := utils.Verify(menu, utils.MenuVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := utils.Verify(menu.Meta, utils.MenuMetaVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := baseMenuService.UpdateBaseMenu(menu); err != nil {
|
||||
global.GVA_LOG.Error("更新失败!", zap.Error(err))
|
||||
response.FailWithMessage("更新失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("更新成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags Menu
|
||||
// @Summary 根据id获取菜单
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.GetById true "菜单id"
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysBaseMenuResponse,msg=string} "根据id获取菜单,返回包括系统菜单列表"
|
||||
// @Router /menu/getBaseMenuById [post]
|
||||
func (a *AuthorityMenuApi) GetBaseMenuById(c *gin.Context) {
|
||||
var idInfo request.GetById
|
||||
_ = c.ShouldBindJSON(&idInfo)
|
||||
if err := utils.Verify(idInfo, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, menu := baseMenuService.GetBaseMenuById(idInfo.ID); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(systemRes.SysBaseMenuResponse{Menu: menu}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags Menu
|
||||
// @Summary 分页获取基础menu列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.PageInfo true "页码, 每页大小"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取基础menu列表,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /menu/getMenuList [post]
|
||||
func (a *AuthorityMenuApi) GetMenuList(c *gin.Context) {
|
||||
var pageInfo request.PageInfo
|
||||
_ = c.ShouldBindJSON(&pageInfo)
|
||||
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, menuList, total := menuService.GetInfoList(); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: menuList,
|
||||
Total: total,
|
||||
Page: pageInfo.Page,
|
||||
PageSize: pageInfo.PageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/request"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system"
|
||||
systemReq "looklook/admin/model/system/request"
|
||||
"looklook/admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type OperationRecordApi struct{}
|
||||
|
||||
// @Tags SysOperationRecord
|
||||
// @Summary 创建SysOperationRecord
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysOperationRecord true "创建SysOperationRecord"
|
||||
// @Success 200 {object} response.Response{msg=string} "创建SysOperationRecord"
|
||||
// @Router /sysOperationRecord/createSysOperationRecord [post]
|
||||
func (s *OperationRecordApi) CreateSysOperationRecord(c *gin.Context) {
|
||||
var sysOperationRecord system.SysOperationRecord
|
||||
_ = c.ShouldBindJSON(&sysOperationRecord)
|
||||
if err := operationRecordService.CreateSysOperationRecord(sysOperationRecord); err != nil {
|
||||
global.GVA_LOG.Error("创建失败!", zap.Error(err))
|
||||
response.FailWithMessage("创建失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("创建成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysOperationRecord
|
||||
// @Summary 删除SysOperationRecord
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysOperationRecord true "SysOperationRecord模型"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除SysOperationRecord"
|
||||
// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
|
||||
func (s *OperationRecordApi) DeleteSysOperationRecord(c *gin.Context) {
|
||||
var sysOperationRecord system.SysOperationRecord
|
||||
_ = c.ShouldBindJSON(&sysOperationRecord)
|
||||
if err := operationRecordService.DeleteSysOperationRecord(sysOperationRecord); err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysOperationRecord
|
||||
// @Summary 批量删除SysOperationRecord
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.IdsReq true "批量删除SysOperationRecord"
|
||||
// @Success 200 {object} response.Response{msg=string} "批量删除SysOperationRecord"
|
||||
// @Router /sysOperationRecord/deleteSysOperationRecordByIds [delete]
|
||||
func (s *OperationRecordApi) DeleteSysOperationRecordByIds(c *gin.Context) {
|
||||
var IDS request.IdsReq
|
||||
_ = c.ShouldBindJSON(&IDS)
|
||||
if err := operationRecordService.DeleteSysOperationRecordByIds(IDS); err != nil {
|
||||
global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("批量删除失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("批量删除成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysOperationRecord
|
||||
// @Summary 用id查询SysOperationRecord
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query system.SysOperationRecord true "Id"
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "用id查询SysOperationRecord"
|
||||
// @Router /sysOperationRecord/findSysOperationRecord [get]
|
||||
func (s *OperationRecordApi) FindSysOperationRecord(c *gin.Context) {
|
||||
var sysOperationRecord system.SysOperationRecord
|
||||
_ = c.ShouldBindQuery(&sysOperationRecord)
|
||||
if err := utils.Verify(sysOperationRecord, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, resysOperationRecord := operationRecordService.GetSysOperationRecord(sysOperationRecord.ID); err != nil {
|
||||
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||
response.FailWithMessage("查询失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"resysOperationRecord": resysOperationRecord}, "查询成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysOperationRecord
|
||||
// @Summary 分页获取SysOperationRecord列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query request.SysOperationRecordSearch true "页码, 每页大小, 搜索条件"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取SysOperationRecord列表,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /sysOperationRecord/getSysOperationRecordList [get]
|
||||
func (s *OperationRecordApi) GetSysOperationRecordList(c *gin.Context) {
|
||||
var pageInfo systemReq.SysOperationRecordSearch
|
||||
_ = c.ShouldBindQuery(&pageInfo)
|
||||
if err, list, total := operationRecordService.GetSysOperationRecordInfoList(pageInfo); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: pageInfo.Page,
|
||||
PageSize: pageInfo.PageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system"
|
||||
systemRes "looklook/admin/model/system/response"
|
||||
"looklook/admin/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type SystemApi struct{}
|
||||
|
||||
// @Tags System
|
||||
// @Summary 获取配置文件内容
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysConfigResponse,msg=string} "获取配置文件内容,返回包括系统配置"
|
||||
// @Router /system/getSystemConfig [post]
|
||||
func (s *SystemApi) GetSystemConfig(c *gin.Context) {
|
||||
if err, config := systemConfigService.GetSystemConfig(); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(systemRes.SysConfigResponse{Config: config}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags System
|
||||
// @Summary 设置配置文件内容
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Param data body system.System true "设置配置文件内容"
|
||||
// @Success 200 {object} response.Response{data=string} "设置配置文件内容"
|
||||
// @Router /system/setSystemConfig [post]
|
||||
func (s *SystemApi) SetSystemConfig(c *gin.Context) {
|
||||
var sys system.System
|
||||
_ = c.ShouldBindJSON(&sys)
|
||||
if err := systemConfigService.SetSystemConfig(sys); err != nil {
|
||||
global.GVA_LOG.Error("设置失败!", zap.Error(err))
|
||||
response.FailWithMessage("设置失败", c)
|
||||
} else {
|
||||
response.OkWithData("设置成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags System
|
||||
// @Summary 重启系统
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{msg=string} "重启系统"
|
||||
// @Router /system/reloadSystem [post]
|
||||
func (s *SystemApi) ReloadSystem(c *gin.Context) {
|
||||
err := utils.Reload()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("重启系统失败!", zap.Error(err))
|
||||
response.FailWithMessage("重启系统失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("重启系统成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags System
|
||||
// @Summary 获取服务器信息
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取服务器信息"
|
||||
// @Router /system/getServerInfo [post]
|
||||
func (s *SystemApi) GetServerInfo(c *gin.Context) {
|
||||
if server, err := systemConfigService.GetServerInfo(); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"server": server}, "获取成功", c)
|
||||
}
|
||||
}
|
|
@ -1,348 +0,0 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/request"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system"
|
||||
systemReq "looklook/admin/model/system/request"
|
||||
systemRes "looklook/admin/model/system/response"
|
||||
"looklook/admin/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// @Tags Base
|
||||
// @Summary 用户登录
|
||||
// @Produce application/json
|
||||
// @Param data body systemReq.Login true "用户名, 密码, 验证码"
|
||||
// @Success 200 {object} response.Response{data=systemRes.LoginResponse,msg=string} "返回包括用户信息,token,过期时间"
|
||||
// @Router /base/login [post]
|
||||
func (b *BaseApi) Login(c *gin.Context) {
|
||||
var l systemReq.Login
|
||||
_ = c.ShouldBindJSON(&l)
|
||||
if err := utils.Verify(l, utils.LoginVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if store.Verify(l.CaptchaId, l.Captcha, true) {
|
||||
u := &system.SysUser{Username: l.Username, Password: l.Password}
|
||||
if err, user := userService.Login(u); err != nil {
|
||||
global.GVA_LOG.Error("登陆失败! 用户名不存在或者密码错误!", zap.Error(err))
|
||||
response.FailWithMessage("用户名不存在或者密码错误", c)
|
||||
} else {
|
||||
b.tokenNext(c, *user)
|
||||
}
|
||||
} else {
|
||||
response.FailWithMessage("验证码错误", c)
|
||||
}
|
||||
}
|
||||
|
||||
// 登录以后签发jwt
|
||||
func (b *BaseApi) tokenNext(c *gin.Context, user system.SysUser) {
|
||||
j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名
|
||||
claims := j.CreateClaims(systemReq.BaseClaims{
|
||||
UUID: user.UUID,
|
||||
ID: user.ID,
|
||||
NickName: user.NickName,
|
||||
Username: user.Username,
|
||||
AuthorityId: user.AuthorityId,
|
||||
})
|
||||
token, err := j.CreateToken(claims)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取token失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取token失败", c)
|
||||
return
|
||||
}
|
||||
if !global.GVA_CONFIG.System.UseMultipoint {
|
||||
response.OkWithDetailed(systemRes.LoginResponse{
|
||||
User: user,
|
||||
Token: token,
|
||||
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
|
||||
}, "登录成功", c)
|
||||
return
|
||||
}
|
||||
|
||||
if err, jwtStr := jwtService.GetRedisJWT(user.Username); err == redis.Nil {
|
||||
if err := jwtService.SetRedisJWT(token, user.Username); err != nil {
|
||||
global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
|
||||
response.FailWithMessage("设置登录状态失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(systemRes.LoginResponse{
|
||||
User: user,
|
||||
Token: token,
|
||||
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
|
||||
}, "登录成功", c)
|
||||
} else if err != nil {
|
||||
global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
|
||||
response.FailWithMessage("设置登录状态失败", c)
|
||||
} else {
|
||||
var blackJWT system.JwtBlacklist
|
||||
blackJWT.Jwt = jwtStr
|
||||
if err := jwtService.JsonInBlacklist(blackJWT); err != nil {
|
||||
response.FailWithMessage("jwt作废失败", c)
|
||||
return
|
||||
}
|
||||
if err := jwtService.SetRedisJWT(token, user.Username); err != nil {
|
||||
response.FailWithMessage("设置登录状态失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(systemRes.LoginResponse{
|
||||
User: user,
|
||||
Token: token,
|
||||
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
|
||||
}, "登录成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 用户注册账号
|
||||
// @Produce application/json
|
||||
// @Param data body systemReq.Register true "用户名, 昵称, 密码, 角色ID"
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysUserResponse,msg=string} "用户注册账号,返回包括用户信息"
|
||||
// @Router /user/register [post]
|
||||
func (b *BaseApi) Register(c *gin.Context) {
|
||||
var r systemReq.Register
|
||||
_ = c.ShouldBindJSON(&r)
|
||||
if err := utils.Verify(r, utils.RegisterVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
var authorities []system.SysAuthority
|
||||
for _, v := range r.AuthorityIds {
|
||||
authorities = append(authorities, system.SysAuthority{
|
||||
AuthorityId: v,
|
||||
})
|
||||
}
|
||||
user := &system.SysUser{Username: r.Username, NickName: r.NickName, Password: r.Password, HeaderImg: r.HeaderImg, AuthorityId: r.AuthorityId, Authorities: authorities}
|
||||
err, userReturn := userService.Register(*user)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("注册失败!", zap.Error(err))
|
||||
response.FailWithDetailed(systemRes.SysUserResponse{User: userReturn}, "注册失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(systemRes.SysUserResponse{User: userReturn}, "注册成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 用户修改密码
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Param data body systemReq.ChangePasswordStruct true "用户名, 原密码, 新密码"
|
||||
// @Success 200 {object} response.Response{msg=string} "用户修改密码"
|
||||
// @Router /user/changePassword [post]
|
||||
func (b *BaseApi) ChangePassword(c *gin.Context) {
|
||||
var user systemReq.ChangePasswordStruct
|
||||
_ = c.ShouldBindJSON(&user)
|
||||
if err := utils.Verify(user, utils.ChangePasswordVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
u := &system.SysUser{Username: user.Username, Password: user.Password}
|
||||
if err, _ := userService.ChangePassword(u, user.NewPassword); err != nil {
|
||||
global.GVA_LOG.Error("修改失败!", zap.Error(err))
|
||||
response.FailWithMessage("修改失败,原密码与当前账户不符", c)
|
||||
} else {
|
||||
response.OkWithMessage("修改成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 分页获取用户列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.PageInfo true "页码, 每页大小"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取用户列表,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /user/getUserList [post]
|
||||
func (b *BaseApi) GetUserList(c *gin.Context) {
|
||||
var pageInfo request.PageInfo
|
||||
_ = c.ShouldBindJSON(&pageInfo)
|
||||
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, list, total := userService.GetUserInfoList(pageInfo); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: pageInfo.Page,
|
||||
PageSize: pageInfo.PageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 更改用户权限
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body systemReq.SetUserAuth true "用户UUID, 角色ID"
|
||||
// @Success 200 {object} response.Response{msg=string} "设置用户权限"
|
||||
// @Router /user/setUserAuthority [post]
|
||||
func (b *BaseApi) SetUserAuthority(c *gin.Context) {
|
||||
var sua systemReq.SetUserAuth
|
||||
_ = c.ShouldBindJSON(&sua)
|
||||
if UserVerifyErr := utils.Verify(sua, utils.SetUserAuthorityVerify); UserVerifyErr != nil {
|
||||
response.FailWithMessage(UserVerifyErr.Error(), c)
|
||||
return
|
||||
}
|
||||
userID := utils.GetUserID(c)
|
||||
uuid := utils.GetUserUuid(c)
|
||||
if err := userService.SetUserAuthority(userID, uuid, sua.AuthorityId); err != nil {
|
||||
global.GVA_LOG.Error("修改失败!", zap.Error(err))
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
} else {
|
||||
claims := utils.GetUserInfo(c)
|
||||
j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名
|
||||
claims.AuthorityId = sua.AuthorityId
|
||||
if token, err := j.CreateToken(*claims); err != nil {
|
||||
global.GVA_LOG.Error("修改失败!", zap.Error(err))
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
} else {
|
||||
c.Header("new-token", token)
|
||||
c.Header("new-expires-at", strconv.FormatInt(claims.ExpiresAt, 10))
|
||||
response.OkWithMessage("修改成功", c)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 设置用户权限
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body systemReq.SetUserAuthorities true "用户UUID, 角色ID"
|
||||
// @Success 200 {object} response.Response{msg=string} "设置用户权限"
|
||||
// @Router /user/setUserAuthorities [post]
|
||||
func (b *BaseApi) SetUserAuthorities(c *gin.Context) {
|
||||
var sua systemReq.SetUserAuthorities
|
||||
_ = c.ShouldBindJSON(&sua)
|
||||
if err := userService.SetUserAuthorities(sua.ID, sua.AuthorityIds); err != nil {
|
||||
global.GVA_LOG.Error("修改失败!", zap.Error(err))
|
||||
response.FailWithMessage("修改失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("修改成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 删除用户
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.GetById true "用户ID"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除用户"
|
||||
// @Router /user/deleteUser [delete]
|
||||
func (b *BaseApi) DeleteUser(c *gin.Context) {
|
||||
var reqId request.GetById
|
||||
_ = c.ShouldBindJSON(&reqId)
|
||||
if err := utils.Verify(reqId, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
jwtId := utils.GetUserID(c)
|
||||
if jwtId == uint(reqId.ID) {
|
||||
response.FailWithMessage("删除失败, 自杀失败", c)
|
||||
return
|
||||
}
|
||||
if err := userService.DeleteUser(reqId.ID); err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败", c)
|
||||
} else {
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 设置用户信息
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysUser true "ID, 用户名, 昵称, 头像链接"
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "设置用户信息"
|
||||
// @Router /user/setUserInfo [put]
|
||||
func (b *BaseApi) SetUserInfo(c *gin.Context) {
|
||||
var user system.SysUser
|
||||
_ = c.ShouldBindJSON(&user)
|
||||
user.Username = ""
|
||||
user.Password = ""
|
||||
user.AuthorityId = ""
|
||||
if err := utils.Verify(user, utils.IdVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err, ReqUser := userService.SetUserInfo(user); err != nil {
|
||||
global.GVA_LOG.Error("设置失败!", zap.Error(err))
|
||||
response.FailWithMessage("设置失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "设置成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 设置用户信息
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysUser true "ID, 用户名, 昵称, 头像链接"
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "设置用户信息"
|
||||
// @Router /user/SetSelfInfo [put]
|
||||
func (b *BaseApi) SetSelfInfo(c *gin.Context) {
|
||||
var user system.SysUser
|
||||
_ = c.ShouldBindJSON(&user)
|
||||
user.Username = ""
|
||||
user.Password = ""
|
||||
user.AuthorityId = ""
|
||||
user.ID = utils.GetUserID(c)
|
||||
if err, ReqUser := userService.SetUserInfo(user); err != nil {
|
||||
global.GVA_LOG.Error("设置失败!", zap.Error(err))
|
||||
response.FailWithMessage("设置失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "设置成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 获取用户信息
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取用户信息"
|
||||
// @Router /user/getUserInfo [get]
|
||||
func (b *BaseApi) GetUserInfo(c *gin.Context) {
|
||||
uuid := utils.GetUserUuid(c)
|
||||
if err, ReqUser := userService.GetUserInfo(uuid); err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 重置用户密码
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysUser true "ID"
|
||||
// @Success 200 {object} response.Response{msg=string} "重置用户密码"
|
||||
// @Router /user/resetPassword [post]
|
||||
func (b *BaseApi) ResetPassword(c *gin.Context) {
|
||||
var user system.SysUser
|
||||
_ = c.ShouldBindJSON(&user)
|
||||
if err := userService.ResetPassword(user.ID); err != nil {
|
||||
global.GVA_LOG.Error("重置失败!", zap.Error(err))
|
||||
response.FailWithMessage("重置失败"+err.Error(), c)
|
||||
} else {
|
||||
response.OkWithMessage("重置成功", c)
|
||||
}
|
||||
}
|
|
@ -1,180 +0,0 @@
|
|||
aliyun-oss:
|
||||
endpoint: yourEndpoint
|
||||
access-key-id: yourAccessKeyId
|
||||
access-key-secret: yourAccessKeySecret
|
||||
bucket-name: yourBucketName
|
||||
bucket-url: yourBucketUrl
|
||||
base-path: yourBasePath
|
||||
autocode:
|
||||
transfer-restart: true
|
||||
root: /Users/seven/Developer/goenv
|
||||
server: /server
|
||||
server-api: /api/v1/autocode
|
||||
server-initialize: /initialize
|
||||
server-model: /model/autocode
|
||||
server-request: /model/autocode/request/
|
||||
server-router: /router/autocode
|
||||
server-service: /service/autocode
|
||||
web: /web/src
|
||||
web-api: /api
|
||||
web-form: /view
|
||||
web-table: /view
|
||||
aws-s3:
|
||||
bucket: xxxxx-10005608
|
||||
region: ap-shanghai
|
||||
secret-id: xxxxxxxx
|
||||
secret-key: xxxxxxxx
|
||||
base-url: https://gin.vue.admin
|
||||
path-prefix: looklook/admin
|
||||
captcha:
|
||||
key-long: 6
|
||||
img-width: 240
|
||||
img-height: 80
|
||||
casbin:
|
||||
model-path: ./resource/rbac_model.conf
|
||||
cors:
|
||||
mode: whitelist
|
||||
whitelist:
|
||||
- allow-origin: example1.com
|
||||
allow-methods: GET, POST
|
||||
allow-headers: content-type
|
||||
expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,
|
||||
Content-Type
|
||||
allow-credentials: true
|
||||
- allow-origin: example2.com
|
||||
allow-methods: GET, POST
|
||||
allow-headers: content-type
|
||||
expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,
|
||||
Content-Type
|
||||
allow-credentials: true
|
||||
db-list:
|
||||
- disable: false
|
||||
type: ""
|
||||
alias-name: ""
|
||||
path: ""
|
||||
port: ""
|
||||
config: ""
|
||||
db-name: ""
|
||||
username: ""
|
||||
password: ""
|
||||
max-idle-conns: 10
|
||||
max-open-conns: 100
|
||||
log-mode: ""
|
||||
log-zap: false
|
||||
email:
|
||||
to: xxx@qq.com
|
||||
port: 465
|
||||
from: xxx@163.com
|
||||
host: smtp.163.com
|
||||
is-ssl: true
|
||||
secret: xxx
|
||||
nickname: test
|
||||
excel:
|
||||
dir: ./resource/excel/
|
||||
hua-wei-obs:
|
||||
path: you-path
|
||||
bucket: you-bucket
|
||||
endpoint: you-endpoint
|
||||
access-key: you-access-key
|
||||
secret-key: you-secret-key
|
||||
jwt:
|
||||
buffer-time: 86400
|
||||
expires-time: 604800
|
||||
issuer: qmPlus
|
||||
signing-key: 3f7ebed7-bc13-42f4-afc3-da4f8a1bcf9a
|
||||
local:
|
||||
path: uploads/file
|
||||
mysql:
|
||||
path: mysql
|
||||
port: "3306"
|
||||
config: charset=utf8mb4&parseTime=True&loc=Local
|
||||
db-name: looklook_admin
|
||||
username: root
|
||||
password: PXDN93VRKUm8TeE7
|
||||
max-idle-conns: 0
|
||||
max-open-conns: 0
|
||||
log-mode: ""
|
||||
log-zap: false
|
||||
pgsql:
|
||||
path: ""
|
||||
port: ""
|
||||
config: ""
|
||||
db-name: ""
|
||||
username: ""
|
||||
password: ""
|
||||
max-idle-conns: 10
|
||||
max-open-conns: 100
|
||||
log-mode: ""
|
||||
log-zap: false
|
||||
qiniu:
|
||||
zone: ZoneHuaDong
|
||||
bucket: ""
|
||||
img-path: ""
|
||||
use-https: false
|
||||
access-key: ""
|
||||
secret-key: ""
|
||||
use-cdn-domains: false
|
||||
redis:
|
||||
db: 0
|
||||
addr: redis:6379
|
||||
password: "G62m50oigInC30sf"
|
||||
system:
|
||||
env: public
|
||||
addr: 8888
|
||||
db-type: mysql
|
||||
oss-type: local
|
||||
use-multipoint: false
|
||||
iplimit-count: 15000
|
||||
iplimit-time: 3600
|
||||
tencent-cos:
|
||||
bucket: xxxxx-10005608
|
||||
region: ap-shanghai
|
||||
secret-id: xxxxxxxx
|
||||
secret-key: xxxxxxxx
|
||||
base-url: https://gin.vue.admin
|
||||
path-prefix: looklook/admin
|
||||
timer:
|
||||
start: true
|
||||
spec: '@daily'
|
||||
detail:
|
||||
- tableName: sys_operation_records
|
||||
compareField: created_at
|
||||
interval: 2160h
|
||||
- tableName: jwt_blacklists
|
||||
compareField: created_at
|
||||
interval: 168h
|
||||
zap:
|
||||
level: info
|
||||
format: console
|
||||
prefix: '[looklook/admin]'
|
||||
director: log
|
||||
showLine: true
|
||||
encode-level: LowercaseColorLevelEncoder
|
||||
stacktrace-key: stacktrace
|
||||
log-in-console: true
|
||||
|
||||
|
||||
# 当前服务信息
|
||||
serviceConf:
|
||||
Log:
|
||||
ServiceName: admin-api
|
||||
Level: error
|
||||
Mode: console
|
||||
|
||||
#监控
|
||||
Prometheus:
|
||||
Host: 0.0.0.0
|
||||
Port: 4013
|
||||
Path: /metrics
|
||||
|
||||
#链路追踪
|
||||
Telemetry:
|
||||
Name: admin-api
|
||||
Endpoint: http://jaeger:14268/api/traces
|
||||
Sampler: 1.0
|
||||
Batcher: jaeger
|
||||
|
||||
rpcConf:
|
||||
bannerRpcConf:
|
||||
Endpoints:
|
||||
- looklook:2005
|
|
@ -1,17 +0,0 @@
|
|||
package config
|
||||
|
||||
type Autocode struct {
|
||||
TransferRestart bool `mapstructure:"transfer-restart" json:"transferRestart" yaml:"transfer-restart"`
|
||||
Root string `mapstructure:"root" json:"root" yaml:"root"`
|
||||
Server string `mapstructure:"server" json:"server" yaml:"server"`
|
||||
SApi string `mapstructure:"server-api" json:"serverApi" yaml:"server-api"`
|
||||
SInitialize string `mapstructure:"server-initialize" json:"serverInitialize" yaml:"server-initialize"`
|
||||
SModel string `mapstructure:"server-model" json:"serverModel" yaml:"server-model"`
|
||||
SRequest string `mapstructure:"server-request" json:"serverRequest" yaml:"server-request"`
|
||||
SRouter string `mapstructure:"server-router" json:"serverRouter" yaml:"server-router"`
|
||||
SService string `mapstructure:"server-service" json:"serverService" yaml:"server-service"`
|
||||
Web string `mapstructure:"web" json:"web" yaml:"web"`
|
||||
WApi string `mapstructure:"web-api" json:"webApi" yaml:"web-api"`
|
||||
WForm string `mapstructure:"web-form" json:"webForm" yaml:"web-form"`
|
||||
WTable string `mapstructure:"web-table" json:"webTable" yaml:"web-table"`
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package config
|
||||
|
||||
type Captcha struct {
|
||||
KeyLong int `mapstructure:"key-long" json:"keyLong" yaml:"key-long"` // 验证码长度
|
||||
ImgWidth int `mapstructure:"img-width" json:"imgWidth" yaml:"img-width"` // 验证码宽度
|
||||
ImgHeight int `mapstructure:"img-height" json:"imgHeight" yaml:"img-height"` // 验证码高度
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package config
|
||||
|
||||
type Casbin struct {
|
||||
ModelPath string `mapstructure:"model-path" json:"modelPath" yaml:"model-path"` // 存放casbin模型的相对路径
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package config
|
||||
|
||||
import "github.com/zeromicro/go-zero/core/service"
|
||||
|
||||
type Server struct {
|
||||
JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
|
||||
Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
|
||||
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
|
||||
Email Email `mapstructure:"email" json:"email" yaml:"email"`
|
||||
Casbin Casbin `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
|
||||
System System `mapstructure:"system" json:"system" yaml:"system"`
|
||||
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
|
||||
// auto
|
||||
AutoCode Autocode `mapstructure:"autoCode" json:"autoCode" yaml:"autoCode"`
|
||||
// gorm
|
||||
Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
|
||||
Pgsql Pgsql `mapstructure:"pgsql" json:"pgsql" yaml:"pgsql"`
|
||||
DBList []DB `mapstructure:"db-list" json:"db-list" yaml:"db-list"`
|
||||
// oss
|
||||
Local Local `mapstructure:"local" json:"local" yaml:"local"`
|
||||
Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"`
|
||||
AliyunOSS AliyunOSS `mapstructure:"aliyun-oss" json:"aliyunOSS" yaml:"aliyun-oss"`
|
||||
HuaWeiObs HuaWeiObs `mapstructure:"hua-wei-obs" json:"huaWeiObs" yaml:"hua-wei-obs"`
|
||||
TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencentCOS" yaml:"tencent-cos"`
|
||||
AwsS3 AwsS3 `mapstructure:"aws-s3" json:"awsS3" yaml:"aws-s3"`
|
||||
|
||||
Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"`
|
||||
Timer Timer `mapstructure:"timer" json:"timer" yaml:"timer"`
|
||||
|
||||
// 跨域配置
|
||||
Cors CORS `mapstructure:"cors" json:"cors" yaml:"cors"`
|
||||
|
||||
//rpcConf
|
||||
RpcConf RpcConf `mapstructure:"rpcConf" json:"rpcConf" yaml:"rpcConf"`
|
||||
|
||||
// 相关监控组件配置使用,prometheus、jaeger等 , zero已经支持好了直接使用go-zero的即可
|
||||
ServiceConf service.ServiceConf `mapstructure:"serviceConf" json:"serviceConf" yaml:"serviceConf"`
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package config
|
||||
|
||||
type CORS struct {
|
||||
Mode string `mapstructure:"mode" json:"mode" yaml:"mode"`
|
||||
Whitelist []CORSWhitelist `mapstructure:"whitelist" json:"whitelist" yaml:"whitelist"`
|
||||
}
|
||||
|
||||
type CORSWhitelist struct {
|
||||
AllowOrigin string `mapstructure:"allow-origin" json:"allow-origin" yaml:"allow-origin"`
|
||||
AllowMethods string `mapstructure:"allow-methods" json:"allow-methods" yaml:"allow-methods"`
|
||||
AllowHeaders string `mapstructure:"allow-headers" json:"allow-headers" yaml:"allow-headers"`
|
||||
ExposeHeaders string `mapstructure:"expose-headers" json:"expose-headers" yaml:"expose-headers"`
|
||||
AllowCredentials bool `mapstructure:"allow-credentials" json:"allow-credentials" yaml:"allow-credentials"`
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package config
|
||||
|
||||
type DB struct {
|
||||
Disable bool `mapstructure:"disable" json:"disable" yaml:"disable"`
|
||||
Type string `mapstructure:"type" json:"type" yaml:"type"`
|
||||
AliasName string `mapstructure:"alias-name" json:"alias-name" yaml:"alias-name"`
|
||||
Path string `mapstructure:"path" json:"path" yaml:"path"` // 服务器地址:端口
|
||||
Port string `mapstructure:"port" json:"port" yaml:"port"` //:端口
|
||||
Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置
|
||||
Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"` // 数据库名
|
||||
Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库用户名
|
||||
Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码
|
||||
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"` // 空闲中的最大连接数
|
||||
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"` // 打开到数据库的最大连接数
|
||||
LogMode string `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"` // 是否开启Gorm全局日志
|
||||
LogZap bool `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"`
|
||||
}
|
||||
|
||||
func (m *DB) Dsn() string {
|
||||
return m.Username + ":" + m.Password + "@tcp(" + m.Path + ":" + m.Port + ")/" + m.Dbname + "?" + m.Config
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package config
|
||||
|
||||
type Email struct {
|
||||
To string `mapstructure:"to" json:"to" yaml:"to"` // 收件人:多个以英文逗号分隔
|
||||
Port int `mapstructure:"port" json:"port" yaml:"port"` // 端口
|
||||
From string `mapstructure:"from" json:"from" yaml:"from"` // 收件人
|
||||
Host string `mapstructure:"host" json:"host" yaml:"host"` // 服务器地址
|
||||
IsSSL bool `mapstructure:"is-ssl" json:"isSSL" yaml:"is-ssl"` // 是否SSL
|
||||
Secret string `mapstructure:"secret" json:"secret" yaml:"secret"` // 密钥
|
||||
Nickname string `mapstructure:"nickname" json:"nickname" yaml:"nickname"` // 昵称
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package config
|
||||
|
||||
type Excel struct {
|
||||
Dir string `mapstructure:"dir" json:"dir" yaml:"dir"`
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package config
|
||||
|
||||
type Mysql struct {
|
||||
Path string `mapstructure:"path" json:"path" yaml:"path"` // 服务器地址
|
||||
Port string `mapstructure:"port" json:"port" yaml:"port"` // 端口
|
||||
Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置
|
||||
Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"` // 数据库名
|
||||
Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库用户名
|
||||
Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码
|
||||
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"` // 空闲中的最大连接数
|
||||
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"` // 打开到数据库的最大连接数
|
||||
LogMode string `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"` // 是否开启Gorm全局日志
|
||||
LogZap bool `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"` // 是否通过zap写入日志文件
|
||||
}
|
||||
|
||||
func (m *Mysql) Dsn() string {
|
||||
return m.Username + ":" + m.Password + "@tcp(" + m.Path + ":" + m.Port + ")/" + m.Dbname + "?" + m.Config
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package config
|
||||
|
||||
type Pgsql struct {
|
||||
Path string `mapstructure:"path" json:"path" yaml:"path"` // 服务器地址:端口
|
||||
Port string `mapstructure:"port" json:"port" yaml:"port"` //:端口
|
||||
Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置
|
||||
Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"` // 数据库名
|
||||
Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库用户名
|
||||
Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码
|
||||
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"` // 空闲中的最大连接数
|
||||
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"` // 打开到数据库的最大连接数
|
||||
LogMode string `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"` // 是否开启Gorm全局日志
|
||||
LogZap bool `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"` // 是否通过zap写入日志文件
|
||||
}
|
||||
|
||||
// Dsn 基于配置文件获取 dsn
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (p *Pgsql) Dsn() string {
|
||||
return "host=" + p.Path + " user=" + p.Username + " password=" + p.Password + " dbname=" + p.Dbname + " port=" + p.Port + " " + p.Config
|
||||
}
|
||||
|
||||
// LinkDsn 根据 dbname 生成 dsn
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (p *Pgsql) LinkDsn(dbname string) string {
|
||||
return "host=" + p.Path + " user=" + p.Username + " password=" + p.Password + " dbname=" + dbname + " port=" + p.Port + " " + p.Config
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package config
|
||||
|
||||
type JWT struct {
|
||||
SigningKey string `mapstructure:"signing-key" json:"signingKey" yaml:"signing-key"` // jwt签名
|
||||
ExpiresTime int64 `mapstructure:"expires-time" json:"expiresTime" yaml:"expires-time"` // 过期时间
|
||||
BufferTime int64 `mapstructure:"buffer-time" json:"bufferTime" yaml:"buffer-time"` // 缓冲时间
|
||||
Issuer string `mapstructure:"issuer" json:"issuer" yaml:"issuer"` // 签发者
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package config
|
||||
|
||||
type AliyunOSS struct {
|
||||
Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"`
|
||||
AccessKeyId string `mapstructure:"access-key-id" json:"accessKeyId" yaml:"access-key-id"`
|
||||
AccessKeySecret string `mapstructure:"access-key-secret" json:"accessKeySecret" yaml:"access-key-secret"`
|
||||
BucketName string `mapstructure:"bucket-name" json:"bucketName" yaml:"bucket-name"`
|
||||
BucketUrl string `mapstructure:"bucket-url" json:"bucketUrl" yaml:"bucket-url"`
|
||||
BasePath string `mapstructure:"base-path" json:"basePath" yaml:"base-path"`
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package config
|
||||
|
||||
type AwsS3 struct {
|
||||
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
|
||||
Region string `mapstructure:"region" json:"region" yaml:"region"`
|
||||
SecretID string `mapstructure:"secret-id" json:"secretID" yaml:"secret-id"`
|
||||
SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"`
|
||||
BaseURL string `mapstructure:"base-url" json:"baseURL" yaml:"base-url"`
|
||||
PathPrefix string `mapstructure:"path-prefix" json:"pathPrefix" yaml:"path-prefix"`
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package config
|
||||
|
||||
type HuaWeiObs struct {
|
||||
Path string `mapstructure:"path" json:"path" yaml:"path"`
|
||||
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
|
||||
Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"`
|
||||
AccessKey string `mapstructure:"access-key" json:"accessKey" yaml:"access-key"`
|
||||
SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"`
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package config
|
||||
|
||||
type Local struct {
|
||||
Path string `mapstructure:"path" json:"path" yaml:"path"` // 本地文件路径
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package config
|
||||
|
||||
type Qiniu struct {
|
||||
Zone string `mapstructure:"zone" json:"zone" yaml:"zone"` // 存储区域
|
||||
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"` // 空间名称
|
||||
ImgPath string `mapstructure:"img-path" json:"imgPath" yaml:"img-path"` // CDN加速域名
|
||||
UseHTTPS bool `mapstructure:"use-https" json:"useHttps" yaml:"use-https"` // 是否使用https
|
||||
AccessKey string `mapstructure:"access-key" json:"accessKey" yaml:"access-key"` // 秘钥AK
|
||||
SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"` // 秘钥SK
|
||||
UseCdnDomains bool `mapstructure:"use-cdn-domains" json:"useCdnDomains" yaml:"use-cdn-domains"` // 上传是否使用CDN上传加速
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package config
|
||||
|
||||
type TencentCOS struct {
|
||||
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
|
||||
Region string `mapstructure:"region" json:"region" yaml:"region"`
|
||||
SecretID string `mapstructure:"secret-id" json:"secretID" yaml:"secret-id"`
|
||||
SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"`
|
||||
BaseURL string `mapstructure:"base-url" json:"baseURL" yaml:"base-url"`
|
||||
PathPrefix string `mapstructure:"path-prefix" json:"pathPrefix" yaml:"path-prefix"`
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package config
|
||||
|
||||
type Redis struct {
|
||||
DB int `mapstructure:"db" json:"db" yaml:"db"` // redis的哪个数据库
|
||||
Addr string `mapstructure:"addr" json:"addr" yaml:"addr"` // 服务器地址:端口
|
||||
Password string `mapstructure:"password" json:"password" yaml:"password"` // 密码
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package config
|
||||
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
)
|
||||
//rpcConf
|
||||
type RpcConf struct{
|
||||
BannerRpcConf zrpc.RpcClientConf `mapstructure:"bannerRpcConf" json:"bannerRpcConf" yaml:"bannerRpcConf"`
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package config
|
||||
|
||||
type System struct {
|
||||
Env string `mapstructure:"env" json:"env" yaml:"env"` // 环境值
|
||||
Addr int `mapstructure:"addr" json:"addr" yaml:"addr"` // 端口值
|
||||
DbType string `mapstructure:"db-type" json:"dbType" yaml:"db-type"` // 数据库类型:mysql(默认)|sqlite|sqlserver|postgresql
|
||||
OssType string `mapstructure:"oss-type" json:"ossType" yaml:"oss-type"` // Oss类型
|
||||
UseMultipoint bool `mapstructure:"use-multipoint" json:"useMultipoint" yaml:"use-multipoint"` // 多点登录拦截
|
||||
LimitCountIP int `mapstructure:"iplimit-count" json:"iplimitCount" yaml:"iplimit-count"`
|
||||
LimitTimeIP int `mapstructure:"iplimit-time" json:"iplimitTime" yaml:"iplimit-time"`
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package config
|
||||
|
||||
type Timer struct {
|
||||
Start bool `mapstructure:"start" json:"start" yaml:"start"` // 是否启用
|
||||
Spec string `mapstructure:"spec" json:"spec" yaml:"spec"` // CRON表达式
|
||||
Detail []Detail `mapstructure:"detail" json:"detail" yaml:"detail"`
|
||||
}
|
||||
|
||||
type Detail struct {
|
||||
TableName string `mapstructure:"tableName" json:"tableName" yaml:"tableName"` // 需要清理的表名
|
||||
CompareField string `mapstructure:"compareField" json:"compareField" yaml:"compareField"` // 需要比较时间的字段
|
||||
Interval string `mapstructure:"interval" json:"interval" yaml:"interval"` // 时间间隔
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package config
|
||||
|
||||
type Zap struct {
|
||||
Level string `mapstructure:"level" json:"level" yaml:"level"` // 级别
|
||||
Format string `mapstructure:"format" json:"format" yaml:"format"` // 输出
|
||||
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` // 日志前缀
|
||||
Director string `mapstructure:"director" json:"director" yaml:"director"` // 日志文件夹
|
||||
ShowLine bool `mapstructure:"show-line" json:"showLine" yaml:"showLine"` // 显示行
|
||||
EncodeLevel string `mapstructure:"encode-level" json:"encodeLevel" yaml:"encode-level"` // 编码级
|
||||
StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktraceKey" yaml:"stacktrace-key"` // 栈名
|
||||
LogInConsole bool `mapstructure:"log-in-console" json:"logInConsole" yaml:"log-in-console"` // 输出控制台
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"looklook/admin/rpc"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/initialize"
|
||||
"looklook/admin/service/system"
|
||||
)
|
||||
|
||||
type server interface {
|
||||
ListenAndServe() error
|
||||
}
|
||||
|
||||
func RunWindowsServer() {
|
||||
|
||||
// log、prometheus、trace、metricsUrl.
|
||||
if err := global.GVA_CONFIG.ServiceConf.SetUp(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if global.GVA_CONFIG.System.UseMultipoint {
|
||||
// 初始化redis服务
|
||||
initialize.Redis()
|
||||
}
|
||||
|
||||
// 从db加载jwt数据
|
||||
if global.GVA_DB != nil {
|
||||
system.LoadAll()
|
||||
}
|
||||
|
||||
//初始化rpc client
|
||||
rpc.InitClient()
|
||||
|
||||
Router := initialize.Routers()
|
||||
|
||||
Router.Static("/form-generator", "./resource/page")
|
||||
|
||||
address := fmt.Sprintf(":%d", global.GVA_CONFIG.System.Addr)
|
||||
s := initServer(address, Router)
|
||||
// 保证文本顺序输出
|
||||
// In order to ensure that the text order output can be deleted
|
||||
time.Sleep(10 * time.Microsecond)
|
||||
global.GVA_LOG.Info("server run success on ", zap.String("address", address))
|
||||
|
||||
global.GVA_LOG.Error(s.ListenAndServe().Error())
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/fvbock/endless"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func initServer(address string, router *gin.Engine) server {
|
||||
s := endless.NewServer(address, router)
|
||||
s.ReadHeaderTimeout = 20 * time.Second
|
||||
s.WriteTimeout = 20 * time.Second
|
||||
s.MaxHeaderBytes = 1 << 20
|
||||
return s
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func initServer(address string, router *gin.Engine) server {
|
||||
return &http.Server{
|
||||
Addr: address,
|
||||
Handler: router,
|
||||
ReadTimeout: 20 * time.Second,
|
||||
WriteTimeout: 20 * time.Second,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/songzhibin97/gkit/cache/local_cache"
|
||||
|
||||
"looklook/admin/global"
|
||||
_ "looklook/admin/packfile"
|
||||
"looklook/admin/utils"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func Viper(path ...string) *viper.Viper {
|
||||
var config string
|
||||
if len(path) == 0 {
|
||||
flag.StringVar(&config, "c", "", "choose config file.")
|
||||
flag.Parse()
|
||||
if config == "" { // 优先级: 命令行 > 环境变量 > 默认值
|
||||
if configEnv := os.Getenv(utils.ConfigEnv); configEnv == "" {
|
||||
config = utils.ConfigFile
|
||||
fmt.Printf("您正在使用config的默认值,config的路径为%v\n", utils.ConfigFile)
|
||||
} else {
|
||||
config = configEnv
|
||||
fmt.Printf("您正在使用GVA_CONFIG环境变量,config的路径为%v\n", config)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("您正在使用命令行的-c参数传递的值,config的路径为%v\n", config)
|
||||
}
|
||||
} else {
|
||||
config = path[0]
|
||||
fmt.Printf("您正在使用func Viper()传递的值,config的路径为%v\n", config)
|
||||
}
|
||||
|
||||
v := viper.New()
|
||||
v.SetConfigFile(config)
|
||||
v.SetConfigType("yaml")
|
||||
err := v.ReadInConfig()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Fatal error config file: %s \n", err))
|
||||
}
|
||||
v.WatchConfig()
|
||||
|
||||
v.OnConfigChange(func(e fsnotify.Event) {
|
||||
fmt.Println("config file changed:", e.Name)
|
||||
if err := v.Unmarshal(&global.GVA_CONFIG); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
})
|
||||
if err := v.Unmarshal(&global.GVA_CONFIG); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
// root 适配性
|
||||
// 根据root位置去找到对应迁移位置,保证root路径有效
|
||||
global.GVA_CONFIG.AutoCode.Root, _ = filepath.Abs("..")
|
||||
global.BlackCache = local_cache.NewCache(
|
||||
local_cache.SetDefaultExpire(time.Second * time.Duration(global.GVA_CONFIG.JWT.ExpiresTime)),
|
||||
)
|
||||
return v
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/utils"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
func Zap() (logger *zap.Logger) {
|
||||
if ok, _ := utils.PathExists(global.GVA_CONFIG.Zap.Director); !ok { // 判断是否有Director文件夹
|
||||
fmt.Printf("create %v directory\n", global.GVA_CONFIG.Zap.Director)
|
||||
_ = os.Mkdir(global.GVA_CONFIG.Zap.Director, os.ModePerm)
|
||||
}
|
||||
// 调试级别
|
||||
debugPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
|
||||
return lev == zap.DebugLevel
|
||||
})
|
||||
// 日志级别
|
||||
infoPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
|
||||
return lev == zap.InfoLevel
|
||||
})
|
||||
// 警告级别
|
||||
warnPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
|
||||
return lev == zap.WarnLevel
|
||||
})
|
||||
// 错误级别
|
||||
errorPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
|
||||
return lev >= zap.ErrorLevel
|
||||
})
|
||||
|
||||
cores := [...]zapcore.Core{
|
||||
getEncoderCore(fmt.Sprintf("./%s/server_debug.log", global.GVA_CONFIG.Zap.Director), debugPriority),
|
||||
getEncoderCore(fmt.Sprintf("./%s/server_info.log", global.GVA_CONFIG.Zap.Director), infoPriority),
|
||||
getEncoderCore(fmt.Sprintf("./%s/server_warn.log", global.GVA_CONFIG.Zap.Director), warnPriority),
|
||||
getEncoderCore(fmt.Sprintf("./%s/server_error.log", global.GVA_CONFIG.Zap.Director), errorPriority),
|
||||
}
|
||||
logger = zap.New(zapcore.NewTee(cores[:]...), zap.AddCaller())
|
||||
|
||||
if global.GVA_CONFIG.Zap.ShowLine {
|
||||
logger = logger.WithOptions(zap.AddCaller())
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
// getEncoderConfig 获取zapcore.EncoderConfig
|
||||
func getEncoderConfig() (config zapcore.EncoderConfig) {
|
||||
config = zapcore.EncoderConfig{
|
||||
MessageKey: "message",
|
||||
LevelKey: "level",
|
||||
TimeKey: "time",
|
||||
NameKey: "logger",
|
||||
CallerKey: "caller",
|
||||
StacktraceKey: global.GVA_CONFIG.Zap.StacktraceKey,
|
||||
LineEnding: zapcore.DefaultLineEnding,
|
||||
EncodeLevel: zapcore.LowercaseLevelEncoder,
|
||||
EncodeTime: CustomTimeEncoder,
|
||||
EncodeDuration: zapcore.SecondsDurationEncoder,
|
||||
EncodeCaller: zapcore.FullCallerEncoder,
|
||||
}
|
||||
switch {
|
||||
case global.GVA_CONFIG.Zap.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认)
|
||||
config.EncodeLevel = zapcore.LowercaseLevelEncoder
|
||||
case global.GVA_CONFIG.Zap.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色
|
||||
config.EncodeLevel = zapcore.LowercaseColorLevelEncoder
|
||||
case global.GVA_CONFIG.Zap.EncodeLevel == "CapitalLevelEncoder": // 大写编码器
|
||||
config.EncodeLevel = zapcore.CapitalLevelEncoder
|
||||
case global.GVA_CONFIG.Zap.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色
|
||||
config.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
||||
default:
|
||||
config.EncodeLevel = zapcore.LowercaseLevelEncoder
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// getEncoder 获取zapcore.Encoder
|
||||
func getEncoder() zapcore.Encoder {
|
||||
if global.GVA_CONFIG.Zap.Format == "json" {
|
||||
return zapcore.NewJSONEncoder(getEncoderConfig())
|
||||
}
|
||||
return zapcore.NewConsoleEncoder(getEncoderConfig())
|
||||
}
|
||||
|
||||
// getEncoderCore 获取Encoder的zapcore.Core
|
||||
func getEncoderCore(fileName string, level zapcore.LevelEnabler) (core zapcore.Core) {
|
||||
writer := utils.GetWriteSyncer(fileName) // 使用file-rotatelogs进行日志分割
|
||||
return zapcore.NewCore(getEncoder(), writer, level)
|
||||
}
|
||||
|
||||
// 自定义日志输出时间格式
|
||||
func CustomTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
||||
enc.AppendString(t.Format(global.GVA_CONFIG.Zap.Prefix + "2006/01/02 - 15:04:05.000"))
|
||||
}
|
5160
admin/docs/docs.go
5160
admin/docs/docs.go
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,51 +0,0 @@
|
|||
package global
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"looklook/admin/utils/timer"
|
||||
"github.com/songzhibin97/gkit/cache/local_cache"
|
||||
|
||||
"golang.org/x/sync/singleflight"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"looklook/admin/config"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/spf13/viper"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
GVA_DB *gorm.DB
|
||||
GVA_DBList map[string]*gorm.DB
|
||||
GVA_REDIS *redis.Client
|
||||
GVA_CONFIG config.Server
|
||||
GVA_VP *viper.Viper
|
||||
// GVA_LOG *oplogging.Logger
|
||||
GVA_LOG *zap.Logger
|
||||
GVA_Timer timer.Timer = timer.NewTimerTask()
|
||||
GVA_Concurrency_Control = &singleflight.Group{}
|
||||
|
||||
BlackCache local_cache.Cache
|
||||
lock sync.RWMutex
|
||||
)
|
||||
|
||||
// GetGlobalDBByDBName 通过名称获取db list中的db
|
||||
func GetGlobalDBByDBName(dbname string) *gorm.DB {
|
||||
lock.RLock()
|
||||
defer lock.RUnlock()
|
||||
return GVA_DBList[dbname]
|
||||
}
|
||||
|
||||
// MustGetGlobalDBByDBName 通过名称获取db 如果不存在则panic
|
||||
func MustGetGlobalDBByDBName(dbname string) *gorm.DB {
|
||||
lock.RLock()
|
||||
defer lock.RUnlock()
|
||||
db, ok := GVA_DBList[dbname]
|
||||
if !ok || db == nil {
|
||||
panic("db no init")
|
||||
}
|
||||
return db
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package global
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type GVA_MODEL struct {
|
||||
ID uint `gorm:"primarykey"` // 主键ID
|
||||
CreatedAt time.Time // 创建时间
|
||||
UpdatedAt time.Time // 更新时间
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` // 删除时间
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package initialize
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const sys = "system"
|
||||
|
||||
func DBList() {
|
||||
dbMap := make(map[string]*gorm.DB)
|
||||
for _, info := range global.GVA_CONFIG.DBList {
|
||||
if info.Disable {
|
||||
continue
|
||||
}
|
||||
switch info.Type {
|
||||
case "mysql":
|
||||
dbMap[info.Dbname] = GormMysqlByConfig(info)
|
||||
case "pgsql":
|
||||
dbMap[info.Dbname] = GormPgSqlByConfig(info)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
// 做特殊判断,是否有迁移
|
||||
// 适配低版本迁移多数据库版本
|
||||
if sysDB, ok := dbMap[sys]; ok {
|
||||
global.GVA_DB = sysDB
|
||||
}
|
||||
global.GVA_DBList = dbMap
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package initialize
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/autocode"
|
||||
"looklook/admin/model/example"
|
||||
"looklook/admin/model/system"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Gorm 初始化数据库并产生数据库全局变量
|
||||
// Author SliverHorn
|
||||
func Gorm() *gorm.DB {
|
||||
switch global.GVA_CONFIG.System.DbType {
|
||||
case "mysql":
|
||||
return GormMysql()
|
||||
case "pgsql":
|
||||
return GormPgSql()
|
||||
default:
|
||||
return GormMysql()
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterTables 注册数据库表专用
|
||||
// Author SliverHorn
|
||||
func RegisterTables(db *gorm.DB) {
|
||||
err := db.AutoMigrate(
|
||||
// 系统模块表
|
||||
system.SysApi{},
|
||||
system.SysUser{},
|
||||
system.SysBaseMenu{},
|
||||
system.JwtBlacklist{},
|
||||
system.SysAuthority{},
|
||||
system.SysDictionary{},
|
||||
system.SysOperationRecord{},
|
||||
system.SysAutoCodeHistory{},
|
||||
system.SysDictionaryDetail{},
|
||||
system.SysBaseMenuParameter{},
|
||||
|
||||
// 示例模块表
|
||||
example.ExaFile{},
|
||||
example.ExaCustomer{},
|
||||
example.ExaFileChunk{},
|
||||
example.ExaFileUploadAndDownload{},
|
||||
|
||||
// 自动化模块表
|
||||
// Code generated by looklook/admin Begin; DO NOT EDIT.
|
||||
autocode.AutoCodeExample{},
|
||||
// Code generated by looklook/admin End; DO NOT EDIT.
|
||||
)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("register table failed", zap.Error(err))
|
||||
os.Exit(0)
|
||||
}
|
||||
global.GVA_LOG.Info("register table success")
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package initialize
|
||||
|
||||
import (
|
||||
"looklook/admin/config"
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/initialize/internal"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// GormMysql 初始化Mysql数据库
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func GormMysql() *gorm.DB {
|
||||
m := global.GVA_CONFIG.Mysql
|
||||
if m.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
mysqlConfig := mysql.Config{
|
||||
DSN: m.Dsn(), // DSN data source name
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
SkipInitializeWithVersion: false, // 根据版本自动配置
|
||||
}
|
||||
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config()); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
}
|
||||
|
||||
// GormMysqlByConfig 初始化Mysql数据库用过传入配置
|
||||
func GormMysqlByConfig(m config.DB) *gorm.DB {
|
||||
if m.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
mysqlConfig := mysql.Config{
|
||||
DSN: m.Dsn(), // DSN data source name
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
SkipInitializeWithVersion: false, // 根据版本自动配置
|
||||
}
|
||||
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config()); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package initialize
|
||||
|
||||
import (
|
||||
"looklook/admin/config"
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/initialize/internal"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// GormPgSql 初始化 Postgresql 数据库
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func GormPgSql() *gorm.DB {
|
||||
p := global.GVA_CONFIG.Pgsql
|
||||
if p.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
pgsqlConfig := postgres.Config{
|
||||
DSN: p.Dsn(), // DSN data source name
|
||||
PreferSimpleProtocol: false,
|
||||
}
|
||||
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config()); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(p.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(p.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
}
|
||||
|
||||
// GormPgSqlByConfig 初始化 Postgresql 数据库 通过参数
|
||||
func GormPgSqlByConfig(p config.DB) *gorm.DB {
|
||||
if p.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
pgsqlConfig := postgres.Config{
|
||||
DSN: p.Dsn(), // DSN data source name
|
||||
PreferSimpleProtocol: false,
|
||||
}
|
||||
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config()); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(p.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(p.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"looklook/admin/global"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
var Gorm = new(_gorm)
|
||||
|
||||
type _gorm struct{}
|
||||
|
||||
// Config gorm 自定义配置
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (g *_gorm) Config() *gorm.Config {
|
||||
config := &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}
|
||||
_default := logger.New(NewWriter(log.New(os.Stdout, "\r\n", log.LstdFlags)), logger.Config{
|
||||
SlowThreshold: 200 * time.Millisecond,
|
||||
LogLevel: logger.Warn,
|
||||
Colorful: true,
|
||||
})
|
||||
switch global.GVA_CONFIG.Mysql.LogMode {
|
||||
case "silent", "Silent":
|
||||
config.Logger = _default.LogMode(logger.Silent)
|
||||
case "error", "Error":
|
||||
config.Logger = _default.LogMode(logger.Error)
|
||||
case "warn", "Warn":
|
||||
config.Logger = _default.LogMode(logger.Warn)
|
||||
case "info", "Info":
|
||||
config.Logger = _default.LogMode(logger.Info)
|
||||
default:
|
||||
config.Logger = _default.LogMode(logger.Info)
|
||||
}
|
||||
return config
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"looklook/admin/global"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
type writer struct {
|
||||
logger.Writer
|
||||
}
|
||||
|
||||
// NewWriter writer 构造函数
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func NewWriter(w logger.Writer) *writer {
|
||||
return &writer{Writer: w}
|
||||
}
|
||||
|
||||
// Printf 格式化打印日志
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (w *writer) Printf(message string, data ...interface{}) {
|
||||
var logZap bool
|
||||
switch global.GVA_CONFIG.System.DbType {
|
||||
case "mysql":
|
||||
logZap = global.GVA_CONFIG.Mysql.LogZap
|
||||
case "pgsql":
|
||||
logZap = global.GVA_CONFIG.Pgsql.LogZap
|
||||
}
|
||||
if logZap {
|
||||
global.GVA_LOG.Info(fmt.Sprintf(message+"\n", data...))
|
||||
} else {
|
||||
w.Writer.Printf(message, data...)
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package initialize
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
email "github.com/flipped-aurora/gva-plugins/email" // 在线仓库模式go
|
||||
//"looklook/admin/plugin/email" // 本地插件仓库地址模式
|
||||
"looklook/admin/plugin/example_plugin"
|
||||
"looklook/admin/utils/plugin"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func PluginInit(group *gin.RouterGroup, Plugin ...plugin.Plugin) {
|
||||
for i := range Plugin {
|
||||
PluginGroup := group.Group(Plugin[i].RouterPath())
|
||||
Plugin[i].Register(PluginGroup)
|
||||
}
|
||||
}
|
||||
|
||||
func InstallPlugin(PublicGroup *gin.RouterGroup, PrivateGroup *gin.RouterGroup) {
|
||||
// 添加开放权限的插件 示例
|
||||
PluginInit(PublicGroup,
|
||||
example_plugin.ExamplePlugin)
|
||||
|
||||
// 添加跟角色挂钩权限的插件 示例 本地示例模式于在线仓库模式注意上方的import 可以自行切换 效果相同
|
||||
PluginInit(PrivateGroup, email.CreateEmailPlug(
|
||||
global.GVA_CONFIG.Email.To,
|
||||
global.GVA_CONFIG.Email.From,
|
||||
global.GVA_CONFIG.Email.Host,
|
||||
global.GVA_CONFIG.Email.Secret,
|
||||
global.GVA_CONFIG.Email.Nickname,
|
||||
global.GVA_CONFIG.Email.Port,
|
||||
global.GVA_CONFIG.Email.IsSSL,
|
||||
))
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package initialize
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"looklook/admin/global"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func Redis() {
|
||||
redisCfg := global.GVA_CONFIG.Redis
|
||||
client := redis.NewClient(&redis.Options{
|
||||
Addr: redisCfg.Addr,
|
||||
Password: redisCfg.Password, // no password set
|
||||
DB: redisCfg.DB, // use default DB
|
||||
})
|
||||
pong, err := client.Ping(context.Background()).Result()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("redis connect ping failed, err:", zap.Error(err))
|
||||
} else {
|
||||
global.GVA_LOG.Info("redis connect ping response:", zap.String("pong", pong))
|
||||
global.GVA_REDIS = client
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
package initialize
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/swaggo/gin-swagger"
|
||||
"github.com/swaggo/gin-swagger/swaggerFiles"
|
||||
_ "looklook/admin/docs"
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/middleware"
|
||||
"looklook/admin/router"
|
||||
)
|
||||
|
||||
// 初始化总路由
|
||||
|
||||
func Routers() *gin.Engine {
|
||||
Router := gin.Default()
|
||||
|
||||
// 如果想要不使用nginx代理前端网页,可以修改 web/.env.production 下的
|
||||
// VUE_APP_BASE_API = /
|
||||
// VUE_APP_BASE_PATH = http://localhost
|
||||
// 然后执行打包命令 npm run build。在打开下面4行注释
|
||||
// Router.LoadHTMLGlob("./dist/*.html") // npm打包成dist的路径
|
||||
// Router.Static("/favicon.ico", "./dist/favicon.ico")
|
||||
// Router.Static("/static", "./dist/assets") // dist里面的静态资源
|
||||
// Router.StaticFile("/", "./dist/index.html") // 前端网页入口页面
|
||||
|
||||
Router.StaticFS(global.GVA_CONFIG.Local.Path, http.Dir(global.GVA_CONFIG.Local.Path)) // 为用户头像和文件提供静态地址
|
||||
// Router.Use(middleware.LoadTls()) // 打开就能玩https了
|
||||
global.GVA_LOG.Info("use middleware logger")
|
||||
// 跨域,如需跨域可以打开下面的注释
|
||||
// Router.Use(middleware.Cors()) // 直接放行全部跨域请求
|
||||
//Router.Use(middleware.CorsByRules()) // 按照配置的规则放行跨域请求
|
||||
global.GVA_LOG.Info("use middleware cors")
|
||||
Router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
global.GVA_LOG.Info("register swagger handler")
|
||||
// 方便统一添加路由组前缀 多服务器上线使用
|
||||
|
||||
// 获取路由组实例
|
||||
systemRouter := router.RouterGroupApp.System
|
||||
exampleRouter := router.RouterGroupApp.Example
|
||||
autocodeRouter := router.RouterGroupApp.Autocode
|
||||
bannerRouter := router.RouterGroupApp.Banner
|
||||
PublicGroup := Router.Group("")
|
||||
{
|
||||
// 健康监测
|
||||
PublicGroup.GET("/health", func(c *gin.Context) {
|
||||
c.JSON(200, "ok")
|
||||
})
|
||||
}
|
||||
{
|
||||
systemRouter.InitBaseRouter(PublicGroup) // 注册基础功能路由 不做鉴权
|
||||
systemRouter.InitInitRouter(PublicGroup) // 自动初始化相关
|
||||
}
|
||||
PrivateGroup := Router.Group("")
|
||||
PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
|
||||
{
|
||||
systemRouter.InitApiRouter(PrivateGroup) // 注册功能api路由
|
||||
systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由
|
||||
systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由
|
||||
systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由
|
||||
systemRouter.InitSystemRouter(PrivateGroup) // system相关路由
|
||||
systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由
|
||||
systemRouter.InitAutoCodeRouter(PrivateGroup) // 创建自动化代码
|
||||
systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由
|
||||
systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理
|
||||
systemRouter.InitAutoCodeHistoryRouter(PrivateGroup) // 自动化代码历史
|
||||
systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录
|
||||
systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理
|
||||
|
||||
exampleRouter.InitExcelRouter(PrivateGroup) // 表格导入导出
|
||||
exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由
|
||||
exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由
|
||||
|
||||
bannerRouter.InitBannerRouter(PrivateGroup) //广告
|
||||
|
||||
// Code generated by looklook/admin Begin; DO NOT EDIT.
|
||||
autocodeRouter.InitSysAutoCodeExampleRouter(PrivateGroup)
|
||||
// Code generated by looklook/admin End; DO NOT EDIT.
|
||||
}
|
||||
|
||||
InstallPlugin(PublicGroup, PrivateGroup) // 安装插件
|
||||
|
||||
global.GVA_LOG.Info("router register success")
|
||||
return Router
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package initialize
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"looklook/admin/config"
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/utils"
|
||||
)
|
||||
|
||||
func Timer() {
|
||||
if global.GVA_CONFIG.Timer.Start {
|
||||
for i := range global.GVA_CONFIG.Timer.Detail {
|
||||
go func(detail config.Detail) {
|
||||
global.GVA_Timer.AddTaskByFunc("ClearDB", global.GVA_CONFIG.Timer.Spec, func() {
|
||||
err := utils.ClearTable(global.GVA_DB, detail.TableName, detail.CompareField, detail.Interval)
|
||||
if err != nil {
|
||||
fmt.Println("timer error:", err)
|
||||
}
|
||||
})
|
||||
}(global.GVA_CONFIG.Timer.Detail[i])
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package initialize
|
||||
|
||||
import "looklook/admin/utils"
|
||||
|
||||
func init() {
|
||||
_ = utils.RegisterRule("PageVerify",
|
||||
utils.Rules{
|
||||
"Page": {utils.NotEmpty()},
|
||||
"PageSize": {utils.NotEmpty()},
|
||||
},
|
||||
)
|
||||
_ = utils.RegisterRule("IdVerify",
|
||||
utils.Rules{
|
||||
"Id": {utils.NotEmpty()},
|
||||
},
|
||||
)
|
||||
_ = utils.RegisterRule("AuthorityIdVerify",
|
||||
utils.Rules{
|
||||
"AuthorityId": {utils.NotEmpty()},
|
||||
},
|
||||
)
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"looklook/admin/core"
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/initialize"
|
||||
)
|
||||
|
||||
//go:generate go env -w GO111MODULE=on
|
||||
//go:generate go env -w GOPROXY=https://goproxy.cn,direct
|
||||
//go:generate go mod tidy
|
||||
//go:generate go mod download
|
||||
|
||||
// @title Swagger Example API
|
||||
// @version 0.0.1
|
||||
// @description This is a sample Server pets
|
||||
// @securityDefinitions.apikey ApiKeyAuth
|
||||
// @in header
|
||||
// @name x-token
|
||||
// @BasePath /
|
||||
func main() {
|
||||
global.GVA_VP = core.Viper() // 初始化Viper
|
||||
global.GVA_LOG = core.Zap() // 初始化zap日志库
|
||||
global.GVA_DB = initialize.Gorm() // gorm连接数据库
|
||||
initialize.Timer()
|
||||
initialize.DBList()
|
||||
if global.GVA_DB != nil {
|
||||
initialize.RegisterTables(global.GVA_DB) // 初始化表
|
||||
// 程序结束前关闭数据库链接
|
||||
db, _ := global.GVA_DB.DB()
|
||||
defer db.Close()
|
||||
}
|
||||
core.RunWindowsServer()
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/service"
|
||||
"looklook/admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService
|
||||
|
||||
// 拦截器
|
||||
func CasbinHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
waitUse, _ := utils.GetClaims(c)
|
||||
// 获取请求的PATH
|
||||
obj := c.Request.URL.Path
|
||||
// 获取请求方法
|
||||
act := c.Request.Method
|
||||
// 获取用户的角色
|
||||
sub := waitUse.AuthorityId
|
||||
e := casbinService.Casbin()
|
||||
// 判断策略中是否存在
|
||||
success, _ := e.Enforce(sub, obj, act)
|
||||
if global.GVA_CONFIG.System.Env == "develop" || success {
|
||||
c.Next()
|
||||
} else {
|
||||
response.FailWithDetailed(gin.H{}, "权限不足", c)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"looklook/admin/config"
|
||||
"looklook/admin/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Cors 直接放行所有跨域请求并放行所有 OPTIONS 方法
|
||||
func Cors() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
method := c.Request.Method
|
||||
origin := c.Request.Header.Get("Origin")
|
||||
c.Header("Access-Control-Allow-Origin", origin)
|
||||
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id")
|
||||
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
|
||||
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
|
||||
c.Header("Access-Control-Allow-Credentials", "true")
|
||||
|
||||
// 放行所有OPTIONS方法
|
||||
if method == "OPTIONS" {
|
||||
c.AbortWithStatus(http.StatusNoContent)
|
||||
}
|
||||
// 处理请求
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// CorsByRules 按照配置处理跨域请求
|
||||
func CorsByRules() gin.HandlerFunc {
|
||||
// 放行全部
|
||||
if global.GVA_CONFIG.Cors.Mode == "allow-all" {
|
||||
return Cors()
|
||||
}
|
||||
return func(c *gin.Context) {
|
||||
whitelist := checkCors(c.GetHeader("origin"))
|
||||
|
||||
// 通过检查, 添加请求头
|
||||
if whitelist != nil {
|
||||
c.Header("Access-Control-Allow-Origin", whitelist.AllowOrigin)
|
||||
c.Header("Access-Control-Allow-Headers", whitelist.AllowHeaders)
|
||||
c.Header("Access-Control-Allow-Methods", whitelist.AllowMethods)
|
||||
c.Header("Access-Control-Expose-Headers", whitelist.ExposeHeaders)
|
||||
if whitelist.AllowCredentials {
|
||||
c.Header("Access-Control-Allow-Credentials", "true")
|
||||
}
|
||||
}
|
||||
|
||||
// 严格白名单模式且未通过检查,直接拒绝处理请求
|
||||
if whitelist == nil && global.GVA_CONFIG.Cors.Mode == "strict-whitelist" && !(c.Request.Method == "GET" && c.Request.URL.Path == "/health") {
|
||||
c.AbortWithStatus(http.StatusForbidden)
|
||||
} else {
|
||||
// 非严格白名单模式,无论是否通过检查均放行所有 OPTIONS 方法
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
c.AbortWithStatus(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理请求
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func checkCors(currentOrigin string) *config.CORSWhitelist {
|
||||
for _, whitelist := range global.GVA_CONFIG.Cors.Whitelist {
|
||||
// 遍历配置中的跨域头,寻找匹配项
|
||||
if currentOrigin == whitelist.AllowOrigin {
|
||||
return &whitelist
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"looklook/admin/plugin/email/utils"
|
||||
utils2 "looklook/admin/utils"
|
||||
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/system"
|
||||
"looklook/admin/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var userService = service.ServiceGroupApp.SystemServiceGroup.UserService
|
||||
|
||||
func ErrorToEmail() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var username string
|
||||
claims, _ := utils2.GetClaims(c)
|
||||
if claims.Username != "" {
|
||||
username = claims.Username
|
||||
} else {
|
||||
id, _ := strconv.Atoi(c.Request.Header.Get("x-user-id"))
|
||||
err, user := userService.FindUserById(id)
|
||||
if err != nil {
|
||||
username = "Unknown"
|
||||
}
|
||||
username = user.Username
|
||||
}
|
||||
body, _ := ioutil.ReadAll(c.Request.Body)
|
||||
record := system.SysOperationRecord{
|
||||
Ip: c.ClientIP(),
|
||||
Method: c.Request.Method,
|
||||
Path: c.Request.URL.Path,
|
||||
Agent: c.Request.UserAgent(),
|
||||
Body: string(body),
|
||||
}
|
||||
now := time.Now()
|
||||
|
||||
c.Next()
|
||||
|
||||
latency := time.Since(now)
|
||||
status := c.Writer.Status()
|
||||
record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()
|
||||
str := "接收到的请求为" + record.Body + "\n" + "请求方式为" + record.Method + "\n" + "报错信息如下" + record.ErrorMessage + "\n" + "耗时" + latency.String() + "\n"
|
||||
if status != 200 {
|
||||
subject := username + "" + record.Ip + "调用了" + record.Path + "报错了"
|
||||
if err := utils.ErrorToEmail(subject, str); err != nil {
|
||||
global.GVA_LOG.Error("ErrorToEmail Failed, err:", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
|
||||
"looklook/admin/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// GinRecovery recover掉项目可能出现的panic,并使用zap记录相关日志
|
||||
func GinRecovery(stack bool) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
// Check for a broken connection, as it is not really a
|
||||
// condition that warrants a panic stack trace.
|
||||
var brokenPipe bool
|
||||
if ne, ok := err.(*net.OpError); ok {
|
||||
if se, ok := ne.Err.(*os.SyscallError); ok {
|
||||
if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
|
||||
brokenPipe = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
httpRequest, _ := httputil.DumpRequest(c.Request, false)
|
||||
if brokenPipe {
|
||||
global.GVA_LOG.Error(c.Request.URL.Path,
|
||||
zap.Any("error", err),
|
||||
zap.String("request", string(httpRequest)),
|
||||
)
|
||||
// If the connection is dead, we can't write a status to it.
|
||||
_ = c.Error(err.(error)) // nolint: errcheck
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
if stack {
|
||||
global.GVA_LOG.Error("[Recovery from panic]",
|
||||
zap.Any("error", err),
|
||||
zap.String("request", string(httpRequest)),
|
||||
zap.String("stack", string(debug.Stack())),
|
||||
)
|
||||
} else {
|
||||
global.GVA_LOG.Error("[Recovery from panic]",
|
||||
zap.Any("error", err),
|
||||
zap.String("request", string(httpRequest)),
|
||||
)
|
||||
}
|
||||
c.AbortWithStatus(http.StatusInternalServerError)
|
||||
}
|
||||
}()
|
||||
c.Next()
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"looklook/admin/utils"
|
||||
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"looklook/admin/model/system"
|
||||
"looklook/admin/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var jwtService = service.ServiceGroupApp.SystemServiceGroup.JwtService
|
||||
|
||||
func JWTAuth() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
|
||||
token := c.Request.Header.Get("x-token")
|
||||
if token == "" {
|
||||
response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
if jwtService.IsBlacklist(token) {
|
||||
response.FailWithDetailed(gin.H{"reload": true}, "您的帐户异地登陆或令牌失效", c)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
j := utils.NewJWT()
|
||||
// parseToken 解析token包含的信息
|
||||
claims, err := j.ParseToken(token)
|
||||
if err != nil {
|
||||
if err == utils.TokenExpired {
|
||||
response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
// 用户被删除的逻辑 需要优化 此处比较消耗性能 如果需要 请自行打开
|
||||
//if err, _ = userService.FindUserByUuid(claims.UUID.String()); err != nil {
|
||||
// _ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: token})
|
||||
// response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
|
||||
// c.Abort()
|
||||
//}
|
||||
if claims.ExpiresAt-time.Now().Unix() < claims.BufferTime {
|
||||
claims.ExpiresAt = time.Now().Unix() + global.GVA_CONFIG.JWT.ExpiresTime
|
||||
newToken, _ := j.CreateTokenByOldToken(token, *claims)
|
||||
newClaims, _ := j.ParseToken(newToken)
|
||||
c.Header("new-token", newToken)
|
||||
c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt, 10))
|
||||
if global.GVA_CONFIG.System.UseMultipoint {
|
||||
err, RedisJwtToken := jwtService.GetRedisJWT(newClaims.Username)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("get redis jwt failed", zap.Error(err))
|
||||
} else { // 当之前的取成功时才进行拉黑操作
|
||||
_ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: RedisJwtToken})
|
||||
}
|
||||
// 无论如何都要记录当前的活跃状态
|
||||
_ = jwtService.SetRedisJWT(newToken, newClaims.Username)
|
||||
}
|
||||
}
|
||||
c.Set("claims", claims)
|
||||
c.Next()
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type LimitConfig struct {
|
||||
// GenerationKey 根据业务生成key 下面CheckOrMark查询生成
|
||||
GenerationKey func(c *gin.Context) string
|
||||
// 检查函数,用户可修改具体逻辑,更加灵活
|
||||
CheckOrMark func(key string, expire int, limit int) error
|
||||
// Expire key 过期时间
|
||||
Expire int
|
||||
// Limit 周期时间
|
||||
Limit int
|
||||
}
|
||||
|
||||
func (l LimitConfig) LimitWithTime() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if err := l.CheckOrMark(l.GenerationKey(c), l.Expire, l.Limit); err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"code": response.ERROR, "msg": err})
|
||||
c.Abort()
|
||||
return
|
||||
} else {
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultGenerationKey 默认生成key
|
||||
func DefaultGenerationKey(c *gin.Context) string {
|
||||
return "GVA_Limit" + c.ClientIP()
|
||||
}
|
||||
|
||||
func DefaultCheckOrMark(key string, expire int, limit int) (err error) {
|
||||
// 判断是否开启redis
|
||||
if global.GVA_REDIS == nil {
|
||||
return err
|
||||
}
|
||||
if err = SetLimitWithTime(key, limit, time.Duration(expire)*time.Second); err != nil {
|
||||
global.GVA_LOG.Error("limit", zap.Error(err))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func DefaultLimit() gin.HandlerFunc {
|
||||
return LimitConfig{
|
||||
GenerationKey: DefaultGenerationKey,
|
||||
CheckOrMark: DefaultCheckOrMark,
|
||||
Expire: global.GVA_CONFIG.System.LimitTimeIP,
|
||||
Limit: global.GVA_CONFIG.System.LimitCountIP,
|
||||
}.LimitWithTime()
|
||||
}
|
||||
|
||||
// SetLimitWithTime 设置访问次数
|
||||
func SetLimitWithTime(key string, limit int, expiration time.Duration) error {
|
||||
count, err := global.GVA_REDIS.Exists(context.Background(), key).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count == 0 {
|
||||
pipe := global.GVA_REDIS.TxPipeline()
|
||||
pipe.Incr(context.Background(), key)
|
||||
pipe.Expire(context.Background(), key, expiration)
|
||||
_, err = pipe.Exec(context.Background())
|
||||
return err
|
||||
} else {
|
||||
// 次数
|
||||
if times, err := global.GVA_REDIS.Get(context.Background(), key).Int(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
if times >= limit {
|
||||
if t, err := global.GVA_REDIS.PTTL(context.Background(), key).Result(); err != nil {
|
||||
return errors.New("请求太过频繁,请稍后再试")
|
||||
} else {
|
||||
return errors.New("请求太过频繁, 请 " + t.String() + " 秒后尝试")
|
||||
}
|
||||
} else {
|
||||
return global.GVA_REDIS.Incr(context.Background(), key).Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/unrolled/secure"
|
||||
)
|
||||
|
||||
// 用https把这个中间件在router里面use一下就好
|
||||
|
||||
func LoadTls() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
middleware := secure.New(secure.Options{
|
||||
SSLRedirect: true,
|
||||
SSLHost: "localhost:443",
|
||||
})
|
||||
err := middleware.Process(c.Writer, c.Request)
|
||||
if err != nil {
|
||||
// 如果出现错误,请不要继续
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
// 继续往下处理
|
||||
c.Next()
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// LogLayout 日志layout
|
||||
type LogLayout struct {
|
||||
Time time.Time
|
||||
Metadata map[string]interface{} // 存储自定义原数据
|
||||
Path string // 访问路径
|
||||
Query string // 携带query
|
||||
Body string // 携带body数据
|
||||
IP string // ip地址
|
||||
UserAgent string // 代理
|
||||
Error string // 错误
|
||||
Cost time.Duration // 花费时间
|
||||
Source string // 来源
|
||||
}
|
||||
|
||||
type Logger struct {
|
||||
// Filter 用户自定义过滤
|
||||
Filter func(c *gin.Context) bool
|
||||
// FilterKeyword 关键字过滤(key)
|
||||
FilterKeyword func(layout *LogLayout) bool
|
||||
// AuthProcess 鉴权处理
|
||||
AuthProcess func(c *gin.Context, layout *LogLayout)
|
||||
// 日志处理
|
||||
Print func(LogLayout)
|
||||
// Source 服务唯一标识
|
||||
Source string
|
||||
}
|
||||
|
||||
func (l Logger) SetLoggerMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
start := time.Now()
|
||||
path := c.Request.URL.Path
|
||||
query := c.Request.URL.RawQuery
|
||||
var body []byte
|
||||
if l.Filter != nil && !l.Filter(c) {
|
||||
body, _ = c.GetRawData()
|
||||
// 将原body塞回去
|
||||
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
|
||||
}
|
||||
c.Next()
|
||||
cost := time.Since(start)
|
||||
layout := LogLayout{
|
||||
Time: time.Now(),
|
||||
Path: path,
|
||||
Query: query,
|
||||
IP: c.ClientIP(),
|
||||
UserAgent: c.Request.UserAgent(),
|
||||
Error: strings.TrimRight(c.Errors.ByType(gin.ErrorTypePrivate).String(), "\n"),
|
||||
Cost: cost,
|
||||
Source: l.Source,
|
||||
}
|
||||
if l.Filter != nil && !l.Filter(c) {
|
||||
layout.Body = string(body)
|
||||
}
|
||||
// 处理鉴权需要的信息
|
||||
l.AuthProcess(c, &layout)
|
||||
if l.FilterKeyword != nil {
|
||||
// 自行判断key/value 脱敏等
|
||||
l.FilterKeyword(&layout)
|
||||
}
|
||||
// 自行处理日志
|
||||
l.Print(layout)
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultLogger() gin.HandlerFunc {
|
||||
return Logger{
|
||||
Print: func(layout LogLayout) {
|
||||
// 标准输出,k8s做收集
|
||||
v, _ := json.Marshal(layout)
|
||||
fmt.Println(string(v))
|
||||
},
|
||||
Source: "GVA",
|
||||
}.SetLoggerMiddleware()
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/common/response"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 处理跨域请求,支持options访问
|
||||
func NeedInit() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if global.GVA_DB == nil {
|
||||
response.OkWithDetailed(gin.H{
|
||||
"needInit": true,
|
||||
}, "前往初始化数据库", c)
|
||||
c.Abort()
|
||||
} else {
|
||||
c.Next()
|
||||
}
|
||||
// 处理请求
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"looklook/admin/utils"
|
||||
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/system"
|
||||
"looklook/admin/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService
|
||||
|
||||
func OperationRecord() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var body []byte
|
||||
var userId int
|
||||
if c.Request.Method != http.MethodGet {
|
||||
var err error
|
||||
body, err = ioutil.ReadAll(c.Request.Body)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("read body from request error:", zap.Error(err))
|
||||
} else {
|
||||
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
|
||||
}
|
||||
}
|
||||
claims, _ := utils.GetClaims(c)
|
||||
if claims.ID != 0 {
|
||||
userId = int(claims.ID)
|
||||
} else {
|
||||
id, err := strconv.Atoi(c.Request.Header.Get("x-user-id"))
|
||||
if err != nil {
|
||||
userId = 0
|
||||
}
|
||||
userId = id
|
||||
}
|
||||
record := system.SysOperationRecord{
|
||||
Ip: c.ClientIP(),
|
||||
Method: c.Request.Method,
|
||||
Path: c.Request.URL.Path,
|
||||
Agent: c.Request.UserAgent(),
|
||||
Body: string(body),
|
||||
UserID: userId,
|
||||
}
|
||||
// 存在某些未知错误 TODO
|
||||
//values := c.Request.Header.Values("content-type")
|
||||
//if len(values) >0 && strings.Contains(values[0], "boundary") {
|
||||
// record.Body = "file"
|
||||
//}
|
||||
writer := responseBodyWriter{
|
||||
ResponseWriter: c.Writer,
|
||||
body: &bytes.Buffer{},
|
||||
}
|
||||
c.Writer = writer
|
||||
now := time.Now()
|
||||
|
||||
c.Next()
|
||||
|
||||
latency := time.Since(now)
|
||||
record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()
|
||||
record.Status = c.Writer.Status()
|
||||
record.Latency = latency
|
||||
record.Resp = writer.body.String()
|
||||
|
||||
if err := operationRecordService.CreateSysOperationRecord(record); err != nil {
|
||||
global.GVA_LOG.Error("create operation record error:", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type responseBodyWriter struct {
|
||||
gin.ResponseWriter
|
||||
body *bytes.Buffer
|
||||
}
|
||||
|
||||
func (r responseBodyWriter) Write(b []byte) (int, error) {
|
||||
r.body.Write(b)
|
||||
return r.ResponseWriter.Write(b)
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// 自动生成模板SysDictionaryDetail
|
||||
package autocode
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
)
|
||||
|
||||
// 如果含有time.Time 请自行import time包
|
||||
type AutoCodeExample struct {
|
||||
global.GVA_MODEL
|
||||
AutoCodeExampleField string `json:"autoCodeExampleField" form:"autoCodeExampleField" gorm:"column:auto_code_example_field;comment:仅作示例条目无实际作用"` // 展示值
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
// 自动生成模板SysDictionaryDetail
|
||||
package request
|
||||
|
||||
import (
|
||||
"looklook/admin/model/autocode"
|
||||
"looklook/admin/model/common/request"
|
||||
)
|
||||
|
||||
// 如果含有time.Time 请自行import time包
|
||||
type AutoCodeExampleSearch struct {
|
||||
autocode.AutoCodeExample
|
||||
request.PageInfo
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package request
|
||||
|
||||
type GetBanner struct{
|
||||
Id int64 `json:"id"`
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package response
|
||||
|
||||
type GetBanner struct{
|
||||
Id int64 `json:"id"`
|
||||
Title string `son:"title"`
|
||||
Forward string `json:"forward"`
|
||||
Img string `json:"img"`
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package request
|
||||
|
||||
// PageInfo Paging common input parameter structure
|
||||
type PageInfo struct {
|
||||
Page int `json:"page" form:"page"` // 页码
|
||||
PageSize int `json:"pageSize" form:"pageSize"` // 每页大小
|
||||
}
|
||||
|
||||
// GetById Find by id structure
|
||||
type GetById struct {
|
||||
ID float64 `json:"id" form:"id"` // 主键ID
|
||||
}
|
||||
|
||||
func (r *GetById) Uint() uint {
|
||||
return uint(r.ID)
|
||||
}
|
||||
|
||||
type IdsReq struct {
|
||||
Ids []int `json:"ids" form:"ids"`
|
||||
}
|
||||
|
||||
// GetAuthorityId Get role by id structure
|
||||
type GetAuthorityId struct {
|
||||
AuthorityId string `json:"authorityId" form:"authorityId"` // 角色ID
|
||||
}
|
||||
|
||||
type Empty struct{}
|
|
@ -1,8 +0,0 @@
|
|||
package response
|
||||
|
||||
type PageResult struct {
|
||||
List interface{} `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
package response
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Code int `json:"code"`
|
||||
Data interface{} `json:"data"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
const (
|
||||
ERROR = 7
|
||||
SUCCESS = 0
|
||||
)
|
||||
|
||||
func Result(code int, data interface{}, msg string, c *gin.Context) {
|
||||
// 开始时间
|
||||
c.JSON(http.StatusOK, Response{
|
||||
code,
|
||||
data,
|
||||
msg,
|
||||
})
|
||||
}
|
||||
|
||||
func Ok(c *gin.Context) {
|
||||
Result(SUCCESS, map[string]interface{}{}, "操作成功", c)
|
||||
}
|
||||
|
||||
func OkWithMessage(message string, c *gin.Context) {
|
||||
Result(SUCCESS, map[string]interface{}{}, message, c)
|
||||
}
|
||||
|
||||
func OkWithData(data interface{}, c *gin.Context) {
|
||||
Result(SUCCESS, data, "操作成功", c)
|
||||
}
|
||||
|
||||
func OkWithDetailed(data interface{}, message string, c *gin.Context) {
|
||||
Result(SUCCESS, data, message, c)
|
||||
}
|
||||
|
||||
func Fail(c *gin.Context) {
|
||||
Result(ERROR, map[string]interface{}{}, "操作失败", c)
|
||||
}
|
||||
|
||||
func FailWithMessage(message string, c *gin.Context) {
|
||||
Result(ERROR, map[string]interface{}{}, message, c)
|
||||
}
|
||||
|
||||
func FailWithDetailed(data interface{}, message string, c *gin.Context) {
|
||||
Result(ERROR, data, message, c)
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package example
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
)
|
||||
|
||||
// file struct, 文件结构体
|
||||
type ExaFile struct {
|
||||
global.GVA_MODEL
|
||||
FileName string
|
||||
FileMd5 string
|
||||
FilePath string
|
||||
ExaFileChunk []ExaFileChunk
|
||||
ChunkTotal int
|
||||
IsFinish bool
|
||||
}
|
||||
|
||||
// file chunk struct, 切片结构体
|
||||
type ExaFileChunk struct {
|
||||
global.GVA_MODEL
|
||||
ExaFileID uint
|
||||
FileChunkNumber int
|
||||
FileChunkPath string
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package example
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
"looklook/admin/model/system"
|
||||
)
|
||||
|
||||
type ExaCustomer struct {
|
||||
global.GVA_MODEL
|
||||
CustomerName string `json:"customerName" form:"customerName" gorm:"comment:客户名"` // 客户名
|
||||
CustomerPhoneData string `json:"customerPhoneData" form:"customerPhoneData" gorm:"comment:客户手机号"` // 客户手机号
|
||||
SysUserID uint `json:"sysUserId" form:"sysUserId" gorm:"comment:管理ID"` // 管理ID
|
||||
SysUserAuthorityID string `json:"sysUserAuthorityID" form:"sysUserAuthorityID" gorm:"comment:管理角色ID"` // 管理角色ID
|
||||
SysUser system.SysUser `json:"sysUser" form:"sysUser" gorm:"comment:管理详情"` // 管理详情
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package example
|
||||
|
||||
import "looklook/admin/model/system"
|
||||
|
||||
type ExcelInfo struct {
|
||||
FileName string `json:"fileName"` // 文件名
|
||||
InfoList []system.SysBaseMenu `json:"infoList"`
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package example
|
||||
|
||||
import (
|
||||
"looklook/admin/global"
|
||||
)
|
||||
|
||||
type ExaFileUploadAndDownload struct {
|
||||
global.GVA_MODEL
|
||||
Name string `json:"name" gorm:"comment:文件名"` // 文件名
|
||||
Url string `json:"url" gorm:"comment:文件地址"` // 文件地址
|
||||
Tag string `json:"tag" gorm:"comment:文件标签"` // 文件标签
|
||||
Key string `json:"key" gorm:"comment:编号"` // 编号
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package response
|
||||
|
||||
import "looklook/admin/model/example"
|
||||
|
||||
type FilePathResponse struct {
|
||||
FilePath string `json:"filePath"`
|
||||
}
|
||||
|
||||
type FileResponse struct {
|
||||
File example.ExaFile `json:"file"`
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package response
|
||||
|
||||
import "looklook/admin/model/example"
|
||||
|
||||
type ExaCustomerResponse struct {
|
||||
Customer example.ExaCustomer `json:"customer"`
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue