493 changed files with 78731 additions and 0 deletions
@ -0,0 +1,76 @@ |
|||
# Contributor Covenant Code of Conduct |
|||
|
|||
## Our Pledge |
|||
|
|||
In the interest of fostering an open and welcoming environment, we as |
|||
contributors and maintainers pledge to making participation in our project and |
|||
our community a harassment-free experience for everyone, regardless of age, body |
|||
size, disability, ethnicity, sex characteristics, gender identity and expression, |
|||
level of experience, education, socio-economic status, nationality, personal |
|||
appearance, race, religion, or sexual identity and orientation. |
|||
|
|||
## Our Standards |
|||
|
|||
Examples of behavior that contributes to creating a positive environment |
|||
include: |
|||
|
|||
* Using welcoming and inclusive language |
|||
* Being respectful of differing viewpoints and experiences |
|||
* Gracefully accepting constructive criticism |
|||
* Focusing on what is best for the community |
|||
* Showing empathy towards other community members |
|||
|
|||
Examples of unacceptable behavior by participants include: |
|||
|
|||
* The use of sexualized language or imagery and unwelcome sexual attention or |
|||
advances |
|||
* Trolling, insulting/derogatory comments, and personal or political attacks |
|||
* Public or private harassment |
|||
* Publishing others' private information, such as a physical or electronic |
|||
address, without explicit permission |
|||
* Other conduct which could reasonably be considered inappropriate in a |
|||
professional setting |
|||
|
|||
## Our Responsibilities |
|||
|
|||
Project maintainers are responsible for clarifying the standards of acceptable |
|||
behavior and are expected to take appropriate and fair corrective action in |
|||
response to any instances of unacceptable behavior. |
|||
|
|||
Project maintainers have the right and responsibility to remove, edit, or |
|||
reject comments, commits, code, wiki edits, issues, and other contributions |
|||
that are not aligned to this Code of Conduct, or to ban temporarily or |
|||
permanently any contributor for other behaviors that they deem inappropriate, |
|||
threatening, offensive, or harmful. |
|||
|
|||
## Scope |
|||
|
|||
This Code of Conduct applies both within project spaces and in public spaces |
|||
when an individual is representing the project or its community. Examples of |
|||
representing a project or community include using an official project e-mail |
|||
address, posting via an official social media account, or acting as an appointed |
|||
representative at an online or offline event. Representation of a project may be |
|||
further defined and clarified by project maintainers. |
|||
|
|||
## Enforcement |
|||
|
|||
Instances of abusive, harassing, or otherwise unacceptable behavior may be |
|||
reported by contacting the project team at 303176530@qq.com. All |
|||
complaints will be reviewed and investigated and will result in a response that |
|||
is deemed necessary and appropriate to the circumstances. The project team is |
|||
obligated to maintain confidentiality with regard to the reporter of an incident. |
|||
Further details of specific enforcement policies may be posted separately. |
|||
|
|||
Project maintainers who do not follow or enforce the Code of Conduct in good |
|||
faith may face temporary or permanent repercussions as determined by other |
|||
members of the project's leadership. |
|||
|
|||
## Attribution |
|||
|
|||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, |
|||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html |
|||
|
|||
[homepage]: https://www.contributor-covenant.org |
|||
|
|||
For answers to common questions about this code of conduct, see |
|||
https://www.contributor-covenant.org/faq |
|||
@ -0,0 +1,19 @@ |
|||
|
|||
### Contributing Guide |
|||
#### 1 Issue Guidelines |
|||
|
|||
- Issues are exclusively for bug reports, feature requests and design-related topics. Other questions may be closed directly. If any questions come up when you are using Element, please hit [Gitter](https://gitter.im/element-en/Lobby) for help. |
|||
|
|||
- Before submitting an issue, please check if similar problems have already been issued. |
|||
|
|||
#### 2 Pull Request Guidelines |
|||
|
|||
- Fork this repository to your own account. Do not create branches here. |
|||
|
|||
- Commit info should be formatted as `[File Name]: Info about commit.` (e.g. `README.md: Fix xxx bug`) |
|||
|
|||
- <font color=red>Make sure PRs are created to `develop` branch instead of `master` branch.</font> |
|||
|
|||
- If your PR fixes a bug, please provide a description about the related bug. |
|||
|
|||
- Merging a PR takes two maintainers: one approves the changes after reviewing, and then the other reviews and merges. |
|||
@ -0,0 +1,5 @@ |
|||
# Security Policy |
|||
|
|||
## Reporting a Vulnerability |
|||
|
|||
Please report security issues to qimiaojiangjizhao@gmail.com |
|||
@ -0,0 +1,148 @@ |
|||
apiVersion: v1 |
|||
kind: ConfigMap |
|||
metadata: |
|||
name: config.yaml |
|||
annotations: |
|||
flipped-aurora/gin-vue-admin: backend |
|||
github: "https://github.com/flipped-aurora/gin-vue-admin.git" |
|||
app.kubernetes.io/version: 0.0.1 |
|||
labels: |
|||
app: gva-server |
|||
version: gva-vue3 |
|||
data: |
|||
config.yaml: | |
|||
# github.com/flipped-aurora/gin-vue-admin/server Global Configuration |
|||
|
|||
# jwt configuration |
|||
jwt: |
|||
signing-key: 'qmPlus' |
|||
expires-time: 604800 |
|||
buffer-time: 86400 |
|||
|
|||
# zap logger configuration |
|||
zap: |
|||
level: 'info' |
|||
format: 'console' |
|||
prefix: '[github.com/flipped-aurora/gin-vue-admin/server]' |
|||
director: 'log' |
|||
link-name: 'latest_log' |
|||
show-line: true |
|||
encode-level: 'LowercaseColorLevelEncoder' |
|||
stacktrace-key: 'stacktrace' |
|||
log-in-console: true |
|||
|
|||
# redis configuration |
|||
redis: |
|||
db: 0 |
|||
addr: '127.0.0.1:6379' |
|||
password: '' |
|||
|
|||
# email configuration |
|||
email: |
|||
to: 'xxx@qq.com' |
|||
port: 465 |
|||
from: 'xxx@163.com' |
|||
host: 'smtp.163.com' |
|||
is-ssl: true |
|||
secret: 'xxx' |
|||
nickname: 'test' |
|||
|
|||
# casbin configuration |
|||
casbin: |
|||
model-path: './resource/rbac_model.conf' |
|||
|
|||
# system configuration |
|||
system: |
|||
env: 'develop' # Change to "develop" to skip authentication for development mode |
|||
addr: 8888 |
|||
db-type: 'mysql' |
|||
oss-type: 'local' # 控制oss选择走本期还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置 |
|||
use-multipoint: false |
|||
|
|||
# captcha configuration |
|||
captcha: |
|||
key-long: 6 |
|||
img-width: 240 |
|||
img-height: 80 |
|||
|
|||
# mysql connect configuration |
|||
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://www.github.com/flipped-aurora/gin-vue-admin/server.com/docs/first) |
|||
mysql: |
|||
path: '' |
|||
config: '' |
|||
db-name: '' |
|||
username: '' |
|||
password: '' |
|||
max-idle-conns: 10 |
|||
max-open-conns: 100 |
|||
log-mode: false |
|||
log-zap: "" |
|||
|
|||
# local configuration |
|||
local: |
|||
path: 'uploads/file' |
|||
|
|||
# autocode configuration |
|||
autocode: |
|||
transfer-restart: true |
|||
root: "" |
|||
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-flow: /view |
|||
web-form: /view |
|||
web-table: /view |
|||
|
|||
# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址) |
|||
qiniu: |
|||
zone: 'ZoneHuaDong' |
|||
bucket: '' |
|||
img-path: '' |
|||
use-https: false |
|||
access-key: '' |
|||
secret-key: '' |
|||
use-cdn-domains: false |
|||
|
|||
|
|||
# aliyun oss configuration |
|||
aliyun-oss: |
|||
endpoint: 'yourEndpoint' |
|||
access-key-id: 'yourAccessKeyId' |
|||
access-key-secret: 'yourAccessKeySecret' |
|||
bucket-name: 'yourBucketName' |
|||
bucket-url: 'yourBucketUrl' |
|||
base-path: 'yourBasePath' |
|||
|
|||
# tencent cos configuration |
|||
tencent-cos: |
|||
bucket: 'xxxxx-10005608' |
|||
region: 'ap-shanghai' |
|||
secret-id: 'xxxxxxxx' |
|||
secret-key: 'xxxxxxxx' |
|||
base-url: 'https://gin.vue.admin' |
|||
path-prefix: 'github.com/flipped-aurora/gin-vue-admin/server' |
|||
|
|||
# excel configuration |
|||
excel: |
|||
dir: './resource/excel/' |
|||
|
|||
|
|||
# timer task db clear table |
|||
Timer: |
|||
start: true |
|||
spec: "@daily" # 定时任务详细配置参考 https://pkg.go.dev/github.com/robfig/cron/v3 |
|||
detail: [ |
|||
# tableName: 需要清理的表名 |
|||
# compareField: 需要比较时间的字段 |
|||
# interval: 时间间隔, 具体配置详看 time.ParseDuration() 中字符串表示 且不能为负数 |
|||
# 2160h = 24 * 30 * 3 -> 三个月 |
|||
{ tableName: "sys_operation_records" , compareField: "created_at", interval: "2160h" }, |
|||
{ tableName: "jwt_blacklists" , compareField: "created_at", interval: "168h" } |
|||
#{ tableName: "log2" , compareField: "created_at", interval: "2160h" } |
|||
] |
|||
@ -0,0 +1,68 @@ |
|||
apiVersion: apps/v1 |
|||
kind: Deployment |
|||
metadata: |
|||
name: gva-server |
|||
annotations: |
|||
flipped-aurora/gin-vue-admin: backend |
|||
github: "https://github.com/flipped-aurora/gin-vue-admin.git" |
|||
app.kubernetes.io/version: 0.0.1 |
|||
labels: |
|||
app: gva-server |
|||
version: gva-vue3 |
|||
spec: |
|||
replicas: 1 |
|||
selector: |
|||
matchLabels: |
|||
app: gva-server |
|||
version: gva-vue3 |
|||
template: |
|||
metadata: |
|||
labels: |
|||
app: gva-server |
|||
version: gva-vue3 |
|||
spec: |
|||
containers: |
|||
- name: gin-vue-admin-container |
|||
image: registry.cn-hangzhou.aliyuncs.com/gin-vue-admin/server:40fc3aa6 |
|||
imagePullPolicy: IfNotPresent |
|||
ports: |
|||
- containerPort: 8888 |
|||
name: http |
|||
volumeMounts: |
|||
- mountPath: /go/src/github.com/flipped-aurora/gin-vue-admin/server/config.yaml |
|||
name: config |
|||
subPath: config.yaml |
|||
- mountPath: /etc/localtime |
|||
name: localtime |
|||
resources: |
|||
limits: |
|||
cpu: 1000m |
|||
memory: 2000Mi |
|||
requests: |
|||
cpu: 100m |
|||
memory: 200Mi |
|||
# readinessProbe: |
|||
# httpGet: |
|||
# path: /ready |
|||
# port: http |
|||
# initialDelaySeconds: 20 |
|||
# periodSeconds: 10 |
|||
# successThreshold: 1 |
|||
# failureThreshold: 3 |
|||
# livenessProbe: |
|||
# httpGet: |
|||
# path: /health |
|||
# port: http |
|||
# initialDelaySeconds: 20 |
|||
# periodSeconds: 10 |
|||
# successThreshold: 1 |
|||
# failureThreshold: 3 |
|||
#imagePullSecrets: |
|||
# - name: docker-registry |
|||
volumes: |
|||
- name: localtime |
|||
hostPath: |
|||
path: /etc/localtime |
|||
- name: config |
|||
configMap: |
|||
name: config.yaml |
|||
@ -0,0 +1,21 @@ |
|||
apiVersion: v1 |
|||
kind: Service |
|||
metadata: |
|||
name: gva-server |
|||
annotations: |
|||
flipped-aurora/gin-vue-admin: backend |
|||
github: "https://github.com/flipped-aurora/gin-vue-admin.git" |
|||
app.kubernetes.io/version: 0.0.1 |
|||
labels: |
|||
app: gva-server |
|||
version: gva-vue3 |
|||
spec: |
|||
selector: |
|||
app: gva-server |
|||
version: gva-vue3 |
|||
ports: |
|||
- port: 8888 |
|||
name: http |
|||
targetPort: 8888 |
|||
type: ClusterIP |
|||
# type: NodePort |
|||
@ -0,0 +1,32 @@ |
|||
apiVersion: v1 |
|||
kind: ConfigMap |
|||
metadata: |
|||
name: my.conf |
|||
data: |
|||
my.conf: | |
|||
server { |
|||
listen 8080; |
|||
server_name localhost; |
|||
|
|||
#charset koi8-r; |
|||
#access_log logs/host.access.log main; |
|||
|
|||
location / { |
|||
root /usr/share/nginx/html; |
|||
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; |
|||
try_files $uri $uri/ /index.html; |
|||
} |
|||
|
|||
location /api { |
|||
proxy_set_header Host $http_host; |
|||
proxy_set_header X-Real-IP $remote_addr; |
|||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
|||
proxy_set_header X-Forwarded-Proto $scheme; |
|||
rewrite ^/api/(.*)$ /$1 break; #重写 |
|||
proxy_pass http://gva-server:8888; # 设置代理服务器的协议和地址 |
|||
} |
|||
|
|||
location /api/swagger/index.html { |
|||
proxy_pass http://gva-server:8888/swagger/index.html; |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
apiVersion: apps/v1 |
|||
kind: Deployment |
|||
metadata: |
|||
name: gva-web |
|||
annotations: |
|||
flipped-aurora/gin-vue-admin: ui |
|||
github: "https://github.com/flipped-aurora/gin-vue-admin.git" |
|||
app.kubernetes.io/version: 0.0.1 |
|||
labels: |
|||
app: gva-web |
|||
version: gva-vue3 |
|||
spec: |
|||
replicas: 1 |
|||
selector: |
|||
matchLabels: |
|||
app: gva-web |
|||
version: gva-vue3 |
|||
template: |
|||
metadata: |
|||
labels: |
|||
app: gva-web |
|||
version: gva-vue3 |
|||
spec: |
|||
containers: |
|||
- name: gin-vue-admin-nginx-container |
|||
image: registry.cn-hangzhou.aliyuncs.com/gin-vue-admin/web:40fc3aa6 |
|||
imagePullPolicy: IfNotPresent |
|||
ports: |
|||
- containerPort: 8080 |
|||
name: http |
|||
readinessProbe: |
|||
tcpSocket: |
|||
port: 8080 |
|||
initialDelaySeconds: 10 |
|||
periodSeconds: 10 |
|||
successThreshold: 1 |
|||
failureThreshold: 3 |
|||
resources: |
|||
limits: |
|||
cpu: 500m |
|||
memory: 1000Mi |
|||
requests: |
|||
cpu: 100m |
|||
memory: 100Mi |
|||
volumeMounts: |
|||
- mountPath: /etc/nginx/conf.d/ |
|||
name: nginx-config |
|||
volumes: |
|||
- name: nginx-config |
|||
configMap: |
|||
name: my.conf |
|||
@ -0,0 +1,21 @@ |
|||
apiVersion: v1 |
|||
kind: Service |
|||
metadata: |
|||
name: gva-web |
|||
annotations: |
|||
flipped-aurora/gin-vue-admin: ui |
|||
github: "https://github.com/flipped-aurora/gin-vue-admin.git" |
|||
app.kubernetes.io/version: 0.0.1 |
|||
labels: |
|||
app: gva-web |
|||
version: gva-vue3 |
|||
spec: |
|||
type: NodePort |
|||
# type: ClusterIP |
|||
ports: |
|||
- name: http |
|||
port: 8080 |
|||
targetPort: 8080 |
|||
selector: |
|||
app: gva-web |
|||
version: gva-vue3 |
|||
@ -0,0 +1,66 @@ |
|||
version: "3" |
|||
|
|||
networks: |
|||
network: |
|||
ipam: |
|||
driver: default |
|||
config: |
|||
- subnet: '177.7.0.0/16' |
|||
|
|||
services: |
|||
web: |
|||
build: |
|||
context: ./web |
|||
dockerfile: ./Dockerfile |
|||
container_name: gva-web |
|||
restart: always |
|||
ports: |
|||
- '8080:8080' |
|||
depends_on: |
|||
- server |
|||
command: [ 'nginx-debug', '-g', 'daemon off;' ] |
|||
networks: |
|||
network: |
|||
ipv4_address: 177.7.0.11 |
|||
|
|||
server: |
|||
build: |
|||
context: ./server |
|||
dockerfile: ./Dockerfile |
|||
container_name: gva-server |
|||
restart: always |
|||
ports: |
|||
- '8888:8888' |
|||
depends_on: |
|||
- mysql |
|||
- redis |
|||
links: |
|||
- mysql |
|||
- redis |
|||
networks: |
|||
network: |
|||
ipv4_address: 177.7.0.12 |
|||
|
|||
mysql: |
|||
image: mysql:8.0.21 |
|||
container_name: gva-mysql |
|||
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci #设置utf8字符集 |
|||
restart: always |
|||
ports: |
|||
- "13306:3306" # host物理直接映射端口为13306 |
|||
environment: |
|||
MYSQL_DATABASE: 'qmPlus' # 初始化启动时要创建的数据库的名称 |
|||
MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码 |
|||
networks: |
|||
network: |
|||
ipv4_address: 177.7.0.13 |
|||
|
|||
redis: |
|||
image: redis:6.0.6 |
|||
container_name: gva-redis # 容器名 |
|||
restart: always |
|||
ports: |
|||
- '16379:6379' |
|||
networks: |
|||
network: |
|||
ipv4_address: 177.7.0.14 |
|||
|
After Width: | Height: | Size: 103 KiB |
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project version="4"> |
|||
<component name="JavaScriptSettings"> |
|||
<option name="languageLevel" value="ES6" /> |
|||
</component> |
|||
</project> |
|||
@ -0,0 +1,8 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project version="4"> |
|||
<component name="ProjectModuleManager"> |
|||
<modules> |
|||
<module fileurl="file://$PROJECT_DIR$/.idea/server.iml" filepath="$PROJECT_DIR$/.idea/server.iml" /> |
|||
</modules> |
|||
</component> |
|||
</project> |
|||
@ -0,0 +1,8 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<module type="WEB_MODULE" version="4"> |
|||
<component name="NewModuleRootManager"> |
|||
<content url="file://$MODULE_DIR$" /> |
|||
<orderEntry type="inheritedJdk" /> |
|||
<orderEntry type="sourceFolder" forTests="false" /> |
|||
</component> |
|||
</module> |
|||
@ -0,0 +1,60 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project version="4"> |
|||
<component name="ChangeListManager"> |
|||
<list default="true" id="5a82fb5a-4b86-499f-8d7e-0122e722e2fe" name="默认更改列表" comment="" /> |
|||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> |
|||
<option name="SHOW_DIALOG" value="false" /> |
|||
<option name="HIGHLIGHT_CONFLICTS" value="true" /> |
|||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> |
|||
<option name="LAST_RESOLUTION" value="IGNORE" /> |
|||
</component> |
|||
<component name="GOROOT" path="L:\任官钰\go\go1.16.8" /> |
|||
<component name="GoLibraries"> |
|||
<option name="indexEntireGoPath" value="false" /> |
|||
</component> |
|||
<component name="ProjectId" id="2072qohkIMKCHF0ii2Su1uR8xQn" /> |
|||
<component name="PropertiesComponent"> |
|||
<property name="WebServerToolWindowFactoryState" value="false" /> |
|||
<property name="configurable.Global.GOPATH.is.expanded" value="true" /> |
|||
<property name="configurable.Module.GOPATH.is.expanded" value="false" /> |
|||
<property name="configurable.Project.GOPATH.is.expanded" value="true" /> |
|||
<property name="go.import.settings.migrated" value="true" /> |
|||
<property name="go.tried.to.enable.integration.vgo.integrator" value="true" /> |
|||
<property name="last_opened_file_path" value="$PROJECT_DIR$" /> |
|||
<property name="settings.editor.selected.configurable" value="go.vgo" /> |
|||
</component> |
|||
<component name="RunDashboard"> |
|||
<option name="ruleStates"> |
|||
<list> |
|||
<RuleState> |
|||
<option name="name" value="ConfigurationTypeDashboardGroupingRule" /> |
|||
</RuleState> |
|||
<RuleState> |
|||
<option name="name" value="StatusDashboardGroupingRule" /> |
|||
</RuleState> |
|||
</list> |
|||
</option> |
|||
</component> |
|||
<component name="RunManager"> |
|||
<configuration name="go build main.go" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true"> |
|||
<module name="server" /> |
|||
<working_directory value="$PROJECT_DIR$" /> |
|||
<kind value="FILE" /> |
|||
<filePath value="$PROJECT_DIR$/main.go" /> |
|||
<directory value="$PROJECT_DIR$/" /> |
|||
<method v="2" /> |
|||
</configuration> |
|||
<recent_temporary> |
|||
<list> |
|||
<item itemvalue="Go Build.go build main.go" /> |
|||
</list> |
|||
</recent_temporary> |
|||
</component> |
|||
<component name="TypeScriptGeneratedFilesManager"> |
|||
<option name="version" value="1" /> |
|||
</component> |
|||
<component name="VgoProject"> |
|||
<integration-enabled>true</integration-enabled> |
|||
<proxy>GOPROXY=https://mirrors.aliyun.com/goproxy/</proxy> |
|||
</component> |
|||
</project> |
|||
@ -0,0 +1,22 @@ |
|||
FROM golang:alpine as builder |
|||
|
|||
WORKDIR /go/src/github.com/flipped-aurora/gin-vue-admin/server |
|||
COPY . . |
|||
|
|||
RUN go env -w GO111MODULE=on |
|||
RUN go env -w GOPROXY=https://goproxy.cn,direct |
|||
RUN go env -w CGO_ENABLED=0 |
|||
RUN go env |
|||
RUN go mod tidy |
|||
RUN go build -o server . |
|||
|
|||
FROM alpine:latest |
|||
LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com" |
|||
|
|||
WORKDIR /go/src/github.com/flipped-aurora/gin-vue-admin/server |
|||
|
|||
COPY --from=0 /go/src/github.com/flipped-aurora/gin-vue-admin/server ./ |
|||
|
|||
EXPOSE 8888 |
|||
|
|||
ENTRYPOINT ./server -c config.docker.yaml |
|||
@ -0,0 +1,54 @@ |
|||
## server项目结构 |
|||
|
|||
```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接口封装 | |
|||
|
|||
@ -0,0 +1,121 @@ |
|||
package autocode |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/autocode" |
|||
autocodeReq "github.com/flipped-aurora/gin-vue-admin/server/model/autocode/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/service" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(response.PageResult{ |
|||
List: list, |
|||
Total: total, |
|||
Page: pageInfo.Page, |
|||
PageSize: pageInfo.PageSize, |
|||
}, "获取成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
package autocode |
|||
|
|||
type ApiGroup struct { |
|||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server Begin; DO NOT EDIT.
|
|||
AutoCodeExampleApi |
|||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server End; DO NOT EDIT.
|
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
package v1 |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/api/v1/autocode" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/api/v1/example" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/api/v1/system" |
|||
) |
|||
|
|||
type ApiGroup struct { |
|||
ExampleApiGroup example.ApiGroup |
|||
SystemApiGroup system.ApiGroup |
|||
AutoCodeApiGroup autocode.ApiGroup |
|||
} |
|||
|
|||
var ApiGroupApp = new(ApiGroup) |
|||
@ -0,0 +1,13 @@ |
|||
package example |
|||
|
|||
import "github.com/flipped-aurora/gin-vue-admin/server/service" |
|||
|
|||
type ApiGroup struct { |
|||
CustomerApi |
|||
ExcelApi |
|||
FileUploadAndDownloadApi |
|||
} |
|||
|
|||
var fileUploadAndDownloadService = service.ServiceGroupApp.ExampleServiceGroup.FileUploadAndDownloadService |
|||
var customerService = service.ServiceGroupApp.ExampleServiceGroup.CustomerService |
|||
var excelService = service.ServiceGroupApp.ExampleServiceGroup.ExcelService |
|||
@ -0,0 +1,140 @@ |
|||
package example |
|||
|
|||
import ( |
|||
"fmt" |
|||
"io/ioutil" |
|||
"mime/multipart" |
|||
"strconv" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
exampleRes "github.com/flipped-aurora/gin-vue-admin/server/model/example/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"切片创建成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("接收文件失败", c) |
|||
return |
|||
} |
|||
f, err := FileHeader.Open() |
|||
if err != nil { |
|||
global.GVA_LOG.Error("文件读取失败!", zap.Any("err", 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.Any("err", err)) |
|||
response.FailWithMessage("检查md5失败", c) |
|||
return |
|||
} |
|||
err, file := fileUploadAndDownloadService.FindOrCreateFile(fileMd5, fileName, chunkTotal) |
|||
if err != nil { |
|||
global.GVA_LOG.Error("查找或创建记录失败!", zap.Any("err", err)) |
|||
response.FailWithMessage("查找或创建记录失败", c) |
|||
return |
|||
} |
|||
err, pathc := utils.BreakPointContinue(cen, fileName, chunkNumber, chunkTotal, fileMd5) |
|||
if err != nil { |
|||
global.GVA_LOG.Error("断点续传失败!", zap.Any("err", err)) |
|||
response.FailWithMessage("断点续传失败", c) |
|||
return |
|||
} |
|||
|
|||
if err = fileUploadAndDownloadService.CreateFileChunk(file.ID, pathc, chunkNumber); err != nil { |
|||
global.GVA_LOG.Error("创建文件记录失败!", zap.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"查找成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"file uploaded, 文件创建成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"缓存切片删除成功"}"
|
|||
// @Router /fileUploadAndDownload/removeChunk [post]
|
|||
func (u *FileUploadAndDownloadApi) RemoveChunk(c *gin.Context) { |
|||
fileMd5 := c.Query("fileMd5") |
|||
fileName := c.Query("fileName") |
|||
filePath := c.Query("filePath") |
|||
err := utils.RemoveChunk(fileMd5) |
|||
if err != nil { |
|||
return |
|||
} |
|||
err = fileUploadAndDownloadService.DeleteFileChunk(fileMd5, fileName, filePath) |
|||
if err != nil { |
|||
global.GVA_LOG.Error("缓存切片删除失败!", zap.Any("err", err)) |
|||
response.FailWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "缓存切片删除失败", c) |
|||
} else { |
|||
response.OkWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "缓存切片删除成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,143 @@ |
|||
package example |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/example" |
|||
exampleRes "github.com/flipped-aurora/gin-vue-admin/server/model/example/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("获取失败"+err.Error(), c) |
|||
} else { |
|||
response.OkWithDetailed(response.PageResult{ |
|||
List: customerList, |
|||
Total: total, |
|||
Page: pageInfo.Page, |
|||
PageSize: pageInfo.PageSize, |
|||
}, "获取成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,101 @@ |
|||
package example |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/example" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"导入成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"加载数据成功"}"
|
|||
// @Router /excel/loadExcel [get]
|
|||
func (e *ExcelApi) LoadExcel(c *gin.Context) { |
|||
menus, err := excelService.ParseExcel2InfoList() |
|||
if err != nil { |
|||
global.GVA_LOG.Error("加载数据失败!", zap.Any("err", 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.Any("err", err)) |
|||
response.FailWithMessage("文件不存在", c) |
|||
return |
|||
} |
|||
c.Writer.Header().Add("success", "true") |
|||
c.File(filePath) |
|||
} |
|||
@ -0,0 +1,83 @@ |
|||
package example |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/example" |
|||
exampleRes "github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"上传成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("接收文件失败", c) |
|||
return |
|||
} |
|||
err, file = fileUploadAndDownloadService.UploadFile(header, noSave) // 文件上传后拿到文件路径
|
|||
if err != nil { |
|||
global.GVA_LOG.Error("修改数据库链接失败!", zap.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(response.PageResult{ |
|||
List: list, |
|||
Total: total, |
|||
Page: pageInfo.Page, |
|||
PageSize: pageInfo.PageSize, |
|||
}, "获取成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
package system |
|||
|
|||
import "github.com/flipped-aurora/gin-vue-admin/server/service" |
|||
|
|||
type ApiGroup struct { |
|||
SystemApiApi |
|||
AuthorityApi |
|||
AutoCodeApi |
|||
BaseApi |
|||
CasbinApi |
|||
DictionaryApi |
|||
DictionaryDetailApi |
|||
SystemApi |
|||
DBApi |
|||
JwtApi |
|||
OperationRecordApi |
|||
AuthorityMenuApi |
|||
} |
|||
|
|||
var authorityService = service.ServiceGroupApp.SystemServiceGroup.AuthorityService |
|||
var apiService = service.ServiceGroupApp.SystemServiceGroup.ApiService |
|||
var menuService = service.ServiceGroupApp.SystemServiceGroup.MenuService |
|||
var casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService |
|||
var autoCodeService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeService |
|||
var autoCodeHistoryService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeHistoryService |
|||
var dictionaryService = service.ServiceGroupApp.SystemServiceGroup.DictionaryService |
|||
var dictionaryDetailService = service.ServiceGroupApp.SystemServiceGroup.DictionaryDetailService |
|||
var initDBService = service.ServiceGroupApp.SystemServiceGroup.InitDBService |
|||
var jwtService = service.ServiceGroupApp.SystemServiceGroup.JwtService |
|||
var baseMenuService = service.ServiceGroupApp.SystemServiceGroup.BaseMenuService |
|||
var operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService |
|||
var userService = service.ServiceGroupApp.SystemServiceGroup.UserService |
|||
var systemConfigService = service.ServiceGroupApp.SystemServiceGroup.SystemConfigService |
|||
@ -0,0 +1,173 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" |
|||
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(response.PageResult{ |
|||
List: list, |
|||
Total: total, |
|||
Page: pageInfo.Page, |
|||
PageSize: pageInfo.PageSize, |
|||
}, "获取成功", c) |
|||
} |
|||
} |
|||
|
|||
// @Tags SysApi
|
|||
// @Summary 根据id获取api
|
|||
// @Security ApiKeyAuth
|
|||
// @accept application/json
|
|||
// @Produce application/json
|
|||
// @Param data body request.GetById true "根据id获取api"
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("修改失败", c) |
|||
} else { |
|||
response.OkWithMessage("修改成功", c) |
|||
} |
|||
} |
|||
|
|||
// @Tags SysApi
|
|||
// @Summary 获取所有的Api 不分页
|
|||
// @Security ApiKeyAuth
|
|||
// @accept application/json
|
|||
// @Produce application/json
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @Router /api/getAllApis [post]
|
|||
func (s *SystemApiApi) GetAllApis(c *gin.Context) { |
|||
if err, apis := apiService.GetAllApis(); err != nil { |
|||
global.GVA_LOG.Error("获取失败!", zap.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("删除失败", c) |
|||
} else { |
|||
response.OkWithMessage("删除成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,166 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" |
|||
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"拷贝成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("设置失败"+err.Error(), c) |
|||
} else { |
|||
response.OkWithMessage("设置成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,224 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"errors" |
|||
"fmt" |
|||
"net/url" |
|||
"os" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/utils" |
|||
|
|||
"github.com/gin-gonic/gin" |
|||
"go.uber.org/zap" |
|||
) |
|||
|
|||
type AutoCodeApi struct { |
|||
} |
|||
|
|||
// @Tags AutoCode
|
|||
// @Summary 删除回滚记录
|
|||
// @Security ApiKeyAuth
|
|||
// @accept application/json
|
|||
// @Produce application/json
|
|||
// @Param data body systemReq.AutoHistoryByID true "删除回滚记录"
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @Router /autoCode/delSysHistory [post]
|
|||
func (autoApi *AutoCodeApi) DelSysHistory(c *gin.Context) { |
|||
var id systemReq.AutoHistoryByID |
|||
_ = c.ShouldBindJSON(&id) |
|||
err := autoCodeHistoryService.DeletePage(id.ID) |
|||
if err != nil { |
|||
global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} |
|||
response.OkWithMessage("删除成功", c) |
|||
|
|||
} |
|||
|
|||
// @Tags AutoCode
|
|||
// @Summary 查询回滚记录
|
|||
// @Security ApiKeyAuth
|
|||
// @accept application/json
|
|||
// @Produce application/json
|
|||
// @Param data body systemReq.SysAutoHistory true "查询回滚记录"
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @Router /autoCode/getSysHistory [post]
|
|||
func (autoApi *AutoCodeApi) GetSysHistory(c *gin.Context) { |
|||
var search systemReq.SysAutoHistory |
|||
_ = c.ShouldBindJSON(&search) |
|||
err, list, total := autoCodeHistoryService.GetSysHistoryPage(search.PageInfo) |
|||
if err != nil { |
|||
global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(response.PageResult{ |
|||
List: list, |
|||
Total: total, |
|||
Page: search.Page, |
|||
PageSize: search.PageSize, |
|||
}, "获取成功", c) |
|||
} |
|||
} |
|||
|
|||
// @Tags AutoCode
|
|||
// @Summary 回滚
|
|||
// @Security ApiKeyAuth
|
|||
// @accept application/json
|
|||
// @Produce application/json
|
|||
// @Param data body systemReq.AutoHistoryByID true "回滚自动生成代码"
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"回滚成功"}"
|
|||
// @Router /autoCode/rollback [post]
|
|||
func (autoApi *AutoCodeApi) RollBack(c *gin.Context) { |
|||
var id systemReq.AutoHistoryByID |
|||
_ = c.ShouldBindJSON(&id) |
|||
if err := autoCodeHistoryService.RollBack(id.ID); err != nil { |
|||
response.FailWithMessage(err.Error(), c) |
|||
return |
|||
} |
|||
response.OkWithMessage("回滚成功", c) |
|||
} |
|||
|
|||
// @Tags AutoCode
|
|||
// @Summary 回滚
|
|||
// @Security ApiKeyAuth
|
|||
// @accept application/json
|
|||
// @Produce application/json
|
|||
// @Param data body systemReq.AutoHistoryByID true "获取meta信息"
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @Router /autoCode/getMeta [post]
|
|||
func (autoApi *AutoCodeApi) GetMeta(c *gin.Context) { |
|||
var id systemReq.AutoHistoryByID |
|||
_ = c.ShouldBindJSON(&id) |
|||
if v, err := autoCodeHistoryService.GetMeta(id.ID); err != nil { |
|||
response.FailWithMessage(err.Error(), c) |
|||
return |
|||
} else { |
|||
response.OkWithDetailed(gin.H{"meta": v}, "获取成功", c) |
|||
} |
|||
|
|||
} |
|||
|
|||
// @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/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.Any("err", err)) |
|||
response.FailWithMessage("预览失败", c) |
|||
} else { |
|||
response.OkWithDetailed(gin.H{"autoCode": autoCode}, "预览成功", c) |
|||
} |
|||
} |
|||
|
|||
// @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.Any("err", 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") |
|||
} |
|||
} |
|||
|
|||
// @Tags AutoCode
|
|||
// @Summary 获取当前数据库所有表
|
|||
// @Security ApiKeyAuth
|
|||
// @accept application/json
|
|||
// @Produce application/json
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @Router /autoCode/getTables [get]
|
|||
func (autoApi *AutoCodeApi) GetTables(c *gin.Context) { |
|||
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname) |
|||
err, tables := autoCodeService.GetTables(dbName) |
|||
if err != nil { |
|||
global.GVA_LOG.Error("查询table失败!", zap.Any("err", err)) |
|||
response.FailWithMessage("查询table失败", c) |
|||
} else { |
|||
response.OkWithDetailed(gin.H{"tables": tables}, "获取成功", c) |
|||
} |
|||
} |
|||
|
|||
// @Tags AutoCode
|
|||
// @Summary 获取当前所有数据库
|
|||
// @Security ApiKeyAuth
|
|||
// @accept application/json
|
|||
// @Produce application/json
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @Router /autoCode/getDatabase [get]
|
|||
func (autoApi *AutoCodeApi) GetDB(c *gin.Context) { |
|||
if err, dbs := autoCodeService.GetDB(); err != nil { |
|||
global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(gin.H{"dbs": dbs}, "获取成功", c) |
|||
} |
|||
} |
|||
|
|||
// @Tags AutoCode
|
|||
// @Summary 获取当前表所有字段
|
|||
// @Security ApiKeyAuth
|
|||
// @accept application/json
|
|||
// @Produce application/json
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @Router /autoCode/getColumn [get]
|
|||
func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) { |
|||
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname) |
|||
tableName := c.Query("tableName") |
|||
if err, columns := autoCodeService.GetColumn(tableName, dbName); err != nil { |
|||
global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(gin.H{"columns": columns}, "获取成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
systemRes "github.com/flipped-aurora/gin-vue-admin/server/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 { |
|||
} |
|||
|
|||
// @Tags Base
|
|||
// @Summary 生成验证码
|
|||
// @Security ApiKeyAuth
|
|||
// @accept application/json
|
|||
// @Produce application/json
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"验证码获取成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("验证码获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(systemRes.SysCaptchaResponse{ |
|||
CaptchaId: id, |
|||
PicPath: b64s, |
|||
}, "验证码获取成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request" |
|||
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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) |
|||
} |
|||
@ -0,0 +1,118 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(response.PageResult{ |
|||
List: list, |
|||
Total: total, |
|||
Page: pageInfo.Page, |
|||
PageSize: pageInfo.PageSize, |
|||
}, "获取成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,118 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(response.PageResult{ |
|||
List: list, |
|||
Total: total, |
|||
Page: pageInfo.Page, |
|||
PageSize: pageInfo.PageSize, |
|||
}, "获取成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request" |
|||
"go.uber.org/zap" |
|||
|
|||
"github.com/gin-gonic/gin" |
|||
) |
|||
|
|||
type DBApi struct { |
|||
} |
|||
|
|||
// @Tags InitDB
|
|||
// @Summary 初始化用户数据库
|
|||
// @Produce application/json
|
|||
// @Param data body request.InitDB true "初始化数据库参数"
|
|||
// @Success 200 {string} string "{"code":0,"data":{},"msg":"自动创建数据库成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("参数校验不通过", c) |
|||
return |
|||
} |
|||
if err := initDBService.InitDB(dbInfo); err != nil { |
|||
global.GVA_LOG.Error("自动创建数据库失败!", zap.Any("err", err)) |
|||
response.FailWithMessage("自动创建数据库失败,请查看后台日志,检查后在进行初始化", c) |
|||
return |
|||
} |
|||
response.OkWithData("自动创建数据库成功", c) |
|||
} |
|||
|
|||
// @Tags CheckDB
|
|||
// @Summary 初始化用户数据库
|
|||
// @Produce application/json
|
|||
// @Success 200 {string} string "{"code":0,"data":{},"msg":"探测完成"}"
|
|||
// @Router /init/checkdb [post]
|
|||
func (i *DBApi) CheckDB(c *gin.Context) { |
|||
if global.GVA_DB != nil { |
|||
global.GVA_LOG.Info("数据库无需初始化") |
|||
response.OkWithDetailed(gin.H{"needInit": false}, "数据库无需初始化", c) |
|||
return |
|||
} else { |
|||
global.GVA_LOG.Info("前往初始化数据库") |
|||
response.OkWithDetailed(gin.H{"needInit": true}, "前往初始化数据库", c) |
|||
return |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"拉黑成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("jwt作废失败", c) |
|||
} else { |
|||
response.OkWithMessage("jwt作废成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,227 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" |
|||
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @Router /menu/getBaseMenuTree [post]
|
|||
func (a *AuthorityMenuApi) GetBaseMenuTree(c *gin.Context) { |
|||
if err, menus := menuService.GetBaseMenuTree(); err != nil { |
|||
global.GVA_LOG.Error("获取失败!", zap.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"添加成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"添加成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(response.PageResult{ |
|||
List: menuList, |
|||
Total: total, |
|||
Page: pageInfo.Page, |
|||
PageSize: pageInfo.PageSize, |
|||
}, "获取成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,119 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(response.PageResult{ |
|||
List: list, |
|||
Total: total, |
|||
Page: pageInfo.Page, |
|||
PageSize: pageInfo.PageSize, |
|||
}, "获取成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/utils" |
|||
|
|||
"github.com/gin-gonic/gin" |
|||
"go.uber.org/zap" |
|||
) |
|||
|
|||
type SystemApi struct { |
|||
} |
|||
|
|||
// @Tags System
|
|||
// @Summary 获取配置文件内容
|
|||
// @Security ApiKeyAuth
|
|||
// @Produce application/json
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @Router /system/getSystemConfig [post]
|
|||
func (s *SystemApi) GetSystemConfig(c *gin.Context) { |
|||
if err, config := systemConfigService.GetSystemConfig(); err != nil { |
|||
global.GVA_LOG.Error("获取失败!", zap.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("设置失败", c) |
|||
} else { |
|||
response.OkWithData("设置成功", c) |
|||
} |
|||
} |
|||
|
|||
// @Tags System
|
|||
// @Summary 重启系统
|
|||
// @Security ApiKeyAuth
|
|||
// @Produce application/json
|
|||
// @Success 200 {string} string "{"code":0,"data":{},"msg":"重启系统成功"}"
|
|||
// @Router /system/reloadSystem [post]
|
|||
func (s *SystemApi) ReloadSystem(c *gin.Context) { |
|||
err := utils.Reload() |
|||
if err != nil { |
|||
global.GVA_LOG.Error("重启系统失败!", zap.Any("err", err)) |
|||
response.FailWithMessage("重启系统失败", c) |
|||
} else { |
|||
response.OkWithMessage("重启系统成功", c) |
|||
} |
|||
} |
|||
|
|||
// @Tags System
|
|||
// @Summary 获取服务器信息
|
|||
// @Security ApiKeyAuth
|
|||
// @Produce application/json
|
|||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @Router /system/getServerInfo [post]
|
|||
func (s *SystemApi) GetServerInfo(c *gin.Context) { |
|||
if server, err := systemConfigService.GetServerInfo(); err != nil { |
|||
global.GVA_LOG.Error("获取失败!", zap.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(gin.H{"server": server}, "获取成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,303 @@ |
|||
package system |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" |
|||
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/utils" |
|||
"strconv" |
|||
|
|||
"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 {string} string "{"success":true,"data":{},"msg":"登陆成功"}"
|
|||
// @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.Any("err", 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.Any("err", 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.Any("err", 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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"注册成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
|
|||
// @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.Any("err", 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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
|||
// @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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
|
|||
// @Router /user/setUserInfo [put]
|
|||
func (b *BaseApi) SetUserInfo(c *gin.Context) { |
|||
var user system.SysUser |
|||
_ = c.ShouldBindJSON(&user) |
|||
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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
|||
// @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.Any("err", err)) |
|||
response.FailWithMessage("获取失败", c) |
|||
} else { |
|||
response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "获取成功", c) |
|||
} |
|||
} |
|||
@ -0,0 +1,131 @@ |
|||
# github.com/flipped-aurora/gin-vue-admin/server Global Configuration |
|||
|
|||
# jwt configuration |
|||
jwt: |
|||
signing-key: 'qmPlus' |
|||
expires-time: 604800 |
|||
buffer-time: 86400 |
|||
|
|||
# zap logger configuration |
|||
zap: |
|||
level: 'info' |
|||
format: 'console' |
|||
prefix: '[github.com/flipped-aurora/gin-vue-admin/server]' |
|||
director: 'log' |
|||
link-name: 'latest_log' |
|||
show-line: true |
|||
encode-level: 'LowercaseColorLevelEncoder' |
|||
stacktrace-key: 'stacktrace' |
|||
log-in-console: true |
|||
|
|||
# redis configuration |
|||
redis: |
|||
db: 0 |
|||
addr: '177.7.0.14:6379' |
|||
password: '' |
|||
|
|||
# email configuration |
|||
email: |
|||
to: 'xxx@qq.com' |
|||
port: 465 |
|||
from: 'xxx@163.com' |
|||
host: 'smtp.163.com' |
|||
is-ssl: true |
|||
secret: 'xxx' |
|||
nickname: 'test' |
|||
|
|||
# casbin configuration |
|||
casbin: |
|||
model-path: './resource/rbac_model.conf' |
|||
|
|||
# system configuration |
|||
system: |
|||
env: 'public' # Change to "develop" to skip authentication for development mode |
|||
addr: 8888 |
|||
db-type: 'mysql' |
|||
oss-type: 'local' # 控制oss选择走本期还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置 |
|||
use-multipoint: false |
|||
|
|||
# captcha configuration |
|||
captcha: |
|||
key-long: 6 |
|||
img-width: 240 |
|||
img-height: 80 |
|||
|
|||
# mysql connect configuration |
|||
mysql: |
|||
path: '' |
|||
config: '' |
|||
db-name: '' |
|||
username: '' |
|||
password: '' |
|||
max-idle-conns: 10 |
|||
max-open-conns: 100 |
|||
log-mode: "" |
|||
log-zap: false |
|||
|
|||
# local configuration |
|||
local: |
|||
path: 'uploads/file' |
|||
|
|||
# autocode configuration |
|||
autocode: |
|||
transfer-restart: true |
|||
root: "" |
|||
server: /server |
|||
server-api: /api/v1 |
|||
server-initialize: /initialize |
|||
server-model: /model |
|||
server-request: /model/request/ |
|||
server-router: /router |
|||
server-service: /service |
|||
web: /web/src |
|||
web-api: /api |
|||
web-form: /view |
|||
web-table: /view |
|||
|
|||
# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址) |
|||
qiniu: |
|||
zone: 'ZoneHuaDong' |
|||
bucket: '' |
|||
img-path: '' |
|||
use-https: false |
|||
access-key: '' |
|||
secret-key: '' |
|||
use-cdn-domains: false |
|||
|
|||
|
|||
# aliyun oss configuration |
|||
aliyun-oss: |
|||
endpoint: 'yourEndpoint' |
|||
access-key-id: 'yourAccessKeyId' |
|||
access-key-secret: 'yourAccessKeySecret' |
|||
bucket-name: 'yourBucketName' |
|||
bucket-url: 'yourBucketUrl' |
|||
|
|||
# tencent cos configuration |
|||
tencent-cos: |
|||
bucket: 'xxxxx-10005608' |
|||
region: 'ap-shanghai' |
|||
secret-id: 'xxxxxxxx' |
|||
secret-key: 'xxxxxxxx' |
|||
base-url: 'https://gin.vue.admin' |
|||
path-prefix: 'github.com/flipped-aurora/gin-vue-admin/server' |
|||
|
|||
# excel configuration |
|||
excel: |
|||
dir: './resource/excel/' |
|||
|
|||
|
|||
# timer task db clear table |
|||
Timer: |
|||
start: true |
|||
spec: "@daily" # 定时任务详细配置参考 https://pkg.go.dev/github.com/robfig/cron/v3 |
|||
detail: [ |
|||
# tableName: 需要清理的表名 |
|||
# compareField: 需要比较时间的字段 |
|||
# interval: 时间间隔, 具体配置详看 time.ParseDuration() 中字符串表示 且不能为负数 |
|||
# 2160h = 24 * 30 * 3 -> 三个月 |
|||
{ tableName: "sys_operation_records" , compareField: "created_at", interval: "2160h" }, |
|||
#{ tableName: "log2" , compareField: "created_at", interval: "2160h" } |
|||
] |
|||
@ -0,0 +1,100 @@ |
|||
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: l:\任官钰\代码\gin-vue-admin-master\gin-vue-admin-master |
|||
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 |
|||
captcha: |
|||
key-long: 6 |
|||
img-width: 240 |
|||
img-height: 80 |
|||
casbin: |
|||
model-path: ./resource/rbac_model.conf |
|||
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/ |
|||
jwt: |
|||
buffer-time: 86400 |
|||
expires-time: 604800 |
|||
issuer: qmPlus |
|||
signing-key: a77a9442-4c2b-466b-a650-9495e04d285c |
|||
local: |
|||
path: uploads/file |
|||
mysql: |
|||
path: 127.0.0.1:3306 |
|||
config: charset=utf8mb4&parseTime=True&loc=Local |
|||
db-name: gva |
|||
username: root |
|||
password: "123456" |
|||
max-idle-conns: 0 |
|||
max-open-conns: 0 |
|||
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: 127.0.0.1:6379 |
|||
password: "" |
|||
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: github.com/flipped-aurora/gin-vue-admin/server |
|||
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: '[github.com/flipped-aurora/gin-vue-admin/server]' |
|||
director: log |
|||
showLine: true |
|||
encode-level: LowercaseColorLevelEncoder |
|||
stacktrace-key: stacktrace |
|||
log-in-console: true |
|||
@ -0,0 +1,17 @@ |
|||
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"` |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
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"` // 验证码高度
|
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
package config |
|||
|
|||
type Casbin struct { |
|||
ModelPath string `mapstructure:"model-path" json:"modelPath" yaml:"model-path"` // 存放casbin模型的相对路径
|
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
package config |
|||
|
|||
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"` |
|||
// 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"` |
|||
TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencentCOS" yaml:"tencent-cos"` |
|||
Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"` |
|||
Timer Timer `mapstructure:"timer" json:"timer" yaml:"timer"` |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
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"` // 昵称
|
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
package config |
|||
|
|||
type Excel struct { |
|||
Dir string `mapstructure:"dir" json:"dir" yaml:"dir"` |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
package config |
|||
|
|||
type Mysql struct { |
|||
Path string `mapstructure:"path" json:"path" yaml:"path"` // 服务器地址:端口
|
|||
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.Dbname + "?" + m.Config |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
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"` // 签发者
|
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
package config |
|||
|
|||
type Local struct { |
|||
Path string `mapstructure:"path" json:"path" yaml:"path"` // 本地文件路径
|
|||
} |
|||
|
|||
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上传加速
|
|||
} |
|||
|
|||
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"` |
|||
} |
|||
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"` |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
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"` // 密码
|
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
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"` |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
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"` // 时间间隔
|
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
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"` // 输出控制台
|
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
package core |
|||
|
|||
import ( |
|||
"fmt" |
|||
"time" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/initialize" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/service/system" |
|||
"go.uber.org/zap" |
|||
) |
|||
|
|||
type server interface { |
|||
ListenAndServe() error |
|||
} |
|||
|
|||
func RunWindowsServer() { |
|||
if global.GVA_CONFIG.System.UseMultipoint { |
|||
// 初始化redis服务
|
|||
initialize.Redis() |
|||
} |
|||
|
|||
// 从db加载jwt数据
|
|||
if global.GVA_DB != nil { |
|||
system.LoadAll() |
|||
} |
|||
|
|||
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)) |
|||
|
|||
fmt.Printf(` |
|||
欢迎使用 github.com/flipped-aurora/gin-vue-admin/server |
|||
当前版本:V2.4.6 Apache |
|||
加群方式:微信号:shouzi_1994 QQ群:622360840 |
|||
默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
|
|||
默认前端文件运行地址:http://127.0.0.1:8080
|
|||
如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.github.com/flipped-aurora/gin-vue-admin/server.com/docs/coffee
|
|||
`, address) |
|||
global.GVA_LOG.Error(s.ListenAndServe().Error()) |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
//go:build !windows
|
|||
// +build !windows
|
|||
|
|||
package core |
|||
|
|||
import ( |
|||
"github.com/fvbock/endless" |
|||
"github.com/gin-gonic/gin" |
|||
"time" |
|||
) |
|||
|
|||
func initServer(address string, router *gin.Engine) server { |
|||
s := endless.NewServer(address, router) |
|||
s.ReadHeaderTimeout = 10 * time.Millisecond |
|||
s.WriteTimeout = 10 * time.Second |
|||
s.MaxHeaderBytes = 1 << 20 |
|||
return s |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
//go:build windows
|
|||
// +build windows
|
|||
|
|||
package core |
|||
|
|||
import ( |
|||
"github.com/gin-gonic/gin" |
|||
"net/http" |
|||
"time" |
|||
) |
|||
|
|||
func initServer(address string, router *gin.Engine) server { |
|||
return &http.Server{ |
|||
Addr: address, |
|||
Handler: router, |
|||
ReadTimeout: 10 * time.Second, |
|||
WriteTimeout: 10 * time.Second, |
|||
MaxHeaderBytes: 1 << 20, |
|||
} |
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
package core |
|||
|
|||
import ( |
|||
"flag" |
|||
"fmt" |
|||
"os" |
|||
"path/filepath" |
|||
"time" |
|||
|
|||
"github.com/songzhibin97/gkit/cache/local_cache" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
_ "github.com/flipped-aurora/gin-vue-admin/server/packfile" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 |
|||
} |
|||
@ -0,0 +1,97 @@ |
|||
package core |
|||
|
|||
import ( |
|||
"fmt" |
|||
"os" |
|||
"time" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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")) |
|||
} |
|||
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,29 @@ |
|||
package global |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/utils/timer" |
|||
"github.com/songzhibin97/gkit/cache/local_cache" |
|||
|
|||
"golang.org/x/sync/singleflight" |
|||
|
|||
"go.uber.org/zap" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/config" |
|||
|
|||
"github.com/go-redis/redis/v8" |
|||
"github.com/spf13/viper" |
|||
"gorm.io/gorm" |
|||
) |
|||
|
|||
var ( |
|||
GVA_DB *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 |
|||
) |
|||
@ -0,0 +1,13 @@ |
|||
package global |
|||
|
|||
import ( |
|||
"gorm.io/gorm" |
|||
"time" |
|||
) |
|||
|
|||
type GVA_MODEL struct { |
|||
ID uint `gorm:"primarykey"` // 主键ID
|
|||
CreatedAt time.Time // 创建时间
|
|||
UpdatedAt time.Time // 更新时间
|
|||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` // 删除时间
|
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
module github.com/flipped-aurora/gin-vue-admin/server |
|||
|
|||
go 1.16 |
|||
|
|||
require ( |
|||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 |
|||
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible |
|||
github.com/casbin/casbin/v2 v2.11.0 |
|||
github.com/casbin/gorm-adapter/v3 v3.0.2 |
|||
github.com/dgrijalva/jwt-go v3.2.0+incompatible |
|||
github.com/flipped-aurora/gva-plugins v0.0.0-20210828060501-fc8b729b9a4a |
|||
github.com/flipped-aurora/ws v1.0.2 |
|||
github.com/fsnotify/fsnotify v1.4.9 |
|||
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 |
|||
github.com/gin-gonic/gin v1.6.3 |
|||
github.com/go-redis/redis/v8 v8.11.0 |
|||
github.com/go-sql-driver/mysql v1.5.0 |
|||
github.com/gookit/color v1.3.1 |
|||
github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84 |
|||
github.com/mojocn/base64Captcha v1.3.1 |
|||
github.com/natefinch/lumberjack v2.0.0+incompatible |
|||
github.com/qiniu/api.v7/v7 v7.4.1 |
|||
github.com/robfig/cron/v3 v3.0.1 |
|||
github.com/satori/go.uuid v1.2.0 |
|||
github.com/shirou/gopsutil v3.21.9+incompatible |
|||
github.com/songzhibin97/gkit v1.1.1 |
|||
github.com/spf13/viper v1.7.0 |
|||
github.com/stretchr/testify v1.7.0 |
|||
github.com/swaggo/gin-swagger v1.3.0 |
|||
github.com/swaggo/swag v1.7.0 |
|||
github.com/tencentyun/cos-go-sdk-v5 v0.7.19 |
|||
github.com/tklauser/go-sysconf v0.3.9 // indirect |
|||
github.com/unrolled/secure v1.0.7 |
|||
github.com/xuri/excelize/v2 v2.4.1 |
|||
go.uber.org/zap v1.16.0 |
|||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c |
|||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect |
|||
gorm.io/driver/mysql v1.0.1 |
|||
gorm.io/gorm v1.20.11 |
|||
nhooyr.io/websocket v1.8.6 |
|||
) |
|||
@ -0,0 +1,785 @@ |
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= |
|||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= |
|||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= |
|||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= |
|||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= |
|||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= |
|||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= |
|||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= |
|||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= |
|||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= |
|||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= |
|||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= |
|||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= |
|||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= |
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= |
|||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= |
|||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= |
|||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= |
|||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= |
|||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= |
|||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= |
|||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= |
|||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= |
|||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= |
|||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= |
|||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= |
|||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= |
|||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= |
|||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= |
|||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= |
|||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= |
|||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= |
|||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= |
|||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= |
|||
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible h1:Ft+KeWIJxFP76LqgJbvtOA1qBIoC8vGkTV3QeCOeJC4= |
|||
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= |
|||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= |
|||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= |
|||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= |
|||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA= |
|||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= |
|||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= |
|||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= |
|||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= |
|||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= |
|||
github.com/casbin/casbin/v2 v2.2.2/go.mod h1:XXtYGrs/0zlOsJMeRteEdVi/FsB0ph7KgNfjoCoJUD8= |
|||
github.com/casbin/casbin/v2 v2.11.0 h1:6M/sWT9gh2pUcL541be/rllWEVxcEV6wdg1t7MN6fHQ= |
|||
github.com/casbin/casbin/v2 v2.11.0/go.mod h1:XXtYGrs/0zlOsJMeRteEdVi/FsB0ph7KgNfjoCoJUD8= |
|||
github.com/casbin/gorm-adapter/v3 v3.0.2 h1:4F2VFElwPyFzvHfgwizD2JQxk2OFLwvRFZct1np0yBg= |
|||
github.com/casbin/gorm-adapter/v3 v3.0.2/go.mod h1:mQI09sqvXfy5p6kZB5HBzZrgKWwxaJ4xMWpd5OGfHRY= |
|||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= |
|||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= |
|||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= |
|||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= |
|||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= |
|||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= |
|||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= |
|||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= |
|||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= |
|||
github.com/codegangsta/negroni v1.0.0 h1:+aYywywx4bnKXWvoWtRfJ91vC59NbEhEY03sZjQhbVY= |
|||
github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0= |
|||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= |
|||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= |
|||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= |
|||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= |
|||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= |
|||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= |
|||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= |
|||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= |
|||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= |
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= |
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
|||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg= |
|||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= |
|||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= |
|||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= |
|||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= |
|||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= |
|||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= |
|||
github.com/emicklei/proto v1.9.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= |
|||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= |
|||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= |
|||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= |
|||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= |
|||
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= |
|||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= |
|||
github.com/flipped-aurora/gin-vue-admin/server v0.0.0-20210823151324-f5410430faf0/go.mod h1:ksHCxOjTTQDk1Y1MrptfG6e9+s3rDJzQXkIZBHl8sws= |
|||
github.com/flipped-aurora/gva-plugins v0.0.0-20210828060501-fc8b729b9a4a h1:GEU1KU8lvWWwvHNTXaoVxonsp8t120oFQnlpAtGqKpM= |
|||
github.com/flipped-aurora/gva-plugins v0.0.0-20210828060501-fc8b729b9a4a/go.mod h1:/DpDUj/vphN4x3UaTDhTvT6aZaCasfKOGbMgPabwGv0= |
|||
github.com/flipped-aurora/ws v1.0.2 h1:oEUz7sgrbPENvgli7Q4QpC0NIEbJucgR4yjcDMg/AjY= |
|||
github.com/flipped-aurora/ws v1.0.2/go.mod h1:RdyM2Fnvxx7f7A6WSmU1aAhDrQIAVW7LS/0LsAUE5mE= |
|||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= |
|||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= |
|||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= |
|||
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc= |
|||
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yHzKvwhsiSIWmbAYM3Dr9AEEbER2dVayfBkg= |
|||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= |
|||
github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc= |
|||
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w= |
|||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= |
|||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= |
|||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= |
|||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= |
|||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= |
|||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= |
|||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= |
|||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= |
|||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= |
|||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= |
|||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= |
|||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= |
|||
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= |
|||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= |
|||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= |
|||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= |
|||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= |
|||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= |
|||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= |
|||
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= |
|||
github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= |
|||
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= |
|||
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= |
|||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= |
|||
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= |
|||
github.com/go-openapi/spec v0.19.14/go.mod h1:gwrgJS15eCUgjLpMjBJmbZezCsw88LmgeEip0M63doA= |
|||
github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ= |
|||
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= |
|||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= |
|||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= |
|||
github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY= |
|||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= |
|||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= |
|||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= |
|||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= |
|||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= |
|||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= |
|||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= |
|||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= |
|||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= |
|||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= |
|||
github.com/go-playground/validator/v10 v10.3.0 h1:nZU+7q+yJoFmwvNgv/LnPUkwPal62+b2xXj0AU1Es7o= |
|||
github.com/go-playground/validator/v10 v10.3.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= |
|||
github.com/go-redis/redis/v8 v8.11.0 h1:O1Td0mQ8UFChQ3N9zFQqo6kTU2cJ+/it88gDB+zg0wo= |
|||
github.com/go-redis/redis/v8 v8.11.0/go.mod h1:DLomh7y2e3ggQXQLd1YgmvIfecPJoFl7WU5SOQ/r06M= |
|||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= |
|||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= |
|||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= |
|||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= |
|||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= |
|||
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= |
|||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= |
|||
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= |
|||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= |
|||
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= |
|||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= |
|||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= |
|||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= |
|||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= |
|||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= |
|||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= |
|||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= |
|||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= |
|||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= |
|||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= |
|||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= |
|||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= |
|||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= |
|||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= |
|||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= |
|||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= |
|||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= |
|||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= |
|||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= |
|||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= |
|||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= |
|||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= |
|||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= |
|||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= |
|||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= |
|||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= |
|||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= |
|||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= |
|||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= |
|||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= |
|||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= |
|||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= |
|||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= |
|||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= |
|||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= |
|||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= |
|||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= |
|||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= |
|||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= |
|||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= |
|||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= |
|||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= |
|||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= |
|||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= |
|||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= |
|||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= |
|||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= |
|||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= |
|||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= |
|||
github.com/gookit/color v1.3.1 h1:PPD/C7sf8u2L8XQPdPgsWRoAiLQGZEZOzU3cf5IYYUk= |
|||
github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= |
|||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= |
|||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= |
|||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= |
|||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= |
|||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= |
|||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= |
|||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= |
|||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= |
|||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= |
|||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= |
|||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= |
|||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= |
|||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= |
|||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= |
|||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= |
|||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= |
|||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= |
|||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= |
|||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= |
|||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= |
|||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= |
|||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= |
|||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= |
|||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= |
|||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= |
|||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= |
|||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= |
|||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= |
|||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= |
|||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= |
|||
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= |
|||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= |
|||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= |
|||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= |
|||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= |
|||
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= |
|||
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= |
|||
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= |
|||
github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= |
|||
github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= |
|||
github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= |
|||
github.com/jackc/pgconn v1.6.1 h1:lwofaXKPbIx6qEaK8mNm7uZuOwxHw+PnAFGDsDFpkRI= |
|||
github.com/jackc/pgconn v1.6.1/go.mod h1:g8mKMqmSUO6AzAvha7vy07g1rbGOlc7iF0nU0ei83hc= |
|||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= |
|||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= |
|||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA= |
|||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= |
|||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= |
|||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= |
|||
github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= |
|||
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= |
|||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= |
|||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= |
|||
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= |
|||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= |
|||
github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= |
|||
github.com/jackc/pgproto3/v2 v2.0.2 h1:q1Hsy66zh4vuNsajBUF2PNqfAMMfxU5mk594lPE9vjY= |
|||
github.com/jackc/pgproto3/v2 v2.0.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= |
|||
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8 h1:Q3tB+ExeflWUW7AFcAhXqk40s9mnNYLk1nOkKNZ5GnU= |
|||
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= |
|||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= |
|||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= |
|||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= |
|||
github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= |
|||
github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= |
|||
github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= |
|||
github.com/jackc/pgtype v1.4.0 h1:pHQfb4jh9iKqHyxPthq1fr+0HwSNIl3btYPbw2m2lbM= |
|||
github.com/jackc/pgtype v1.4.0/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= |
|||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= |
|||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= |
|||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= |
|||
github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= |
|||
github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= |
|||
github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= |
|||
github.com/jackc/pgx/v4 v4.7.1 h1:aqUSOcStk6fik+lSE+tqfFhvt/EwT8q/oMtJbP9CjXI= |
|||
github.com/jackc/pgx/v4 v4.7.1/go.mod h1:nu42q3aPjuC1M0Nak4bnoprKlXPINqopEKqbq5AZSC4= |
|||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= |
|||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= |
|||
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= |
|||
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= |
|||
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= |
|||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= |
|||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= |
|||
github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E= |
|||
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= |
|||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= |
|||
github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84 h1:pS0A6cr4aHYZnYwC7Uw+rwgb39+nzkm2QhwZ+S6Gn5I= |
|||
github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A= |
|||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= |
|||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= |
|||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= |
|||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= |
|||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= |
|||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= |
|||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= |
|||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= |
|||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= |
|||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= |
|||
github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= |
|||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= |
|||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= |
|||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= |
|||
github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8= |
|||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= |
|||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= |
|||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= |
|||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= |
|||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= |
|||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= |
|||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= |
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= |
|||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= |
|||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= |
|||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= |
|||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= |
|||
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= |
|||
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA= |
|||
github.com/lestrrat-go/strftime v1.0.3/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g= |
|||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= |
|||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= |
|||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= |
|||
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= |
|||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= |
|||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= |
|||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= |
|||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= |
|||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= |
|||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= |
|||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= |
|||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= |
|||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= |
|||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= |
|||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= |
|||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= |
|||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= |
|||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= |
|||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= |
|||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= |
|||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= |
|||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= |
|||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= |
|||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= |
|||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= |
|||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= |
|||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= |
|||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= |
|||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= |
|||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= |
|||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= |
|||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= |
|||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= |
|||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= |
|||
github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4= |
|||
github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= |
|||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= |
|||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= |
|||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= |
|||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= |
|||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= |
|||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= |
|||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= |
|||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= |
|||
github.com/mojocn/base64Captcha v1.3.1 h1:2Wbkt8Oc8qjmNJ5GyOfSo4tgVQPsbKMftqASnq8GlT0= |
|||
github.com/mojocn/base64Captcha v1.3.1/go.mod h1:wAQCKEc5bDujxKRmbT6/vTnTt5CjStQ8bRfPWUuz/iY= |
|||
github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ= |
|||
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= |
|||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= |
|||
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= |
|||
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= |
|||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= |
|||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= |
|||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= |
|||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= |
|||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= |
|||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= |
|||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= |
|||
github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= |
|||
github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= |
|||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= |
|||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= |
|||
github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= |
|||
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= |
|||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= |
|||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= |
|||
github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= |
|||
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= |
|||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
|||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
|||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= |
|||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
|||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= |
|||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
|||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= |
|||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= |
|||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= |
|||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= |
|||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= |
|||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= |
|||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= |
|||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= |
|||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= |
|||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= |
|||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= |
|||
github.com/qiniu/api.v7/v7 v7.4.1 h1:BnNUBimLk6nrA/mIwsww9yJRupmViSsb1ndLMC7a9OY= |
|||
github.com/qiniu/api.v7/v7 v7.4.1/go.mod h1:VE5oC5rkE1xul0u1S2N0b2Uxq9/6hZzhyqjgK25XDcM= |
|||
github.com/richardlehane/mscfb v1.0.3 h1:rD8TBkYWkObWO0oLDFCbwMeZ4KoalxQy+QgniCj3nKI= |
|||
github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= |
|||
github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o= |
|||
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= |
|||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= |
|||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= |
|||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= |
|||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= |
|||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= |
|||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= |
|||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= |
|||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= |
|||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= |
|||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= |
|||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= |
|||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= |
|||
github.com/shirou/gopsutil v3.20.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= |
|||
github.com/shirou/gopsutil v3.21.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= |
|||
github.com/shirou/gopsutil v3.21.9+incompatible h1:LTLpUnfX81MkHeCtSrwNKZwuW5Id6kCa7/P43NdcNn4= |
|||
github.com/shirou/gopsutil v3.21.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= |
|||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= |
|||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY= |
|||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= |
|||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= |
|||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= |
|||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= |
|||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= |
|||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= |
|||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= |
|||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= |
|||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= |
|||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= |
|||
github.com/songzhibin97/gkit v1.1.1 h1:RmnCBLA7+OY40VEa2Uf2nGfbIMs4/5QT6tXDEHsMXiQ= |
|||
github.com/songzhibin97/gkit v1.1.1/go.mod h1:V4E7H6DQuxX17xpLOqyH1j51GQctKBIIV3i2r5xkE5s= |
|||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= |
|||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= |
|||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= |
|||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= |
|||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= |
|||
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= |
|||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= |
|||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= |
|||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= |
|||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= |
|||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= |
|||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= |
|||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= |
|||
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= |
|||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= |
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
|||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
|||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= |
|||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= |
|||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= |
|||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= |
|||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= |
|||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= |
|||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= |
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= |
|||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= |
|||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= |
|||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= |
|||
github.com/swaggo/gin-swagger v1.3.0 h1:eOmp7r57oUgZPw2dJOjcGNMse9cvXcI4tTqBcnZtPsI= |
|||
github.com/swaggo/gin-swagger v1.3.0/go.mod h1:oy1BRA6WvgtCp848lhxce7BnWH4C8Bxa0m5SkWx+cS0= |
|||
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y= |
|||
github.com/swaggo/swag v1.7.0 h1:5bCA/MTLQoIqDXXyHfOpMeDvL9j68OY/udlK4pQoo4E= |
|||
github.com/swaggo/swag v1.7.0/go.mod h1:BdPIL73gvS9NBsdi7M1JOxLvlbfvNRaBP8m6WT6Aajo= |
|||
github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ= |
|||
github.com/tencentyun/cos-go-sdk-v5 v0.7.19 h1:janAfTO4MglOrUFuKGTQJBuMc66+F7TgtEIt1wPsJ+k= |
|||
github.com/tencentyun/cos-go-sdk-v5 v0.7.19/go.mod h1:wQBO5HdAkLjj2q6XQiIfDSP8DXDNrppDRw2Kp/1BODA= |
|||
github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo= |
|||
github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= |
|||
github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= |
|||
github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= |
|||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= |
|||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= |
|||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= |
|||
github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q= |
|||
github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= |
|||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= |
|||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= |
|||
github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4= |
|||
github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= |
|||
github.com/unrolled/secure v1.0.7 h1:BcQHp3iKZyZCKj5gRqwQG+5urnGBF00wGgoPPwtheVQ= |
|||
github.com/unrolled/secure v1.0.7/go.mod h1:uGc1OcRF8gCVBA+ANksKmvM85Hka6SZtQIbrKc3sHS4= |
|||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= |
|||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= |
|||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= |
|||
github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 h1:EpI0bqf/eX9SdZDwlMmahKM+CDBgNbsXMhsN28XrM8o= |
|||
github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= |
|||
github.com/xuri/excelize/v2 v2.4.1 h1:veeeFLAJwsNEBPBlDepzPIYS1eLyBVcXNZUW79exZ1E= |
|||
github.com/xuri/excelize/v2 v2.4.1/go.mod h1:rSu0C3papjzxQA3sdK8cU544TebhrPUoTOaGPIh0Q1A= |
|||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= |
|||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= |
|||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= |
|||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= |
|||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= |
|||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= |
|||
go.opentelemetry.io/otel v1.0.0-RC2/go.mod h1:w1thVQ7qbAy8MHb0IFj8a5Q2QU0l2ksf8u/CN8m3NOM= |
|||
go.opentelemetry.io/otel/sdk v1.0.0-RC2/go.mod h1:fgwHyiDn4e5k40TD9VX243rOxXR+jzsWBZYA2P5jpEw= |
|||
go.opentelemetry.io/otel/trace v1.0.0-RC2/go.mod h1:JPQ+z6nNw9mqEGT8o3eoPTdnNI+Aj5JcxEsVGREIAy4= |
|||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= |
|||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= |
|||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= |
|||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= |
|||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= |
|||
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= |
|||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= |
|||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= |
|||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= |
|||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= |
|||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= |
|||
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= |
|||
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= |
|||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= |
|||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= |
|||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= |
|||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= |
|||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= |
|||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |
|||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |
|||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |
|||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |
|||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |
|||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= |
|||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= |
|||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= |
|||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= |
|||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= |
|||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= |
|||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= |
|||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= |
|||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= |
|||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= |
|||
golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= |
|||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= |
|||
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk= |
|||
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= |
|||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= |
|||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= |
|||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= |
|||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= |
|||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= |
|||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= |
|||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= |
|||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= |
|||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= |
|||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= |
|||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= |
|||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= |
|||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= |
|||
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= |
|||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= |
|||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
|||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
|||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
|||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
|||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
|||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
|||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
|||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
|||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
|||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
|||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |
|||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |
|||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |
|||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |
|||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= |
|||
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
|||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
|||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
|||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
|||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= |
|||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= |
|||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= |
|||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= |
|||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= |
|||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= |
|||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= |
|||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= |
|||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 h1:4CSI6oo7cOjJKajidEljs9h+uP0rRZBPPPhcCbj5mw8= |
|||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= |
|||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= |
|||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= |
|||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= |
|||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
|||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
|||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
|||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
|||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
|||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
|||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
|||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= |
|||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
|||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
|||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
|||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
|||
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71 h1:ikCpsnYR+Ew0vu99XlDp55lGgDJdIMx3f4a18jfse/s= |
|||
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
|||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= |
|||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
|||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
|||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= |
|||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= |
|||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= |
|||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= |
|||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= |
|||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= |
|||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= |
|||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= |
|||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= |
|||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE= |
|||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= |
|||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
|||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
|||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
|||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= |
|||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= |
|||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= |
|||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= |
|||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= |
|||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= |
|||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= |
|||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= |
|||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= |
|||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= |
|||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= |
|||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= |
|||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= |
|||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= |
|||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
|||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
|||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
|||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
|||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
|||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
|||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
|||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
|||
golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= |
|||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= |
|||
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= |
|||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= |
|||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
|||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
|||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
|||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
|||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
|||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= |
|||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
|||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= |
|||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= |
|||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= |
|||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= |
|||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= |
|||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= |
|||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= |
|||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= |
|||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= |
|||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= |
|||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= |
|||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= |
|||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= |
|||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= |
|||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= |
|||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= |
|||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= |
|||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= |
|||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= |
|||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= |
|||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= |
|||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= |
|||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= |
|||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= |
|||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= |
|||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= |
|||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= |
|||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= |
|||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= |
|||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= |
|||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= |
|||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= |
|||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= |
|||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= |
|||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= |
|||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= |
|||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= |
|||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= |
|||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= |
|||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= |
|||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
|||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
|||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= |
|||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
|||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= |
|||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= |
|||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= |
|||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= |
|||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= |
|||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= |
|||
gopkg.in/ini.v1 v1.55.0 h1:E8yzL5unfpW3M6fz/eB7Cb5MQAYSZ7GKo4Qth+N2sgQ= |
|||
gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= |
|||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= |
|||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= |
|||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= |
|||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= |
|||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= |
|||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= |
|||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
|||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
|||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
|||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
|||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
|||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
|||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= |
|||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= |
|||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
|||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= |
|||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
|||
gorm.io/driver/mysql v0.3.0/go.mod h1:A7H1JD9dKdcjeUTpTuWKEC+E1a74qzW7/zaXqKaTbfM= |
|||
gorm.io/driver/mysql v1.0.1 h1:omJoilUzyrAp0xNoio88lGJCroGdIOen9hq2A/+3ifw= |
|||
gorm.io/driver/mysql v1.0.1/go.mod h1:KtqSthtg55lFp3S5kUXqlGaelnWpKitn4k1xZTnoiPw= |
|||
gorm.io/driver/postgres v0.2.6 h1:hoE6SzA5wKOo6AYxz2V7ooxnzD6S6ToLAHHDDawt+b0= |
|||
gorm.io/driver/postgres v0.2.6/go.mod h1:AsPyuhKFOplSmQwOPsycVKbe0dRxF8v18KZ7p9i8dIs= |
|||
gorm.io/driver/sqlserver v0.2.4 h1:AGofGL/TfzTZotzIHlaLISfxEKJpzj0ATbtXJW+ga1A= |
|||
gorm.io/driver/sqlserver v0.2.4/go.mod h1:TcPfkdce5b8qlCMgyUeUdm7HQa1ZzWUuxzI+odcueLA= |
|||
gorm.io/gorm v0.2.19/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= |
|||
gorm.io/gorm v0.2.23/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= |
|||
gorm.io/gorm v1.9.19/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= |
|||
gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= |
|||
gorm.io/gorm v1.20.11 h1:jYHQ0LLUViV85V8dM1TP9VBBkfzKTnuTXDjYObkI6yc= |
|||
gorm.io/gorm v1.20.11/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= |
|||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= |
|||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= |
|||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= |
|||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= |
|||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= |
|||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= |
|||
nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= |
|||
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= |
|||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= |
|||
@ -0,0 +1,118 @@ |
|||
package initialize |
|||
|
|||
import ( |
|||
"os" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/initialize/internal" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/autocode" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/example" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
|
|||
"go.uber.org/zap" |
|||
"gorm.io/driver/mysql" |
|||
"gorm.io/gorm" |
|||
"gorm.io/gorm/logger" |
|||
) |
|||
|
|||
//@author: SliverHorn
|
|||
//@function: Gorm
|
|||
//@description: 初始化数据库并产生数据库全局变量
|
|||
//@return: *gorm.DB
|
|||
|
|||
func Gorm() *gorm.DB { |
|||
switch global.GVA_CONFIG.System.DbType { |
|||
case "mysql": |
|||
return GormMysql() |
|||
default: |
|||
return GormMysql() |
|||
} |
|||
} |
|||
|
|||
// MysqlTables
|
|||
//@author: SliverHorn
|
|||
//@function: MysqlTables
|
|||
//@description: 注册数据库表专用
|
|||
//@param: db *gorm.DB
|
|||
|
|||
func MysqlTables(db *gorm.DB) { |
|||
err := db.AutoMigrate( |
|||
system.SysUser{}, |
|||
system.SysAuthority{}, |
|||
system.SysApi{}, |
|||
system.SysBaseMenu{}, |
|||
system.SysBaseMenuParameter{}, |
|||
system.JwtBlacklist{}, |
|||
system.SysDictionary{}, |
|||
system.SysDictionaryDetail{}, |
|||
example.ExaFileUploadAndDownload{}, |
|||
example.ExaFile{}, |
|||
example.ExaFileChunk{}, |
|||
example.ExaCustomer{}, |
|||
system.SysOperationRecord{}, |
|||
system.SysAutoCodeHistory{}, |
|||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server Begin; DO NOT EDIT.
|
|||
autocode.AutoCodeExample{}, |
|||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server End; DO NOT EDIT.
|
|||
) |
|||
if err != nil { |
|||
global.GVA_LOG.Error("register table failed", zap.Any("err", err)) |
|||
os.Exit(0) |
|||
} |
|||
global.GVA_LOG.Info("register table success") |
|||
} |
|||
|
|||
//@author: SliverHorn
|
|||
//@function: GormMysql
|
|||
//@description: 初始化Mysql数据库
|
|||
//@return: *gorm.DB
|
|||
|
|||
func GormMysql() *gorm.DB { |
|||
m := global.GVA_CONFIG.Mysql |
|||
if m.Dbname == "" { |
|||
return nil |
|||
} |
|||
dsn := m.Username + ":" + m.Password + "@tcp(" + m.Path + ")/" + m.Dbname + "?" + m.Config |
|||
mysqlConfig := mysql.Config{ |
|||
DSN: dsn, // DSN data source name
|
|||
DefaultStringSize: 191, // string 类型字段的默认长度
|
|||
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
|
|||
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
|
|||
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
|
|||
SkipInitializeWithVersion: false, // 根据版本自动配置
|
|||
} |
|||
if db, err := gorm.Open(mysql.New(mysqlConfig), gormConfig()); err != nil { |
|||
//global.GVA_LOG.Error("MySQL启动异常", zap.Any("err", err))
|
|||
//os.Exit(0)
|
|||
//return nil
|
|||
return nil |
|||
} else { |
|||
sqlDB, _ := db.DB() |
|||
sqlDB.SetMaxIdleConns(m.MaxIdleConns) |
|||
sqlDB.SetMaxOpenConns(m.MaxOpenConns) |
|||
return db |
|||
} |
|||
} |
|||
|
|||
//@author: SliverHorn
|
|||
//@function: gormConfig
|
|||
//@description: 根据配置决定是否开启日志
|
|||
//@param: mod bool
|
|||
//@return: *gorm.Config
|
|||
|
|||
func gormConfig() *gorm.Config { |
|||
config := &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true} |
|||
switch global.GVA_CONFIG.Mysql.LogMode { |
|||
case "silent", "Silent": |
|||
config.Logger = internal.Default.LogMode(logger.Silent) |
|||
case "error", "Error": |
|||
config.Logger = internal.Default.LogMode(logger.Error) |
|||
case "warn", "Warn": |
|||
config.Logger = internal.Default.LogMode(logger.Warn) |
|||
case "info", "Info": |
|||
config.Logger = internal.Default.LogMode(logger.Info) |
|||
default: |
|||
config.Logger = internal.Default.LogMode(logger.Info) |
|||
} |
|||
return config |
|||
} |
|||
@ -0,0 +1,153 @@ |
|||
package internal |
|||
|
|||
import ( |
|||
"context" |
|||
"fmt" |
|||
"io/ioutil" |
|||
"log" |
|||
"os" |
|||
"time" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"gorm.io/gorm/logger" |
|||
"gorm.io/gorm/utils" |
|||
) |
|||
|
|||
type config struct { |
|||
SlowThreshold time.Duration |
|||
Colorful bool |
|||
LogLevel logger.LogLevel |
|||
} |
|||
|
|||
var ( |
|||
Discard = New(log.New(ioutil.Discard, "", log.LstdFlags), config{}) |
|||
Default = New(log.New(os.Stdout, "\r\n", log.LstdFlags), config{ |
|||
SlowThreshold: 200 * time.Millisecond, |
|||
LogLevel: logger.Warn, |
|||
Colorful: true, |
|||
}) |
|||
Recorder = traceRecorder{Interface: Default, BeginAt: time.Now()} |
|||
) |
|||
|
|||
func New(writer logger.Writer, config config) logger.Interface { |
|||
var ( |
|||
infoStr = "%s\n[info] " |
|||
warnStr = "%s\n[warn] " |
|||
errStr = "%s\n[error] " |
|||
traceStr = "%s\n[%.3fms] [rows:%v] %s\n" |
|||
traceWarnStr = "%s %s\n[%.3fms] [rows:%v] %s\n" |
|||
traceErrStr = "%s %s\n[%.3fms] [rows:%v] %s\n" |
|||
) |
|||
|
|||
if config.Colorful { |
|||
infoStr = logger.Green + "%s\n" + logger.Reset + logger.Green + "[info] " + logger.Reset |
|||
warnStr = logger.BlueBold + "%s\n" + logger.Reset + logger.Magenta + "[warn] " + logger.Reset |
|||
errStr = logger.Magenta + "%s\n" + logger.Reset + logger.Red + "[error] " + logger.Reset |
|||
traceStr = logger.Green + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s\n" |
|||
traceWarnStr = logger.Green + "%s " + logger.Yellow + "%s\n" + logger.Reset + logger.RedBold + "[%.3fms] " + logger.Yellow + "[rows:%v]" + logger.Magenta + " %s\n" + logger.Reset |
|||
traceErrStr = logger.RedBold + "%s " + logger.MagentaBold + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s\n" |
|||
} |
|||
|
|||
return &_logger{ |
|||
Writer: writer, |
|||
config: config, |
|||
infoStr: infoStr, |
|||
warnStr: warnStr, |
|||
errStr: errStr, |
|||
traceStr: traceStr, |
|||
traceWarnStr: traceWarnStr, |
|||
traceErrStr: traceErrStr, |
|||
} |
|||
} |
|||
|
|||
type _logger struct { |
|||
config |
|||
logger.Writer |
|||
infoStr, warnStr, errStr string |
|||
traceStr, traceErrStr, traceWarnStr string |
|||
} |
|||
|
|||
// LogMode log mode
|
|||
func (c *_logger) LogMode(level logger.LogLevel) logger.Interface { |
|||
newLogger := *c |
|||
newLogger.LogLevel = level |
|||
return &newLogger |
|||
} |
|||
|
|||
// Info print info
|
|||
func (c *_logger) Info(ctx context.Context, message string, data ...interface{}) { |
|||
if c.LogLevel >= logger.Info { |
|||
c.Printf(c.infoStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...) |
|||
} |
|||
} |
|||
|
|||
// Warn print warn messages
|
|||
func (c *_logger) Warn(ctx context.Context, message string, data ...interface{}) { |
|||
if c.LogLevel >= logger.Warn { |
|||
c.Printf(c.warnStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...) |
|||
} |
|||
} |
|||
|
|||
// Error print error messages
|
|||
func (c *_logger) Error(ctx context.Context, message string, data ...interface{}) { |
|||
if c.LogLevel >= logger.Error { |
|||
c.Printf(c.errStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...) |
|||
} |
|||
} |
|||
|
|||
// Trace print sql message
|
|||
func (c *_logger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { |
|||
if c.LogLevel > 0 { |
|||
elapsed := time.Since(begin) |
|||
switch { |
|||
case err != nil && c.LogLevel >= logger.Error: |
|||
sql, rows := fc() |
|||
if rows == -1 { |
|||
c.Printf(c.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql) |
|||
} else { |
|||
c.Printf(c.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql) |
|||
} |
|||
case elapsed > c.SlowThreshold && c.SlowThreshold != 0 && c.LogLevel >= logger.Warn: |
|||
sql, rows := fc() |
|||
slowLog := fmt.Sprintf("SLOW SQL >= %v", c.SlowThreshold) |
|||
if rows == -1 { |
|||
c.Printf(c.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql) |
|||
} else { |
|||
c.Printf(c.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql) |
|||
} |
|||
case c.LogLevel >= logger.Info: |
|||
sql, rows := fc() |
|||
if rows == -1 { |
|||
c.Printf(c.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql) |
|||
} else { |
|||
c.Printf(c.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
func (c *_logger) Printf(message string, data ...interface{}) { |
|||
if global.GVA_CONFIG.Mysql.LogZap { |
|||
global.GVA_LOG.Info(fmt.Sprintf(message, data...)) |
|||
} else { |
|||
c.Writer.Printf(message, data...) |
|||
} |
|||
} |
|||
|
|||
type traceRecorder struct { |
|||
logger.Interface |
|||
BeginAt time.Time |
|||
SQL string |
|||
RowsAffected int64 |
|||
Err error |
|||
} |
|||
|
|||
func (t traceRecorder) New() *traceRecorder { |
|||
return &traceRecorder{Interface: t.Interface, BeginAt: time.Now()} |
|||
} |
|||
|
|||
func (t *traceRecorder) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { |
|||
t.BeginAt = begin |
|||
t.SQL, t.RowsAffected = fc() |
|||
t.Err = err |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
package initialize |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
email "github.com/flipped-aurora/gva-plugins/email" // 在线仓库模式go
|
|||
//"github.com/flipped-aurora/gin-vue-admin/server/plugin/email" // 本地插件仓库地址模式
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/plugin/example_plugin" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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, |
|||
)) |
|||
|
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
package initialize |
|||
|
|||
import ( |
|||
"context" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/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.Any("err", err)) |
|||
} else { |
|||
global.GVA_LOG.Info("redis connect ping response:", zap.String("pong", pong)) |
|||
global.GVA_REDIS = client |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
package initialize |
|||
|
|||
import ( |
|||
"net/http" |
|||
|
|||
_ "github.com/flipped-aurora/gin-vue-admin/server/docs" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/middleware" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/router" |
|||
"github.com/gin-gonic/gin" |
|||
"github.com/swaggo/gin-swagger" |
|||
"github.com/swaggo/gin-swagger/swaggerFiles" |
|||
) |
|||
|
|||
// 初始化总路由
|
|||
|
|||
func Routers() *gin.Engine { |
|||
var 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()) // 如需跨域可以打开
|
|||
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 |
|||
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.InitSysOperationRecordRouter(PrivateGroup) // 操作记录
|
|||
systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理
|
|||
exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由
|
|||
exampleRouter.InitExcelRouter(PrivateGroup) // 表格导入导出
|
|||
exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由
|
|||
|
|||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server Begin; DO NOT EDIT.
|
|||
autocodeRouter.InitSysAutoCodeExampleRouter(PrivateGroup) |
|||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server End; DO NOT EDIT.
|
|||
} |
|||
|
|||
InstallPlugin(PublicGroup, PrivateGroup) // 安装插件
|
|||
|
|||
global.GVA_LOG.Info("router register success") |
|||
return Router |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
package initialize |
|||
|
|||
import ( |
|||
"fmt" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/config" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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]) |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
package initialize |
|||
|
|||
import "github.com/flipped-aurora/gin-vue-admin/server/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()}, |
|||
}, |
|||
) |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/28 - 10:28:19.554 [31merror[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/api/v1/system/sys_initdb.go:34 自动创建数据库失败! {"err": "Error 1045: Access denied for user 'root'@'localhost' (using password: YES)"} |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/28 - 10:28:29.736 [31merror[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/api/v1/system/sys_initdb.go:34 自动创建数据库失败! {"err": "Error 1045: Access denied for user 'root'@'localhost' (using password: YES)"} |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/28 - 10:28:42.301 [31merror[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/api/v1/system/sys_initdb.go:34 自动创建数据库失败! {"err": "Error 1045: Access denied for user 'root'@'localhost' (using password: YES)"} |
|||
@ -0,0 +1,26 @@ |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/28 - 10:21:37.972 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:31 use middleware logger |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/28 - 10:21:37.973 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:34 use middleware cors |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/28 - 10:21:37.973 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:36 register swagger handler |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/28 - 10:21:37.973 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:79 router register success |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/28 - 10:21:37.992 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/core/server.go:37 server run success on {"address": ":8888"} |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/28 - 10:28:07.133 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/api/v1/system/sys_initdb.go:52 前往初始化数据库 |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/28 - 10:39:39.739 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/api/v1/system/sys_initdb.go:52 前往初始化数据库 |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 09:48:02.681 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/gorm.go:62 register table success |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 09:48:02.734 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:31 use middleware logger |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 09:48:02.734 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:34 use middleware cors |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 09:48:02.734 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:36 register swagger handler |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 09:48:02.735 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:79 router register success |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 09:48:02.738 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/core/server.go:37 server run success on {"address": ":8888"} |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 13:03:45.227 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/api/v1/system/sys_initdb.go:48 数据库无需初始化 |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 13:46:21.044 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/gorm.go:62 register table success |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 13:46:21.045 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:31 use middleware logger |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 13:46:21.045 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:34 use middleware cors |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 13:46:21.045 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:36 register swagger handler |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 13:46:21.046 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:79 router register success |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/10/29 - 13:46:21.056 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/core/server.go:37 server run success on {"address": ":8888"} |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/11/01 - 08:00:11.465 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/gorm.go:62 register table success |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/11/01 - 08:00:11.510 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:31 use middleware logger |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/11/01 - 08:00:11.510 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:34 use middleware cors |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/11/01 - 08:00:11.510 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:36 register swagger handler |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/11/01 - 08:00:11.510 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/initialize/router.go:79 router register success |
|||
[github.com/flipped-aurora/gin-vue-admin/server]2021/11/01 - 08:00:11.516 [34minfo[0m l:/任官钰/代码/gin-vue-admin-master/gin-vue-admin-master/server/core/server.go:37 server run success on {"address": ":8888"} |
|||
@ -0,0 +1,33 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/core" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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() |
|||
if global.GVA_DB != nil { |
|||
initialize.MysqlTables(global.GVA_DB) // 初始化表
|
|||
// 程序结束前关闭数据库链接
|
|||
db, _ := global.GVA_DB.DB() |
|||
defer db.Close() |
|||
} |
|||
core.RunWindowsServer() |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
package middleware |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/service" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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) |
|||
// 获取请求的URI
|
|||
obj := c.Request.URL.RequestURI() |
|||
// 获取请求方法
|
|||
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 |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
package middleware |
|||
|
|||
import ( |
|||
"github.com/gin-gonic/gin" |
|||
"net/http" |
|||
) |
|||
|
|||
// 处理跨域请求,支持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() |
|||
} |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
package middleware |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/plugin/email/utils" |
|||
utils2 "github.com/flipped-aurora/gin-vue-admin/server/utils" |
|||
"io/ioutil" |
|||
"strconv" |
|||
"time" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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.Any("err", err)) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
package middleware |
|||
|
|||
import ( |
|||
"net" |
|||
"net/http" |
|||
"net/http/httputil" |
|||
"os" |
|||
"runtime/debug" |
|||
"strings" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/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() |
|||
} |
|||
} |
|||
@ -0,0 +1,72 @@ |
|||
package middleware |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/utils" |
|||
"strconv" |
|||
"time" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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.Any("err", err)) |
|||
} else { // 当之前的取成功时才进行拉黑操作
|
|||
_ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: RedisJwtToken}) |
|||
} |
|||
// 无论如何都要记录当前的活跃状态
|
|||
_ = jwtService.SetRedisJWT(newToken, newClaims.Username) |
|||
} |
|||
} |
|||
c.Set("claims", claims) |
|||
c.Next() |
|||
} |
|||
} |
|||
@ -0,0 +1,94 @@ |
|||
package middleware |
|||
|
|||
import ( |
|||
"context" |
|||
"errors" |
|||
"net/http" |
|||
"time" |
|||
|
|||
"go.uber.org/zap" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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() |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
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() |
|||
} |
|||
} |
|||
@ -0,0 +1,87 @@ |
|||
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() |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
package middleware |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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() |
|||
} |
|||
// 处理请求
|
|||
} |
|||
} |
|||
@ -0,0 +1,85 @@ |
|||
package middleware |
|||
|
|||
import ( |
|||
"bytes" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/utils" |
|||
"io/ioutil" |
|||
"net/http" |
|||
"strconv" |
|||
"time" |
|||
|
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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.Any("err", 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.Any("err", 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) |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
// 自动生成模板SysDictionaryDetail
|
|||
package autocode |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
) |
|||
|
|||
// 如果含有time.Time 请自行import time包
|
|||
type AutoCodeExample struct { |
|||
global.GVA_MODEL |
|||
AutoCodeExampleField string `json:"autoCodeExampleField" form:"autoCodeExampleField" gorm:"column:auto_code_example_field;comment:仅作示例条目无实际作用"` // 展示值
|
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
// 自动生成模板SysDictionaryDetail
|
|||
package request |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/autocode" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request" |
|||
) |
|||
|
|||
// 如果含有time.Time 请自行import time包
|
|||
type AutoCodeExampleSearch struct { |
|||
autocode.AutoCodeExample |
|||
request.PageInfo |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
package request |
|||
|
|||
// Paging common input parameter structure
|
|||
type PageInfo struct { |
|||
Page int `json:"page" form:"page"` // 页码
|
|||
PageSize int `json:"pageSize" form:"pageSize"` // 每页大小
|
|||
} |
|||
|
|||
// Find by id structure
|
|||
type GetById struct { |
|||
ID float64 `json:"id" form:"id"` // 主键ID
|
|||
} |
|||
|
|||
type IdsReq struct { |
|||
Ids []int `json:"ids" form:"ids"` |
|||
} |
|||
|
|||
// Get role by id structure
|
|||
type GetAuthorityId struct { |
|||
AuthorityId string `json:"authorityId" form:"authorityId"` // 角色ID
|
|||
} |
|||
|
|||
type Empty struct{} |
|||
@ -0,0 +1,8 @@ |
|||
package response |
|||
|
|||
type PageResult struct { |
|||
List interface{} `json:"list"` |
|||
Total int64 `json:"total"` |
|||
Page int `json:"page"` |
|||
PageSize int `json:"pageSize"` |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
package response |
|||
|
|||
import ( |
|||
"github.com/gin-gonic/gin" |
|||
"net/http" |
|||
) |
|||
|
|||
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) |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
package example |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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 |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
package example |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/global" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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:管理详情"` // 管理详情
|
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
package example |
|||
|
|||
import "github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
|
|||
type ExcelInfo struct { |
|||
FileName string `json:"fileName"` // 文件名
|
|||
InfoList []system.SysBaseMenu `json:"infoList"` |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
package example |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/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:编号"` // 编号
|
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
package response |
|||
|
|||
import "github.com/flipped-aurora/gin-vue-admin/server/model/example" |
|||
|
|||
type FilePathResponse struct { |
|||
FilePath string `json:"filePath"` |
|||
} |
|||
|
|||
type FileResponse struct { |
|||
File example.ExaFile `json:"file"` |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
package response |
|||
|
|||
import "github.com/flipped-aurora/gin-vue-admin/server/model/example" |
|||
|
|||
type ExaCustomerResponse struct { |
|||
Customer example.ExaCustomer `json:"customer"` |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
package response |
|||
|
|||
import "github.com/flipped-aurora/gin-vue-admin/server/model/example" |
|||
|
|||
type ExaFileResponse struct { |
|||
File example.ExaFileUploadAndDownload `json:"file"` |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
package request |
|||
|
|||
import ( |
|||
"github.com/dgrijalva/jwt-go" |
|||
uuid "github.com/satori/go.uuid" |
|||
) |
|||
|
|||
// Custom claims structure
|
|||
type CustomClaims struct { |
|||
BaseClaims |
|||
BufferTime int64 |
|||
jwt.StandardClaims |
|||
} |
|||
|
|||
type BaseClaims struct { |
|||
UUID uuid.UUID |
|||
ID uint |
|||
Username string |
|||
NickName string |
|||
AuthorityId string |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
package request |
|||
|
|||
import ( |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request" |
|||
"github.com/flipped-aurora/gin-vue-admin/server/model/system" |
|||
) |
|||
|
|||
// api分页条件查询及排序结构体
|
|||
type SearchApiParams struct { |
|||
system.SysApi |
|||
request.PageInfo |
|||
OrderKey string `json:"orderKey"` // 排序
|
|||
Desc bool `json:"desc"` // 排序方式:升序false(默认)|降序true
|
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue