mirror of
https://github.com/flipped-aurora/gin-vue-admin.git
synced 2026-09-25 05:50:19 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33cb2ed43d | ||
|
|
b56e521c5f | ||
|
|
639b930ac9 | ||
|
|
607235eb01 | ||
|
|
dbfeb4b0fa | ||
|
|
432725b80d | ||
|
|
91c2909c4a | ||
|
|
699a2f7956 | ||
|
|
7c2751ad37 | ||
|
|
50b524fa7a | ||
|
|
aee26bc9b2 | ||
|
|
78de254230 | ||
|
|
22fe4053e9 | ||
|
|
e73f9ac8f2 | ||
|
|
19987234e5 | ||
|
|
33239f28f8 | ||
|
|
350f4572ed | ||
|
|
ab29267d64 | ||
|
|
b410820868 | ||
|
|
b1268e0001 | ||
|
|
9fe661269d | ||
|
|
a715a77e76 | ||
|
|
20933f77f5 | ||
|
|
c618fcafaa | ||
|
|
350ce2ad35 | ||
|
|
eef8580e89 | ||
|
|
406fc05970 | ||
|
|
2b6cb775d8 | ||
|
|
fe27fd4c86 | ||
|
|
784dca2baa | ||
|
|
6cff6414c2 | ||
|
|
b84b6c3464 | ||
|
|
bd3931d62d | ||
|
|
7ababb626b | ||
|
|
62b2833c2f | ||
|
|
190c82bbe6 | ||
|
|
b8055d45e7 | ||
|
|
fe09bb3c91 | ||
|
|
84d0a91c44 | ||
|
|
9d95f660e3 | ||
|
|
2d76d1f50c | ||
|
|
df3b921654 | ||
|
|
e98fccdcfd | ||
|
|
7b9b940b6a | ||
|
|
3a4b750d93 | ||
|
|
40e3555d13 | ||
|
|
4b6adb3919 | ||
|
|
66aece580f | ||
|
|
09fc200d55 | ||
|
|
b17b56dba0 | ||
|
|
a9d0531a56 | ||
|
|
a7a2c85f82 | ||
|
|
83a06fcd2b | ||
|
|
d2d7b22a8f | ||
|
|
92b78ab3c8 | ||
|
|
0bed3bab98 | ||
|
|
a60637fb79 | ||
|
|
f1218264be | ||
|
|
18cf63facc | ||
|
|
9f8e1775af | ||
|
|
0e39f3ad05 | ||
|
|
4fc90c0168 | ||
|
|
57b4f539f9 | ||
|
|
8667ce5fb4 | ||
|
|
0ed922bb29 | ||
|
|
80eff97be3 | ||
|
|
e5cfe5cd99 | ||
|
|
1d8b952a6d | ||
|
|
c204f7a514 | ||
|
|
6e2ef1e29c | ||
|
|
5f0402043a | ||
|
|
6ad7ccdd6e | ||
|
|
90a2fd7f19 | ||
|
|
58c8b11f85 | ||
|
|
4d700be9ae | ||
|
|
da0d02b990 | ||
|
|
854cb59f6b | ||
|
|
33cbee23d4 | ||
|
|
0497cf384d | ||
|
|
acd8fa3810 | ||
|
|
9d024bca3b | ||
|
|
7434c9db55 | ||
|
|
a3ab0b3243 | ||
|
|
64608f6b05 | ||
|
|
a207c982b7 | ||
|
|
072acac399 | ||
|
|
8049466dff | ||
|
|
80077ba94d | ||
|
|
bd4744557f | ||
|
|
d8072634ef | ||
|
|
27158f7075 | ||
|
|
f06f1fb7f1 | ||
|
|
8bb7b75f05 | ||
|
|
0c9e92abb0 | ||
|
|
7a8787b1a0 | ||
|
|
78f71c8b13 | ||
|
|
a0a35e8253 | ||
|
|
e892e3f9e1 | ||
|
|
2dadc98485 | ||
|
|
1bd2b4629e | ||
|
|
ce52cbf6ac | ||
|
|
0abcb5aba1 | ||
|
|
ca7bdc913e | ||
|
|
2de7d34b4a | ||
|
|
0eea78f796 | ||
|
|
95fa7e8130 | ||
|
|
fd78876dd3 | ||
|
|
eaa3075516 | ||
|
|
92338fd219 | ||
|
|
26d32c02ea | ||
|
|
e03efc33d7 | ||
|
|
2d1188af11 | ||
|
|
66666ed5fd | ||
|
|
dfcb283899 | ||
|
|
24215f8b28 | ||
|
|
ddc2b4c2ad | ||
|
|
10cef483f4 | ||
|
|
51dde2f71e | ||
|
|
5e0117e7c6 | ||
|
|
3b3535faec | ||
|
|
3e1067faba | ||
|
|
722382f60e | ||
|
|
e47a512fc8 | ||
|
|
0627359b6e | ||
|
|
01d1e4c7f5 | ||
|
|
3f564e8179 | ||
|
|
b6f3038a73 | ||
|
|
e67354f34c | ||
|
|
a04982425f | ||
|
|
2e6f99edf0 | ||
|
|
9307d08bb6 | ||
|
|
2cdcd98e08 | ||
|
|
7540ee942f | ||
|
|
7bfad03b2e | ||
|
|
9dacd7056b | ||
|
|
4ebe66a29c | ||
|
|
6ebed9eff6 | ||
|
|
cc13685062 | ||
|
|
6b28490d7b | ||
|
|
27ba592434 | ||
|
|
cf5daffe69 | ||
|
|
192c0e529d | ||
|
|
c300e16de9 | ||
|
|
e46eecfc8e | ||
|
|
1e2add4b97 | ||
|
|
975f515691 | ||
|
|
05f8ae2aae | ||
|
|
525b3a0da9 | ||
|
|
03265e03fc | ||
|
|
28c928890a | ||
|
|
6f3e8683a0 | ||
|
|
ba7a16250b | ||
|
|
1cbbce741a | ||
|
|
9f9f6b7a08 |
@@ -1,64 +0,0 @@
|
||||
name: gin-vue-admin build test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "*"
|
||||
paths-ignore:
|
||||
- "./db/**"
|
||||
- "**.md"
|
||||
pull_request:
|
||||
branches:
|
||||
- "*"
|
||||
paths-ignore:
|
||||
- "./db/**"
|
||||
- "**.md"
|
||||
|
||||
jobs:
|
||||
frontend:
|
||||
name: Frontend build
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.8.0]
|
||||
steps:
|
||||
- name: Check out branch
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Build test
|
||||
run: |
|
||||
npm install
|
||||
npm run build
|
||||
working-directory: ./web
|
||||
|
||||
backend:
|
||||
name: Backend build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go 1.6
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.16
|
||||
id: go
|
||||
|
||||
- name: Check out branch
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Download dependencies
|
||||
run: |
|
||||
go get -v -t -d ./...
|
||||
if [ -f Gopkg.toml ]; then
|
||||
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||
dep ensure
|
||||
fi
|
||||
working-directory: ./server
|
||||
|
||||
- name: Test and Build
|
||||
run: |
|
||||
go build -v -race
|
||||
working-directory: ./server
|
||||
@@ -0,0 +1,269 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ '*' ]
|
||||
pull_request:
|
||||
release:
|
||||
types: [ created, edited ]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
gva_version:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
init:
|
||||
if: github.repository_owner == 'flipped-aurora'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: init
|
||||
run: |
|
||||
echo "flipped-aurora"
|
||||
frontend:
|
||||
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'release'
|
||||
name: Frontend node ${{ matrix.node-version }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.8.0]
|
||||
steps:
|
||||
- name: Check out branch
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Build test
|
||||
run: |
|
||||
npm install
|
||||
npm run build
|
||||
working-directory: ./web
|
||||
|
||||
backend:
|
||||
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'release'
|
||||
name: Backend go
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.18]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }}
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
|
||||
- name: Check out branch
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Download dependencies
|
||||
run: |
|
||||
go get -v -t -d ./...
|
||||
if [ -f Gopkg.toml ]; then
|
||||
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||
dep ensure
|
||||
fi
|
||||
working-directory: ./server
|
||||
|
||||
- name: Test and Build
|
||||
run: |
|
||||
go build -v -race
|
||||
working-directory: ./server
|
||||
|
||||
devops-test:
|
||||
if: github.ref == 'refs/heads/test'
|
||||
name: devops-test
|
||||
needs:
|
||||
- init
|
||||
- backend
|
||||
- frontend
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.8.0]
|
||||
go-version: [1.18]
|
||||
steps:
|
||||
- name: Check out branch
|
||||
uses: actions/checkout@v2
|
||||
- name: Sed Config
|
||||
env:
|
||||
PROD: ${{ secrets.PROD }}
|
||||
TESTING: ${{ secrets.TESTING }}
|
||||
shell: bash
|
||||
run: |
|
||||
git branch
|
||||
ls -l
|
||||
sed -i "s/${PROD}/${TESTING}/g" web/.env.production
|
||||
sed -i 's/${basePath}:${basePort}/${basePath}/g' web/src/view/systemTools/formCreate/index.vue
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.1.2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Build-Node
|
||||
run: |
|
||||
cd web/ && yarn install && yarn run build
|
||||
- name: Use Go ${{ matrix.go-version }}
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Build-go
|
||||
run: |
|
||||
cd server/ && go mod tidy && CGO_ENABLED=0 go build && mkdir ../web/ser && mv server ../web/ser/ && cd ../web/ser/ && ls -s
|
||||
- name: restart
|
||||
env:
|
||||
KEY: ${{ secrets.KEY }}
|
||||
HOST: ${{ secrets.HOST }}
|
||||
USER: ${{ secrets.USER }}
|
||||
PROT: ${{ secrets.PROT }}
|
||||
MKDIRTEST: ${{ secrets.MKDIRTEST }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh/ && echo "$KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
|
||||
ssh-keyscan github.com >> ~/.ssh/known_hosts
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/dist/* ${USER}@${HOST}:${MKDIRTEST}dist/
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/ser/* ${USER}@${HOST}:${MKDIRTEST}
|
||||
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIRTEST}resource/ && rm -rf ${MKDIRTEST}resource/*"
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r server/resource/* ${USER}@${HOST}:${MKDIRTEST}resource/
|
||||
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIRTEST} && bash restart.sh > /dev/null 2>&1 &"
|
||||
|
||||
release-pr:
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.repository_owner == 'flipped-aurora'}}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out branch
|
||||
uses: actions/checkout@v2
|
||||
- name: Sed Config
|
||||
env:
|
||||
GVA_VERSION: ${{ inputs.gva_version }}
|
||||
shell: bash
|
||||
run: |
|
||||
sed -i 's/当前版本.*`$/当前版本:v'${GVA_VERSION##v}'`/' web/src/core/config.js
|
||||
sed -i 's/当前版本.*$/当前版本:v'${GVA_VERSION##v}'/' server/core/server.go
|
||||
sed -i 's/当前版本.*$/当前版本:v'${GVA_VERSION##v}'/' web/src/core/gin-vue-admin.js
|
||||
sed -i 's/"version": ".*",$/"version": "'${GVA_VERSION##v}'",/' web/package.json
|
||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git add . && git commit -m "release: v${GVA_VERSION##v}"
|
||||
- name: Push
|
||||
uses: ad-m/github-push-action@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ github.ref }}
|
||||
- uses: google-github-actions/release-please-action@v3
|
||||
with:
|
||||
command: release-pr
|
||||
release-type: simple
|
||||
changelog-path: docs/CHANGELOG.md
|
||||
release-as: ${{ inputs.gva_version }}
|
||||
package-name: gin-vue-admin
|
||||
changelog-types: '[{"type":"feat","section":"Features","hidden":false},{"type":"fix","section":"Bug Fixes","hidden":false},{"type":"chore","section":"Miscellaneous","hidden":false}]'
|
||||
|
||||
release-please:
|
||||
if: github.ref == 'refs/heads/main' || github.event_name == 'release'
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- init
|
||||
- backend
|
||||
- frontend
|
||||
outputs:
|
||||
release_created: ${{ steps.release_please.outputs.release_created }}
|
||||
tag_name: ${{ steps.release_please.outputs.tag_name }}
|
||||
steps:
|
||||
- uses: google-github-actions/release-please-action@v3
|
||||
id: release_please
|
||||
with:
|
||||
#token: ${{ secrets.GAV_TOKEN }}
|
||||
command: github-release
|
||||
#signoff: "github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
|
||||
release-type: simple
|
||||
changelog-path: docs/CHANGELOG.md
|
||||
#release-as: ${{ inputs.deploy_target }}
|
||||
package-name: gin-vue-admin
|
||||
#extra-files: |
|
||||
# x-release-please-version.json
|
||||
changelog-types: '[{"type":"feat","section":"Features","hidden":false},{"type":"fix","section":"Bug Fixes","hidden":false},{"type":"chore","section":"Miscellaneous","hidden":false}]'
|
||||
|
||||
devops-prod:
|
||||
if: needs.release-please.outputs.release_created || github.event_name == 'release'
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- init
|
||||
- release-please
|
||||
name: devops-prod
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: ['16.x']
|
||||
go-version: ['1.18']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: tag major and minor versions
|
||||
run: |
|
||||
echo " ${{ needs.release-please.outputs.tag_name }}"
|
||||
- name: Sed Config
|
||||
shell: bash
|
||||
run: |
|
||||
git branch
|
||||
ls -l
|
||||
sed -i 's/${basePath}:${basePort}/${basePath}/g' web/src/view/systemTools/formCreate/index.vue
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.1.2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Build-Node
|
||||
run: |
|
||||
cd web/ && yarn install && yarn run build
|
||||
- name: Use Go ${{ matrix.go-version }}
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Build-go
|
||||
run: |
|
||||
cd server/ && go mod tidy && CGO_ENABLED=0 go build && mkdir ../web/ser && mv server ../web/ser/ && cd ../web/ser/ && ls -s
|
||||
- name: restart
|
||||
env:
|
||||
KEY: ${{ secrets.KEY }}
|
||||
HOST: ${{ secrets.HOST }}
|
||||
USER: ${{ secrets.USER }}
|
||||
PROT: ${{ secrets.PROT }}
|
||||
MKDIR: ${{ secrets.MKDIR }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh/ && echo "$KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
|
||||
ssh-keyscan github.com >> ~/.ssh/known_hosts
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/dist/* ${USER}@${HOST}:${MKDIR}dist/
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/ser/* ${USER}@${HOST}:${MKDIR}
|
||||
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR}resource/ && rm -rf ${MKDIR}resource/*"
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r server/resource/* ${USER}@${HOST}:${MKDIR}resource/
|
||||
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR} && bash restart.sh > /dev/null 2>&1 &"
|
||||
|
||||
docker:
|
||||
name: docker
|
||||
if: github.ref == 'refs/heads/stop-stop-stop'
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- init
|
||||
- release-please
|
||||
steps:
|
||||
- name: Check out branch
|
||||
uses: actions/checkout@v2
|
||||
- name: Login to Aliyun Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ${{ secrets.ALIYUN_REGISTRY }}
|
||||
username: ${{ secrets.ALIYUN_DOCKERHUB_USER }}
|
||||
password: ${{ secrets.ALIYUN_DOCKERHUB_PASSWORD }}
|
||||
- name: Sed Config
|
||||
shell: bash
|
||||
run: |
|
||||
sed -i 56c"\ && yarn install && yarn build" Makefile
|
||||
make image TAGS_OPT="latest"
|
||||
sed -i 's#./entrypoint.sh"#./entrypoint.sh","actions"#g' deploy/docker/Dockerfile
|
||||
sed -i "s#COPY build/ /usr/share/nginx/html/#COPY . /opt/gva#g" deploy/docker/Dockerfile
|
||||
sed -i 16c"\ && cd /opt/gva/server/ && go mod tidy && cd /opt/gva/web/ && yarn" deploy/docker/Dockerfile
|
||||
sed -i "s#open: true#open: false#g" web/vite.config.js
|
||||
make images TAGS_OPT="latest"
|
||||
docker push registry.cn-hangzhou.aliyuncs.com/gva/gin-vue-admin:latest
|
||||
docker push registry.cn-hangzhou.aliyuncs.com/gva/web:latest
|
||||
docker push registry.cn-hangzhou.aliyuncs.com/gva/server:latest
|
||||
docker push registry.cn-hangzhou.aliyuncs.com/gva/all:latest
|
||||
@@ -1,55 +0,0 @@
|
||||
name: devops-test
|
||||
on:
|
||||
push:
|
||||
branches: [test]
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: ['16.x']
|
||||
go-version: ['1.16']
|
||||
steps:
|
||||
- name: Check out branch
|
||||
uses: actions/checkout@v2
|
||||
- name: Sed Config
|
||||
env:
|
||||
PROD: ${{ secrets.PROD }}
|
||||
TESTING: ${{ secrets.TESTING }}
|
||||
shell: bash
|
||||
run: |
|
||||
git branch
|
||||
ls -l
|
||||
sed -i "s/${PROD}/${TESTING}/g" web/.env.production
|
||||
sed -i 's/${basePath}:${basePort}/${basePath}/g' web/src/view/systemTools/formCreate/index.vue
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.1.2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Build-Node
|
||||
run: |
|
||||
cd web/ && yarn install && yarn run build
|
||||
- name: Use Go ${{ matrix.go-version }}
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Build-go
|
||||
run: |
|
||||
cd server/ && go mod tidy && go build && mkdir ../web/ser && mv server ../web/ser/ && cd ../web/ser/ && ls -s
|
||||
- name: restart
|
||||
env:
|
||||
KEY: ${{ secrets.KEY }}
|
||||
HOST: ${{ secrets.HOST }}
|
||||
USER: ${{ secrets.USER }}
|
||||
PROT: ${{ secrets.PROT }}
|
||||
MKDIRTEST: ${{ secrets.MKDIRTEST }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh/ && echo "$KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
|
||||
ssh-keyscan github.com >> ~/.ssh/known_hosts
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/dist/* ${USER}@${HOST}:${MKDIRTEST}dist/
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/ser/* ${USER}@${HOST}:${MKDIRTEST}
|
||||
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIRTEST}resource/ && rm -rf ${MKDIRTEST}resource/*"
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r server/resource/* ${USER}@${HOST}:${MKDIRTEST}resource/
|
||||
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIRTEST} && bash restart.sh > /dev/null 2>&1 &"
|
||||
@@ -1,52 +0,0 @@
|
||||
name: devops
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: ['16.x']
|
||||
go-version: ['1.16']
|
||||
steps:
|
||||
- name: Check out branch
|
||||
uses: actions/checkout@v2
|
||||
- name: Sed Config
|
||||
shell: bash
|
||||
run: |
|
||||
git branch
|
||||
ls -l
|
||||
sed -i 's/${basePath}:${basePort}/${basePath}/g' web/src/view/systemTools/formCreate/index.vue
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.1.2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Build-Node
|
||||
run: |
|
||||
cd web/ && yarn install && yarn run build
|
||||
- name: Use Go ${{ matrix.go-version }}
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Build-go
|
||||
run: |
|
||||
cd server/ && go mod tidy && go build && mkdir ../web/ser && mv server ../web/ser/ && cd ../web/ser/ && ls -s
|
||||
- name: restart
|
||||
env:
|
||||
KEY: ${{ secrets.KEY }}
|
||||
HOST: ${{ secrets.HOST }}
|
||||
USER: ${{ secrets.USER }}
|
||||
PROT: ${{ secrets.PROT }}
|
||||
MKDIR: ${{ secrets.MKDIR }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh/ && echo "$KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
|
||||
ssh-keyscan github.com >> ~/.ssh/known_hosts
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/dist/* ${USER}@${HOST}:${MKDIR}dist/
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/ser/* ${USER}@${HOST}:${MKDIR}
|
||||
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR}resource/ && rm -rf ${MKDIR}resource/*"
|
||||
scp -P ${PROT} -o StrictHostKeyChecking=no -r server/resource/* ${USER}@${HOST}:${MKDIR}resource/
|
||||
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR} && bash restart.sh > /dev/null 2>&1 &"
|
||||
@@ -1,32 +0,0 @@
|
||||
name: Docker-CICD
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out branch
|
||||
uses: actions/checkout@v2
|
||||
- name: Login to Aliyun Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ${{ secrets.ALIYUN_REGISTRY }}
|
||||
username: ${{ secrets.ALIYUN_DOCKERHUB_USER }}
|
||||
password: ${{ secrets.ALIYUN_DOCKERHUB_PASSWORD }}
|
||||
- name: Sed Config
|
||||
shell: bash
|
||||
run: |
|
||||
sed -i 56c"\ && yarn install && yarn build" Makefile
|
||||
make image TAGS_OPT="latest"
|
||||
sed -i 's#./entrypoint.sh"#./entrypoint.sh","actions"#g' deploy/docker/Dockerfile
|
||||
sed -i "s#COPY build/ /usr/share/nginx/html/#COPY . /opt/gva#g" deploy/docker/Dockerfile
|
||||
sed -i 16c"\ && cd /opt/gva/server/ && go mod tidy && cd /opt/gva/web/ && yarn" deploy/docker/Dockerfile
|
||||
sed -i "s#open: true#open: false#g" web/vite.config.js
|
||||
make images TAGS_OPT="latest"
|
||||
docker push registry.cn-hangzhou.aliyuncs.com/gva/gin-vue-admin:latest
|
||||
docker push registry.cn-hangzhou.aliyuncs.com/gva/web:latest
|
||||
docker push registry.cn-hangzhou.aliyuncs.com/gva/server:latest
|
||||
docker push registry.cn-hangzhou.aliyuncs.com/gva/all:latest
|
||||
@@ -1,114 +0,0 @@
|
||||
name: GIN-VUE-ADMIN Docker Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [stopstopstop]
|
||||
#workflow_dispatch:
|
||||
# inputs:
|
||||
# webtag:
|
||||
# description: 'Set web tag, Default latest'
|
||||
# required: true
|
||||
# default: "latest"
|
||||
# servertag:
|
||||
# description: 'Set server tag, Default latest'
|
||||
# required: true
|
||||
# default: "latest"
|
||||
|
||||
jobs:
|
||||
GIN_VUE_ADMIN_WEB:
|
||||
name: GIN VUE ADMIN WEB
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Private Actions Checkout
|
||||
uses: actions/checkout@v2.3.4
|
||||
- name: Docker Setup QEMU
|
||||
uses: docker/setup-qemu-action@v1.2.0
|
||||
- name: Docker Setup Buildx
|
||||
uses: docker/setup-buildx-action@v1.6.0
|
||||
- name: Docker Login
|
||||
uses: docker/login-action@v1.10.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Docker Login in Aliyun
|
||||
uses: docker/login-action@v1.10.0
|
||||
with:
|
||||
registry: ${{ secrets.DOCKERHUB_REGISTRY_ALIYUN }}
|
||||
username: ${{ secrets.DOCKERHUB_ACCOUNT_ALIYUN }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD_ALIYUN }}
|
||||
- name: Build and push Docker images
|
||||
uses: docker/build-push-action@v2.7.0
|
||||
with:
|
||||
context: .
|
||||
# 这里是适配 arm64 ,主要看你们的程序是否支持 arm64
|
||||
platforms: linux/amd64,linux/arm64
|
||||
file: web/Dockerfile
|
||||
push: true
|
||||
# 这里是给docker 打标签,默认不上传 latest
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/web:${{ github.event.inputs.webtag }}
|
||||
${{ secrets.DOCKERHUB_REGISTRY_ALIYUN }}/${{ secrets.DOCKERHUB_USERNAME_ALIYUN }}web:${{ github.event.inputs.webtag }}
|
||||
cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/web:${{ github.event.inputs.webtag }}.cache
|
||||
cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/web:${{ github.event.inputs.webtag }}.cache,mode=max
|
||||
# 漏洞扫描
|
||||
- name: Scan for vulnerabilities
|
||||
uses: crazy-max/ghaction-container-scan@v1
|
||||
with:
|
||||
image: ${{ secrets.DOCKERHUB_USERNAME }}/web:${{ github.event.inputs.webtag }}
|
||||
dockerfile: web/Dockerfile
|
||||
# 更新 docker 描述页面
|
||||
- name: Docker Hub Description
|
||||
uses: peter-evans/dockerhub-description@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
repository: ${{ secrets.DOCKERHUB_USERNAME }}/web
|
||||
|
||||
GIN_VUE_ADMIN_SERVER:
|
||||
name: GIN VUE ADMIN SERVER
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Private Actions Checkout
|
||||
uses: actions/checkout@v2.3.4
|
||||
- name: Docker Setup QEMU
|
||||
uses: docker/setup-qemu-action@v1.2.0
|
||||
- name: Docker Setup Buildx
|
||||
uses: docker/setup-buildx-action@v1.6.0
|
||||
- name: Docker Login
|
||||
uses: docker/login-action@v1.10.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Docker Login in Aliyun
|
||||
uses: docker/login-action@v1.10.0
|
||||
with:
|
||||
registry: ${{ secrets.DOCKERHUB_REGISTRY_ALIYUN }}
|
||||
username: ${{ secrets.DOCKERHUB_ACCOUNT_ALIYUN }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD_ALIYUN }}
|
||||
- name: Build and push Docker images
|
||||
uses: docker/build-push-action@v2.7.0
|
||||
with:
|
||||
context: .
|
||||
# 这里是适配 arm64 ,主要看你们的程序是否支持 arm64
|
||||
platforms: linux/amd64,linux/arm64
|
||||
file: server/Dockerfile
|
||||
push: true
|
||||
# 这里是给docker 打标签,默认不上传 latest
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/server:${{ github.event.inputs.servertag }}
|
||||
${{ secrets.DOCKERHUB_REGISTRY_ALIYUN }}/${{ secrets.DOCKERHUB_USERNAME_ALIYUN }}server:${{ github.event.inputs.servertag }}
|
||||
cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/server:${{ github.event.inputs.servertag }}.cache
|
||||
cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/server:${{ github.event.inputs.servertag }}.cache,mode=max
|
||||
# 漏洞扫描
|
||||
- name: Scan for vulnerabilities
|
||||
uses: crazy-max/ghaction-container-scan@v1
|
||||
with:
|
||||
image: ${{ secrets.DOCKERHUB_USERNAME }}/server:${{ github.event.inputs.servertag }}
|
||||
dockerfile: server/Dockerfile
|
||||
# 更新 docker 描述页面
|
||||
- name: Docker Hub Description
|
||||
uses: peter-evans/dockerhub-description@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
repository: ${{ secrets.DOCKERHUB_USERNAME }}/server
|
||||
@@ -2,7 +2,7 @@ SHELL = /bin/bash
|
||||
|
||||
#SCRIPT_DIR = $(shell pwd)/etc/script
|
||||
#请选择golang版本
|
||||
BUILD_IMAGE_SERVER = golang:1.16
|
||||
BUILD_IMAGE_SERVER = golang:1.18
|
||||
#请选择node版本
|
||||
BUILD_IMAGE_WEB = node:16
|
||||
#项目名称
|
||||
|
||||
+5
-5
@@ -3,11 +3,11 @@
|
||||
<img src="http://qmplusimg.henrongyi.top/gvalogo.jpg" width=300" height="300" />
|
||||
</div>
|
||||
<div align=center>
|
||||
<img src="https://img.shields.io/badge/golang-1.16-blue"/>
|
||||
<img src="https://img.shields.io/badge/gin-1.7.0-lightBlue"/>
|
||||
<img src="https://img.shields.io/badge/vue-3.2.25-brightgreen"/>
|
||||
<img src="https://img.shields.io/badge/element--plus-2.0.1-green"/>
|
||||
<img src="https://img.shields.io/badge/gorm-1.22.5-red"/>
|
||||
<img src="https://img.shields.io/badge/golang-1.18-blue"/>
|
||||
<img src="https://img.shields.io/badge/gin-1.9.1-lightBlue"/>
|
||||
<img src="https://img.shields.io/badge/vue-3.3.4-brightgreen"/>
|
||||
<img src="https://img.shields.io/badge/element--plus-2.3.8-green"/>
|
||||
<img src="https://img.shields.io/badge/gorm-1.25.2-red"/>
|
||||
</div>
|
||||
|
||||
English | [简体中文](./README.md)
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
<img src="http://qmplusimg.henrongyi.top/gvalogo.jpg" width=300" height="300" />
|
||||
</div>
|
||||
<div align=center>
|
||||
<img src="https://img.shields.io/badge/golang-1.16-blue"/>
|
||||
<img src="https://img.shields.io/badge/gin-1.7.0-lightBlue"/>
|
||||
<img src="https://img.shields.io/badge/vue-3.2.25-brightgreen"/>
|
||||
<img src="https://img.shields.io/badge/element--plus-2.0.1-green"/>
|
||||
<img src="https://img.shields.io/badge/gorm-1.22.5-red"/>
|
||||
<img src="https://img.shields.io/badge/golang-1.18-blue"/>
|
||||
<img src="https://img.shields.io/badge/gin-1.9.1-lightBlue"/>
|
||||
<img src="https://img.shields.io/badge/vue-3.3.4-brightgreen"/>
|
||||
<img src="https://img.shields.io/badge/element--plus-2.3.8-green"/>
|
||||
<img src="https://img.shields.io/badge/gorm-1.25.2-red"/>
|
||||
</div>
|
||||
|
||||
[English](./README-en.md) | 简体中文
|
||||
@@ -66,8 +66,8 @@ Gin-vue-admin 是一套为快速研发准备的一整套前后端分离架构式
|
||||
Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-admin 贡献代码或提供建议,请阅读以下内容。
|
||||
|
||||
#### 1.2.1 Issue 规范
|
||||
- issue 仅用于提交 Bug 或 Feature 以及设计相关的内容,其它内容可能会被直接关闭。如果你在使用时产生了疑问,请到 Slack 或 [Gitter](https://gitter.im/ElemeFE/element) 里咨询。
|
||||
|
||||
- issue 仅用于提交 Bug 或 Feature 以及设计相关的内容,其它内容可能会被直接关闭。
|
||||
|
||||
- 在提交 issue 之前,请搜索相关内容是否已被提出。
|
||||
|
||||
#### 1.2.2 Pull Request 规范
|
||||
@@ -314,8 +314,8 @@ swag init
|
||||
- 前端文件参考: [web/src/view/superAdmin/api/api.vue](https://github.com/flipped-aurora/gin-vue-admin/blob/master/web/src/view/superAdmin/api/api.vue)
|
||||
- 后台文件参考: [server/router/sys_api.go](https://github.com/flipped-aurora/gin-vue-admin/blob/master/server/router/sys_api.go)
|
||||
- 多点登录限制:需要在`config.yaml`中把`system`中的`use-multipoint`修改为true(需要自行配置Redis和Config中的Redis参数,测试阶段,有bug请及时反馈)。
|
||||
- 分片长传:提供文件分片上传和大文件分片上传功能示例。
|
||||
- 表单生成器:表单生成器借助 [@form-generator](https://github.com/JakHuang/form-generator) 。
|
||||
- 分片上传:提供文件分片上传和大文件分片上传功能示例。
|
||||
- 表单生成器:表单生成器借助 [@Variant Form](https://github.com/vform666/variant-form) 。
|
||||
- 代码生成器:后台基础逻辑以及简单curd的代码生成器。
|
||||
|
||||
## 6. 知识库
|
||||
|
||||
@@ -34,7 +34,7 @@ services:
|
||||
ipv4_address: 177.7.0.11
|
||||
|
||||
server:
|
||||
image: golang:1.16
|
||||
image: golang:1.18
|
||||
container_name: gva-server
|
||||
hostname: gva-server
|
||||
restart: always
|
||||
@@ -63,8 +63,10 @@ services:
|
||||
ports:
|
||||
- "13306:3306" # host物理直接映射端口为13306
|
||||
environment:
|
||||
#MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码
|
||||
MYSQL_DATABASE: 'qmPlus' # 初始化启动时要创建的数据库的名称
|
||||
MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码
|
||||
MYSQL_USER: 'gva'
|
||||
MYSQL_PASSWORD: 'Aa@6447985'
|
||||
volumes:
|
||||
- mysql:/var/lib/mysql
|
||||
networks:
|
||||
|
||||
@@ -55,8 +55,10 @@ services:
|
||||
ports:
|
||||
- "13306:3306" # host物理直接映射端口为13306
|
||||
environment:
|
||||
#MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码
|
||||
MYSQL_DATABASE: 'qmPlus' # 初始化启动时要创建的数据库的名称
|
||||
MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码
|
||||
MYSQL_USER: 'gva'
|
||||
MYSQL_PASSWORD: 'Aa@6447985'
|
||||
volumes:
|
||||
- mysql:/var/lib/mysql
|
||||
networks:
|
||||
|
||||
@@ -29,7 +29,7 @@ spec:
|
||||
- containerPort: 8888
|
||||
name: http
|
||||
volumeMounts:
|
||||
- mountPath: /go/src/github.com/flipped-aurora/gin-vue-admin/server/config.yaml
|
||||
- mountPath: /go/src/github.com/flipped-aurora/gin-vue-admin/server/config.docker.yaml
|
||||
name: config
|
||||
subPath: config.yaml
|
||||
- mountPath: /etc/localtime
|
||||
|
||||
@@ -3,13 +3,11 @@ package example
|
||||
import "github.com/flipped-aurora/gin-vue-admin/server/service"
|
||||
|
||||
type ApiGroup struct {
|
||||
ExcelApi
|
||||
CustomerApi
|
||||
FileUploadAndDownloadApi
|
||||
}
|
||||
|
||||
var (
|
||||
excelService = service.ServiceGroupApp.ExampleServiceGroup.ExcelService
|
||||
customerService = service.ServiceGroupApp.ExampleServiceGroup.CustomerService
|
||||
fileUploadAndDownloadService = service.ServiceGroupApp.ExampleServiceGroup.FileUploadAndDownloadService
|
||||
)
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"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/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 文件,作为导入的模板
|
||||
|
||||
// ExportExcel
|
||||
// @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
|
||||
err := c.ShouldBindJSON(&excelInfo)
|
||||
if err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if strings.Index(excelInfo.FileName, "..") > -1 {
|
||||
response.FailWithMessage("包含非法字符", c)
|
||||
return
|
||||
}
|
||||
filePath := global.GVA_CONFIG.Excel.Dir + excelInfo.FileName
|
||||
err = excelService.ParseInfoList2Excel(excelInfo.InfoList, filePath)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("转换Excel失败!", zap.Error(err))
|
||||
response.FailWithMessage("转换Excel失败", c)
|
||||
return
|
||||
}
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
// ImportExcel
|
||||
// @Tags excel
|
||||
// @Summary 导入Excel文件
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file formData file true "导入Excel文件"
|
||||
// @Success 200 {object} response.Response{msg=string} "导入Excel文件"
|
||||
// @Router /excel/importExcel [post]
|
||||
func (e *ExcelApi) ImportExcel(c *gin.Context) {
|
||||
_, header, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("接收文件失败!", zap.Error(err))
|
||||
response.FailWithMessage("接收文件失败", c)
|
||||
return
|
||||
}
|
||||
_ = c.SaveUploadedFile(header, global.GVA_CONFIG.Excel.Dir+"ExcelImport.xlsx")
|
||||
response.OkWithMessage("导入成功", c)
|
||||
}
|
||||
|
||||
// LoadExcel
|
||||
// @Tags excel
|
||||
// @Summary 加载Excel数据
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "加载Excel数据,返回包括列表,总数,页码,每页数量"
|
||||
// @Router /excel/loadExcel [get]
|
||||
func (e *ExcelApi) LoadExcel(c *gin.Context) {
|
||||
menus, err := excelService.ParseExcel2InfoList()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("加载数据失败!", zap.Error(err))
|
||||
response.FailWithMessage("加载数据失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: menus,
|
||||
Total: int64(len(menus)),
|
||||
Page: 1,
|
||||
PageSize: 999,
|
||||
}, "加载数据成功", c)
|
||||
}
|
||||
|
||||
// DownloadTemplate
|
||||
// @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
|
||||
|
||||
fi, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("文件不存在!", zap.Error(err))
|
||||
response.FailWithMessage("文件不存在", c)
|
||||
return
|
||||
}
|
||||
if fi.IsDir() {
|
||||
global.GVA_LOG.Error("不支持下载文件夹!", zap.Error(err))
|
||||
response.FailWithMessage("不支持下载文件夹", c)
|
||||
return
|
||||
}
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.File(filePath)
|
||||
}
|
||||
@@ -17,6 +17,7 @@ type ApiGroup struct {
|
||||
AutoCodeHistoryApi
|
||||
DictionaryDetailApi
|
||||
AuthorityBtnApi
|
||||
ChatGptApi
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -35,4 +36,5 @@ var (
|
||||
autoCodeHistoryService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeHistoryService
|
||||
dictionaryDetailService = service.ServiceGroupApp.SystemServiceGroup.DictionaryDetailService
|
||||
authorityBtnService = service.ServiceGroupApp.SystemServiceGroup.AuthorityBtnService
|
||||
chatGptService = service.ServiceGroupApp.SystemServiceGroup.ChatGptService
|
||||
)
|
||||
|
||||
@@ -212,3 +212,20 @@ func (s *SystemApiApi) DeleteApisByIds(c *gin.Context) {
|
||||
}
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
|
||||
// FreshCasbin
|
||||
// @Tags SysApi
|
||||
// @Summary 刷新casbin缓存
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{msg=string} "刷新成功"
|
||||
// @Router /api/freshCasbin [get]
|
||||
func (s *SystemApiApi) FreshCasbin(c *gin.Context) {
|
||||
err := apiService.FreshCasbin()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("刷新失败!", zap.Error(err))
|
||||
response.FailWithMessage("刷新失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithMessage("刷新成功", c)
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ type AuthorityBtnApi struct{}
|
||||
func (a *AuthorityBtnApi) GetAuthorityBtn(c *gin.Context) {
|
||||
var req request.SysAuthorityBtnReq
|
||||
err := c.ShouldBindJSON(&req)
|
||||
if err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
res, err := authorityBtnService.GetAuthorityBtn(req)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||
|
||||
@@ -11,8 +11,6 @@ import (
|
||||
"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/utils"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
@@ -20,8 +18,6 @@ import (
|
||||
|
||||
type AutoCodeApi struct{}
|
||||
|
||||
var caser = cases.Title(language.English)
|
||||
|
||||
// PreviewTemp
|
||||
// @Tags AutoCode
|
||||
// @Summary 预览创建后的代码
|
||||
@@ -39,7 +35,7 @@ func (autoApi *AutoCodeApi) PreviewTemp(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
a.Pretreatment() // 处理go关键字
|
||||
a.PackageT = caser.String(a.Package)
|
||||
a.PackageT = utils.FirstUpper(a.Package)
|
||||
autoCode, err := autoCodeService.PreviewTemp(a)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("预览失败!", zap.Error(err))
|
||||
@@ -77,7 +73,7 @@ func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) {
|
||||
apiIds = ids
|
||||
}
|
||||
}
|
||||
a.PackageT = caser.String(a.Package)
|
||||
a.PackageT = utils.FirstUpper(a.Package)
|
||||
err := autoCodeService.CreateTemp(a, apiIds...)
|
||||
if err != nil {
|
||||
if errors.Is(err, system.ErrAutoMove) {
|
||||
@@ -106,12 +102,22 @@ func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) {
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前所有数据库"
|
||||
// @Router /autoCode/getDatabase [get]
|
||||
func (autoApi *AutoCodeApi) GetDB(c *gin.Context) {
|
||||
dbs, err := autoCodeService.Database().GetDB()
|
||||
businessDB := c.Query("businessDB")
|
||||
dbs, err := autoCodeService.Database(businessDB).GetDB(businessDB)
|
||||
var dbList []map[string]interface{}
|
||||
for _, db := range global.GVA_CONFIG.DBList {
|
||||
var item = make(map[string]interface{})
|
||||
item["aliasName"] = db.AliasName
|
||||
item["dbName"] = db.Dbname
|
||||
item["disable"] = db.Disable
|
||||
item["dbtype"] = db.Type
|
||||
dbList = append(dbList, item)
|
||||
}
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"dbs": dbs}, "获取成功", c)
|
||||
response.OkWithDetailed(gin.H{"dbs": dbs, "dbList": dbList}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +131,8 @@ func (autoApi *AutoCodeApi) GetDB(c *gin.Context) {
|
||||
// @Router /autoCode/getTables [get]
|
||||
func (autoApi *AutoCodeApi) GetTables(c *gin.Context) {
|
||||
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
|
||||
tables, err := autoCodeService.Database().GetTables(dbName)
|
||||
businessDB := c.Query("businessDB")
|
||||
tables, err := autoCodeService.Database(businessDB).GetTables(businessDB, dbName)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询table失败!", zap.Error(err))
|
||||
response.FailWithMessage("查询table失败", c)
|
||||
@@ -143,9 +150,10 @@ func (autoApi *AutoCodeApi) GetTables(c *gin.Context) {
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前表所有字段"
|
||||
// @Router /autoCode/getColumn [get]
|
||||
func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) {
|
||||
businessDB := c.Query("businessDB")
|
||||
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
|
||||
tableName := c.Query("tableName")
|
||||
columns, err := autoCodeService.Database().GetColumn(tableName, dbName)
|
||||
columns, err := autoCodeService.Database(businessDB).GetColumn(businessDB, tableName, dbName)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
@@ -172,6 +180,7 @@ func (autoApi *AutoCodeApi) CreatePackage(c *gin.Context) {
|
||||
}
|
||||
err := autoCodeService.CreateAutoCode(&a)
|
||||
if err != nil {
|
||||
|
||||
global.GVA_LOG.Error("创建成功!", zap.Error(err))
|
||||
response.FailWithMessage("创建失败", c)
|
||||
} else {
|
||||
@@ -253,7 +262,7 @@ func (autoApi *AutoCodeApi) AutoPlug(c *gin.Context) {
|
||||
// @Produce application/json
|
||||
// @Param plug formData file true "this is a test file"
|
||||
// @Success 200 {object} response.Response{data=[]interface{},msg=string} "安装插件成功"
|
||||
// @Router /autoCode/createPlug [post]
|
||||
// @Router /autoCode/installPlugin [post]
|
||||
func (autoApi *AutoCodeApi) InstallPlugin(c *gin.Context) {
|
||||
header, err := c.FormFile("plug")
|
||||
if err != nil {
|
||||
@@ -283,3 +292,24 @@ func (autoApi *AutoCodeApi) InstallPlugin(c *gin.Context) {
|
||||
"msg": serverStr,
|
||||
}}, c)
|
||||
}
|
||||
|
||||
// PubPlug
|
||||
// @Tags AutoCode
|
||||
// @Summary 打包插件
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysAutoCode true "打包插件"
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "打包插件成功"
|
||||
// @Router /autoCode/pubPlug [get]
|
||||
func (autoApi *AutoCodeApi) PubPlug(c *gin.Context) {
|
||||
plugName := c.Query("plugName")
|
||||
snake := strings.ToLower(plugName)
|
||||
zipPath, err := autoCodeService.PubPlug(snake)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("打包失败!", zap.Error(err))
|
||||
response.FailWithMessage("打包失败"+err.Error(), c)
|
||||
return
|
||||
}
|
||||
response.OkWithMessage(fmt.Sprintf("打包成功,文件路径为:%s", zipPath), c)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"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"
|
||||
@@ -21,9 +23,22 @@ type BaseApi struct{}
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysCaptchaResponse,msg=string} "生成验证码,返回包括随机数id,base64,验证码长度"
|
||||
// @Success 200 {object} response.Response{data=systemRes.SysCaptchaResponse,msg=string} "生成验证码,返回包括随机数id,base64,验证码长度,是否开启验证码"
|
||||
// @Router /base/captcha [post]
|
||||
func (b *BaseApi) Captcha(c *gin.Context) {
|
||||
// 判断验证码是否开启
|
||||
openCaptcha := global.GVA_CONFIG.Captcha.OpenCaptcha // 是否开启防爆次数
|
||||
openCaptchaTimeOut := global.GVA_CONFIG.Captcha.OpenCaptchaTimeOut // 缓存超时时间
|
||||
key := c.ClientIP()
|
||||
v, ok := global.BlackCache.Get(key)
|
||||
if !ok {
|
||||
global.BlackCache.Set(key, 1, time.Second*time.Duration(openCaptchaTimeOut))
|
||||
}
|
||||
|
||||
var oc bool
|
||||
if openCaptcha == 0 || openCaptcha < interfaceToInt(v) {
|
||||
oc = true
|
||||
}
|
||||
// 字符,公式,验证码配置
|
||||
// 生成默认数字的driver
|
||||
driver := base64Captcha.NewDriverDigit(global.GVA_CONFIG.Captcha.ImgHeight, global.GVA_CONFIG.Captcha.ImgWidth, global.GVA_CONFIG.Captcha.KeyLong, 0.7, 80)
|
||||
@@ -39,5 +54,17 @@ func (b *BaseApi) Captcha(c *gin.Context) {
|
||||
CaptchaId: id,
|
||||
PicPath: b64s,
|
||||
CaptchaLength: global.GVA_CONFIG.Captcha.KeyLong,
|
||||
OpenCaptcha: oc,
|
||||
}, "验证码获取成功", c)
|
||||
}
|
||||
|
||||
// 类型转换
|
||||
func interfaceToInt(v interface{}) (i int) {
|
||||
switch v := v.(type) {
|
||||
case int:
|
||||
i = v
|
||||
default:
|
||||
i = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
|
||||
sysModel "github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type ChatGptApi struct{}
|
||||
|
||||
func (chat *ChatGptApi) CreateSK(c *gin.Context) {
|
||||
var option sysModel.SysChatGptOption
|
||||
c.ShouldBindJSON(&option)
|
||||
err := chatGptService.CreateSK(option)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("创建失败!", zap.Error(err))
|
||||
response.FailWithMessage("创建失败"+err.Error(), c)
|
||||
return
|
||||
}
|
||||
response.OkWithMessage("创建成功", c)
|
||||
}
|
||||
|
||||
func (chat *ChatGptApi) GetSK(c *gin.Context) {
|
||||
var option sysModel.SysChatGptOption
|
||||
c.ShouldBindJSON(&option)
|
||||
_, err := chatGptService.GetSK()
|
||||
if err != nil {
|
||||
response.OkWithDetailed(gin.H{
|
||||
"ok": false,
|
||||
}, "无sk或获取失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(gin.H{
|
||||
"ok": true,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
|
||||
func (chat *ChatGptApi) DeleteSK(c *gin.Context) {
|
||||
err := chatGptService.DeleteSK()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败"+err.Error(), c)
|
||||
return
|
||||
}
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
|
||||
func (chat *ChatGptApi) GetTable(c *gin.Context) {
|
||||
var req request.ChatGptRequest
|
||||
err := c.ShouldBindJSON(&req)
|
||||
if err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
sql, results, err := chatGptService.GetTable(req)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||
response.FailWithDetailed(gin.H{
|
||||
"sql": sql,
|
||||
"results": results,
|
||||
}, "生成失败"+err.Error(), c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(gin.H{
|
||||
"sql": sql,
|
||||
"results": results,
|
||||
}, "ChatGpt生成完成", c)
|
||||
}
|
||||
@@ -28,6 +28,7 @@ func (a *AuthorityMenuApi) GetMenu(c *gin.Context) {
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||
response.FailWithMessage("获取失败", c)
|
||||
return
|
||||
}
|
||||
if menus == nil {
|
||||
menus = []system.SysMenu{}
|
||||
|
||||
@@ -2,6 +2,7 @@ package system
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
|
||||
@@ -12,7 +13,7 @@ import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
@@ -26,6 +27,8 @@ import (
|
||||
func (b *BaseApi) Login(c *gin.Context) {
|
||||
var l systemReq.Login
|
||||
err := c.ShouldBindJSON(&l)
|
||||
key := c.ClientIP()
|
||||
|
||||
if err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
@@ -35,22 +38,39 @@ func (b *BaseApi) Login(c *gin.Context) {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if store.Verify(l.CaptchaId, l.Captcha, true) {
|
||||
|
||||
// 判断验证码是否开启
|
||||
openCaptcha := global.GVA_CONFIG.Captcha.OpenCaptcha // 是否开启防爆次数
|
||||
openCaptchaTimeOut := global.GVA_CONFIG.Captcha.OpenCaptchaTimeOut // 缓存超时时间
|
||||
v, ok := global.BlackCache.Get(key)
|
||||
if !ok {
|
||||
global.BlackCache.Set(key, 1, time.Second*time.Duration(openCaptchaTimeOut))
|
||||
}
|
||||
|
||||
var oc bool = openCaptcha == 0 || openCaptcha < interfaceToInt(v)
|
||||
|
||||
if !oc || store.Verify(l.CaptchaId, l.Captcha, true) {
|
||||
u := &system.SysUser{Username: l.Username, Password: l.Password}
|
||||
user, err := userService.Login(u)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("登陆失败! 用户名不存在或者密码错误!", zap.Error(err))
|
||||
// 验证码次数+1
|
||||
global.BlackCache.Increment(key, 1)
|
||||
response.FailWithMessage("用户名不存在或者密码错误", c)
|
||||
return
|
||||
}
|
||||
if user.Enable != 1 {
|
||||
global.GVA_LOG.Error("登陆失败! 用户被禁止登录!")
|
||||
// 验证码次数+1
|
||||
global.BlackCache.Increment(key, 1)
|
||||
response.FailWithMessage("用户被禁止登录", c)
|
||||
return
|
||||
}
|
||||
b.TokenNext(c, *user)
|
||||
return
|
||||
}
|
||||
// 验证码次数+1
|
||||
global.BlackCache.Increment(key, 1)
|
||||
response.FailWithMessage("验证码错误", c)
|
||||
}
|
||||
|
||||
@@ -74,7 +94,7 @@ func (b *BaseApi) TokenNext(c *gin.Context, user system.SysUser) {
|
||||
response.OkWithDetailed(systemRes.LoginResponse{
|
||||
User: user,
|
||||
Token: token,
|
||||
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
|
||||
ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
|
||||
}, "登录成功", c)
|
||||
return
|
||||
}
|
||||
@@ -88,7 +108,7 @@ func (b *BaseApi) TokenNext(c *gin.Context, user system.SysUser) {
|
||||
response.OkWithDetailed(systemRes.LoginResponse{
|
||||
User: user,
|
||||
Token: token,
|
||||
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
|
||||
ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
|
||||
}, "登录成功", c)
|
||||
} else if err != nil {
|
||||
global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
|
||||
@@ -107,7 +127,7 @@ func (b *BaseApi) TokenNext(c *gin.Context, user system.SysUser) {
|
||||
response.OkWithDetailed(systemRes.LoginResponse{
|
||||
User: user,
|
||||
Token: token,
|
||||
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
|
||||
ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
|
||||
}, "登录成功", c)
|
||||
}
|
||||
}
|
||||
@@ -137,7 +157,7 @@ func (b *BaseApi) Register(c *gin.Context) {
|
||||
AuthorityId: v,
|
||||
})
|
||||
}
|
||||
user := &system.SysUser{Username: r.Username, NickName: r.NickName, Password: r.Password, HeaderImg: r.HeaderImg, AuthorityId: r.AuthorityId, Authorities: authorities, Enable: r.Enable}
|
||||
user := &system.SysUser{Username: r.Username, NickName: r.NickName, Password: r.Password, HeaderImg: r.HeaderImg, AuthorityId: r.AuthorityId, Authorities: authorities, Enable: r.Enable, Phone: r.Phone, Email: r.Email}
|
||||
userReturn, err := userService.Register(*user)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("注册失败!", zap.Error(err))
|
||||
@@ -248,7 +268,7 @@ func (b *BaseApi) SetUserAuthority(c *gin.Context) {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
} else {
|
||||
c.Header("new-token", token)
|
||||
c.Header("new-expires-at", strconv.FormatInt(claims.ExpiresAt, 10))
|
||||
c.Header("new-expires-at", strconv.FormatInt(claims.ExpiresAt.Unix(), 10))
|
||||
response.OkWithMessage("修改成功", c)
|
||||
}
|
||||
}
|
||||
@@ -379,7 +399,7 @@ func (b *BaseApi) SetSelfInfo(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
user.ID = utils.GetUserID(c)
|
||||
err = userService.SetUserInfo(system.SysUser{
|
||||
err = userService.SetSelfInfo(system.SysUser{
|
||||
GVA_MODEL: global.GVA_MODEL{
|
||||
ID: user.ID,
|
||||
},
|
||||
|
||||
+77
-77
@@ -2,45 +2,43 @@
|
||||
|
||||
# jwt configuration
|
||||
jwt:
|
||||
signing-key: 'qmPlus'
|
||||
expires-time: 604800
|
||||
buffer-time: 86400
|
||||
issuer: 'qmPlus'
|
||||
|
||||
signing-key: qmPlus
|
||||
expires-time: 7d
|
||||
buffer-time: 1d
|
||||
issuer: qmPlus
|
||||
# zap logger configuration
|
||||
zap:
|
||||
level: 'info'
|
||||
prefix: '[github.com/flipped-aurora/gin-vue-admin/server]'
|
||||
format: 'console'
|
||||
director: 'log'
|
||||
encode-level: 'LowercaseColorLevelEncoder'
|
||||
stacktrace-key: 'stacktrace'
|
||||
max-age: 30 # 默认日志留存默认以天为单位
|
||||
level: info
|
||||
format: console
|
||||
prefix: "[github.com/flipped-aurora/gin-vue-admin/server]"
|
||||
director: 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: ''
|
||||
addr: 177.7.0.14:6379
|
||||
password: ""
|
||||
|
||||
# email configuration
|
||||
email:
|
||||
to: 'xxx@qq.com'
|
||||
to: xxx@qq.com
|
||||
port: 465
|
||||
from: 'xxx@163.com'
|
||||
host: 'smtp.163.com'
|
||||
from: xxx@163.com
|
||||
host: smtp.163.com
|
||||
is-ssl: true
|
||||
secret: 'xxx'
|
||||
nickname: 'test'
|
||||
secret: xxx
|
||||
nickname: test
|
||||
|
||||
# system configuration
|
||||
system:
|
||||
env: 'public' # Change to "develop" to skip authentication for development mode
|
||||
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函数配置
|
||||
db-type: mysql
|
||||
oss-type: local # 控制oss选择走本地还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
|
||||
use-redis: false # 使用redis
|
||||
use-multipoint: false
|
||||
# IP限制次数 一个小时15000次
|
||||
@@ -53,16 +51,18 @@ captcha:
|
||||
key-long: 6
|
||||
img-width: 240
|
||||
img-height: 80
|
||||
open-captcha: 0 # 0代表一直开启,大于0代表限制次数
|
||||
open-captcha-timeout: 3600 # open-captcha大于0时才生效
|
||||
|
||||
# mysql connect configuration
|
||||
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master)
|
||||
mysql:
|
||||
path: ''
|
||||
port: ''
|
||||
config: ''
|
||||
db-name: ''
|
||||
username: ''
|
||||
password: ''
|
||||
path: ""
|
||||
port: ""
|
||||
config: ""
|
||||
db-name: ""
|
||||
username: ""
|
||||
password: ""
|
||||
max-idle-conns: 10
|
||||
max-open-conns: 100
|
||||
log-mode: ""
|
||||
@@ -71,27 +71,27 @@ mysql:
|
||||
# pgsql connect configuration
|
||||
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master)
|
||||
pgsql:
|
||||
path: ''
|
||||
port: ''
|
||||
config: ''
|
||||
db-name: ''
|
||||
username: ''
|
||||
password: ''
|
||||
path: ""
|
||||
port: ""
|
||||
config: ""
|
||||
db-name: ""
|
||||
username: ""
|
||||
password: ""
|
||||
max-idle-conns: 10
|
||||
max-open-conns: 100
|
||||
log-mode: ""
|
||||
log-zap: false
|
||||
|
||||
db-list:
|
||||
- disabled: true # 是否启用
|
||||
- disable: true # 是否禁用
|
||||
type: "" # 数据库的类型,目前支持mysql、pgsql
|
||||
alias-name: "" # 数据库的名称,注意: alias-name 需要在db-list中唯一
|
||||
path: ''
|
||||
port: ''
|
||||
config: ''
|
||||
db-name: ''
|
||||
username: ''
|
||||
password: ''
|
||||
path: ""
|
||||
port: ""
|
||||
config: ""
|
||||
db-name: ""
|
||||
username: ""
|
||||
password: ""
|
||||
max-idle-conns: 10
|
||||
max-open-conns: 100
|
||||
log-mode: ""
|
||||
@@ -100,8 +100,8 @@ db-list:
|
||||
|
||||
# local configuration
|
||||
local:
|
||||
path: 'uploads/file' # 访问路径
|
||||
store-path: 'uploads/file' # 存储路径
|
||||
path: uploads/file
|
||||
store-path: uploads/file
|
||||
|
||||
# autocode configuration
|
||||
autocode:
|
||||
@@ -124,70 +124,70 @@ autocode:
|
||||
|
||||
# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
|
||||
qiniu:
|
||||
zone: 'ZoneHuaDong'
|
||||
bucket: ''
|
||||
img-path: ''
|
||||
zone: ZoneHuaDong
|
||||
bucket: ""
|
||||
img-path: ""
|
||||
use-https: false
|
||||
access-key: ''
|
||||
secret-key: ''
|
||||
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'
|
||||
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'
|
||||
bucket: xxxxx-10005608
|
||||
region: ap-shanghai
|
||||
secret-id: your-secret-id
|
||||
secret-key: your-secret-key
|
||||
base-url: https://gin.vue.admin
|
||||
path-prefix: github.com/flipped-aurora/gin-vue-admin/server
|
||||
|
||||
# aws s3 configuration (minio compatible)
|
||||
aws-s3:
|
||||
bucket: xxxxx-10005608
|
||||
region: ap-shanghai
|
||||
endpoint: ''
|
||||
endpoint: ""
|
||||
s3-force-path-style: false
|
||||
disable-ssl: false
|
||||
secret-id: xxxxxxxx
|
||||
secret-key: xxxxxxxx
|
||||
secret-id: your-secret-id
|
||||
secret-key: your-secret-key
|
||||
base-url: https://gin.vue.admin
|
||||
path-prefix: github.com/flipped-aurora/gin-vue-admin/server
|
||||
|
||||
# huawei obs configuration
|
||||
hua-wei-obs:
|
||||
path: 'you-path'
|
||||
bucket: 'you-bucket'
|
||||
endpoint: 'you-endpoint'
|
||||
access-key: 'you-access-key'
|
||||
secret-key: 'you-secret-key'
|
||||
path: you-path
|
||||
bucket: you-bucket
|
||||
endpoint: you-endpoint
|
||||
access-key: you-access-key
|
||||
secret-key: you-secret-key
|
||||
|
||||
# excel configuration
|
||||
excel:
|
||||
dir: './resource/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: "sys_operation_records"
|
||||
compareField: "created_at"
|
||||
interval: "2160h"
|
||||
- tableName: "jwt_blacklists"
|
||||
compareField: "created_at"
|
||||
interval: "168h"
|
||||
- tableName: sys_operation_records
|
||||
compareField: created_at
|
||||
interval: 2160h
|
||||
- tableName: jwt_blacklists
|
||||
compareField: created_at
|
||||
interval: 168h
|
||||
|
||||
# 跨域配置
|
||||
# 需要配合 server/initialize/router.go#L32 使用
|
||||
# 需要配合 server/initialize/router.go -> `Router.Use(middleware.CorsByRules())` 使用
|
||||
cors:
|
||||
mode: whitelist # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝
|
||||
whitelist:
|
||||
@@ -200,4 +200,4 @@ cors:
|
||||
allow-headers: content-type
|
||||
allow-methods: GET, POST
|
||||
expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type
|
||||
allow-credentials: true # 布尔值
|
||||
allow-credentials: true # 布尔值
|
||||
+49
-13
@@ -10,7 +10,7 @@ jwt:
|
||||
zap:
|
||||
level: info
|
||||
format: console
|
||||
prefix: [github.com/flipped-aurora/gin-vue-admin/server]
|
||||
prefix: "[github.com/flipped-aurora/gin-vue-admin/server]"
|
||||
director: log
|
||||
show-line: true
|
||||
encode-level: LowercaseColorLevelEncoder
|
||||
@@ -35,22 +35,26 @@ email:
|
||||
|
||||
# system configuration
|
||||
system:
|
||||
env: public # Change to "develop" to skip authentication for development mode
|
||||
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-redis: false # 使用redis
|
||||
oss-type: local # 控制oss选择走本地还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
|
||||
use-redis: false # 使用redis
|
||||
use-multipoint: false
|
||||
# IP限制次数 一个小时15000次
|
||||
iplimit-count: 15000
|
||||
# IP限制一个小时
|
||||
iplimit-time: 3600
|
||||
# 路由全局前缀
|
||||
router-prefix: ""
|
||||
|
||||
# captcha configuration
|
||||
captcha:
|
||||
key-long: 6
|
||||
img-width: 240
|
||||
img-height: 80
|
||||
open-captcha: 0 # 0代表一直开启,大于0代表限制次数
|
||||
open-captcha-timeout: 3600 # open-captcha大于0时才生效
|
||||
|
||||
# mysql connect configuration
|
||||
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master)
|
||||
@@ -79,10 +83,42 @@ pgsql:
|
||||
max-open-conns: 100
|
||||
log-mode: ""
|
||||
log-zap: false
|
||||
|
||||
oracle:
|
||||
path: ""
|
||||
port: ""
|
||||
config: ""
|
||||
db-name: ""
|
||||
username: ""
|
||||
password: ""
|
||||
max-idle-conns: 10
|
||||
max-open-conns: 100
|
||||
log-mode: ""
|
||||
log-zap: false
|
||||
mssql:
|
||||
path: ""
|
||||
port: ""
|
||||
config: ""
|
||||
db-name: ""
|
||||
username: ""
|
||||
password: ""
|
||||
max-idle-conns: 10
|
||||
max-open-conns: 100
|
||||
log-mode: ""
|
||||
log-zap: false
|
||||
sqlite:
|
||||
path: ""
|
||||
port: ""
|
||||
config: ""
|
||||
db-name: ""
|
||||
username: ""
|
||||
password: ""
|
||||
max-idle-conns: 10
|
||||
max-open-conns: 100
|
||||
log-mode: ""
|
||||
log-zap: false
|
||||
db-list:
|
||||
- disabled: true # 是否启用
|
||||
type: "" # 数据库的类型,目前支持mysql、pgsql
|
||||
- disable: true # 是否禁用
|
||||
type: "" # 数据库的类型,目前支持mysql、pgsql、mssql、oracle
|
||||
alias-name: "" # 数据库的名称,注意: alias-name 需要在db-list中唯一
|
||||
path: ""
|
||||
port: ""
|
||||
@@ -95,7 +131,6 @@ db-list:
|
||||
log-mode: ""
|
||||
log-zap: false
|
||||
|
||||
|
||||
# local configuration
|
||||
local:
|
||||
path: uploads/file
|
||||
@@ -175,7 +210,7 @@ excel:
|
||||
# timer task db clear table
|
||||
Timer:
|
||||
start: true
|
||||
spec: "@daily" # 定时任务详细配置参考 https://pkg.go.dev/github.com/robfig/cron/v3
|
||||
spec: "@daily" # 定时任务详细配置参考 https://pkg.go.dev/github.com/robfig/cron/v3
|
||||
detail:
|
||||
- tableName: sys_operation_records
|
||||
compareField: created_at
|
||||
@@ -185,14 +220,15 @@ Timer:
|
||||
interval: 168h
|
||||
|
||||
# 跨域配置
|
||||
# 需要配合 server/initialize/router.go#L32 使用
|
||||
# 需要配合 server/initialize/router.go -> `Router.Use(middleware.CorsByRules())` 使用
|
||||
cors:
|
||||
mode: whitelist # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝
|
||||
mode: strict-whitelist # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝
|
||||
whitelist:
|
||||
- allow-origin: example1.com
|
||||
allow-headers: content-type
|
||||
allow-methods: GET, POST
|
||||
allow-headers: Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id
|
||||
allow-methods: POST, GET
|
||||
expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type
|
||||
|
||||
allow-credentials: true # 布尔值
|
||||
- allow-origin: example2.com
|
||||
allow-headers: content-type
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package config
|
||||
|
||||
type Captcha struct {
|
||||
KeyLong int `mapstructure:"key-long" json:"key-long" yaml:"key-long"` // 验证码长度
|
||||
ImgWidth int `mapstructure:"img-width" json:"img-width" yaml:"img-width"` // 验证码宽度
|
||||
ImgHeight int `mapstructure:"img-height" json:"img-height" yaml:"img-height"` // 验证码高度
|
||||
KeyLong int `mapstructure:"key-long" json:"key-long" yaml:"key-long"` // 验证码长度
|
||||
ImgWidth int `mapstructure:"img-width" json:"img-width" yaml:"img-width"` // 验证码宽度
|
||||
ImgHeight int `mapstructure:"img-height" json:"img-height" yaml:"img-height"` // 验证码高度
|
||||
OpenCaptcha int `mapstructure:"open-captcha" json:"open-captcha" yaml:"open-captcha"` // 防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码此数,如3代表错误三次后出现验证码
|
||||
OpenCaptchaTimeOut int `mapstructure:"open-captcha-timeout" json:"open-captcha-timeout" yaml:"open-captcha-timeout"` // 防爆破验证码超时时间,单位:s(秒)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,10 @@ type Server struct {
|
||||
AutoCode Autocode `mapstructure:"autocode" json:"autocode" yaml:"autocode"`
|
||||
// gorm
|
||||
Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
|
||||
Mssql Mssql `mapstructure:"mssql" json:"mssql" yaml:"mssql"`
|
||||
Pgsql Pgsql `mapstructure:"pgsql" json:"pgsql" yaml:"pgsql"`
|
||||
Oracle Oracle `mapstructure:"oracle" json:"oracle" yaml:"oracle"`
|
||||
Sqlite Sqlite `mapstructure:"sqlite" json:"sqlite" yaml:"sqlite"`
|
||||
DBList []SpecializedDB `mapstructure:"db-list" json:"db-list" yaml:"db-list"`
|
||||
// oss
|
||||
Local Local `mapstructure:"local" json:"local" yaml:"local"`
|
||||
|
||||
@@ -15,6 +15,9 @@ type GeneralDB struct {
|
||||
Dbname string `mapstructure:"db-name" json:"db-name" yaml:"db-name"` // 数据库名
|
||||
Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库用户名
|
||||
Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码
|
||||
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` //全局表前缀,单独定义TableName则不生效
|
||||
Singular bool `mapstructure:"singular" json:"singular" yaml:"singular"` //是否开启全局禁用复数,true表示开启
|
||||
Engine string `mapstructure:"engine" json:"engine" yaml:"engine" default:"InnoDB"` //数据库引擎,默认InnoDB
|
||||
MaxIdleConns int `mapstructure:"max-idle-conns" json:"max-idle-conns" yaml:"max-idle-conns"` // 空闲中的最大连接数
|
||||
MaxOpenConns int `mapstructure:"max-open-conns" json:"max-open-conns" yaml:"max-open-conns"` // 打开到数据库的最大连接数
|
||||
LogMode string `mapstructure:"log-mode" json:"log-mode" yaml:"log-mode"` // 是否开启Gorm全局日志
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package config
|
||||
|
||||
type Mssql struct {
|
||||
GeneralDB `yaml:",inline" mapstructure:",squash"`
|
||||
}
|
||||
//dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
|
||||
func (m *Mssql) Dsn() string {
|
||||
return "sqlserver://" + m.Username + ":" + m.Password + "@" + m.Path + ":" + m.Port + "?database=" + m.Dbname + "&encrypt=disable"
|
||||
}
|
||||
|
||||
func (m *Mssql) GetLogMode() string {
|
||||
return m.LogMode
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package config
|
||||
|
||||
type Oracle struct {
|
||||
GeneralDB `yaml:",inline" mapstructure:",squash"`
|
||||
}
|
||||
|
||||
func (m *Oracle) Dsn() string {
|
||||
return "oracle://" + m.Username + ":" + m.Password + "@" + m.Path + ":" + m.Port + "/" + m.Dbname + "?" + m.Config
|
||||
|
||||
}
|
||||
|
||||
func (m *Oracle) GetLogMode() string {
|
||||
return m.LogMode
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type Sqlite struct {
|
||||
GeneralDB `yaml:",inline" mapstructure:",squash"`
|
||||
}
|
||||
|
||||
func (s *Sqlite) Dsn() string {
|
||||
return filepath.Join(s.Path, s.Dbname+".db")
|
||||
}
|
||||
|
||||
func (s *Sqlite) GetLogMode() string {
|
||||
return s.LogMode
|
||||
}
|
||||
@@ -9,4 +9,5 @@ type System struct {
|
||||
UseRedis bool `mapstructure:"use-redis" json:"use-redis" yaml:"use-redis"` // 使用redis
|
||||
LimitCountIP int `mapstructure:"iplimit-count" json:"iplimit-count" yaml:"iplimit-count"`
|
||||
LimitTimeIP int `mapstructure:"iplimit-time" json:"iplimit-time" yaml:"iplimit-time"`
|
||||
RouterPrefix string `mapstructure:"router-prefix" json:"router-prefix" yaml:"router-prefix"`
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ func RunWindowsServer() {
|
||||
|
||||
fmt.Printf(`
|
||||
欢迎使用 gin-vue-admin
|
||||
当前版本:v2.5.4
|
||||
当前版本:v2.5.7
|
||||
加群方式:微信号:shouzi_1994 QQ群:622360840
|
||||
插件市场:https://plugin.gin-vue-admin.com
|
||||
GVA讨论社区:https://support.qq.com/products/371961
|
||||
|
||||
+355
-313
@@ -1,22 +1,14 @@
|
||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
// This file was generated by swaggo/swag
|
||||
// Code generated by swaggo/swag. DO NOT EDIT.
|
||||
|
||||
package docs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
import "github.com/swaggo/swag"
|
||||
|
||||
"github.com/alecthomas/template"
|
||||
"github.com/swaggo/swag"
|
||||
)
|
||||
|
||||
var doc = `{
|
||||
const docTemplate = `{
|
||||
"schemes": {{ marshal .Schemes }},
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "{{.Description}}",
|
||||
"description": "{{escape .Description}}",
|
||||
"title": "{{.Title}}",
|
||||
"contact": {},
|
||||
"version": "{{.Version}}"
|
||||
@@ -174,6 +166,40 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/freshCasbin": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"SysApi"
|
||||
],
|
||||
"summary": "刷新casbin缓存",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "刷新成功",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"msg": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/getAllApis": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -1475,7 +1501,7 @@ var doc = `{
|
||||
"summary": "生成验证码",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "生成验证码,返回包括随机数id,base64,验证码长度",
|
||||
"description": "生成验证码,返回包括随机数id,base64,验证码长度,是否开启验证码",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
@@ -1997,161 +2023,6 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/excel/downloadTemplate": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"excel"
|
||||
],
|
||||
"summary": "下载模板",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "模板名称",
|
||||
"name": "fileName",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/excel/exportExcel": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/octet-stream"
|
||||
],
|
||||
"tags": [
|
||||
"excel"
|
||||
],
|
||||
"summary": "导出Excel",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "导出Excel文件信息",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/example.ExcelInfo"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/excel/importExcel": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"excel"
|
||||
],
|
||||
"summary": "导入Excel文件",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "file",
|
||||
"description": "导入Excel文件",
|
||||
"name": "file",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "导入Excel文件",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"msg": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/excel/loadExcel": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"excel"
|
||||
],
|
||||
"summary": "加载Excel数据",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "加载Excel数据,返回包括列表,总数,页码,每页数量",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/response.PageResult"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/fileUploadAndDownload/breakpointContinue": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -4940,6 +4811,14 @@ var doc = `{
|
||||
"key-long": {
|
||||
"description": "验证码长度",
|
||||
"type": "integer"
|
||||
},
|
||||
"open-captcha": {
|
||||
"description": "防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码此数,如3代表错误三次后出现验证码",
|
||||
"type": "integer"
|
||||
},
|
||||
"open-captcha-timeout": {
|
||||
"description": "防爆破验证码超时时间,单位:s(秒)",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4960,39 +4839,6 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.Email": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"from": {
|
||||
"description": "收件人",
|
||||
"type": "string"
|
||||
},
|
||||
"host": {
|
||||
"description": "服务器地址",
|
||||
"type": "string"
|
||||
},
|
||||
"is-ssl": {
|
||||
"description": "是否SSL",
|
||||
"type": "boolean"
|
||||
},
|
||||
"nickname": {
|
||||
"description": "昵称",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"description": "端口",
|
||||
"type": "integer"
|
||||
},
|
||||
"secret": {
|
||||
"description": "密钥",
|
||||
"type": "string"
|
||||
},
|
||||
"to": {
|
||||
"description": "收件人:多个以英文逗号分隔",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.Excel": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -5055,7 +4901,7 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.Mysql": {
|
||||
"config.Mssql": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
@@ -5066,6 +4912,11 @@ var doc = `{
|
||||
"description": "数据库名",
|
||||
"type": "string"
|
||||
},
|
||||
"engine": {
|
||||
"description": "数据库引擎,默认InnoDB",
|
||||
"type": "string",
|
||||
"default": "InnoDB"
|
||||
},
|
||||
"log-mode": {
|
||||
"description": "是否开启Gorm全局日志",
|
||||
"type": "string"
|
||||
@@ -5094,6 +4945,130 @@ var doc = `{
|
||||
"description": ":端口",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "全局表前缀,单独定义TableName则不生效",
|
||||
"type": "string"
|
||||
},
|
||||
"singular": {
|
||||
"description": "是否开启全局禁用复数,true表示开启",
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"description": "数据库用户名",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.Mysql": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
"description": "高级配置",
|
||||
"type": "string"
|
||||
},
|
||||
"db-name": {
|
||||
"description": "数据库名",
|
||||
"type": "string"
|
||||
},
|
||||
"engine": {
|
||||
"description": "数据库引擎,默认InnoDB",
|
||||
"type": "string",
|
||||
"default": "InnoDB"
|
||||
},
|
||||
"log-mode": {
|
||||
"description": "是否开启Gorm全局日志",
|
||||
"type": "string"
|
||||
},
|
||||
"log-zap": {
|
||||
"description": "是否通过zap写入日志文件",
|
||||
"type": "boolean"
|
||||
},
|
||||
"max-idle-conns": {
|
||||
"description": "空闲中的最大连接数",
|
||||
"type": "integer"
|
||||
},
|
||||
"max-open-conns": {
|
||||
"description": "打开到数据库的最大连接数",
|
||||
"type": "integer"
|
||||
},
|
||||
"password": {
|
||||
"description": "数据库密码",
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"description": "服务器地址:端口",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"description": ":端口",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "全局表前缀,单独定义TableName则不生效",
|
||||
"type": "string"
|
||||
},
|
||||
"singular": {
|
||||
"description": "是否开启全局禁用复数,true表示开启",
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"description": "数据库用户名",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.Oracle": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
"description": "高级配置",
|
||||
"type": "string"
|
||||
},
|
||||
"db-name": {
|
||||
"description": "数据库名",
|
||||
"type": "string"
|
||||
},
|
||||
"engine": {
|
||||
"description": "数据库引擎,默认InnoDB",
|
||||
"type": "string",
|
||||
"default": "InnoDB"
|
||||
},
|
||||
"log-mode": {
|
||||
"description": "是否开启Gorm全局日志",
|
||||
"type": "string"
|
||||
},
|
||||
"log-zap": {
|
||||
"description": "是否通过zap写入日志文件",
|
||||
"type": "boolean"
|
||||
},
|
||||
"max-idle-conns": {
|
||||
"description": "空闲中的最大连接数",
|
||||
"type": "integer"
|
||||
},
|
||||
"max-open-conns": {
|
||||
"description": "打开到数据库的最大连接数",
|
||||
"type": "integer"
|
||||
},
|
||||
"password": {
|
||||
"description": "数据库密码",
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"description": "服务器地址:端口",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"description": ":端口",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "全局表前缀,单独定义TableName则不生效",
|
||||
"type": "string"
|
||||
},
|
||||
"singular": {
|
||||
"description": "是否开启全局禁用复数,true表示开启",
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"description": "数据库用户名",
|
||||
"type": "string"
|
||||
@@ -5111,6 +5086,11 @@ var doc = `{
|
||||
"description": "数据库名",
|
||||
"type": "string"
|
||||
},
|
||||
"engine": {
|
||||
"description": "数据库引擎,默认InnoDB",
|
||||
"type": "string",
|
||||
"default": "InnoDB"
|
||||
},
|
||||
"log-mode": {
|
||||
"description": "是否开启Gorm全局日志",
|
||||
"type": "string"
|
||||
@@ -5139,6 +5119,14 @@ var doc = `{
|
||||
"description": ":端口",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "全局表前缀,单独定义TableName则不生效",
|
||||
"type": "string"
|
||||
},
|
||||
"singular": {
|
||||
"description": "是否开启全局禁用复数,true表示开启",
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"description": "数据库用户名",
|
||||
"type": "string"
|
||||
@@ -5203,7 +5191,11 @@ var doc = `{
|
||||
},
|
||||
"autocode": {
|
||||
"description": "auto",
|
||||
"$ref": "#/definitions/config.Autocode"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/config.Autocode"
|
||||
}
|
||||
]
|
||||
},
|
||||
"aws-s3": {
|
||||
"$ref": "#/definitions/config.AwsS3"
|
||||
@@ -5213,7 +5205,11 @@ var doc = `{
|
||||
},
|
||||
"cors": {
|
||||
"description": "跨域配置",
|
||||
"$ref": "#/definitions/config.CORS"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/config.CORS"
|
||||
}
|
||||
]
|
||||
},
|
||||
"db-list": {
|
||||
"type": "array",
|
||||
@@ -5222,7 +5218,7 @@ var doc = `{
|
||||
}
|
||||
},
|
||||
"email": {
|
||||
"$ref": "#/definitions/config.Email"
|
||||
"$ref": "#/definitions/github_com_flipped-aurora_gin-vue-admin_server_config.Email"
|
||||
},
|
||||
"excel": {
|
||||
"$ref": "#/definitions/config.Excel"
|
||||
@@ -5235,11 +5231,25 @@ var doc = `{
|
||||
},
|
||||
"local": {
|
||||
"description": "oss",
|
||||
"$ref": "#/definitions/config.Local"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/config.Local"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mssql": {
|
||||
"$ref": "#/definitions/config.Mssql"
|
||||
},
|
||||
"mysql": {
|
||||
"description": "gorm",
|
||||
"$ref": "#/definitions/config.Mysql"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/config.Mysql"
|
||||
}
|
||||
]
|
||||
},
|
||||
"oracle": {
|
||||
"$ref": "#/definitions/config.Oracle"
|
||||
},
|
||||
"pgsql": {
|
||||
"$ref": "#/definitions/config.Pgsql"
|
||||
@@ -5281,6 +5291,11 @@ var doc = `{
|
||||
"disable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"engine": {
|
||||
"description": "数据库引擎,默认InnoDB",
|
||||
"type": "string",
|
||||
"default": "InnoDB"
|
||||
},
|
||||
"log-mode": {
|
||||
"description": "是否开启Gorm全局日志",
|
||||
"type": "string"
|
||||
@@ -5309,6 +5324,14 @@ var doc = `{
|
||||
"description": ":端口",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "全局表前缀,单独定义TableName则不生效",
|
||||
"type": "string"
|
||||
},
|
||||
"singular": {
|
||||
"description": "是否开启全局禁用复数,true表示开启",
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -5343,6 +5366,9 @@ var doc = `{
|
||||
"description": "Oss类型",
|
||||
"type": "string"
|
||||
},
|
||||
"router-prefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"use-multipoint": {
|
||||
"description": "多点登录拦截",
|
||||
"type": "boolean"
|
||||
@@ -5461,7 +5487,11 @@ var doc = `{
|
||||
},
|
||||
"sysUser": {
|
||||
"description": "管理详情",
|
||||
"$ref": "#/definitions/system.SysUser"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/system.SysUser"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sysUserAuthorityID": {
|
||||
"description": "管理角色ID",
|
||||
@@ -5574,18 +5604,36 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"example.ExcelInfo": {
|
||||
"github_com_flipped-aurora_gin-vue-admin_server_config.Email": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fileName": {
|
||||
"description": "文件名",
|
||||
"from": {
|
||||
"description": "收件人",
|
||||
"type": "string"
|
||||
},
|
||||
"infoList": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/system.SysBaseMenu"
|
||||
}
|
||||
"host": {
|
||||
"description": "服务器地址",
|
||||
"type": "string"
|
||||
},
|
||||
"is-ssl": {
|
||||
"description": "是否SSL",
|
||||
"type": "boolean"
|
||||
},
|
||||
"nickname": {
|
||||
"description": "昵称",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"description": "端口",
|
||||
"type": "integer"
|
||||
},
|
||||
"secret": {
|
||||
"description": "密钥",
|
||||
"type": "string"
|
||||
},
|
||||
"to": {
|
||||
"description": "收件人:多个以英文逗号分隔",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5752,28 +5800,40 @@ var doc = `{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"authorityId": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"example": "int 角色id"
|
||||
},
|
||||
"authorityIds": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
}
|
||||
"type": "string",
|
||||
"example": "[]uint 角色id"
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"example": "电子邮箱"
|
||||
},
|
||||
"enable": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"example": "int 是否启用"
|
||||
},
|
||||
"headerImg": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "头像链接"
|
||||
},
|
||||
"nickName": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "昵称"
|
||||
},
|
||||
"passWord": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "密码"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "电话号码"
|
||||
},
|
||||
"userName": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "用户名"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5967,9 +6027,7 @@ var doc = `{
|
||||
"response.PageResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"list": {
|
||||
"type": "object"
|
||||
},
|
||||
"list": {},
|
||||
"page": {
|
||||
"type": "integer"
|
||||
},
|
||||
@@ -5998,9 +6056,7 @@ var doc = `{
|
||||
"code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"data": {
|
||||
"type": "object"
|
||||
},
|
||||
"data": {},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
}
|
||||
@@ -6084,6 +6140,9 @@ var doc = `{
|
||||
"captchaLength": {
|
||||
"type": "integer"
|
||||
},
|
||||
"openCaptcha": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"picPath": {
|
||||
"type": "string"
|
||||
}
|
||||
@@ -6135,6 +6194,10 @@ var doc = `{
|
||||
"description": "是否自动移动文件",
|
||||
"type": "boolean"
|
||||
},
|
||||
"businessDB": {
|
||||
"description": "业务数据库",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Struct中文名称",
|
||||
"type": "string"
|
||||
@@ -6219,6 +6282,38 @@ var doc = `{
|
||||
"require": {
|
||||
"description": "是否必填",
|
||||
"type": "boolean"
|
||||
},
|
||||
"sort": {
|
||||
"description": "是否增加排序",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"system.Meta": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"activeName": {
|
||||
"type": "string"
|
||||
},
|
||||
"closeTab": {
|
||||
"description": "自动关闭tab",
|
||||
"type": "boolean"
|
||||
},
|
||||
"defaultMenu": {
|
||||
"description": "是否是基础路由(开发中)",
|
||||
"type": "boolean"
|
||||
},
|
||||
"icon": {
|
||||
"description": "菜单图标",
|
||||
"type": "string"
|
||||
},
|
||||
"keepAlive": {
|
||||
"description": "是否缓存",
|
||||
"type": "boolean"
|
||||
},
|
||||
"title": {
|
||||
"description": "菜单名",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -6346,10 +6441,6 @@ var doc = `{
|
||||
"$ref": "#/definitions/system.SysBaseMenu"
|
||||
}
|
||||
},
|
||||
"closeTab": {
|
||||
"description": "自动关闭tab",
|
||||
"type": "boolean"
|
||||
},
|
||||
"component": {
|
||||
"description": "对应前端文件路径",
|
||||
"type": "string"
|
||||
@@ -6358,32 +6449,28 @@ var doc = `{
|
||||
"description": "创建时间",
|
||||
"type": "string"
|
||||
},
|
||||
"defaultMenu": {
|
||||
"description": "是否是基础路由(开发中)",
|
||||
"type": "boolean"
|
||||
},
|
||||
"hidden": {
|
||||
"description": "是否在列表隐藏",
|
||||
"type": "boolean"
|
||||
},
|
||||
"icon": {
|
||||
"description": "菜单图标",
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"description": "主键ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"keepAlive": {
|
||||
"description": "是否缓存",
|
||||
"type": "boolean"
|
||||
},
|
||||
"menuBtn": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/system.SysBaseMenuBtn"
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"description": "附加属性",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/system.Meta"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"description": "路由name",
|
||||
"type": "string"
|
||||
@@ -6406,10 +6493,6 @@ var doc = `{
|
||||
"description": "排序标记",
|
||||
"type": "integer"
|
||||
},
|
||||
"title": {
|
||||
"description": "菜单名",
|
||||
"type": "string"
|
||||
},
|
||||
"updatedAt": {
|
||||
"description": "更新时间",
|
||||
"type": "string"
|
||||
@@ -6571,10 +6654,6 @@ var doc = `{
|
||||
"$ref": "#/definitions/system.SysMenu"
|
||||
}
|
||||
},
|
||||
"closeTab": {
|
||||
"description": "自动关闭tab",
|
||||
"type": "boolean"
|
||||
},
|
||||
"component": {
|
||||
"description": "对应前端文件路径",
|
||||
"type": "string"
|
||||
@@ -6583,26 +6662,14 @@ var doc = `{
|
||||
"description": "创建时间",
|
||||
"type": "string"
|
||||
},
|
||||
"defaultMenu": {
|
||||
"description": "是否是基础路由(开发中)",
|
||||
"type": "boolean"
|
||||
},
|
||||
"hidden": {
|
||||
"description": "是否在列表隐藏",
|
||||
"type": "boolean"
|
||||
},
|
||||
"icon": {
|
||||
"description": "菜单图标",
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"description": "主键ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"keepAlive": {
|
||||
"description": "是否缓存",
|
||||
"type": "boolean"
|
||||
},
|
||||
"menuBtn": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -6612,6 +6679,14 @@ var doc = `{
|
||||
"menuId": {
|
||||
"type": "string"
|
||||
},
|
||||
"meta": {
|
||||
"description": "附加属性",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/system.Meta"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"description": "路由name",
|
||||
"type": "string"
|
||||
@@ -6634,10 +6709,6 @@ var doc = `{
|
||||
"description": "排序标记",
|
||||
"type": "integer"
|
||||
},
|
||||
"title": {
|
||||
"description": "菜单名",
|
||||
"type": "string"
|
||||
},
|
||||
"updatedAt": {
|
||||
"description": "更新时间",
|
||||
"type": "string"
|
||||
@@ -6792,49 +6863,20 @@ var doc = `{
|
||||
}
|
||||
}`
|
||||
|
||||
type swaggerInfo struct {
|
||||
Version string
|
||||
Host string
|
||||
BasePath string
|
||||
Schemes []string
|
||||
Title string
|
||||
Description string
|
||||
}
|
||||
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = swaggerInfo{
|
||||
Version: "0.0.1",
|
||||
Host: "",
|
||||
BasePath: "/",
|
||||
Schemes: []string{},
|
||||
Title: "Swagger Example API",
|
||||
Description: "This is a sample Server pets",
|
||||
}
|
||||
|
||||
type s struct{}
|
||||
|
||||
func (s *s) ReadDoc() string {
|
||||
sInfo := SwaggerInfo
|
||||
sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1)
|
||||
|
||||
t, err := template.New("swagger_info").Funcs(template.FuncMap{
|
||||
"marshal": func(v interface{}) string {
|
||||
a, _ := json.Marshal(v)
|
||||
return string(a)
|
||||
},
|
||||
}).Parse(doc)
|
||||
if err != nil {
|
||||
return doc
|
||||
}
|
||||
|
||||
var tpl bytes.Buffer
|
||||
if err := t.Execute(&tpl, sInfo); err != nil {
|
||||
return doc
|
||||
}
|
||||
|
||||
return tpl.String()
|
||||
var SwaggerInfo = &swag.Spec{
|
||||
Version: "0.0.1",
|
||||
Host: "",
|
||||
BasePath: "",
|
||||
Schemes: []string{},
|
||||
Title: "Swagger Example API",
|
||||
Description: "This is a sample Server pets",
|
||||
InfoInstanceName: "swagger",
|
||||
SwaggerTemplate: docTemplate,
|
||||
LeftDelim: "{{",
|
||||
RightDelim: "}}",
|
||||
}
|
||||
|
||||
func init() {
|
||||
swag.Register(swag.Name, &s{})
|
||||
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
|
||||
}
|
||||
|
||||
+400
-261
@@ -6,7 +6,6 @@
|
||||
"contact": {},
|
||||
"version": "0.0.1"
|
||||
},
|
||||
"basePath": "/",
|
||||
"paths": {
|
||||
"/api/createApi": {
|
||||
"post": {
|
||||
@@ -158,6 +157,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/freshCasbin": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"SysApi"
|
||||
],
|
||||
"summary": "刷新casbin缓存",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "刷新成功",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"msg": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/getAllApis": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -1459,7 +1492,7 @@
|
||||
"summary": "生成验证码",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "生成验证码,返回包括随机数id,base64,验证码长度",
|
||||
"description": "生成验证码,返回包括随机数id,base64,验证码长度,是否开启验证码",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
@@ -1981,161 +2014,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/excel/downloadTemplate": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"excel"
|
||||
],
|
||||
"summary": "下载模板",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "模板名称",
|
||||
"name": "fileName",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/excel/exportExcel": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/octet-stream"
|
||||
],
|
||||
"tags": [
|
||||
"excel"
|
||||
],
|
||||
"summary": "导出Excel",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "导出Excel文件信息",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/example.ExcelInfo"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/excel/importExcel": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"excel"
|
||||
],
|
||||
"summary": "导入Excel文件",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "file",
|
||||
"description": "导入Excel文件",
|
||||
"name": "file",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "导入Excel文件",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"msg": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/excel/loadExcel": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"excel"
|
||||
],
|
||||
"summary": "加载Excel数据",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "加载Excel数据,返回包括列表,总数,页码,每页数量",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/response.PageResult"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/fileUploadAndDownload/breakpointContinue": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -4924,6 +4802,14 @@
|
||||
"key-long": {
|
||||
"description": "验证码长度",
|
||||
"type": "integer"
|
||||
},
|
||||
"open-captcha": {
|
||||
"description": "防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码此数,如3代表错误三次后出现验证码",
|
||||
"type": "integer"
|
||||
},
|
||||
"open-captcha-timeout": {
|
||||
"description": "防爆破验证码超时时间,单位:s(秒)",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4944,39 +4830,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.Email": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"from": {
|
||||
"description": "收件人",
|
||||
"type": "string"
|
||||
},
|
||||
"host": {
|
||||
"description": "服务器地址",
|
||||
"type": "string"
|
||||
},
|
||||
"is-ssl": {
|
||||
"description": "是否SSL",
|
||||
"type": "boolean"
|
||||
},
|
||||
"nickname": {
|
||||
"description": "昵称",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"description": "端口",
|
||||
"type": "integer"
|
||||
},
|
||||
"secret": {
|
||||
"description": "密钥",
|
||||
"type": "string"
|
||||
},
|
||||
"to": {
|
||||
"description": "收件人:多个以英文逗号分隔",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.Excel": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -5039,7 +4892,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.Mysql": {
|
||||
"config.Mssql": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
@@ -5050,6 +4903,11 @@
|
||||
"description": "数据库名",
|
||||
"type": "string"
|
||||
},
|
||||
"engine": {
|
||||
"description": "数据库引擎,默认InnoDB",
|
||||
"type": "string",
|
||||
"default": "InnoDB"
|
||||
},
|
||||
"log-mode": {
|
||||
"description": "是否开启Gorm全局日志",
|
||||
"type": "string"
|
||||
@@ -5078,6 +4936,130 @@
|
||||
"description": ":端口",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "全局表前缀,单独定义TableName则不生效",
|
||||
"type": "string"
|
||||
},
|
||||
"singular": {
|
||||
"description": "是否开启全局禁用复数,true表示开启",
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"description": "数据库用户名",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.Mysql": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
"description": "高级配置",
|
||||
"type": "string"
|
||||
},
|
||||
"db-name": {
|
||||
"description": "数据库名",
|
||||
"type": "string"
|
||||
},
|
||||
"engine": {
|
||||
"description": "数据库引擎,默认InnoDB",
|
||||
"type": "string",
|
||||
"default": "InnoDB"
|
||||
},
|
||||
"log-mode": {
|
||||
"description": "是否开启Gorm全局日志",
|
||||
"type": "string"
|
||||
},
|
||||
"log-zap": {
|
||||
"description": "是否通过zap写入日志文件",
|
||||
"type": "boolean"
|
||||
},
|
||||
"max-idle-conns": {
|
||||
"description": "空闲中的最大连接数",
|
||||
"type": "integer"
|
||||
},
|
||||
"max-open-conns": {
|
||||
"description": "打开到数据库的最大连接数",
|
||||
"type": "integer"
|
||||
},
|
||||
"password": {
|
||||
"description": "数据库密码",
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"description": "服务器地址:端口",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"description": ":端口",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "全局表前缀,单独定义TableName则不生效",
|
||||
"type": "string"
|
||||
},
|
||||
"singular": {
|
||||
"description": "是否开启全局禁用复数,true表示开启",
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"description": "数据库用户名",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.Oracle": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
"description": "高级配置",
|
||||
"type": "string"
|
||||
},
|
||||
"db-name": {
|
||||
"description": "数据库名",
|
||||
"type": "string"
|
||||
},
|
||||
"engine": {
|
||||
"description": "数据库引擎,默认InnoDB",
|
||||
"type": "string",
|
||||
"default": "InnoDB"
|
||||
},
|
||||
"log-mode": {
|
||||
"description": "是否开启Gorm全局日志",
|
||||
"type": "string"
|
||||
},
|
||||
"log-zap": {
|
||||
"description": "是否通过zap写入日志文件",
|
||||
"type": "boolean"
|
||||
},
|
||||
"max-idle-conns": {
|
||||
"description": "空闲中的最大连接数",
|
||||
"type": "integer"
|
||||
},
|
||||
"max-open-conns": {
|
||||
"description": "打开到数据库的最大连接数",
|
||||
"type": "integer"
|
||||
},
|
||||
"password": {
|
||||
"description": "数据库密码",
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"description": "服务器地址:端口",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"description": ":端口",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "全局表前缀,单独定义TableName则不生效",
|
||||
"type": "string"
|
||||
},
|
||||
"singular": {
|
||||
"description": "是否开启全局禁用复数,true表示开启",
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"description": "数据库用户名",
|
||||
"type": "string"
|
||||
@@ -5095,6 +5077,11 @@
|
||||
"description": "数据库名",
|
||||
"type": "string"
|
||||
},
|
||||
"engine": {
|
||||
"description": "数据库引擎,默认InnoDB",
|
||||
"type": "string",
|
||||
"default": "InnoDB"
|
||||
},
|
||||
"log-mode": {
|
||||
"description": "是否开启Gorm全局日志",
|
||||
"type": "string"
|
||||
@@ -5123,6 +5110,72 @@
|
||||
"description": ":端口",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "全局表前缀,单独定义TableName则不生效",
|
||||
"type": "string"
|
||||
},
|
||||
"singular": {
|
||||
"description": "是否开启全局禁用复数,true表示开启",
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"description": "数据库用户名",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.Sqlite": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
"description": "高级配置",
|
||||
"type": "string"
|
||||
},
|
||||
"db-name": {
|
||||
"description": "数据库名",
|
||||
"type": "string"
|
||||
},
|
||||
"engine": {
|
||||
"description": "数据库引擎,默认InnoDB",
|
||||
"type": "string",
|
||||
"default": "InnoDB"
|
||||
},
|
||||
"log-mode": {
|
||||
"description": "是否开启Gorm全局日志",
|
||||
"type": "string"
|
||||
},
|
||||
"log-zap": {
|
||||
"description": "是否通过zap写入日志文件",
|
||||
"type": "boolean"
|
||||
},
|
||||
"max-idle-conns": {
|
||||
"description": "空闲中的最大连接数",
|
||||
"type": "integer"
|
||||
},
|
||||
"max-open-conns": {
|
||||
"description": "打开到数据库的最大连接数",
|
||||
"type": "integer"
|
||||
},
|
||||
"password": {
|
||||
"description": "数据库密码",
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"description": "服务器地址:端口",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"description": ":端口",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "全局表前缀,单独定义TableName则不生效",
|
||||
"type": "string"
|
||||
},
|
||||
"singular": {
|
||||
"description": "是否开启全局禁用复数,true表示开启",
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"description": "数据库用户名",
|
||||
"type": "string"
|
||||
@@ -5187,7 +5240,11 @@
|
||||
},
|
||||
"autocode": {
|
||||
"description": "auto",
|
||||
"$ref": "#/definitions/config.Autocode"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/config.Autocode"
|
||||
}
|
||||
]
|
||||
},
|
||||
"aws-s3": {
|
||||
"$ref": "#/definitions/config.AwsS3"
|
||||
@@ -5197,7 +5254,11 @@
|
||||
},
|
||||
"cors": {
|
||||
"description": "跨域配置",
|
||||
"$ref": "#/definitions/config.CORS"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/config.CORS"
|
||||
}
|
||||
]
|
||||
},
|
||||
"db-list": {
|
||||
"type": "array",
|
||||
@@ -5206,7 +5267,7 @@
|
||||
}
|
||||
},
|
||||
"email": {
|
||||
"$ref": "#/definitions/config.Email"
|
||||
"$ref": "#/definitions/github_com_flipped-aurora_gin-vue-admin_server_config.Email"
|
||||
},
|
||||
"excel": {
|
||||
"$ref": "#/definitions/config.Excel"
|
||||
@@ -5219,15 +5280,32 @@
|
||||
},
|
||||
"local": {
|
||||
"description": "oss",
|
||||
"$ref": "#/definitions/config.Local"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/config.Local"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mssql": {
|
||||
"$ref": "#/definitions/config.Mssql"
|
||||
},
|
||||
"mysql": {
|
||||
"description": "gorm",
|
||||
"$ref": "#/definitions/config.Mysql"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/config.Mysql"
|
||||
}
|
||||
]
|
||||
},
|
||||
"oracle": {
|
||||
"$ref": "#/definitions/config.Oracle"
|
||||
},
|
||||
"pgsql": {
|
||||
"$ref": "#/definitions/config.Pgsql"
|
||||
},
|
||||
"sqlite": {
|
||||
"$ref": "#/definitions/config.Sqlite"
|
||||
},
|
||||
"qiniu": {
|
||||
"$ref": "#/definitions/config.Qiniu"
|
||||
},
|
||||
@@ -5265,6 +5343,11 @@
|
||||
"disable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"engine": {
|
||||
"description": "数据库引擎,默认InnoDB",
|
||||
"type": "string",
|
||||
"default": "InnoDB"
|
||||
},
|
||||
"log-mode": {
|
||||
"description": "是否开启Gorm全局日志",
|
||||
"type": "string"
|
||||
@@ -5293,6 +5376,14 @@
|
||||
"description": ":端口",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "全局表前缀,单独定义TableName则不生效",
|
||||
"type": "string"
|
||||
},
|
||||
"singular": {
|
||||
"description": "是否开启全局禁用复数,true表示开启",
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -5327,6 +5418,9 @@
|
||||
"description": "Oss类型",
|
||||
"type": "string"
|
||||
},
|
||||
"router-prefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"use-multipoint": {
|
||||
"description": "多点登录拦截",
|
||||
"type": "boolean"
|
||||
@@ -5445,7 +5539,11 @@
|
||||
},
|
||||
"sysUser": {
|
||||
"description": "管理详情",
|
||||
"$ref": "#/definitions/system.SysUser"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/system.SysUser"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sysUserAuthorityID": {
|
||||
"description": "管理角色ID",
|
||||
@@ -5558,18 +5656,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"example.ExcelInfo": {
|
||||
"github_com_flipped-aurora_gin-vue-admin_server_config.Email": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fileName": {
|
||||
"description": "文件名",
|
||||
"from": {
|
||||
"description": "收件人",
|
||||
"type": "string"
|
||||
},
|
||||
"infoList": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/system.SysBaseMenu"
|
||||
}
|
||||
"host": {
|
||||
"description": "服务器地址",
|
||||
"type": "string"
|
||||
},
|
||||
"is-ssl": {
|
||||
"description": "是否SSL",
|
||||
"type": "boolean"
|
||||
},
|
||||
"nickname": {
|
||||
"description": "昵称",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"description": "端口",
|
||||
"type": "integer"
|
||||
},
|
||||
"secret": {
|
||||
"description": "密钥",
|
||||
"type": "string"
|
||||
},
|
||||
"to": {
|
||||
"description": "收件人:多个以英文逗号分隔",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5736,28 +5852,40 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"authorityId": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"example": "int 角色id"
|
||||
},
|
||||
"authorityIds": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
}
|
||||
"type": "string",
|
||||
"example": "[]uint 角色id"
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"example": "电子邮箱"
|
||||
},
|
||||
"enable": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"example": "int 是否启用"
|
||||
},
|
||||
"headerImg": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "头像链接"
|
||||
},
|
||||
"nickName": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "昵称"
|
||||
},
|
||||
"passWord": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "密码"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "电话号码"
|
||||
},
|
||||
"userName": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "用户名"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5951,9 +6079,7 @@
|
||||
"response.PageResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"list": {
|
||||
"type": "object"
|
||||
},
|
||||
"list": {},
|
||||
"page": {
|
||||
"type": "integer"
|
||||
},
|
||||
@@ -5982,9 +6108,7 @@
|
||||
"code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"data": {
|
||||
"type": "object"
|
||||
},
|
||||
"data": {},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
}
|
||||
@@ -6068,6 +6192,9 @@
|
||||
"captchaLength": {
|
||||
"type": "integer"
|
||||
},
|
||||
"openCaptcha": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"picPath": {
|
||||
"type": "string"
|
||||
}
|
||||
@@ -6119,6 +6246,10 @@
|
||||
"description": "是否自动移动文件",
|
||||
"type": "boolean"
|
||||
},
|
||||
"businessDB": {
|
||||
"description": "业务数据库",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Struct中文名称",
|
||||
"type": "string"
|
||||
@@ -6203,6 +6334,38 @@
|
||||
"require": {
|
||||
"description": "是否必填",
|
||||
"type": "boolean"
|
||||
},
|
||||
"sort": {
|
||||
"description": "是否增加排序",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"system.Meta": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"activeName": {
|
||||
"type": "string"
|
||||
},
|
||||
"closeTab": {
|
||||
"description": "自动关闭tab",
|
||||
"type": "boolean"
|
||||
},
|
||||
"defaultMenu": {
|
||||
"description": "是否是基础路由(开发中)",
|
||||
"type": "boolean"
|
||||
},
|
||||
"icon": {
|
||||
"description": "菜单图标",
|
||||
"type": "string"
|
||||
},
|
||||
"keepAlive": {
|
||||
"description": "是否缓存",
|
||||
"type": "boolean"
|
||||
},
|
||||
"title": {
|
||||
"description": "菜单名",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -6330,10 +6493,6 @@
|
||||
"$ref": "#/definitions/system.SysBaseMenu"
|
||||
}
|
||||
},
|
||||
"closeTab": {
|
||||
"description": "自动关闭tab",
|
||||
"type": "boolean"
|
||||
},
|
||||
"component": {
|
||||
"description": "对应前端文件路径",
|
||||
"type": "string"
|
||||
@@ -6342,32 +6501,28 @@
|
||||
"description": "创建时间",
|
||||
"type": "string"
|
||||
},
|
||||
"defaultMenu": {
|
||||
"description": "是否是基础路由(开发中)",
|
||||
"type": "boolean"
|
||||
},
|
||||
"hidden": {
|
||||
"description": "是否在列表隐藏",
|
||||
"type": "boolean"
|
||||
},
|
||||
"icon": {
|
||||
"description": "菜单图标",
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"description": "主键ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"keepAlive": {
|
||||
"description": "是否缓存",
|
||||
"type": "boolean"
|
||||
},
|
||||
"menuBtn": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/system.SysBaseMenuBtn"
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"description": "附加属性",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/system.Meta"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"description": "路由name",
|
||||
"type": "string"
|
||||
@@ -6390,10 +6545,6 @@
|
||||
"description": "排序标记",
|
||||
"type": "integer"
|
||||
},
|
||||
"title": {
|
||||
"description": "菜单名",
|
||||
"type": "string"
|
||||
},
|
||||
"updatedAt": {
|
||||
"description": "更新时间",
|
||||
"type": "string"
|
||||
@@ -6555,10 +6706,6 @@
|
||||
"$ref": "#/definitions/system.SysMenu"
|
||||
}
|
||||
},
|
||||
"closeTab": {
|
||||
"description": "自动关闭tab",
|
||||
"type": "boolean"
|
||||
},
|
||||
"component": {
|
||||
"description": "对应前端文件路径",
|
||||
"type": "string"
|
||||
@@ -6567,26 +6714,14 @@
|
||||
"description": "创建时间",
|
||||
"type": "string"
|
||||
},
|
||||
"defaultMenu": {
|
||||
"description": "是否是基础路由(开发中)",
|
||||
"type": "boolean"
|
||||
},
|
||||
"hidden": {
|
||||
"description": "是否在列表隐藏",
|
||||
"type": "boolean"
|
||||
},
|
||||
"icon": {
|
||||
"description": "菜单图标",
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"description": "主键ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"keepAlive": {
|
||||
"description": "是否缓存",
|
||||
"type": "boolean"
|
||||
},
|
||||
"menuBtn": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -6596,6 +6731,14 @@
|
||||
"menuId": {
|
||||
"type": "string"
|
||||
},
|
||||
"meta": {
|
||||
"description": "附加属性",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/system.Meta"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"description": "路由name",
|
||||
"type": "string"
|
||||
@@ -6618,10 +6761,6 @@
|
||||
"description": "排序标记",
|
||||
"type": "integer"
|
||||
},
|
||||
"title": {
|
||||
"description": "菜单名",
|
||||
"type": "string"
|
||||
},
|
||||
"updatedAt": {
|
||||
"description": "更新时间",
|
||||
"type": "string"
|
||||
|
||||
+235
-168
@@ -1,4 +1,3 @@
|
||||
basePath: /
|
||||
definitions:
|
||||
config.AliyunOSS:
|
||||
properties:
|
||||
@@ -100,6 +99,12 @@ definitions:
|
||||
key-long:
|
||||
description: 验证码长度
|
||||
type: integer
|
||||
open-captcha:
|
||||
description: 防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码此数,如3代表错误三次后出现验证码
|
||||
type: integer
|
||||
open-captcha-timeout:
|
||||
description: 防爆破验证码超时时间,单位:s(秒)
|
||||
type: integer
|
||||
type: object
|
||||
config.Detail:
|
||||
properties:
|
||||
@@ -113,30 +118,6 @@ definitions:
|
||||
description: 需要清理的表名
|
||||
type: string
|
||||
type: object
|
||||
config.Email:
|
||||
properties:
|
||||
from:
|
||||
description: 收件人
|
||||
type: string
|
||||
host:
|
||||
description: 服务器地址
|
||||
type: string
|
||||
is-ssl:
|
||||
description: 是否SSL
|
||||
type: boolean
|
||||
nickname:
|
||||
description: 昵称
|
||||
type: string
|
||||
port:
|
||||
description: 端口
|
||||
type: integer
|
||||
secret:
|
||||
description: 密钥
|
||||
type: string
|
||||
to:
|
||||
description: 收件人:多个以英文逗号分隔
|
||||
type: string
|
||||
type: object
|
||||
config.Excel:
|
||||
properties:
|
||||
dir:
|
||||
@@ -179,7 +160,7 @@ definitions:
|
||||
description: 本地文件存储路径
|
||||
type: string
|
||||
type: object
|
||||
config.Mysql:
|
||||
config.Mssql:
|
||||
properties:
|
||||
config:
|
||||
description: 高级配置
|
||||
@@ -187,6 +168,10 @@ definitions:
|
||||
db-name:
|
||||
description: 数据库名
|
||||
type: string
|
||||
engine:
|
||||
default: InnoDB
|
||||
description: 数据库引擎,默认InnoDB
|
||||
type: string
|
||||
log-mode:
|
||||
description: 是否开启Gorm全局日志
|
||||
type: string
|
||||
@@ -208,6 +193,98 @@ definitions:
|
||||
port:
|
||||
description: :端口
|
||||
type: string
|
||||
prefix:
|
||||
description: 全局表前缀,单独定义TableName则不生效
|
||||
type: string
|
||||
singular:
|
||||
description: 是否开启全局禁用复数,true表示开启
|
||||
type: boolean
|
||||
username:
|
||||
description: 数据库用户名
|
||||
type: string
|
||||
type: object
|
||||
config.Mysql:
|
||||
properties:
|
||||
config:
|
||||
description: 高级配置
|
||||
type: string
|
||||
db-name:
|
||||
description: 数据库名
|
||||
type: string
|
||||
engine:
|
||||
default: InnoDB
|
||||
description: 数据库引擎,默认InnoDB
|
||||
type: string
|
||||
log-mode:
|
||||
description: 是否开启Gorm全局日志
|
||||
type: string
|
||||
log-zap:
|
||||
description: 是否通过zap写入日志文件
|
||||
type: boolean
|
||||
max-idle-conns:
|
||||
description: 空闲中的最大连接数
|
||||
type: integer
|
||||
max-open-conns:
|
||||
description: 打开到数据库的最大连接数
|
||||
type: integer
|
||||
password:
|
||||
description: 数据库密码
|
||||
type: string
|
||||
path:
|
||||
description: 服务器地址:端口
|
||||
type: string
|
||||
port:
|
||||
description: :端口
|
||||
type: string
|
||||
prefix:
|
||||
description: 全局表前缀,单独定义TableName则不生效
|
||||
type: string
|
||||
singular:
|
||||
description: 是否开启全局禁用复数,true表示开启
|
||||
type: boolean
|
||||
username:
|
||||
description: 数据库用户名
|
||||
type: string
|
||||
type: object
|
||||
config.Oracle:
|
||||
properties:
|
||||
config:
|
||||
description: 高级配置
|
||||
type: string
|
||||
db-name:
|
||||
description: 数据库名
|
||||
type: string
|
||||
engine:
|
||||
default: InnoDB
|
||||
description: 数据库引擎,默认InnoDB
|
||||
type: string
|
||||
log-mode:
|
||||
description: 是否开启Gorm全局日志
|
||||
type: string
|
||||
log-zap:
|
||||
description: 是否通过zap写入日志文件
|
||||
type: boolean
|
||||
max-idle-conns:
|
||||
description: 空闲中的最大连接数
|
||||
type: integer
|
||||
max-open-conns:
|
||||
description: 打开到数据库的最大连接数
|
||||
type: integer
|
||||
password:
|
||||
description: 数据库密码
|
||||
type: string
|
||||
path:
|
||||
description: 服务器地址:端口
|
||||
type: string
|
||||
port:
|
||||
description: :端口
|
||||
type: string
|
||||
prefix:
|
||||
description: 全局表前缀,单独定义TableName则不生效
|
||||
type: string
|
||||
singular:
|
||||
description: 是否开启全局禁用复数,true表示开启
|
||||
type: boolean
|
||||
username:
|
||||
description: 数据库用户名
|
||||
type: string
|
||||
@@ -220,6 +297,10 @@ definitions:
|
||||
db-name:
|
||||
description: 数据库名
|
||||
type: string
|
||||
engine:
|
||||
default: InnoDB
|
||||
description: 数据库引擎,默认InnoDB
|
||||
type: string
|
||||
log-mode:
|
||||
description: 是否开启Gorm全局日志
|
||||
type: string
|
||||
@@ -241,6 +322,12 @@ definitions:
|
||||
port:
|
||||
description: :端口
|
||||
type: string
|
||||
prefix:
|
||||
description: 全局表前缀,单独定义TableName则不生效
|
||||
type: string
|
||||
singular:
|
||||
description: 是否开启全局禁用复数,true表示开启
|
||||
type: boolean
|
||||
username:
|
||||
description: 数据库用户名
|
||||
type: string
|
||||
@@ -286,21 +373,23 @@ definitions:
|
||||
aliyun-oss:
|
||||
$ref: '#/definitions/config.AliyunOSS'
|
||||
autocode:
|
||||
$ref: '#/definitions/config.Autocode'
|
||||
allOf:
|
||||
- $ref: '#/definitions/config.Autocode'
|
||||
description: auto
|
||||
aws-s3:
|
||||
$ref: '#/definitions/config.AwsS3'
|
||||
captcha:
|
||||
$ref: '#/definitions/config.Captcha'
|
||||
cors:
|
||||
$ref: '#/definitions/config.CORS'
|
||||
allOf:
|
||||
- $ref: '#/definitions/config.CORS'
|
||||
description: 跨域配置
|
||||
db-list:
|
||||
items:
|
||||
$ref: '#/definitions/config.SpecializedDB'
|
||||
type: array
|
||||
email:
|
||||
$ref: '#/definitions/config.Email'
|
||||
$ref: '#/definitions/github_com_flipped-aurora_gin-vue-admin_server_config.Email'
|
||||
excel:
|
||||
$ref: '#/definitions/config.Excel'
|
||||
hua-wei-obs:
|
||||
@@ -308,11 +397,17 @@ definitions:
|
||||
jwt:
|
||||
$ref: '#/definitions/config.JWT'
|
||||
local:
|
||||
$ref: '#/definitions/config.Local'
|
||||
allOf:
|
||||
- $ref: '#/definitions/config.Local'
|
||||
description: oss
|
||||
mssql:
|
||||
$ref: '#/definitions/config.Mssql'
|
||||
mysql:
|
||||
$ref: '#/definitions/config.Mysql'
|
||||
allOf:
|
||||
- $ref: '#/definitions/config.Mysql'
|
||||
description: gorm
|
||||
oracle:
|
||||
$ref: '#/definitions/config.Oracle'
|
||||
pgsql:
|
||||
$ref: '#/definitions/config.Pgsql'
|
||||
qiniu:
|
||||
@@ -340,6 +435,10 @@ definitions:
|
||||
type: string
|
||||
disable:
|
||||
type: boolean
|
||||
engine:
|
||||
default: InnoDB
|
||||
description: 数据库引擎,默认InnoDB
|
||||
type: string
|
||||
log-mode:
|
||||
description: 是否开启Gorm全局日志
|
||||
type: string
|
||||
@@ -361,6 +460,12 @@ definitions:
|
||||
port:
|
||||
description: :端口
|
||||
type: string
|
||||
prefix:
|
||||
description: 全局表前缀,单独定义TableName则不生效
|
||||
type: string
|
||||
singular:
|
||||
description: 是否开启全局禁用复数,true表示开启
|
||||
type: boolean
|
||||
type:
|
||||
type: string
|
||||
username:
|
||||
@@ -385,6 +490,8 @@ definitions:
|
||||
oss-type:
|
||||
description: Oss类型
|
||||
type: string
|
||||
router-prefix:
|
||||
type: string
|
||||
use-multipoint:
|
||||
description: 多点登录拦截
|
||||
type: boolean
|
||||
@@ -468,7 +575,8 @@ definitions:
|
||||
description: 主键ID
|
||||
type: integer
|
||||
sysUser:
|
||||
$ref: '#/definitions/system.SysUser'
|
||||
allOf:
|
||||
- $ref: '#/definitions/system.SysUser'
|
||||
description: 管理详情
|
||||
sysUserAuthorityID:
|
||||
description: 管理角色ID
|
||||
@@ -548,15 +656,29 @@ definitions:
|
||||
description: 文件地址
|
||||
type: string
|
||||
type: object
|
||||
example.ExcelInfo:
|
||||
github_com_flipped-aurora_gin-vue-admin_server_config.Email:
|
||||
properties:
|
||||
fileName:
|
||||
description: 文件名
|
||||
from:
|
||||
description: 收件人
|
||||
type: string
|
||||
host:
|
||||
description: 服务器地址
|
||||
type: string
|
||||
is-ssl:
|
||||
description: 是否SSL
|
||||
type: boolean
|
||||
nickname:
|
||||
description: 昵称
|
||||
type: string
|
||||
port:
|
||||
description: 端口
|
||||
type: integer
|
||||
secret:
|
||||
description: 密钥
|
||||
type: string
|
||||
to:
|
||||
description: 收件人:多个以英文逗号分隔
|
||||
type: string
|
||||
infoList:
|
||||
items:
|
||||
$ref: '#/definitions/system.SysBaseMenu'
|
||||
type: array
|
||||
type: object
|
||||
request.AddMenuAuthorityInfo:
|
||||
properties:
|
||||
@@ -671,20 +793,31 @@ definitions:
|
||||
request.Register:
|
||||
properties:
|
||||
authorityId:
|
||||
type: integer
|
||||
example: int 角色id
|
||||
type: string
|
||||
authorityIds:
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
example: '[]uint 角色id'
|
||||
type: string
|
||||
email:
|
||||
example: 电子邮箱
|
||||
type: string
|
||||
enable:
|
||||
type: integer
|
||||
example: int 是否启用
|
||||
type: string
|
||||
headerImg:
|
||||
example: 头像链接
|
||||
type: string
|
||||
nickName:
|
||||
example: 昵称
|
||||
type: string
|
||||
passWord:
|
||||
example: 密码
|
||||
type: string
|
||||
phone:
|
||||
example: 电话号码
|
||||
type: string
|
||||
userName:
|
||||
example: 用户名
|
||||
type: string
|
||||
type: object
|
||||
request.RollBack:
|
||||
@@ -817,8 +950,7 @@ definitions:
|
||||
type: object
|
||||
response.PageResult:
|
||||
properties:
|
||||
list:
|
||||
type: object
|
||||
list: {}
|
||||
page:
|
||||
type: integer
|
||||
pageSize:
|
||||
@@ -837,8 +969,7 @@ definitions:
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
data:
|
||||
type: object
|
||||
data: {}
|
||||
msg:
|
||||
type: string
|
||||
type: object
|
||||
@@ -892,6 +1023,8 @@ definitions:
|
||||
type: string
|
||||
captchaLength:
|
||||
type: integer
|
||||
openCaptcha:
|
||||
type: boolean
|
||||
picPath:
|
||||
type: string
|
||||
type: object
|
||||
@@ -926,6 +1059,9 @@ definitions:
|
||||
autoMoveFile:
|
||||
description: 是否自动移动文件
|
||||
type: boolean
|
||||
businessDB:
|
||||
description: 业务数据库
|
||||
type: string
|
||||
description:
|
||||
description: Struct中文名称
|
||||
type: string
|
||||
@@ -988,6 +1124,29 @@ definitions:
|
||||
require:
|
||||
description: 是否必填
|
||||
type: boolean
|
||||
sort:
|
||||
description: 是否增加排序
|
||||
type: boolean
|
||||
type: object
|
||||
system.Meta:
|
||||
properties:
|
||||
activeName:
|
||||
type: string
|
||||
closeTab:
|
||||
description: 自动关闭tab
|
||||
type: boolean
|
||||
defaultMenu:
|
||||
description: 是否是基础路由(开发中)
|
||||
type: boolean
|
||||
icon:
|
||||
description: 菜单图标
|
||||
type: string
|
||||
keepAlive:
|
||||
description: 是否缓存
|
||||
type: boolean
|
||||
title:
|
||||
description: 菜单名
|
||||
type: string
|
||||
type: object
|
||||
system.SysApi:
|
||||
properties:
|
||||
@@ -1076,34 +1235,26 @@ definitions:
|
||||
items:
|
||||
$ref: '#/definitions/system.SysBaseMenu'
|
||||
type: array
|
||||
closeTab:
|
||||
description: 自动关闭tab
|
||||
type: boolean
|
||||
component:
|
||||
description: 对应前端文件路径
|
||||
type: string
|
||||
createdAt:
|
||||
description: 创建时间
|
||||
type: string
|
||||
defaultMenu:
|
||||
description: 是否是基础路由(开发中)
|
||||
type: boolean
|
||||
hidden:
|
||||
description: 是否在列表隐藏
|
||||
type: boolean
|
||||
icon:
|
||||
description: 菜单图标
|
||||
type: string
|
||||
id:
|
||||
description: 主键ID
|
||||
type: integer
|
||||
keepAlive:
|
||||
description: 是否缓存
|
||||
type: boolean
|
||||
menuBtn:
|
||||
items:
|
||||
$ref: '#/definitions/system.SysBaseMenuBtn'
|
||||
type: array
|
||||
meta:
|
||||
allOf:
|
||||
- $ref: '#/definitions/system.Meta'
|
||||
description: 附加属性
|
||||
name:
|
||||
description: 路由name
|
||||
type: string
|
||||
@@ -1120,9 +1271,6 @@ definitions:
|
||||
sort:
|
||||
description: 排序标记
|
||||
type: integer
|
||||
title:
|
||||
description: 菜单名
|
||||
type: string
|
||||
updatedAt:
|
||||
description: 更新时间
|
||||
type: string
|
||||
@@ -1237,36 +1385,28 @@ definitions:
|
||||
items:
|
||||
$ref: '#/definitions/system.SysMenu'
|
||||
type: array
|
||||
closeTab:
|
||||
description: 自动关闭tab
|
||||
type: boolean
|
||||
component:
|
||||
description: 对应前端文件路径
|
||||
type: string
|
||||
createdAt:
|
||||
description: 创建时间
|
||||
type: string
|
||||
defaultMenu:
|
||||
description: 是否是基础路由(开发中)
|
||||
type: boolean
|
||||
hidden:
|
||||
description: 是否在列表隐藏
|
||||
type: boolean
|
||||
icon:
|
||||
description: 菜单图标
|
||||
type: string
|
||||
id:
|
||||
description: 主键ID
|
||||
type: integer
|
||||
keepAlive:
|
||||
description: 是否缓存
|
||||
type: boolean
|
||||
menuBtn:
|
||||
items:
|
||||
$ref: '#/definitions/system.SysBaseMenuBtn'
|
||||
type: array
|
||||
menuId:
|
||||
type: string
|
||||
meta:
|
||||
allOf:
|
||||
- $ref: '#/definitions/system.Meta'
|
||||
description: 附加属性
|
||||
name:
|
||||
description: 路由name
|
||||
type: string
|
||||
@@ -1283,9 +1423,6 @@ definitions:
|
||||
sort:
|
||||
description: 排序标记
|
||||
type: integer
|
||||
title:
|
||||
description: 菜单名
|
||||
type: string
|
||||
updatedAt:
|
||||
description: 更新时间
|
||||
type: string
|
||||
@@ -1480,6 +1617,25 @@ paths:
|
||||
summary: 删除选中Api
|
||||
tags:
|
||||
- SysApi
|
||||
/api/freshCasbin:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 刷新成功
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/response.Response'
|
||||
- properties:
|
||||
msg:
|
||||
type: string
|
||||
type: object
|
||||
summary: 刷新casbin缓存
|
||||
tags:
|
||||
- SysApi
|
||||
/api/getAllApis:
|
||||
post:
|
||||
consumes:
|
||||
@@ -2212,7 +2368,7 @@ paths:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 生成验证码,返回包括随机数id,base64,验证码长度
|
||||
description: 生成验证码,返回包括随机数id,base64,验证码长度,是否开启验证码
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/response.Response'
|
||||
@@ -2515,95 +2671,6 @@ paths:
|
||||
summary: 发送邮件
|
||||
tags:
|
||||
- System
|
||||
/excel/downloadTemplate:
|
||||
get:
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
parameters:
|
||||
- description: 模板名称
|
||||
in: query
|
||||
name: fileName
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: 下载模板
|
||||
tags:
|
||||
- excel
|
||||
/excel/exportExcel:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: 导出Excel文件信息
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/example.ExcelInfo'
|
||||
produces:
|
||||
- application/octet-stream
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: 导出Excel
|
||||
tags:
|
||||
- excel
|
||||
/excel/importExcel:
|
||||
post:
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
parameters:
|
||||
- description: 导入Excel文件
|
||||
in: formData
|
||||
name: file
|
||||
required: true
|
||||
type: file
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 导入Excel文件
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/response.Response'
|
||||
- properties:
|
||||
msg:
|
||||
type: string
|
||||
type: object
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: 导入Excel文件
|
||||
tags:
|
||||
- excel
|
||||
/excel/loadExcel:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 加载Excel数据,返回包括列表,总数,页码,每页数量
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/response.Response'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/response.PageResult'
|
||||
msg:
|
||||
type: string
|
||||
type: object
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: 加载Excel数据
|
||||
tags:
|
||||
- excel
|
||||
/fileUploadAndDownload/breakpointContinue:
|
||||
post:
|
||||
consumes:
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/config"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/spf13/viper"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
+115
-43
@@ -1,59 +1,131 @@
|
||||
module github.com/flipped-aurora/gin-vue-admin/server
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible
|
||||
github.com/aws/aws-sdk-go v1.42.27
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
|
||||
github.com/casbin/casbin/v2 v2.51.0
|
||||
github.com/casbin/gorm-adapter/v3 v3.7.3
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible
|
||||
github.com/aws/aws-sdk-go v1.44.307
|
||||
github.com/casbin/casbin/v2 v2.71.1
|
||||
github.com/casbin/gorm-adapter/v3 v3.18.0
|
||||
github.com/flipped-aurora/ws v1.0.2
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
|
||||
github.com/gin-gonic/gin v1.7.0
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
github.com/go-openapi/spec v0.20.3 // indirect
|
||||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.4
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/golang-jwt/jwt/v4 v4.3.0
|
||||
github.com/gookit/color v1.3.1
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/glebarez/sqlite v1.8.0
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/gofrs/uuid/v5 v5.0.0
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/gookit/color v1.5.4
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible
|
||||
github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
|
||||
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mitchellh/mapstructure v1.2.2 // indirect
|
||||
github.com/mojocn/base64Captcha v1.3.1
|
||||
github.com/mojocn/base64Captcha v1.3.5
|
||||
github.com/otiai10/copy v1.7.0
|
||||
github.com/pelletier/go-toml v1.6.0 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/qiniu/api.v7/v7 v7.4.1
|
||||
github.com/redis/go-redis/v9 v9.0.5
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/shirou/gopsutil/v3 v3.22.5
|
||||
github.com/songzhibin97/gkit v1.2.7
|
||||
github.com/spf13/afero v1.2.2 // indirect
|
||||
github.com/spf13/cast v1.3.1 // indirect
|
||||
github.com/sashabaranov/go-openai v1.14.1
|
||||
github.com/shirou/gopsutil/v3 v3.23.6
|
||||
github.com/songzhibin97/gkit v1.2.11
|
||||
github.com/spf13/viper v1.16.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/swaggo/gin-swagger v1.3.0
|
||||
github.com/swaggo/swag v1.16.1
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.42
|
||||
github.com/unrolled/secure v1.13.0
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/crypto v0.10.0
|
||||
golang.org/x/sync v0.3.0
|
||||
golang.org/x/text v0.11.0
|
||||
gorm.io/driver/mysql v1.5.1
|
||||
gorm.io/driver/postgres v1.5.2
|
||||
gorm.io/driver/sqlserver v1.5.1
|
||||
gorm.io/gorm v1.25.2
|
||||
nhooyr.io/websocket v1.8.7
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/clbanning/mxj v1.8.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.1 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/spec v0.20.9 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/google/go-querystring v1.0.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgx/v5 v5.3.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/microsoft/go-mssqldb v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mozillazg/go-httpheader v0.2.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.7.0
|
||||
github.com/stretchr/testify v1.7.1
|
||||
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/unrolled/secure v1.0.7
|
||||
github.com/xuri/excelize/v2 v2.4.1
|
||||
go.uber.org/zap v1.16.0
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/text v0.3.7
|
||||
golang.org/x/tools v0.1.5 // indirect
|
||||
gopkg.in/ini.v1 v1.55.0 // indirect
|
||||
gorm.io/driver/mysql v1.3.3
|
||||
gorm.io/driver/postgres v1.3.4
|
||||
gorm.io/gorm v1.23.4
|
||||
nhooyr.io/websocket v1.8.6
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/image v0.5.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sys v0.10.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
golang.org/x/tools v0.9.1 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/plugin/dbresolver v1.4.1 // indirect
|
||||
modernc.org/libc v1.24.1 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.6.0 // indirect
|
||||
modernc.org/sqlite v1.23.0 // indirect
|
||||
)
|
||||
|
||||
+477
-663
File diff suppressed because it is too large
Load Diff
@@ -17,8 +17,12 @@ func DBList() {
|
||||
switch info.Type {
|
||||
case "mysql":
|
||||
dbMap[info.AliasName] = GormMysqlByConfig(config.Mysql{GeneralDB: info.GeneralDB})
|
||||
case "mssql":
|
||||
dbMap[info.AliasName] = GormMssqlByConfig(config.Mssql{GeneralDB: info.GeneralDB})
|
||||
case "pgsql":
|
||||
dbMap[info.AliasName] = GormPgSqlByConfig(config.Pgsql{GeneralDB: info.GeneralDB})
|
||||
case "oracle":
|
||||
dbMap[info.AliasName] = GormOracleByConfig(config.Oracle{GeneralDB: info.GeneralDB})
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ func (e *ensureTables) MigrateTable(ctx context.Context) (context.Context, error
|
||||
sysModel.SysBaseMenuBtn{},
|
||||
sysModel.SysAuthorityBtn{},
|
||||
sysModel.SysAutoCode{},
|
||||
sysModel.SysChatGptOption{},
|
||||
|
||||
adapter.CasbinRule{},
|
||||
|
||||
@@ -83,7 +84,7 @@ func (e *ensureTables) TableCreated(ctx context.Context) bool {
|
||||
sysModel.SysBaseMenuBtn{},
|
||||
sysModel.SysAuthorityBtn{},
|
||||
sysModel.SysAutoCode{},
|
||||
|
||||
sysModel.SysChatGptOption{},
|
||||
adapter.CasbinRule{},
|
||||
|
||||
example.ExaFile{},
|
||||
|
||||
@@ -19,6 +19,12 @@ func Gorm() *gorm.DB {
|
||||
return GormMysql()
|
||||
case "pgsql":
|
||||
return GormPgSql()
|
||||
case "oracle":
|
||||
return GormOracle()
|
||||
case "mssql":
|
||||
return GormMssql()
|
||||
case "sqlite":
|
||||
return GormSqlite()
|
||||
default:
|
||||
return GormMysql()
|
||||
}
|
||||
@@ -26,7 +32,8 @@ func Gorm() *gorm.DB {
|
||||
|
||||
// RegisterTables 注册数据库表专用
|
||||
// Author SliverHorn
|
||||
func RegisterTables(db *gorm.DB) {
|
||||
func RegisterTables() {
|
||||
db := global.GVA_DB
|
||||
err := db.AutoMigrate(
|
||||
// 系统模块表
|
||||
system.SysApi{},
|
||||
@@ -42,17 +49,12 @@ func RegisterTables(db *gorm.DB) {
|
||||
system.SysBaseMenuBtn{},
|
||||
system.SysAuthorityBtn{},
|
||||
system.SysAutoCode{},
|
||||
system.SysChatGptOption{},
|
||||
|
||||
// 示例模块表
|
||||
example.ExaFile{},
|
||||
example.ExaCustomer{},
|
||||
example.ExaFileChunk{},
|
||||
example.ExaFileUploadAndDownload{},
|
||||
|
||||
// 自动化模块表
|
||||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server Begin; DO NOT EDIT.
|
||||
|
||||
// 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.Error(err))
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* @Author: 逆光飞翔 191180776@qq.com
|
||||
* @Date: 2022-12-08 17:25:49
|
||||
* @LastEditors: 逆光飞翔 191180776@qq.com
|
||||
* @LastEditTime: 2022-12-08 18:00:00
|
||||
* @FilePath: \server\initialize\gorm_mssql.go
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"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/initialize/internal"
|
||||
"gorm.io/driver/sqlserver"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// GormMssql 初始化Mssql数据库
|
||||
// Author [LouisZhang](191180776@qq.com)
|
||||
func GormMssql() *gorm.DB {
|
||||
m := global.GVA_CONFIG.Mssql
|
||||
if m.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
mssqlConfig := sqlserver.Config{
|
||||
DSN: m.Dsn(), // DSN data source name
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
}
|
||||
if db, err := gorm.Open(sqlserver.New(mssqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
db.InstanceSet("gorm:table_options", "ENGINE="+m.Engine)
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
}
|
||||
|
||||
// GormMssqlByConfig 初始化Mysql数据库用过传入配置
|
||||
func GormMssqlByConfig(m config.Mssql) *gorm.DB {
|
||||
if m.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
mssqlConfig := sqlserver.Config{
|
||||
DSN: m.Dsn(), // DSN data source name
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
}
|
||||
if db, err := gorm.Open(sqlserver.New(mssqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
db.InstanceSet("gorm:table_options", "ENGINE=InnoDB")
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"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/initialize/internal"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -21,9 +22,10 @@ func GormMysql() *gorm.DB {
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
SkipInitializeWithVersion: false, // 根据版本自动配置
|
||||
}
|
||||
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config()); err != nil {
|
||||
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
db.InstanceSet("gorm:table_options", "ENGINE="+m.Engine)
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
|
||||
@@ -41,9 +43,10 @@ func GormMysqlByConfig(m config.Mysql) *gorm.DB {
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
SkipInitializeWithVersion: false, // 根据版本自动配置
|
||||
}
|
||||
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config()); err != nil {
|
||||
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
db.InstanceSet("gorm:table_options", "ENGINE=InnoDB")
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
//"github.com/dzwvip/oracle"
|
||||
"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/initialize/internal"
|
||||
|
||||
//_ "github.com/godror/godror"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// GormOracle 初始化oracle数据库
|
||||
// 如果需要Oracle库 放开import里的注释 把下方 mysql.Config 改为 oracle.Config ; mysql.New 改为 oracle.New
|
||||
func GormOracle() *gorm.DB {
|
||||
m := global.GVA_CONFIG.Oracle
|
||||
if m.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
oracleConfig := mysql.Config{
|
||||
DSN: m.Dsn(), // DSN data source name
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
}
|
||||
if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
}
|
||||
|
||||
// GormOracleByConfig 初始化Oracle数据库用过传入配置
|
||||
func GormOracleByConfig(m config.Oracle) *gorm.DB {
|
||||
if m.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
oracleConfig := mysql.Config{
|
||||
DSN: m.Dsn(), // DSN data source name
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
}
|
||||
if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ func GormPgSql() *gorm.DB {
|
||||
DSN: p.Dsn(), // DSN data source name
|
||||
PreferSimpleProtocol: false,
|
||||
}
|
||||
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config()); err != nil {
|
||||
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config(p.Prefix, p.Singular)); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
@@ -39,7 +39,7 @@ func GormPgSqlByConfig(p config.Pgsql) *gorm.DB {
|
||||
DSN: p.Dsn(), // DSN data source name
|
||||
PreferSimpleProtocol: false,
|
||||
}
|
||||
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config()); err != nil {
|
||||
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config(p.Prefix, p.Singular)); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"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/initialize/internal"
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// GormSqlite 初始化Sqlite数据库
|
||||
func GormSqlite() *gorm.DB {
|
||||
s := global.GVA_CONFIG.Sqlite
|
||||
if s.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if db, err := gorm.Open(sqlite.Open(s.Dsn()), internal.Gorm.Config(s.Prefix, s.Singular)); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(s.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(s.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
}
|
||||
|
||||
// GormSqliteByConfig 初始化Sqlite数据库用过传入配置
|
||||
func GormSqliteByConfig(s config.Sqlite) *gorm.DB {
|
||||
if s.Dbname == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if db, err := gorm.Open(sqlite.Open(s.Dsn()), internal.Gorm.Config(s.Prefix, s.Singular)); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(s.MaxIdleConns)
|
||||
sqlDB.SetMaxOpenConns(s.MaxOpenConns)
|
||||
return db
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"gorm.io/gorm/schema"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
@@ -20,9 +21,15 @@ type _gorm struct{}
|
||||
|
||||
// Config gorm 自定义配置
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (g *_gorm) Config() *gorm.Config {
|
||||
config := &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}
|
||||
_default := logger.New(NewWriter(log.New(os.Stdout, "\r\n", log.LstdFlags)), logger.Config{
|
||||
func (g *_gorm) Config(prefix string, singular bool) *gorm.Config {
|
||||
config := &gorm.Config{
|
||||
NamingStrategy: schema.NamingStrategy{
|
||||
TablePrefix: prefix,
|
||||
SingularTable: singular,
|
||||
},
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
}
|
||||
_default := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), logger.Config{
|
||||
SlowThreshold: 200 * time.Millisecond,
|
||||
LogLevel: logger.Warn,
|
||||
Colorful: true,
|
||||
@@ -33,6 +40,8 @@ func (g *_gorm) Config() *gorm.Config {
|
||||
logMode = &global.GVA_CONFIG.Mysql
|
||||
case "pgsql":
|
||||
logMode = &global.GVA_CONFIG.Pgsql
|
||||
case "oracle":
|
||||
logMode = &global.GVA_CONFIG.Oracle
|
||||
default:
|
||||
logMode = &global.GVA_CONFIG.Mysql
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package initialize
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"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/plugin/email"
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
||||
+12
-15
@@ -3,12 +3,12 @@ package initialize
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
_ "github.com/flipped-aurora/gin-vue-admin/server/docs"
|
||||
"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"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
"github.com/swaggo/gin-swagger/swaggerFiles"
|
||||
)
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
func Routers() *gin.Engine {
|
||||
Router := gin.Default()
|
||||
InstallPlugin(Router) // 安装插件
|
||||
systemRouter := router.RouterGroupApp.System
|
||||
exampleRouter := router.RouterGroupApp.Example
|
||||
// 如果想要不使用nginx代理前端网页,可以修改 web/.env.production 下的
|
||||
@@ -27,31 +28,32 @@ func Routers() *gin.Engine {
|
||||
// Router.Static("/static", "./dist/assets") // dist里面的静态资源
|
||||
// Router.StaticFile("/", "./dist/index.html") // 前端网页入口页面
|
||||
|
||||
Router.StaticFS(global.GVA_CONFIG.Local.Path, http.Dir(global.GVA_CONFIG.Local.StorePath)) // 为用户头像和文件提供静态地址
|
||||
Router.StaticFS(global.GVA_CONFIG.Local.StorePath, http.Dir(global.GVA_CONFIG.Local.StorePath)) // 为用户头像和文件提供静态地址
|
||||
// Router.Use(middleware.LoadTls()) // 如果需要使用https 请打开此中间件 然后前往 core/server.go 将启动模式 更变为 Router.RunTLS("端口","你的cre/pem文件","你的key文件")
|
||||
// 跨域,如需跨域可以打开下面的注释
|
||||
// Router.Use(middleware.Cors()) // 直接放行全部跨域请求
|
||||
//Router.Use(middleware.CorsByRules()) // 按照配置的规则放行跨域请求
|
||||
// Router.Use(middleware.CorsByRules()) // 按照配置的规则放行跨域请求
|
||||
//global.GVA_LOG.Info("use middleware cors")
|
||||
Router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
docs.SwaggerInfo.BasePath = global.GVA_CONFIG.System.RouterPrefix
|
||||
Router.GET(global.GVA_CONFIG.System.RouterPrefix+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
global.GVA_LOG.Info("register swagger handler")
|
||||
// 方便统一添加路由组前缀 多服务器上线使用
|
||||
|
||||
PublicGroup := Router.Group("")
|
||||
PublicGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
|
||||
{
|
||||
// 健康监测
|
||||
PublicGroup.GET("/health", func(c *gin.Context) {
|
||||
c.JSON(200, "ok")
|
||||
c.JSON(http.StatusOK, "ok")
|
||||
})
|
||||
}
|
||||
{
|
||||
systemRouter.InitBaseRouter(PublicGroup) // 注册基础功能路由 不做鉴权
|
||||
systemRouter.InitInitRouter(PublicGroup) // 自动初始化相关
|
||||
}
|
||||
PrivateGroup := Router.Group("")
|
||||
PrivateGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
|
||||
PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
|
||||
{
|
||||
systemRouter.InitApiRouter(PrivateGroup) // 注册功能api路由
|
||||
systemRouter.InitApiRouter(PrivateGroup, PublicGroup) // 注册功能api路由
|
||||
systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由
|
||||
systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由
|
||||
systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由
|
||||
@@ -64,18 +66,13 @@ func Routers() *gin.Engine {
|
||||
systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录
|
||||
systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理
|
||||
systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 字典详情管理
|
||||
systemRouter.InitChatGptRouter(PrivateGroup) // chatGpt接口
|
||||
|
||||
exampleRouter.InitExcelRouter(PrivateGroup) // 表格导入导出
|
||||
exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由
|
||||
exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由
|
||||
|
||||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server Begin; DO NOT EDIT.
|
||||
|
||||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server End; DO NOT EDIT.
|
||||
}
|
||||
|
||||
InstallPlugin(Router) // 安装插件
|
||||
|
||||
global.GVA_LOG.Info("router register success")
|
||||
return Router
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ func main() {
|
||||
initialize.Timer()
|
||||
initialize.DBList()
|
||||
if global.GVA_DB != nil {
|
||||
initialize.RegisterTables(global.GVA_DB) // 初始化表
|
||||
initialize.RegisterTables() // 初始化表
|
||||
// 程序结束前关闭数据库链接
|
||||
db, _ := global.GVA_DB.DB()
|
||||
defer db.Close()
|
||||
|
||||
@@ -1,34 +1,38 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"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"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService
|
||||
|
||||
// 拦截器
|
||||
// CasbinHandler 拦截器
|
||||
func CasbinHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
waitUse, _ := utils.GetClaims(c)
|
||||
// 获取请求的PATH
|
||||
obj := c.Request.URL.Path
|
||||
// 获取请求方法
|
||||
act := c.Request.Method
|
||||
// 获取用户的角色
|
||||
sub := strconv.Itoa(int(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
|
||||
if global.GVA_CONFIG.System.Env != "develop" {
|
||||
waitUse, _ := utils.GetClaims(c)
|
||||
//获取请求的PATH
|
||||
path := c.Request.URL.Path
|
||||
obj := strings.TrimPrefix(path, global.GVA_CONFIG.System.RouterPrefix)
|
||||
// 获取请求方法
|
||||
act := c.Request.Method
|
||||
// 获取用户的角色
|
||||
sub := strconv.Itoa(int(waitUse.AuthorityId))
|
||||
e := casbinService.Casbin() // 判断策略中是否存在
|
||||
success, _ := e.Enforce(sub, obj, act)
|
||||
if !success {
|
||||
response.FailWithDetailed(gin.H{}, "权限不足", c)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ func CorsByRules() gin.HandlerFunc {
|
||||
c.AbortWithStatus(http.StatusForbidden)
|
||||
} else {
|
||||
// 非严格白名单模式,无论是否通过检查均放行所有 OPTIONS 方法
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
if c.Request.Method == http.MethodOptions {
|
||||
c.AbortWithStatus(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -35,7 +37,7 @@ func JWTAuth() gin.HandlerFunc {
|
||||
// parseToken 解析token包含的信息
|
||||
claims, err := j.ParseToken(token)
|
||||
if err != nil {
|
||||
if err == utils.TokenExpired {
|
||||
if errors.Is(err, utils.TokenExpired) {
|
||||
response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c)
|
||||
c.Abort()
|
||||
return
|
||||
@@ -53,13 +55,13 @@ func JWTAuth() gin.HandlerFunc {
|
||||
// response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
|
||||
// c.Abort()
|
||||
//}
|
||||
if claims.ExpiresAt-time.Now().Unix() < claims.BufferTime {
|
||||
if claims.ExpiresAt.Unix()-time.Now().Unix() < claims.BufferTime {
|
||||
dr, _ := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
|
||||
claims.ExpiresAt = time.Now().Add(dr).Unix()
|
||||
claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(dr))
|
||||
newToken, _ := j.CreateTokenByOldToken(token, *claims)
|
||||
newClaims, _ := j.ParseToken(newToken)
|
||||
c.Header("new-token", newToken)
|
||||
c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt, 10))
|
||||
c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt.Unix(), 10))
|
||||
if global.GVA_CONFIG.System.UseMultipoint {
|
||||
RedisJwtToken, err := jwtService.GetRedisJWT(newClaims.Username)
|
||||
if err != nil {
|
||||
|
||||
@@ -64,8 +64,10 @@ func (l Logger) SetLoggerMiddleware() gin.HandlerFunc {
|
||||
if l.Filter != nil && !l.Filter(c) {
|
||||
layout.Body = string(body)
|
||||
}
|
||||
// 处理鉴权需要的信息
|
||||
l.AuthProcess(c, &layout)
|
||||
if l.AuthProcess != nil {
|
||||
// 处理鉴权需要的信息
|
||||
l.AuthProcess(c, &layout)
|
||||
}
|
||||
if l.FilterKeyword != nil {
|
||||
// 自行判断key/value 脱敏等
|
||||
l.FilterKeyword(&layout)
|
||||
|
||||
@@ -56,8 +56,8 @@ func OperationRecord() gin.HandlerFunc {
|
||||
body, _ = json.Marshal(&m)
|
||||
}
|
||||
claims, _ := utils.GetClaims(c)
|
||||
if claims.ID != 0 {
|
||||
userId = int(claims.ID)
|
||||
if claims.BaseClaims.ID != 0 {
|
||||
userId = int(claims.BaseClaims.ID)
|
||||
} else {
|
||||
id, err := strconv.Atoi(c.Request.Header.Get("x-user-id"))
|
||||
if err != nil {
|
||||
@@ -75,7 +75,7 @@ func OperationRecord() gin.HandlerFunc {
|
||||
}
|
||||
|
||||
// 上传文件时候 中间件日志进行裁断操作
|
||||
if strings.Contains(c.GetHeader("Content-Type"), "multipart/form-data") {
|
||||
if strings.Contains(c.GetHeader("Content-Type"), "multipart/form-data") {
|
||||
if len(record.Body) > 1024 {
|
||||
// 截断
|
||||
newBody := respPool.Get().([]byte)
|
||||
@@ -100,20 +100,20 @@ func OperationRecord() gin.HandlerFunc {
|
||||
record.Latency = latency
|
||||
record.Resp = writer.body.String()
|
||||
|
||||
if strings.Contains(c.Writer.Header().Get("Pragma"), "public") ||
|
||||
strings.Contains(c.Writer.Header().Get("Expires"), "0") ||
|
||||
if strings.Contains(c.Writer.Header().Get("Pragma"), "public") ||
|
||||
strings.Contains(c.Writer.Header().Get("Expires"), "0") ||
|
||||
strings.Contains(c.Writer.Header().Get("Cache-Control"), "must-revalidate, post-check=0, pre-check=0") ||
|
||||
strings.Contains(c.Writer.Header().Get("Content-Type"), "application/force-download") ||
|
||||
strings.Contains(c.Writer.Header().Get("Content-Type"), "application/octet-stream") ||
|
||||
strings.Contains(c.Writer.Header().Get("Content-Type"), "application/vnd.ms-excel") ||
|
||||
strings.Contains(c.Writer.Header().Get("Content-Type"), "application/download") ||
|
||||
strings.Contains(c.Writer.Header().Get("Content-Disposition"), "attachment") ||
|
||||
strings.Contains(c.Writer.Header().Get("Content-Type"), "application/force-download") ||
|
||||
strings.Contains(c.Writer.Header().Get("Content-Type"), "application/octet-stream") ||
|
||||
strings.Contains(c.Writer.Header().Get("Content-Type"), "application/vnd.ms-excel") ||
|
||||
strings.Contains(c.Writer.Header().Get("Content-Type"), "application/download") ||
|
||||
strings.Contains(c.Writer.Header().Get("Content-Disposition"), "attachment") ||
|
||||
strings.Contains(c.Writer.Header().Get("Content-Transfer-Encoding"), "binary") {
|
||||
if len(record.Resp) > 1024 {
|
||||
// 截断
|
||||
newBody := respPool.Get().([]byte)
|
||||
copy(newBody, record.Resp)
|
||||
record.Body = string(newBody)
|
||||
record.Resp = string(newBody)
|
||||
defer respPool.Put(newBody[:0])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
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"`
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"github.com/gofrs/uuid/v5"
|
||||
jwt "github.com/golang-jwt/jwt/v4"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
// Custom claims structure
|
||||
type CustomClaims struct {
|
||||
BaseClaims
|
||||
BufferTime int64
|
||||
jwt.StandardClaims
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
type BaseClaims struct {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
)
|
||||
|
||||
type ChatGptRequest struct {
|
||||
system.ChatGpt
|
||||
request.PageInfo
|
||||
}
|
||||
@@ -7,12 +7,13 @@ import (
|
||||
)
|
||||
|
||||
type InitDB struct {
|
||||
DBType string `json:"dbType"` // 数据库类型
|
||||
Host string `json:"host"` // 服务器地址
|
||||
Port string `json:"port"` // 数据库连接端口
|
||||
UserName string `json:"userName" binding:"required"` // 数据库用户名
|
||||
Password string `json:"password"` // 数据库密码
|
||||
DBName string `json:"dbName" binding:"required"` // 数据库名
|
||||
DBType string `json:"dbType"` // 数据库类型
|
||||
Host string `json:"host"` // 服务器地址
|
||||
Port string `json:"port"` // 数据库连接端口
|
||||
UserName string `json:"userName"` // 数据库用户名
|
||||
Password string `json:"password"` // 数据库密码
|
||||
DBName string `json:"dbName" binding:"required"` // 数据库名
|
||||
DBPath string `json:"dbPath"` // sqlite数据库文件路径
|
||||
}
|
||||
|
||||
// MysqlEmptyDsn msyql 空数据库 建库链接
|
||||
@@ -39,6 +40,12 @@ func (i *InitDB) PgsqlEmptyDsn() string {
|
||||
return "host=" + i.Host + " user=" + i.UserName + " password=" + i.Password + " port=" + i.Port + " dbname=" + "postgres" + " " + "sslmode=disable TimeZone=Asia/Shanghai"
|
||||
}
|
||||
|
||||
// SqliteEmptyDsn sqlite 空数据库 建库链接
|
||||
// Author Kafumio
|
||||
func (i *InitDB) SqliteEmptyDsn() string {
|
||||
return i.DBPath + "\\" + i.DBName + ".db"
|
||||
}
|
||||
|
||||
// ToMysqlConfig 转换 config.Mysql
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (i *InitDB) ToMysqlConfig() config.Mysql {
|
||||
@@ -74,3 +81,21 @@ func (i *InitDB) ToPgsqlConfig() config.Pgsql {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ToSqliteConfig 转换 config.Sqlite
|
||||
// Author [Kafumio](https://github.com/Kafumio)
|
||||
func (i *InitDB) ToSqliteConfig() config.Sqlite {
|
||||
return config.Sqlite{
|
||||
GeneralDB: config.GeneralDB{
|
||||
Path: i.DBPath,
|
||||
Port: i.Port,
|
||||
Dbname: i.DBName,
|
||||
Username: i.UserName,
|
||||
Password: i.Password,
|
||||
MaxIdleConns: 10,
|
||||
MaxOpenConns: 100,
|
||||
LogMode: "error",
|
||||
Config: "",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
package request
|
||||
|
||||
import model "github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
)
|
||||
|
||||
// User register structure
|
||||
// Register User register structure
|
||||
type Register struct {
|
||||
Username string `json:"userName"`
|
||||
Password string `json:"passWord"`
|
||||
NickName string `json:"nickName" gorm:"default:'QMPlusUser'"`
|
||||
HeaderImg string `json:"headerImg" gorm:"default:'https://qmplusimg.henrongyi.top/gva_header.jpg'"`
|
||||
AuthorityId uint `json:"authorityId" gorm:"default:888"`
|
||||
Enable int `json:"enable"`
|
||||
AuthorityIds []uint `json:"authorityIds"`
|
||||
Username string `json:"userName" example:"用户名"`
|
||||
Password string `json:"passWord" example:"密码"`
|
||||
NickName string `json:"nickName" example:"昵称"`
|
||||
HeaderImg string `json:"headerImg" example:"头像链接"`
|
||||
AuthorityId uint `json:"authorityId" swaggertype:"string" example:"int 角色id"`
|
||||
Enable int `json:"enable" swaggertype:"string" example:"int 是否启用"`
|
||||
AuthorityIds []uint `json:"authorityIds" swaggertype:"string" example:"[]uint 角色id"`
|
||||
Phone string `json:"phone" example:"电话号码"`
|
||||
Email string `json:"email" example:"电子邮箱"`
|
||||
}
|
||||
|
||||
// User login structure
|
||||
@@ -40,13 +44,13 @@ type SetUserAuthorities struct {
|
||||
}
|
||||
|
||||
type ChangeUserInfo struct {
|
||||
ID uint `gorm:"primarykey"` // 主键ID
|
||||
NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称
|
||||
Phone string `json:"phone" gorm:"comment:用户手机号"` // 用户手机号
|
||||
AuthorityIds []uint `json:"authorityIds" gorm:"-"` // 角色ID
|
||||
Email string `json:"email" gorm:"comment:用户邮箱"` // 用户邮箱
|
||||
HeaderImg string `json:"headerImg" gorm:"default:https://qmplusimg.henrongyi.top/gva_header.jpg;comment:用户头像"` // 用户头像
|
||||
SideMode string `json:"sideMode" gorm:"comment:用户侧边主题"` // 用户侧边主题
|
||||
Enable int `json:"enable" gorm:"comment:冻结用户"` //冻结用户
|
||||
Authorities []model.SysAuthority `json:"-" gorm:"many2many:sys_user_authority;"`
|
||||
ID uint `gorm:"primarykey"` // 主键ID
|
||||
NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称
|
||||
Phone string `json:"phone" gorm:"comment:用户手机号"` // 用户手机号
|
||||
AuthorityIds []uint `json:"authorityIds" gorm:"-"` // 角色ID
|
||||
Email string `json:"email" gorm:"comment:用户邮箱"` // 用户邮箱
|
||||
HeaderImg string `json:"headerImg" gorm:"default:https://qmplusimg.henrongyi.top/gva_header.jpg;comment:用户头像"` // 用户头像
|
||||
SideMode string `json:"sideMode" gorm:"comment:用户侧边主题"` // 用户侧边主题
|
||||
Enable int `json:"enable" gorm:"comment:冻结用户"` //冻结用户
|
||||
Authorities []system.SysAuthority `json:"-" gorm:"many2many:sys_user_authority;"`
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ type AutoCodeHistory struct {
|
||||
ID uint `json:"ID" gorm:"column:id"`
|
||||
CreatedAt time.Time `json:"CreatedAt" gorm:"column:created_at"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt" gorm:"column:updated_at"`
|
||||
BusinessDB string `json:"businessDB" gorm:"column:business_db"`
|
||||
TableName string `json:"tableName" gorm:"column:table_name"`
|
||||
StructName string `json:"structName" gorm:"column:struct_name"`
|
||||
StructCNName string `json:"structCNName" gorm:"column:struct_cn_name"`
|
||||
|
||||
@@ -3,5 +3,6 @@ package response
|
||||
type SysCaptchaResponse struct {
|
||||
CaptchaId string `json:"captchaId"`
|
||||
PicPath string `json:"picPath"`
|
||||
CaptchaLength int `json:"captchaLength""`
|
||||
CaptchaLength int `json:"captchaLength"`
|
||||
OpenCaptcha bool `json:"openCaptcha"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package response
|
||||
|
||||
type ChatGptResponse struct {
|
||||
}
|
||||
@@ -10,7 +10,7 @@ type SysAuthority struct {
|
||||
DeletedAt *time.Time `sql:"index"`
|
||||
AuthorityId uint `json:"authorityId" gorm:"not null;unique;primary_key;comment:角色ID;size:90"` // 角色ID
|
||||
AuthorityName string `json:"authorityName" gorm:"comment:角色名"` // 角色名
|
||||
ParentId uint `json:"parentId" gorm:"comment:父角色ID"` // 父角色ID
|
||||
ParentId *uint `json:"parentId" gorm:"comment:父角色ID"` // 父角色ID
|
||||
DataAuthorityId []*SysAuthority `json:"dataAuthorityId" gorm:"many2many:sys_data_authority_id;"`
|
||||
Children []SysAuthority `json:"children" gorm:"-"`
|
||||
SysBaseMenus []SysBaseMenu `json:"menus" gorm:"many2many:sys_authority_menus;"`
|
||||
|
||||
@@ -19,12 +19,18 @@ type AutoCodeStruct struct {
|
||||
AutoCreateApiToSql bool `json:"autoCreateApiToSql"` // 是否自动创建api
|
||||
AutoCreateResource bool `json:"autoCreateResource"` // 是否自动创建资源标识
|
||||
AutoMoveFile bool `json:"autoMoveFile"` // 是否自动移动文件
|
||||
BusinessDB string `json:"businessDB"` // 业务数据库
|
||||
Fields []*Field `json:"fields,omitempty"`
|
||||
HasTimer bool
|
||||
DictTypes []string `json:"-"`
|
||||
Package string `json:"package"`
|
||||
PackageT string `json:"-"`
|
||||
NeedValid bool `json:"-"`
|
||||
NeedSort bool `json:"-"`
|
||||
HasPic bool `json:"-"`
|
||||
HasRichText bool `json:"-"`
|
||||
HasFile bool `json:"-"`
|
||||
NeedJSON bool `json:"-"`
|
||||
}
|
||||
|
||||
func (a *AutoCodeStruct) Pretreatment() {
|
||||
@@ -61,6 +67,7 @@ type Field struct {
|
||||
Require bool `json:"require"` // 是否必填
|
||||
ErrorText string `json:"errorText"` // 校验失败文字
|
||||
Clearable bool `json:"clearable"` // 是否可清空
|
||||
Sort bool `json:"sort"` // 是否增加排序
|
||||
}
|
||||
|
||||
var ErrAutoMove error = errors.New("创建代码成功并移动文件成功")
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
type SysAutoCodeHistory struct {
|
||||
global.GVA_MODEL
|
||||
Package string `json:"package"`
|
||||
BusinessDB string `json:"businessDB"`
|
||||
TableName string `json:"tableName"`
|
||||
RequestMeta string `gorm:"type:text" json:"requestMeta,omitempty"` // 前端传入的结构化信息
|
||||
AutoCodePath string `gorm:"type:text" json:"autoCodePath,omitempty"` // 其他meta信息 path;path
|
||||
|
||||
@@ -6,33 +6,34 @@ import (
|
||||
|
||||
type SysBaseMenu struct {
|
||||
global.GVA_MODEL
|
||||
MenuLevel uint `json:"-"`
|
||||
ParentId string `json:"parentId" gorm:"comment:父菜单ID"` // 父菜单ID
|
||||
Path string `json:"path" gorm:"comment:路由path"` // 路由path
|
||||
Name string `json:"name" gorm:"comment:路由name"` // 路由name
|
||||
Hidden bool `json:"hidden" gorm:"comment:是否在列表隐藏"` // 是否在列表隐藏
|
||||
Component string `json:"component" gorm:"comment:对应前端文件路径"` // 对应前端文件路径
|
||||
Sort int `json:"sort" gorm:"comment:排序标记"` // 排序标记
|
||||
Meta `json:"meta" gorm:"embedded;comment:附加属性"` // 附加属性
|
||||
SysAuthoritys []SysAuthority `json:"authoritys" gorm:"many2many:sys_authority_menus;"`
|
||||
Children []SysBaseMenu `json:"children" gorm:"-"`
|
||||
Parameters []SysBaseMenuParameter `json:"parameters"`
|
||||
MenuBtn []SysBaseMenuBtn `json:"menuBtn"`
|
||||
MenuLevel uint `json:"-"`
|
||||
ParentId string `json:"parentId" gorm:"comment:父菜单ID"` // 父菜单ID
|
||||
Path string `json:"path" gorm:"comment:路由path"` // 路由path
|
||||
Name string `json:"name" gorm:"comment:路由name"` // 路由name
|
||||
Hidden bool `json:"hidden" gorm:"comment:是否在列表隐藏"` // 是否在列表隐藏
|
||||
Component string `json:"component" gorm:"comment:对应前端文件路径"` // 对应前端文件路径
|
||||
Sort int `json:"sort" gorm:"comment:排序标记"` // 排序标记
|
||||
Meta `json:"meta" gorm:"embedded;comment:附加属性"` // 附加属性
|
||||
SysAuthoritys []SysAuthority `json:"authoritys" gorm:"many2many:sys_authority_menus;"`
|
||||
Children []SysBaseMenu `json:"children" gorm:"-"`
|
||||
Parameters []SysBaseMenuParameter `json:"parameters"`
|
||||
MenuBtn []SysBaseMenuBtn `json:"menuBtn"`
|
||||
}
|
||||
|
||||
type Meta struct {
|
||||
KeepAlive bool `json:"keepAlive" gorm:"comment:是否缓存"` // 是否缓存
|
||||
ActiveName string `json:"activeName" gorm:"comment:高亮菜单"`
|
||||
KeepAlive bool `json:"keepAlive" gorm:"comment:是否缓存"` // 是否缓存
|
||||
DefaultMenu bool `json:"defaultMenu" gorm:"comment:是否是基础路由(开发中)"` // 是否是基础路由(开发中)
|
||||
Title string `json:"title" gorm:"comment:菜单名"` // 菜单名
|
||||
Icon string `json:"icon" gorm:"comment:菜单图标"` // 菜单图标
|
||||
CloseTab bool `json:"closeTab" gorm:"comment:自动关闭tab"` // 自动关闭tab
|
||||
Title string `json:"title" gorm:"comment:菜单名"` // 菜单名
|
||||
Icon string `json:"icon" gorm:"comment:菜单图标"` // 菜单图标
|
||||
CloseTab bool `json:"closeTab" gorm:"comment:自动关闭tab"` // 自动关闭tab
|
||||
}
|
||||
|
||||
type SysBaseMenuParameter struct {
|
||||
global.GVA_MODEL
|
||||
SysBaseMenuID uint
|
||||
Type string `json:"type" gorm:"comment:地址栏携带参数为params还是query"` // 地址栏携带参数为params还是query
|
||||
Key string `json:"key" gorm:"comment:地址栏携带参数的key"` // 地址栏携带参数的key
|
||||
Key string `json:"key" gorm:"comment:地址栏携带参数的key"` // 地址栏携带参数的key
|
||||
Value string `json:"value" gorm:"comment:地址栏携带参数的值"` // 地址栏携带参数的值
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package system
|
||||
|
||||
type ChatGpt struct {
|
||||
DBName string `json:"dbname,omitempty"`
|
||||
Chat string `json:"chat,omitempty"`
|
||||
ChatID string `json:"chatID,omitempty"`
|
||||
}
|
||||
|
||||
type SysChatGptOption struct {
|
||||
SK string `json:"sk"`
|
||||
}
|
||||
|
||||
type ChatField struct {
|
||||
TABLE_NAME string
|
||||
COLUMN_NAME string
|
||||
COLUMN_COMMENT string
|
||||
}
|
||||
|
||||
type ChatFieldNoTable struct {
|
||||
COLUMN_NAME string
|
||||
COLUMN_COMMENT string
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package system
|
||||
|
||||
import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/satori/go.uuid"
|
||||
"github.com/gofrs/uuid/v5"
|
||||
)
|
||||
|
||||
type SysUser struct {
|
||||
|
||||
@@ -43,7 +43,7 @@ func ErrorToEmail(subject string, body string) error {
|
||||
//@return: error
|
||||
|
||||
func EmailTest(subject string, body string) error {
|
||||
to := []string{global.GlobalConfig.From}
|
||||
to := []string{global.GlobalConfig.To}
|
||||
return send(to, subject, body)
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Create{{.StructName}}(c *gin.Con
|
||||
return
|
||||
}
|
||||
{{- end }}
|
||||
if err := {{.Abbreviation}}Service.Create{{.StructName}}({{.Abbreviation}}); err != nil {
|
||||
if err := {{.Abbreviation}}Service.Create{{.StructName}}(&{{.Abbreviation}}); err != nil {
|
||||
global.GVA_LOG.Error("创建失败!", zap.Error(err))
|
||||
response.FailWithMessage("创建失败", c)
|
||||
} else {
|
||||
@@ -108,7 +108,7 @@ func ({{.Abbreviation}}Api *{{.StructName}}Api) Delete{{.StructName}}ByIds(c *gi
|
||||
{{- if .AutoCreateResource }}
|
||||
deletedBy := utils.GetUserID(c)
|
||||
{{- end }}
|
||||
if err := {{.Abbreviation}}Service.Delete{{.StructName}}ByIds(IDS,deletedBy); err != nil {
|
||||
if err := {{.Abbreviation}}Service.Delete{{.StructName}}ByIds(IDS{{- if .AutoCreateResource }},deletedBy{{- end }}); err != nil {
|
||||
global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("批量删除失败", c)
|
||||
} else {
|
||||
|
||||
@@ -4,6 +4,7 @@ package {{.Package}}
|
||||
import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
{{ if .HasTimer }}"time"{{ end }}
|
||||
{{ if .NeedJSON }}"gorm.io/datatypes"{{ end }}
|
||||
)
|
||||
|
||||
// {{.StructName}} 结构体
|
||||
@@ -11,6 +12,14 @@ type {{.StructName}} struct {
|
||||
global.GVA_MODEL {{- range .Fields}}
|
||||
{{- if eq .FieldType "enum" }}
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};type:enum({{.DataTypeLong}});comment:{{.Comment}};"`
|
||||
{{- else if eq .FieldType "picture" }}
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}"`
|
||||
{{- else if eq .FieldType "file" }}
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}"`
|
||||
{{- else if eq .FieldType "pictures" }}
|
||||
{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}"`
|
||||
{{- else if eq .FieldType "richtext" }}
|
||||
{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;"`
|
||||
{{- else if ne .FieldType "string" }}
|
||||
{{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}"`
|
||||
{{- else }}
|
||||
|
||||
@@ -17,4 +17,8 @@ type {{.StructName}}Search struct{
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
request.PageInfo
|
||||
{{- if .NeedSort}}
|
||||
Sort string `json:"sort" form:"sort"`
|
||||
Order string `json:"order" form:"order"`
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,17 @@ import (
|
||||
type {{.StructName}}Service struct {
|
||||
}
|
||||
|
||||
{{- $db := "" }}
|
||||
{{- if eq .BusinessDB "" }}
|
||||
{{- $db = "global.GVA_DB" }}
|
||||
{{- else}}
|
||||
{{- $db = printf "global.MustGetGlobalDBByDBName(\"%s\")" .BusinessDB }}
|
||||
{{- end}}
|
||||
|
||||
// Create{{.StructName}} 创建{{.StructName}}记录
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
func ({{.Abbreviation}}Service *{{.StructName}}Service) Create{{.StructName}}({{.Abbreviation}} {{.Package}}.{{.StructName}}) (err error) {
|
||||
err = global.GVA_DB.Create(&{{.Abbreviation}}).Error
|
||||
func ({{.Abbreviation}}Service *{{.StructName}}Service) Create{{.StructName}}({{.Abbreviation}} *{{.Package}}.{{.StructName}}) (err error) {
|
||||
err = {{$db}}.Create({{.Abbreviation}}).Error
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -24,7 +31,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service) Create{{.StructName}}({{
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}({{.Abbreviation}} {{.Package}}.{{.StructName}}) (err error) {
|
||||
{{- if .AutoCreateResource }}
|
||||
err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
|
||||
err = {{$db}}.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Model(&{{.Package}}.{{.StructName}}{}).Where("id = ?", {{.Abbreviation}}.ID).Update("deleted_by", {{.Abbreviation}}.DeletedBy).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -34,16 +41,16 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}({{.
|
||||
return nil
|
||||
})
|
||||
{{- else }}
|
||||
err = global.GVA_DB.Delete(&{{.Abbreviation}}).Error
|
||||
err = {{$db}}.Delete(&{{.Abbreviation}}).Error
|
||||
{{- end }}
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete{{.StructName}}ByIds 批量删除{{.StructName}}记录
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}ByIds(ids request.IdsReq,deleted_by uint) (err error) {
|
||||
func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}ByIds(ids request.IdsReq{{- if .AutoCreateResource }},deleted_by uint{{- end}}) (err error) {
|
||||
{{- if .AutoCreateResource }}
|
||||
err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
|
||||
err = {{$db}}.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Model(&{{.Package}}.{{.StructName}}{}).Where("id in ?", ids.Ids).Update("deleted_by", deleted_by).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -53,7 +60,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}ById
|
||||
return nil
|
||||
})
|
||||
{{- else}}
|
||||
err = global.GVA_DB.Delete(&[]{{.Package}}.{{.StructName}}{},"id in ?",ids.Ids).Error
|
||||
err = {{$db}}.Delete(&[]{{.Package}}.{{.StructName}}{},"id in ?",ids.Ids).Error
|
||||
{{- end}}
|
||||
return err
|
||||
}
|
||||
@@ -61,14 +68,14 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Delete{{.StructName}}ById
|
||||
// Update{{.StructName}} 更新{{.StructName}}记录
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
func ({{.Abbreviation}}Service *{{.StructName}}Service)Update{{.StructName}}({{.Abbreviation}} {{.Package}}.{{.StructName}}) (err error) {
|
||||
err = global.GVA_DB.Save(&{{.Abbreviation}}).Error
|
||||
err = {{$db}}.Save(&{{.Abbreviation}}).Error
|
||||
return err
|
||||
}
|
||||
|
||||
// Get{{.StructName}} 根据id获取{{.StructName}}记录
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}(id uint) ({{.Abbreviation}} {{.Package}}.{{.StructName}}, err error) {
|
||||
err = global.GVA_DB.Where("id = ?", id).First(&{{.Abbreviation}}).Error
|
||||
err = {{$db}}.Where("id = ?", id).First(&{{.Abbreviation}}).Error
|
||||
return
|
||||
}
|
||||
|
||||
@@ -78,7 +85,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoLis
|
||||
limit := info.PageSize
|
||||
offset := info.PageSize * (info.Page - 1)
|
||||
// 创建db
|
||||
db := global.GVA_DB.Model(&{{.Package}}.{{.StructName}}{})
|
||||
db := {{$db}}.Model(&{{.Package}}.{{.StructName}}{})
|
||||
var {{.Abbreviation}}s []{{.Package}}.{{.StructName}}
|
||||
// 如果有条件搜索 下方会自动创建搜索语句
|
||||
if info.StartCreatedAt !=nil && info.EndCreatedAt !=nil {
|
||||
@@ -105,6 +112,23 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoLis
|
||||
if err!=nil {
|
||||
return
|
||||
}
|
||||
{{- if .NeedSort}}
|
||||
var OrderStr string
|
||||
orderMap := make(map[string]bool)
|
||||
{{- range .Fields}}
|
||||
{{- if .Sort}}
|
||||
orderMap["{{.ColumnName}}"] = true
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
if orderMap[info.Sort] {
|
||||
OrderStr = info.Sort
|
||||
if info.Order == "descending" {
|
||||
OrderStr = OrderStr + " desc"
|
||||
}
|
||||
db = db.Order(OrderStr)
|
||||
}
|
||||
{{- end}}
|
||||
|
||||
err = db.Limit(limit).Offset(offset).Find(&{{.Abbreviation}}s).Error
|
||||
return {{.Abbreviation}}s, total, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
package {{ .PackageName }}
|
||||
|
||||
type ApiGroup struct {
|
||||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server Begin; DO NOT EDIT.
|
||||
|
||||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server End; DO NOT EDIT.
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
package {{ .PackageName }}
|
||||
|
||||
type RouterGroup struct {
|
||||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server Begin; DO NOT EDIT.
|
||||
|
||||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server End; DO NOT EDIT.
|
||||
}
|
||||
|
||||
@@ -2,8 +2,5 @@ package {{ .PackageName }}
|
||||
|
||||
|
||||
type ServiceGroup struct {
|
||||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server Begin; DO NOT EDIT.
|
||||
|
||||
// Code generated by github.com/flipped-aurora/gin-vue-admin/server End; DO NOT EDIT.
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
{{- if eq .FieldType "string" }}
|
||||
<el-input v-model="formData.{{.FieldJson}}" :clearable="{{.Clearable}}" placeholder="请输入" />
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "richtext" }}
|
||||
<RichEdit v-model="formData.{{.FieldJson}}"/>
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "int" }}
|
||||
{{- if .DictType }}
|
||||
<el-select v-model="formData.{{ .FieldJson }}" placeholder="请选择" :clearable="{{.Clearable}}">
|
||||
@@ -30,11 +33,17 @@
|
||||
<el-option v-for="item in [{{ .DataTypeLong }}]" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
{{- end }}
|
||||
</el-form-item>
|
||||
{{- if eq .FieldType "picture" }}
|
||||
<SelectImage v-model="formData.{{ .FieldJson }}" />
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "pictures" }}
|
||||
<SelectImage v-model="formData.{{ .FieldJson }}" multiple />
|
||||
{{- end }}
|
||||
</el-form-item>
|
||||
{{- end }}
|
||||
<el-form-item>
|
||||
<el-button size="small" type="primary" @click="save">保存</el-button>
|
||||
<el-button size="small" type="primary" @click="back">返回</el-button>
|
||||
<el-button type="primary" @click="save">保存</el-button>
|
||||
<el-button type="primary" @click="back">返回</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@@ -59,6 +68,18 @@ import { getDictFunc } from '@/utils/format'
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { ref, reactive } from 'vue'
|
||||
{{- if .HasPic }}
|
||||
import SelectImage from '@/components/selectImage/selectImage.vue'
|
||||
{{- end }}
|
||||
{{- if .HasFile }}
|
||||
import SelectFile from '@/components/selectFile/selectFile.vue'
|
||||
{{- end }}
|
||||
|
||||
{{- if .HasRichText }}
|
||||
// 富文本组件
|
||||
import RichEdit from '@/components/richtext/rich-edit.vue'
|
||||
{{- end }}
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
@@ -83,6 +104,15 @@ const formData = ref({
|
||||
{{- if eq .FieldType "float64" }}
|
||||
{{.FieldJson}}: 0,
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "picture" }}
|
||||
{{.FieldJson}}: "",
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "pictures" }}
|
||||
{{.FieldJson}}: [],
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "file" }}
|
||||
{{.FieldJson}}: [],
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
})
|
||||
// 验证规则
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="gva-search-box">
|
||||
<el-form :inline="true" :model="searchInfo" class="demo-form-inline">
|
||||
<el-form-item label="创建时间">
|
||||
<el-date-picker v-model="searchInfo.startCreatedAt" type="datetime" placeholder="开始时间"></el-date-picker>
|
||||
<el-form ref="elSearchFormRef" :inline="true" :model="searchInfo" class="demo-form-inline" :rules="searchRule" @keyup.enter="onSubmit">
|
||||
<el-form-item label="创建日期" prop="createdAt">
|
||||
<template #label>
|
||||
<span>
|
||||
创建日期
|
||||
<el-tooltip content="搜索范围是开始日期(包含)至结束日期(不包含)">
|
||||
<el-icon><QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<el-date-picker v-model="searchInfo.startCreatedAt" type="datetime" placeholder="开始日期" :disabled-date="time=> searchInfo.endCreatedAt ? time.getTime() > searchInfo.endCreatedAt.getTime() : false"></el-date-picker>
|
||||
—
|
||||
<el-date-picker v-model="searchInfo.endCreatedAt" type="datetime" placeholder="结束时间"></el-date-picker>
|
||||
<el-date-picker v-model="searchInfo.endCreatedAt" type="datetime" placeholder="结束日期" :disabled-date="time=> searchInfo.startCreatedAt ? time.getTime() < searchInfo.startCreatedAt.getTime() : false"></el-date-picker>
|
||||
</el-form-item>
|
||||
{{- range .Fields}} {{- if .FieldSearchType}} {{- if eq .FieldType "bool" }}
|
||||
<el-form-item label="{{.FieldDesc}}" prop="{{.FieldJson}}">
|
||||
@@ -29,7 +37,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
{{- else}}
|
||||
<el-form-item label="{{.FieldDesc}}">
|
||||
<el-form-item label="{{.FieldDesc}}" prop="{{.FieldJson}}">
|
||||
|
||||
|
||||
{{- if eq .FieldType "float64" "int"}}
|
||||
@@ -48,9 +56,17 @@
|
||||
{{- end}}
|
||||
{{- else if eq .FieldType "time.Time"}}
|
||||
{{if eq .FieldSearchType "BETWEEN" "NOT BETWEEN"}}
|
||||
<el-date-picker v-model="searchInfo.start{{.FieldName}}" type="datetime" placeholder="搜索条件(起)"></el-date-picker>
|
||||
<template #label>
|
||||
<span>
|
||||
{{.FieldDesc}}
|
||||
<el-tooltip content="搜索范围是开始日期(包含)至结束日期(不包含)">
|
||||
<el-icon><QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<el-date-picker v-model="searchInfo.start{{.FieldName}}" type="datetime" placeholder="开始日期" :disabled-date="time=> searchInfo.end{{.FieldName}} ? time.getTime() > searchInfo.end{{.FieldName}}.getTime() : false"></el-date-picker>
|
||||
—
|
||||
<el-date-picker v-model="searchInfo.end{{.FieldName}}" type="datetime" placeholder="搜索条件(止)"></el-date-picker>
|
||||
<el-date-picker v-model="searchInfo.end{{.FieldName}}" type="datetime" placeholder="结束日期" :disabled-date="time=> searchInfo.start{{.FieldName}} ? time.getTime() < searchInfo.start{{.FieldName}}.getTime() : false"></el-date-picker>
|
||||
{{- else}}
|
||||
<el-date-picker v-model="searchInfo.{{.FieldJson}}" type="datetime" placeholder="搜索条件"></el-date-picker>
|
||||
{{- end}}
|
||||
@@ -60,22 +76,22 @@
|
||||
|
||||
</el-form-item>{{ end }}{{ end }}{{ end }}
|
||||
<el-form-item>
|
||||
<el-button size="small" type="primary" icon="search" @click="onSubmit">查询</el-button>
|
||||
<el-button size="small" icon="refresh" @click="onReset">重置</el-button>
|
||||
<el-button type="primary" icon="search" @click="onSubmit">查询</el-button>
|
||||
<el-button icon="refresh" @click="onReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="gva-table-box">
|
||||
<div class="gva-btn-list">
|
||||
<el-button size="small" type="primary" icon="plus" @click="openDialog">新增</el-button>
|
||||
<el-button type="primary" icon="plus" @click="openDialog">新增</el-button>
|
||||
<el-popover v-model:visible="deleteVisible" placement="top" width="160">
|
||||
<p>确定要删除吗?</p>
|
||||
<div style="text-align: right; margin-top: 8px;">
|
||||
<el-button size="small" type="primary" link @click="deleteVisible = false">取消</el-button>
|
||||
<el-button size="small" type="primary" @click="onDelete">确定</el-button>
|
||||
<el-button type="primary" link @click="deleteVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="onDelete">确定</el-button>
|
||||
</div>
|
||||
<template #reference>
|
||||
<el-button icon="delete" size="small" style="margin-left: 10px;" :disabled="!multipleSelection.length" @click="deleteVisible = true">删除</el-button>
|
||||
<el-button icon="delete" style="margin-left: 10px;" :disabled="!multipleSelection.length" @click="deleteVisible = true">删除</el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
@@ -86,6 +102,9 @@
|
||||
:data="tableData"
|
||||
row-key="ID"
|
||||
@selection-change="handleSelectionChange"
|
||||
{{- if .NeedSort}}
|
||||
@sort-change="sortChange"
|
||||
{{- end}}
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column align="left" label="日期" width="180">
|
||||
@@ -93,27 +112,55 @@
|
||||
</el-table-column>
|
||||
{{- range .Fields}}
|
||||
{{- if .DictType}}
|
||||
<el-table-column align="left" label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120">
|
||||
<el-table-column {{- if .Sort}} sortable{{- end}} align="left" label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120">
|
||||
<template #default="scope">
|
||||
{{"{{"}} filterDict(scope.row.{{.FieldJson}},{{.DictType}}Options) {{"}}"}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "bool" }}
|
||||
<el-table-column align="left" label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120">
|
||||
<el-table-column {{- if .Sort}} sortable{{- end}} align="left" label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120">
|
||||
<template #default="scope">{{"{{"}} formatBoolean(scope.row.{{.FieldJson}}) {{"}}"}}</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "time.Time" }}
|
||||
<el-table-column align="left" label="{{.FieldDesc}}" width="180">
|
||||
<el-table-column {{- if .Sort}} sortable{{- end}} align="left" label="{{.FieldDesc}}" width="180">
|
||||
<template #default="scope">{{"{{"}} formatDate(scope.row.{{.FieldJson}}) {{"}}"}}</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "picture" }}
|
||||
<el-table-column label="{{.FieldDesc}}" width="200">
|
||||
<template #default="scope">
|
||||
<el-image style="width: 100px; height: 100px" :src="getUrl(scope.row.{{.FieldJson}})" fit="cover"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "pictures" }}
|
||||
<el-table-column label="{{.FieldDesc}}" width="200">
|
||||
<template #default="scope">
|
||||
<div class="multiple-img-box">
|
||||
<el-image v-for="(item,index) in scope.row.{{.FieldJson}}" style="width: 80px; height: 80px" :src="getUrl(item)" fit="cover"/>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "richtext" }}
|
||||
<el-table-column label="{{.FieldDesc}}" width="200">
|
||||
<template #default="scope">
|
||||
[富文本内容]
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else if eq .FieldType "file" }}
|
||||
<el-table-column label="{{.FieldDesc}}" width="200">
|
||||
<template #default="scope">
|
||||
<div class="file-list">
|
||||
<el-tag v-for="file in scope.row.{{.FieldJson}}" :key="file.uid">{{"{{"}}file.name{{"}}"}}</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
{{- else }}
|
||||
<el-table-column align="left" label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120" />
|
||||
<el-table-column {{- if .Sort}} sortable{{- end}} align="left" label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120" />
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
<el-table-column align="left" label="按钮组">
|
||||
<el-table-column align="left" label="操作">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link icon="edit" size="small" class="table-button" @click="update{{.StructName}}Func(scope.row)">变更</el-button>
|
||||
<el-button type="primary" link icon="delete" size="small" @click="deleteRow(scope.row)">删除</el-button>
|
||||
<el-button type="primary" link icon="edit" class="table-button" @click="update{{.StructName}}Func(scope.row)">变更</el-button>
|
||||
<el-button type="primary" link icon="delete" @click="deleteRow(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -129,7 +176,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog v-model="dialogFormVisible" :before-close="closeDialog" title="弹窗操作">
|
||||
<el-dialog v-model="dialogFormVisible" :before-close="closeDialog" :title="type==='create'?'添加':'修改'" destroy-on-close>
|
||||
<el-form :model="formData" label-position="right" ref="elFormRef" :rules="rule" label-width="80px">
|
||||
{{- range .Fields}}
|
||||
<el-form-item label="{{.FieldDesc}}:" prop="{{.FieldJson}}" >
|
||||
@@ -139,6 +186,9 @@
|
||||
{{- if eq .FieldType "string" }}
|
||||
<el-input v-model="formData.{{.FieldJson}}" :clearable="{{.Clearable}}" placeholder="请输入" />
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "richtext" }}
|
||||
<RichEdit v-model="formData.{{.FieldJson}}"/>
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "int" }}
|
||||
{{- if .DictType}}
|
||||
<el-select v-model="formData.{{ .FieldJson }}" placeholder="请选择" style="width:100%" :clearable="{{.Clearable}}" >
|
||||
@@ -158,14 +208,23 @@
|
||||
<el-select v-model="formData.{{ .FieldJson }}" placeholder="请选择" style="width:100%" :clearable="{{.Clearable}}" >
|
||||
<el-option v-for="item in [{{.DataTypeLong}}]" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "picture" }}
|
||||
<SelectImage v-model="formData.{{ .FieldJson }}" />
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "pictures" }}
|
||||
<SelectImage v-model="formData.{{ .FieldJson }}" multiple />
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "file" }}
|
||||
<SelectFile v-model="formData.{{ .FieldJson }}" />
|
||||
{{- end }}
|
||||
</el-form-item>
|
||||
{{- end }}
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button size="small" @click="closeDialog">取 消</el-button>
|
||||
<el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
|
||||
<el-button @click="closeDialog">取 消</el-button>
|
||||
<el-button type="primary" @click="enterDialog">确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
@@ -188,6 +247,25 @@ import {
|
||||
get{{.StructName}}List
|
||||
} from '@/api/{{.PackageName}}'
|
||||
|
||||
{{- if or .HasPic .HasFile}}
|
||||
import { getUrl } from '@/utils/image'
|
||||
{{- end }}
|
||||
{{- if .HasPic }}
|
||||
// 图片选择组件
|
||||
import SelectImage from '@/components/selectImage/selectImage.vue'
|
||||
{{- end }}
|
||||
|
||||
{{- if .HasRichText }}
|
||||
// 富文本组件
|
||||
import RichEdit from '@/components/richtext/rich-edit.vue'
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- if .HasFile }}
|
||||
// 文件选择组件
|
||||
import SelectFile from '@/components/selectFile/selectFile.vue'
|
||||
{{- end }}
|
||||
|
||||
// 全量引入格式化工具 请按需保留
|
||||
import { getDictFunc, formatDate, formatBoolean, filterDict } from '@/utils/format'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
@@ -214,6 +292,15 @@ const formData = ref({
|
||||
{{- if eq .FieldType "float64" }}
|
||||
{{.FieldJson}}: 0,
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "picture" }}
|
||||
{{.FieldJson}}: "",
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "pictures" }}
|
||||
{{.FieldJson}}: [],
|
||||
{{- end }}
|
||||
{{- if eq .FieldType "file" }}
|
||||
{{.FieldJson}}: [],
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
})
|
||||
|
||||
@@ -225,13 +312,54 @@ const rule = reactive({
|
||||
required: true,
|
||||
message: '{{ .ErrorText }}',
|
||||
trigger: ['input','blur'],
|
||||
}],
|
||||
},
|
||||
{{- if eq .FieldType "string" }}
|
||||
{
|
||||
whitespace: true,
|
||||
message: '不能只输入空格',
|
||||
trigger: ['input', 'blur'],
|
||||
}
|
||||
{{- end }}
|
||||
],
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
})
|
||||
|
||||
const elFormRef = ref()
|
||||
const searchRule = reactive({
|
||||
createdAt: [
|
||||
{ validator: (rule, value, callback) => {
|
||||
if (searchInfo.value.startCreatedAt && !searchInfo.value.endCreatedAt) {
|
||||
callback(new Error('请填写结束日期'))
|
||||
} else if (!searchInfo.value.startCreatedAt && searchInfo.value.endCreatedAt) {
|
||||
callback(new Error('请填写开始日期'))
|
||||
} else if (searchInfo.value.startCreatedAt && searchInfo.value.endCreatedAt && (searchInfo.value.startCreatedAt.getTime() === searchInfo.value.endCreatedAt.getTime() || searchInfo.value.startCreatedAt.getTime() > searchInfo.value.endCreatedAt.getTime())) {
|
||||
callback(new Error('开始日期应当早于结束日期'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}, trigger: 'change' }
|
||||
],
|
||||
{{- range .Fields }}
|
||||
{{- if .FieldSearchType}}
|
||||
{{- if eq .FieldType "time.Time" }}
|
||||
{{.FieldJson }} : [{ validator: (rule, value, callback) => {
|
||||
if (searchInfo.value.start{{.FieldName}} && !searchInfo.value.end{{.FieldName}}) {
|
||||
callback(new Error('请填写结束日期'))
|
||||
} else if (!searchInfo.value.start{{.FieldName}} && searchInfo.value.end{{.FieldName}}) {
|
||||
callback(new Error('请填写开始日期'))
|
||||
} else if (searchInfo.value.start{{.FieldName}} && searchInfo.value.end{{.FieldName}} && (searchInfo.value.start{{.FieldName}}.getTime() === searchInfo.value.end{{.FieldName}}.getTime() || searchInfo.value.start{{.FieldName}}.getTime() > searchInfo.value.end{{.FieldName}}.getTime())) {
|
||||
callback(new Error('开始日期应当早于结束日期'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}, trigger: 'change' }],
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
})
|
||||
|
||||
const elFormRef = ref()
|
||||
const elSearchFormRef = ref()
|
||||
|
||||
// =========== 表格控制部分 ===========
|
||||
const page = ref(1)
|
||||
@@ -240,20 +368,33 @@ const pageSize = ref(10)
|
||||
const tableData = ref([])
|
||||
const searchInfo = ref({})
|
||||
|
||||
{{- if .NeedSort}}
|
||||
// 排序
|
||||
const sortChange = ({ prop, order }) => {
|
||||
searchInfo.value.sort = prop
|
||||
searchInfo.value.order = order
|
||||
getTableData()
|
||||
}
|
||||
{{- end}}
|
||||
|
||||
// 重置
|
||||
const onReset = () => {
|
||||
searchInfo.value = {}
|
||||
getTableData()
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const onSubmit = () => {
|
||||
page.value = 1
|
||||
pageSize.value = 10
|
||||
{{- range .Fields}}{{- if eq .FieldType "bool" }}
|
||||
if (searchInfo.value.{{.FieldJson}} === ""){
|
||||
searchInfo.value.{{.FieldJson}}=null
|
||||
}{{ end }}{{ end }}
|
||||
getTableData()
|
||||
elSearchFormRef.value?.validate(async(valid) => {
|
||||
if (!valid) return
|
||||
page.value = 1
|
||||
pageSize.value = 10
|
||||
{{- range .Fields}}{{- if eq .FieldType "bool" }}
|
||||
if (searchInfo.value.{{.FieldJson}} === ""){
|
||||
searchInfo.value.{{.FieldJson}}=null
|
||||
}{{ end }}{{ end }}
|
||||
getTableData()
|
||||
})
|
||||
}
|
||||
|
||||
// 分页
|
||||
@@ -431,7 +572,19 @@ const enterDialog = async () => {
|
||||
}
|
||||
})
|
||||
}
|
||||
{{if .HasFile }}
|
||||
const downloadFile = (url) => {
|
||||
window.open(getUrl(url), '_blank')
|
||||
}
|
||||
{{end}}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
{{if .HasFile }}
|
||||
.file-list{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
}
|
||||
{{end}}
|
||||
</style>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,7 +1,6 @@
|
||||
package example
|
||||
|
||||
type RouterGroup struct {
|
||||
ExcelRouter
|
||||
CustomerRouter
|
||||
FileUploadAndDownloadRouter
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
v1 "github.com/flipped-aurora/gin-vue-admin/server/api/v1"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ExcelRouter struct{}
|
||||
|
||||
func (e *ExcelRouter) InitExcelRouter(Router *gin.RouterGroup) {
|
||||
excelRouter := Router.Group("excel")
|
||||
exaExcelApi := v1.ApiGroupApp.ExampleApiGroup.ExcelApi
|
||||
{
|
||||
excelRouter.POST("importExcel", exaExcelApi.ImportExcel) // 导入Excel
|
||||
excelRouter.GET("loadExcel", exaExcelApi.LoadExcel) // 加载Excel数据
|
||||
excelRouter.POST("exportExcel", exaExcelApi.ExportExcel) // 导出Excel
|
||||
excelRouter.GET("downloadTemplate", exaExcelApi.DownloadTemplate) // 下载模板文件
|
||||
}
|
||||
}
|
||||
@@ -15,4 +15,5 @@ type RouterGroup struct {
|
||||
OperationRecordRouter
|
||||
DictionaryDetailRouter
|
||||
AuthorityBtnRouter
|
||||
ChatGptRouter
|
||||
}
|
||||
|
||||
@@ -8,9 +8,11 @@ import (
|
||||
|
||||
type ApiRouter struct{}
|
||||
|
||||
func (s *ApiRouter) InitApiRouter(Router *gin.RouterGroup) {
|
||||
func (s *ApiRouter) InitApiRouter(Router *gin.RouterGroup, RouterPub *gin.RouterGroup) {
|
||||
apiRouter := Router.Group("api").Use(middleware.OperationRecord())
|
||||
apiRouterWithoutRecord := Router.Group("api")
|
||||
|
||||
apiPublicRouterWithoutRecord := RouterPub.Group("api")
|
||||
apiRouterApi := v1.ApiGroupApp.SystemApiGroup.SystemApiApi
|
||||
{
|
||||
apiRouter.POST("createApi", apiRouterApi.CreateApi) // 创建Api
|
||||
@@ -23,4 +25,7 @@ func (s *ApiRouter) InitApiRouter(Router *gin.RouterGroup) {
|
||||
apiRouterWithoutRecord.POST("getAllApis", apiRouterApi.GetAllApis) // 获取所有api
|
||||
apiRouterWithoutRecord.POST("getApiList", apiRouterApi.GetApiList) // 获取Api列表
|
||||
}
|
||||
{
|
||||
apiPublicRouterWithoutRecord.GET("freshCasbin", apiRouterApi.FreshCasbin) // 刷新casbin权限
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,5 +21,6 @@ func (s *AutoCodeRouter) InitAutoCodeRouter(Router *gin.RouterGroup) {
|
||||
autoCodeRouter.POST("delPackage", autoCodeApi.DelPackage) // 删除package包
|
||||
autoCodeRouter.POST("createPlug", autoCodeApi.AutoPlug) // 自动插件包模板
|
||||
autoCodeRouter.POST("installPlugin", autoCodeApi.InstallPlugin) // 自动安装插件
|
||||
autoCodeRouter.POST("pubPlug", autoCodeApi.PubPlug) // 打包插件
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
v1 "github.com/flipped-aurora/gin-vue-admin/server/api/v1"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/middleware"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ChatGptRouter struct{}
|
||||
|
||||
func (s *ChatGptRouter) InitChatGptRouter(Router *gin.RouterGroup) {
|
||||
chatGptRouter := Router.Group("chatGpt").Use(middleware.OperationRecord())
|
||||
chatGptApi := v1.ApiGroupApp.SystemApiGroup.ChatGptApi
|
||||
{
|
||||
chatGptRouter.POST("createSK", chatGptApi.CreateSK)
|
||||
chatGptRouter.GET("getSK", chatGptApi.GetSK)
|
||||
chatGptRouter.DELETE("deleteSK", chatGptApi.DeleteSK)
|
||||
chatGptRouter.POST("getTable", chatGptApi.GetTable)
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ func (s *InitRouter) InitInitRouter(Router *gin.RouterGroup) {
|
||||
initRouter := Router.Group("init")
|
||||
dbApi := v1.ApiGroupApp.SystemApiGroup.DBApi
|
||||
{
|
||||
initRouter.POST("initdb", dbApi.InitDB) // 创建Api
|
||||
initRouter.POST("checkdb", dbApi.CheckDB) // 创建Api
|
||||
initRouter.POST("initdb", dbApi.InitDB) // 初始化数据库
|
||||
initRouter.POST("checkdb", dbApi.CheckDB) // 检测是否需要初始化数据库
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package example
|
||||
|
||||
type ServiceGroup struct {
|
||||
ExcelService
|
||||
CustomerService
|
||||
FileUploadAndDownloadService
|
||||
}
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
|
||||
type ExcelService struct{}
|
||||
|
||||
func (exa *ExcelService) ParseInfoList2Excel(infoList []system.SysBaseMenu, filePath string) error {
|
||||
excel := excelize.NewFile()
|
||||
excel.SetSheetRow("Sheet1", "A1", &[]string{"ID", "路由Name", "路由Path", "是否隐藏", "父节点", "排序", "文件名称"})
|
||||
for i, menu := range infoList {
|
||||
axis := fmt.Sprintf("A%d", i+2)
|
||||
excel.SetSheetRow("Sheet1", axis, &[]interface{}{
|
||||
menu.ID,
|
||||
menu.Name,
|
||||
menu.Path,
|
||||
menu.Hidden,
|
||||
menu.ParentId,
|
||||
menu.Sort,
|
||||
menu.Component,
|
||||
})
|
||||
}
|
||||
err := excel.SaveAs(filePath)
|
||||
return err
|
||||
}
|
||||
|
||||
func (exa *ExcelService) ParseExcel2InfoList() ([]system.SysBaseMenu, error) {
|
||||
skipHeader := true
|
||||
fixedHeader := []string{"ID", "路由Name", "路由Path", "是否隐藏", "父节点", "排序", "文件名称"}
|
||||
file, err := excelize.OpenFile(global.GVA_CONFIG.Excel.Dir + "ExcelImport.xlsx")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
menus := make([]system.SysBaseMenu, 0)
|
||||
rows, err := file.Rows("Sheet1")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
row, err := rows.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if skipHeader {
|
||||
if exa.compareStrSlice(row, fixedHeader) {
|
||||
skipHeader = false
|
||||
continue
|
||||
} else {
|
||||
return nil, errors.New("Excel格式错误")
|
||||
}
|
||||
}
|
||||
if len(row) != len(fixedHeader) {
|
||||
continue
|
||||
}
|
||||
id, _ := strconv.Atoi(row[0])
|
||||
hidden, _ := strconv.ParseBool(row[3])
|
||||
sort, _ := strconv.Atoi(row[5])
|
||||
menu := system.SysBaseMenu{
|
||||
GVA_MODEL: global.GVA_MODEL{
|
||||
ID: uint(id),
|
||||
},
|
||||
Name: row[1],
|
||||
Path: row[2],
|
||||
Hidden: hidden,
|
||||
ParentId: row[4],
|
||||
Sort: sort,
|
||||
Component: row[6],
|
||||
}
|
||||
menus = append(menus, menu)
|
||||
}
|
||||
return menus, nil
|
||||
}
|
||||
|
||||
func (exa *ExcelService) compareStrSlice(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
if (b == nil) != (a == nil) {
|
||||
return false
|
||||
}
|
||||
for key, value := range a {
|
||||
if value != b[key] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -94,15 +94,15 @@ func (e *FileUploadAndDownloadService) UploadFile(header *multipart.FileHeader,
|
||||
if uploadErr != nil {
|
||||
panic(err)
|
||||
}
|
||||
s := strings.Split(header.Filename, ".")
|
||||
f := example.ExaFileUploadAndDownload{
|
||||
Url: filePath,
|
||||
Name: header.Filename,
|
||||
Tag: s[len(s)-1],
|
||||
Key: key,
|
||||
}
|
||||
if noSave == "0" {
|
||||
s := strings.Split(header.Filename, ".")
|
||||
f := example.ExaFileUploadAndDownload{
|
||||
Url: filePath,
|
||||
Name: header.Filename,
|
||||
Tag: s[len(s)-1],
|
||||
Key: key,
|
||||
}
|
||||
return f, e.Upload(f)
|
||||
}
|
||||
return
|
||||
return f, nil
|
||||
}
|
||||
|
||||
@@ -16,4 +16,5 @@ type ServiceGroup struct {
|
||||
OperationRecordService
|
||||
DictionaryDetailService
|
||||
AuthorityBtnService
|
||||
ChatGptService
|
||||
}
|
||||
|
||||
@@ -43,12 +43,7 @@ func (apiService *ApiService) DeleteApi(api system.SysApi) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
success := CasbinServiceApp.ClearCasbin(1, entity.Path, entity.Method)
|
||||
if !success {
|
||||
return errors.New(entity.Path + ":" + entity.Method + "casbin同步清理失败")
|
||||
}
|
||||
e := CasbinServiceApp.Casbin()
|
||||
err = e.InvalidateCache()
|
||||
CasbinServiceApp.ClearCasbin(1, entity.Path, entity.Method)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -105,7 +100,7 @@ func (apiService *ApiService) GetAPIInfoList(api system.SysApi, info request.Pag
|
||||
} else {
|
||||
OrderStr = order
|
||||
}
|
||||
} else { // didn't matched any order key in `orderMap`
|
||||
} else { // didn't match any order key in `orderMap`
|
||||
err = fmt.Errorf("非法的排序字段: %v", order)
|
||||
return apiList, total, err
|
||||
}
|
||||
@@ -179,16 +174,23 @@ func (apiService *ApiService) DeleteApisByIds(ids request.IdsReq) (err error) {
|
||||
return err
|
||||
} else {
|
||||
for _, sysApi := range apis {
|
||||
success := CasbinServiceApp.ClearCasbin(1, sysApi.Path, sysApi.Method)
|
||||
if !success {
|
||||
return errors.New(sysApi.Path + ":" + sysApi.Method + "casbin同步清理失败")
|
||||
}
|
||||
CasbinServiceApp.ClearCasbin(1, sysApi.Path, sysApi.Method)
|
||||
}
|
||||
e := CasbinServiceApp.Casbin()
|
||||
err = e.InvalidateCache()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
//@author: [piexlmax](https://github.com/piexlmax)
|
||||
//@function: DeleteApis
|
||||
//@description: 删除选中API
|
||||
//@param: apis []model.SysApi
|
||||
//@return: err error
|
||||
|
||||
func (apiService *ApiService) FreshCasbin() (err error) {
|
||||
e := CasbinServiceApp.Casbin()
|
||||
err = e.LoadPolicy()
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ func (authorityService *AuthorityService) DeleteAuthority(auth *system.SysAuthor
|
||||
if !errors.Is(global.GVA_DB.Where("parent_id = ?", auth.AuthorityId).First(&system.SysAuthority{}).Error, gorm.ErrRecordNotFound) {
|
||||
return errors.New("此角色存在子角色不允许删除")
|
||||
}
|
||||
db := global.GVA_DB.Preload("SysBaseMenus").Where("authority_id = ?", auth.AuthorityId).First(auth)
|
||||
db := global.GVA_DB.Preload("SysBaseMenus").Preload("DataAuthorityId").Where("authority_id = ?", auth.AuthorityId).First(auth)
|
||||
err = db.Unscoped().Delete(auth).Error
|
||||
if err != nil {
|
||||
return
|
||||
@@ -125,14 +125,21 @@ func (authorityService *AuthorityService) DeleteAuthority(auth *system.SysAuthor
|
||||
return
|
||||
}
|
||||
// err = db.Association("SysBaseMenus").Delete(&auth)
|
||||
} else {
|
||||
err = db.Error
|
||||
}
|
||||
if len(auth.DataAuthorityId) > 0 {
|
||||
err = global.GVA_DB.Model(auth).Association("DataAuthorityId").Delete(auth.DataAuthorityId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
err = global.GVA_DB.Delete(&[]system.SysUserAuthority{}, "sys_authority_authority_id = ?", auth.AuthorityId).Error
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = global.GVA_DB.Delete(&[]system.SysAuthorityBtn{}, "authority_id = ?", auth.AuthorityId).Error
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
authorityId := strconv.Itoa(int(auth.AuthorityId))
|
||||
CasbinServiceApp.ClearCasbin(0, authorityId)
|
||||
return err
|
||||
@@ -148,13 +155,13 @@ func (authorityService *AuthorityService) GetAuthorityInfoList(info request.Page
|
||||
limit := info.PageSize
|
||||
offset := info.PageSize * (info.Page - 1)
|
||||
db := global.GVA_DB.Model(&system.SysAuthority{})
|
||||
err = db.Where("parent_id = ?", "0").Count(&total).Error
|
||||
if err = db.Where("parent_id = ?", "0").Count(&total).Error; total == 0 || err != nil {
|
||||
return
|
||||
}
|
||||
var authority []system.SysAuthority
|
||||
err = db.Limit(limit).Offset(offset).Preload("DataAuthorityId").Where("parent_id = ?", "0").Find(&authority).Error
|
||||
if len(authority) > 0 {
|
||||
for k := range authority {
|
||||
err = authorityService.findChildrenAuthority(&authority[k])
|
||||
}
|
||||
for k := range authority {
|
||||
err = authorityService.findChildrenAuthority(&authority[k])
|
||||
}
|
||||
return authority, total, err
|
||||
}
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"archive/zip"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -18,12 +13,11 @@ import (
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
cp "github.com/otiai10/copy"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
ast2 "github.com/flipped-aurora/gin-vue-admin/server/utils/ast"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/resource/autocode_template/subcontract"
|
||||
cp "github.com/otiai10/copy"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
|
||||
@@ -53,23 +47,10 @@ type autoPackage struct {
|
||||
var (
|
||||
packageInjectionMap map[string]astInjectionMeta
|
||||
injectionPaths []injectionMeta
|
||||
caser = cases.Title(language.English)
|
||||
)
|
||||
|
||||
func Init(Package string) {
|
||||
injectionPaths = []injectionMeta{
|
||||
{
|
||||
path: filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.SInitialize, "gorm.go"),
|
||||
funcName: "MysqlTables",
|
||||
structNameF: Package + ".%s{},",
|
||||
},
|
||||
{
|
||||
path: filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.SInitialize, "router.go"),
|
||||
funcName: "Routers",
|
||||
structNameF: Package + "Router.Init%sRouter(PrivateGroup)",
|
||||
},
|
||||
{
|
||||
path: filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Server, fmt.Sprintf(global.GVA_CONFIG.AutoCode.SApi, Package), "enter.go"),
|
||||
@@ -144,22 +125,37 @@ type AutoCodeService struct{}
|
||||
|
||||
var AutoCodeServiceApp = new(AutoCodeService)
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@function: PreviewTemp
|
||||
//@description: 预览创建代码
|
||||
//@param: model.AutoCodeStruct
|
||||
//@return: map[string]string, error
|
||||
// @author: [songzhibin97](https://github.com/songzhibin97)
|
||||
// @function: PreviewTemp
|
||||
// @description: 预览创建代码
|
||||
// @param: model.AutoCodeStruct
|
||||
// @return: map[string]string, error
|
||||
|
||||
func (autoCodeService *AutoCodeService) PreviewTemp(autoCode system.AutoCodeStruct) (map[string]string, error) {
|
||||
makeDictTypes(&autoCode)
|
||||
for i := range autoCode.Fields {
|
||||
if autoCode.Fields[i].FieldType == "time.Time" {
|
||||
autoCode.HasTimer = true
|
||||
break
|
||||
}
|
||||
if autoCode.Fields[i].Require {
|
||||
autoCode.NeedValid = true
|
||||
break
|
||||
}
|
||||
if autoCode.Fields[i].Sort {
|
||||
autoCode.NeedSort = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "picture" {
|
||||
autoCode.HasPic = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "richtext" {
|
||||
autoCode.HasRichText = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "pictures" {
|
||||
autoCode.HasPic = true
|
||||
autoCode.NeedJSON = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "file" {
|
||||
autoCode.HasFile = true
|
||||
autoCode.NeedJSON = true
|
||||
}
|
||||
}
|
||||
dataList, _, needMkdir, err := autoCodeService.getNeedList(&autoCode)
|
||||
@@ -233,26 +229,41 @@ func makeDictTypes(autoCode *system.AutoCodeStruct) {
|
||||
}
|
||||
}
|
||||
|
||||
//@author: [piexlmax](https://github.com/piexlmax)
|
||||
//@function: CreateTemp
|
||||
//@description: 创建代码
|
||||
//@param: model.AutoCodeStruct
|
||||
//@return: err error
|
||||
// @author: [piexlmax](https://github.com/piexlmax)
|
||||
// @function: CreateTemp
|
||||
// @description: 创建代码
|
||||
// @param: model.AutoCodeStruct
|
||||
// @return: err error
|
||||
|
||||
func (autoCodeService *AutoCodeService) CreateTemp(autoCode system.AutoCodeStruct, ids ...uint) (err error) {
|
||||
makeDictTypes(&autoCode)
|
||||
for i := range autoCode.Fields {
|
||||
if autoCode.Fields[i].FieldType == "time.Time" {
|
||||
autoCode.HasTimer = true
|
||||
break
|
||||
}
|
||||
if autoCode.Fields[i].Require {
|
||||
autoCode.NeedValid = true
|
||||
break
|
||||
}
|
||||
if autoCode.Fields[i].Sort {
|
||||
autoCode.NeedSort = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "picture" {
|
||||
autoCode.HasPic = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "richtext" {
|
||||
autoCode.HasRichText = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "pictures" {
|
||||
autoCode.NeedJSON = true
|
||||
autoCode.HasPic = true
|
||||
}
|
||||
if autoCode.Fields[i].FieldType == "file" {
|
||||
autoCode.NeedJSON = true
|
||||
autoCode.HasFile = true
|
||||
}
|
||||
}
|
||||
// 增加判断: 重复创建struct
|
||||
if autoCode.AutoMoveFile && AutoCodeHistoryServiceApp.Repeat(autoCode.StructName, autoCode.Package) {
|
||||
if autoCode.AutoMoveFile && AutoCodeHistoryServiceApp.Repeat(autoCode.BusinessDB, autoCode.StructName, autoCode.Package) {
|
||||
return RepeatErr
|
||||
}
|
||||
dataList, fileList, needMkdir, err := autoCodeService.getNeedList(&autoCode)
|
||||
@@ -305,6 +316,22 @@ func (autoCodeService *AutoCodeService) CreateTemp(autoCode system.AutoCodeStruc
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// 在gorm.go 注入 自动迁移
|
||||
path := filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.SInitialize, "gorm.go")
|
||||
autoCode.BusinessDB = utils.MaheHump(autoCode.BusinessDB) // 这里将 数据库中间存在 - 的转换为驼峰
|
||||
ast2.AddRegisterTablesAst(path, "RegisterTables", autoCode.Package, autoCode.BusinessDB, autoCode.StructName)
|
||||
}
|
||||
|
||||
{
|
||||
// router.go 注入 自动迁移
|
||||
path := filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.SInitialize, "router.go")
|
||||
ast2.AddRouterCode(path, "Routers", autoCode.Package, autoCode.StructName)
|
||||
}
|
||||
// 给各个enter进行注入
|
||||
err = injectionCode(autoCode.StructName, &injectionCodeMeta)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -316,15 +343,6 @@ func (autoCodeService *AutoCodeService) CreateTemp(autoCode system.AutoCodeStruc
|
||||
bf.WriteString(";")
|
||||
}
|
||||
}
|
||||
|
||||
var gormPath = filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.SInitialize, "gorm.go")
|
||||
var routePath = filepath.Join(global.GVA_CONFIG.AutoCode.Root,
|
||||
global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.SInitialize, "router.go")
|
||||
var imporStr = fmt.Sprintf("github.com/flipped-aurora/gin-vue-admin/server/model/%s", autoCode.Package)
|
||||
_ = ImportReference(routePath, "", "", autoCode.Package, "")
|
||||
_ = ImportReference(gormPath, imporStr, "", "", "")
|
||||
|
||||
} else { // 打包
|
||||
if err = utils.ZipFiles("./ginvueadmin.zip", fileList, ".", "."); err != nil {
|
||||
return err
|
||||
@@ -364,11 +382,11 @@ func (autoCodeService *AutoCodeService) CreateTemp(autoCode system.AutoCodeStruc
|
||||
return nil
|
||||
}
|
||||
|
||||
//@author: [piexlmax](https://github.com/piexlmax)
|
||||
//@function: GetAllTplFile
|
||||
//@description: 获取 pathName 文件夹下所有 tpl 文件
|
||||
//@param: pathName string, fileList []string
|
||||
//@return: []string, error
|
||||
// @author: [piexlmax](https://github.com/piexlmax)
|
||||
// @function: GetAllTplFile
|
||||
// @description: 获取 pathName 文件夹下所有 tpl 文件
|
||||
// @param: pathName string, fileList []string
|
||||
// @return: []string, error
|
||||
|
||||
func (autoCodeService *AutoCodeService) GetAllTplFile(pathName string, fileList []string) ([]string, error) {
|
||||
files, err := os.ReadDir(pathName)
|
||||
@@ -387,22 +405,26 @@ func (autoCodeService *AutoCodeService) GetAllTplFile(pathName string, fileList
|
||||
return fileList, err
|
||||
}
|
||||
|
||||
//@author: [piexlmax](https://github.com/piexlmax)
|
||||
//@function: GetDB
|
||||
//@description: 获取指定数据库和指定数据表的所有字段名,类型值等
|
||||
//@param: tableName string, dbName string
|
||||
//@return: err error, Columns []request.ColumnReq
|
||||
// @author: [piexlmax](https://github.com/piexlmax)
|
||||
// @function: GetDB
|
||||
// @description: 获取指定数据库和指定数据表的所有字段名,类型值等
|
||||
// @param: tableName string, dbName string
|
||||
// @return: err error, Columns []request.ColumnReq
|
||||
|
||||
func (autoCodeService *AutoCodeService) DropTable(tableName string) error {
|
||||
return global.GVA_DB.Exec("DROP TABLE " + tableName).Error
|
||||
func (autoCodeService *AutoCodeService) DropTable(BusinessDb, tableName string) error {
|
||||
if BusinessDb != "" {
|
||||
return global.MustGetGlobalDBByDBName(BusinessDb).Exec("DROP TABLE " + tableName).Error
|
||||
} else {
|
||||
return global.GVA_DB.Exec("DROP TABLE " + tableName).Error
|
||||
}
|
||||
}
|
||||
|
||||
//@author: [SliverHorn](https://github.com/SliverHorn)
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@function: addAutoMoveFile
|
||||
//@description: 生成对应的迁移文件路径
|
||||
//@param: *tplData
|
||||
//@return: null
|
||||
// @author: [SliverHorn](https://github.com/SliverHorn)
|
||||
// @author: [songzhibin97](https://github.com/songzhibin97)
|
||||
// @function: addAutoMoveFile
|
||||
// @description: 生成对应的迁移文件路径
|
||||
// @param: *tplData
|
||||
// @return: null
|
||||
|
||||
func (autoCodeService *AutoCodeService) addAutoMoveFile(data *tplData) {
|
||||
base := filepath.Base(data.autoCodePath)
|
||||
@@ -442,49 +464,49 @@ func (autoCodeService *AutoCodeService) addAutoMoveFile(data *tplData) {
|
||||
}
|
||||
}
|
||||
|
||||
//@author: [piexlmax](https://github.com/piexlmax)
|
||||
//@author: [SliverHorn](https://github.com/SliverHorn)
|
||||
//@function: CreateApi
|
||||
//@description: 自动创建api数据,
|
||||
//@param: a *model.AutoCodeStruct
|
||||
//@return: err error
|
||||
// @author: [piexlmax](https://github.com/piexlmax)
|
||||
// @author: [SliverHorn](https://github.com/SliverHorn)
|
||||
// @function: CreateApi
|
||||
// @description: 自动创建api数据,
|
||||
// @param: a *model.AutoCodeStruct
|
||||
// @return: err error
|
||||
|
||||
func (autoCodeService *AutoCodeService) AutoCreateApi(a *system.AutoCodeStruct) (ids []uint, err error) {
|
||||
apiList := []system.SysApi{
|
||||
{
|
||||
Path: "/" + a.Abbreviation + "/" + "create" + a.StructName,
|
||||
Description: "新增" + a.Description,
|
||||
ApiGroup: a.Abbreviation,
|
||||
ApiGroup: a.Description,
|
||||
Method: "POST",
|
||||
},
|
||||
{
|
||||
Path: "/" + a.Abbreviation + "/" + "delete" + a.StructName,
|
||||
Description: "删除" + a.Description,
|
||||
ApiGroup: a.Abbreviation,
|
||||
ApiGroup: a.Description,
|
||||
Method: "DELETE",
|
||||
},
|
||||
{
|
||||
Path: "/" + a.Abbreviation + "/" + "delete" + a.StructName + "ByIds",
|
||||
Description: "批量删除" + a.Description,
|
||||
ApiGroup: a.Abbreviation,
|
||||
ApiGroup: a.Description,
|
||||
Method: "DELETE",
|
||||
},
|
||||
{
|
||||
Path: "/" + a.Abbreviation + "/" + "update" + a.StructName,
|
||||
Description: "更新" + a.Description,
|
||||
ApiGroup: a.Abbreviation,
|
||||
ApiGroup: a.Description,
|
||||
Method: "PUT",
|
||||
},
|
||||
{
|
||||
Path: "/" + a.Abbreviation + "/" + "find" + a.StructName,
|
||||
Description: "根据ID获取" + a.Description,
|
||||
ApiGroup: a.Abbreviation,
|
||||
ApiGroup: a.Description,
|
||||
Method: "GET",
|
||||
},
|
||||
{
|
||||
Path: "/" + a.Abbreviation + "/" + "get" + a.StructName + "List",
|
||||
Description: "获取" + a.Description + "列表",
|
||||
ApiGroup: a.Abbreviation,
|
||||
ApiGroup: a.Description,
|
||||
Method: "GET",
|
||||
},
|
||||
}
|
||||
@@ -569,9 +591,7 @@ func (autoCodeService *AutoCodeService) getNeedList(autoCode *system.AutoCodeStr
|
||||
func injectionCode(structName string, bf *strings.Builder) error {
|
||||
for _, meta := range injectionPaths {
|
||||
code := fmt.Sprintf(meta.structNameF, structName)
|
||||
if err := utils.AutoInjectionCode(meta.path, meta.funcName, code); err != nil {
|
||||
return err
|
||||
}
|
||||
ast2.ImportForAutoEnter(meta.path, meta.funcName, code)
|
||||
bf.WriteString(fmt.Sprintf("%s@%s@%s;", meta.path, meta.funcName, code))
|
||||
}
|
||||
return nil
|
||||
@@ -645,179 +665,13 @@ func (autoCodeService *AutoCodeService) CreatePackageTemp(packageName string) er
|
||||
// 创建完成后在对应的位置插入结构代码
|
||||
for _, v := range pendingTemp {
|
||||
meta := packageInjectionMap[v.name]
|
||||
if err := ImportReference(meta.path, fmt.Sprintf(meta.importCodeF, v.name, packageName), fmt.Sprintf(meta.structNameF, caser.String(packageName)), fmt.Sprintf(meta.packageNameF, packageName), meta.groupName); err != nil {
|
||||
if err := ast2.ImportReference(meta.path, fmt.Sprintf(meta.importCodeF, v.name, packageName), fmt.Sprintf(meta.structNameF, utils.FirstUpper(packageName)), fmt.Sprintf(meta.packageNameF, packageName), meta.groupName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Visitor struct {
|
||||
ImportCode string
|
||||
StructName string
|
||||
PackageName string
|
||||
GroupName string
|
||||
}
|
||||
|
||||
func (vi *Visitor) Visit(node ast.Node) ast.Visitor {
|
||||
switch n := node.(type) {
|
||||
case *ast.GenDecl:
|
||||
// 查找有没有import context包
|
||||
// Notice:没有考虑没有import任何包的情况
|
||||
if n.Tok == token.IMPORT && vi.ImportCode != "" {
|
||||
vi.addImport(n)
|
||||
// 不需要再遍历子树
|
||||
return nil
|
||||
}
|
||||
if n.Tok == token.TYPE && vi.StructName != "" && vi.PackageName != "" && vi.GroupName != "" {
|
||||
vi.addStruct(n)
|
||||
return nil
|
||||
}
|
||||
case *ast.FuncDecl:
|
||||
if n.Name.Name == "Routers" {
|
||||
vi.addFuncBodyVar(n)
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
return vi
|
||||
}
|
||||
|
||||
func (vi *Visitor) addStruct(genDecl *ast.GenDecl) ast.Visitor {
|
||||
for i := range genDecl.Specs {
|
||||
switch n := genDecl.Specs[i].(type) {
|
||||
case *ast.TypeSpec:
|
||||
if strings.Index(n.Name.Name, "Group") > -1 {
|
||||
switch t := n.Type.(type) {
|
||||
case *ast.StructType:
|
||||
f := &ast.Field{
|
||||
Names: []*ast.Ident{
|
||||
{
|
||||
Name: vi.StructName,
|
||||
Obj: &ast.Object{
|
||||
Kind: ast.Var,
|
||||
Name: vi.StructName,
|
||||
},
|
||||
},
|
||||
},
|
||||
Type: &ast.SelectorExpr{
|
||||
X: &ast.Ident{
|
||||
Name: vi.PackageName,
|
||||
},
|
||||
Sel: &ast.Ident{
|
||||
Name: vi.GroupName,
|
||||
},
|
||||
},
|
||||
}
|
||||
t.Fields.List = append(t.Fields.List, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return vi
|
||||
}
|
||||
|
||||
func (vi *Visitor) addImport(genDecl *ast.GenDecl) ast.Visitor {
|
||||
// 是否已经import
|
||||
hasImported := false
|
||||
for _, v := range genDecl.Specs {
|
||||
importSpec := v.(*ast.ImportSpec)
|
||||
// 如果已经包含
|
||||
if importSpec.Path.Value == strconv.Quote(vi.ImportCode) {
|
||||
hasImported = true
|
||||
}
|
||||
}
|
||||
if !hasImported {
|
||||
genDecl.Specs = append(genDecl.Specs, &ast.ImportSpec{
|
||||
Path: &ast.BasicLit{
|
||||
Kind: token.STRING,
|
||||
Value: strconv.Quote(vi.ImportCode),
|
||||
},
|
||||
})
|
||||
}
|
||||
return vi
|
||||
}
|
||||
|
||||
func (vi *Visitor) addFuncBodyVar(funDecl *ast.FuncDecl) ast.Visitor {
|
||||
hasVar := false
|
||||
for _, v := range funDecl.Body.List {
|
||||
switch varSpec := v.(type) {
|
||||
case *ast.AssignStmt:
|
||||
for i := range varSpec.Lhs {
|
||||
switch nn := varSpec.Lhs[i].(type) {
|
||||
case *ast.Ident:
|
||||
if nn.Name == vi.PackageName+"Router" {
|
||||
hasVar = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !hasVar {
|
||||
assignStmt := &ast.AssignStmt{
|
||||
Lhs: []ast.Expr{
|
||||
&ast.Ident{
|
||||
Name: vi.PackageName + "Router",
|
||||
Obj: &ast.Object{
|
||||
Kind: ast.Var,
|
||||
Name: vi.PackageName + "Router",
|
||||
},
|
||||
},
|
||||
},
|
||||
Tok: token.DEFINE,
|
||||
Rhs: []ast.Expr{
|
||||
&ast.SelectorExpr{
|
||||
X: &ast.SelectorExpr{
|
||||
X: &ast.Ident{
|
||||
Name: "router",
|
||||
},
|
||||
Sel: &ast.Ident{
|
||||
Name: "RouterGroupApp",
|
||||
},
|
||||
},
|
||||
Sel: &ast.Ident{
|
||||
Name: caser.String(vi.PackageName),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
funDecl.Body.List = append(funDecl.Body.List, funDecl.Body.List[1])
|
||||
index := 1
|
||||
copy(funDecl.Body.List[index+1:], funDecl.Body.List[index:])
|
||||
funDecl.Body.List[index] = assignStmt
|
||||
}
|
||||
return vi
|
||||
}
|
||||
|
||||
func ImportReference(filepath, importCode, structName, packageName, groupName string) error {
|
||||
fSet := token.NewFileSet()
|
||||
fParser, err := parser.ParseFile(fSet, filepath, nil, parser.ParseComments)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
importCode = strings.TrimSpace(importCode)
|
||||
v := &Visitor{
|
||||
ImportCode: importCode,
|
||||
StructName: structName,
|
||||
PackageName: packageName,
|
||||
GroupName: groupName,
|
||||
}
|
||||
if importCode == "" {
|
||||
ast.Print(fSet, fParser)
|
||||
}
|
||||
|
||||
ast.Walk(v, fParser)
|
||||
|
||||
var output []byte
|
||||
buffer := bytes.NewBuffer(output)
|
||||
err = format.Node(buffer, fSet, fParser)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// 写回数据
|
||||
return os.WriteFile(filepath, buffer.Bytes(), 0o600)
|
||||
}
|
||||
|
||||
// CreatePlug 自动创建插件模板
|
||||
func (autoCodeService *AutoCodeService) CreatePlug(plug system.AutoPlugReq) error {
|
||||
// 检查列表参数是否有效
|
||||
@@ -944,3 +798,153 @@ func skipMacSpecialDocument(src string) (bool, error) {
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (autoCodeService *AutoCodeService) PubPlug(plugName string) (zipPath string, err error) {
|
||||
if plugName == "" {
|
||||
return "", errors.New("插件名称不能为空")
|
||||
}
|
||||
|
||||
// 防止路径穿越
|
||||
plugName = filepath.Clean(plugName)
|
||||
|
||||
webPath := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Web, "plugin", plugName)
|
||||
serverPath := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", plugName)
|
||||
// 创建一个新的zip文件
|
||||
|
||||
// 判断目录是否存在
|
||||
webInfo, err := os.Stat(webPath)
|
||||
if err != nil {
|
||||
return "", errors.New("web路径不存在")
|
||||
}
|
||||
serverInfo, err := os.Stat(serverPath)
|
||||
if err != nil {
|
||||
return "", errors.New("server路径不存在")
|
||||
}
|
||||
|
||||
fileName := plugName + ".zip"
|
||||
// 创建一个新的zip文件
|
||||
zipFile, err := os.Create(fileName)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
defer zipFile.Close()
|
||||
|
||||
// 创建一个zip写入器
|
||||
zipWriter := zip.NewWriter(zipFile)
|
||||
defer zipWriter.Close()
|
||||
|
||||
// 创建一个新的文件头
|
||||
webHeader, err := zip.FileInfoHeader(webInfo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个新的文件头
|
||||
serverHeader, err := zip.FileInfoHeader(serverInfo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
webHeader.Name = filepath.Join(plugName, "web", "plugin")
|
||||
serverHeader.Name = filepath.Join(plugName, "server", "plugin")
|
||||
|
||||
// 将文件添加到zip归档中
|
||||
_, err = zipWriter.CreateHeader(serverHeader)
|
||||
_, err = zipWriter.CreateHeader(webHeader)
|
||||
|
||||
// 遍历webPath目录并将所有非隐藏文件添加到zip归档中
|
||||
err = filepath.Walk(webPath, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 跳过隐藏文件
|
||||
if strings.HasPrefix(info.Name(), ".") {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建一个新的文件头
|
||||
header, err := zip.FileInfoHeader(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 将文件头的名称设置为文件的相对路径
|
||||
rel, _ := filepath.Rel(webPath, path)
|
||||
header.Name = filepath.Join(plugName, "web", "plugin", plugName, rel)
|
||||
|
||||
// 将文件添加到zip归档中
|
||||
writer, err := zipWriter.CreateHeader(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 打开文件并将其内容复制到zip归档中
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
_, err = io.Copy(writer, file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 遍历serverPath目录并将所有非隐藏文件添加到zip归档中
|
||||
err = filepath.Walk(serverPath, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 跳过隐藏文件和目录
|
||||
if strings.HasPrefix(info.Name(), ".") {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建一个新的文件头
|
||||
header, err := zip.FileInfoHeader(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 将文件头的名称设置为文件的相对路径
|
||||
rel, _ := filepath.Rel(serverPath, path)
|
||||
header.Name = filepath.Join(plugName, "server", "plugin", plugName, rel)
|
||||
// 将文件添加到zip归档中
|
||||
writer, err := zipWriter.CreateHeader(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 打开文件并将其内容复制到zip归档中
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
_, err = io.Copy(writer, file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, fileName), nil
|
||||
}
|
||||
|
||||
@@ -6,18 +6,44 @@ import (
|
||||
)
|
||||
|
||||
type Database interface {
|
||||
GetDB() (data []response.Db, err error)
|
||||
GetTables(dbName string) (data []response.Table, err error)
|
||||
GetColumn(tableName string, dbName string) (data []response.Column, err error)
|
||||
GetDB(businessDB string) (data []response.Db, err error)
|
||||
GetTables(businessDB string, dbName string) (data []response.Table, err error)
|
||||
GetColumn(businessDB string, tableName string, dbName string) (data []response.Column, err error)
|
||||
}
|
||||
|
||||
func (autoCodeService *AutoCodeService) Database() Database {
|
||||
switch global.GVA_CONFIG.System.DbType {
|
||||
case "mysql":
|
||||
return AutoCodeMysql
|
||||
case "pgsql":
|
||||
return AutoCodePgsql
|
||||
default:
|
||||
func (autoCodeService *AutoCodeService) Database(businessDB string) Database {
|
||||
|
||||
if businessDB == "" {
|
||||
switch global.GVA_CONFIG.System.DbType {
|
||||
case "mysql":
|
||||
return AutoCodeMysql
|
||||
case "pgsql":
|
||||
return AutoCodePgsql
|
||||
case "sqlite":
|
||||
return AutoCodeSqlite
|
||||
default:
|
||||
return AutoCodeMysql
|
||||
}
|
||||
} else {
|
||||
for _, info := range global.GVA_CONFIG.DBList {
|
||||
if info.AliasName == businessDB {
|
||||
switch info.Type {
|
||||
case "mysql":
|
||||
return AutoCodeMysql
|
||||
case "mssql":
|
||||
return AutoCodeMssql
|
||||
case "pgsql":
|
||||
return AutoCodePgsql
|
||||
case "oracle":
|
||||
return AutoCodeOracle
|
||||
case "sqlite":
|
||||
return AutoCodeSqlite
|
||||
default:
|
||||
return AutoCodeMysql
|
||||
}
|
||||
}
|
||||
}
|
||||
return AutoCodeMysql
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/model/system/response"
|
||||
)
|
||||
|
||||
var AutoCodeMssql = new(autoCodeMssql)
|
||||
|
||||
type autoCodeMssql struct{}
|
||||
|
||||
// GetDB 获取数据库的所有数据库名
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (s *autoCodeMssql) GetDB(businessDB string) (data []response.Db, err error) {
|
||||
var entities []response.Db
|
||||
sql := "select name AS 'database' from sysdatabases;"
|
||||
if businessDB == "" {
|
||||
err = global.GVA_DB.Raw(sql).Scan(&entities).Error
|
||||
} else {
|
||||
err = global.GVA_DBList[businessDB].Raw(sql).Scan(&entities).Error
|
||||
}
|
||||
return entities, err
|
||||
}
|
||||
|
||||
// GetTables 获取数据库的所有表名
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (s *autoCodeMssql) GetTables(businessDB string, dbName string) (data []response.Table, err error) {
|
||||
var entities []response.Table
|
||||
|
||||
sql := fmt.Sprintf(`select name as 'table_name' from %s.DBO.sysobjects where xtype='U'`, dbName)
|
||||
if businessDB == "" {
|
||||
err = global.GVA_DB.Raw(sql).Scan(&entities).Error
|
||||
} else {
|
||||
err = global.GVA_DBList[businessDB].Raw(sql).Scan(&entities).Error
|
||||
}
|
||||
|
||||
return entities, err
|
||||
}
|
||||
|
||||
// GetColumn 获取指定数据库和指定数据表的所有字段名,类型值等
|
||||
// Author [piexlmax](https://github.com/piexlmax)
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (s *autoCodeMssql) GetColumn(businessDB string, tableName string, dbName string) (data []response.Column, err error) {
|
||||
var entities []response.Column
|
||||
sql := fmt.Sprintf(`select sc.name as column_name,st.name as data_type, sc.length as data_type_long
|
||||
from %s.DBO.syscolumns sc,systypes st where sc.xtype=st.xtype and st.usertype=0 and sc.id in (select id from %s.DBO.sysobjects where xtype='U' and name='%s');`, dbName, dbName, tableName)
|
||||
|
||||
if businessDB == "" {
|
||||
err = global.GVA_DB.Raw(sql).Scan(&entities).Error
|
||||
} else {
|
||||
err = global.GVA_DBList[businessDB].Raw(sql).Scan(&entities).Error
|
||||
}
|
||||
|
||||
return entities, err
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user