Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .deepsource.toml +8 -0
- .drone.yml +173 -0
- .gitattributes +1 -0
- .github/FUNDING.yml +12 -0
- .github/ISSUE_TEMPLATE/bug_report.md +25 -0
- .github/ISSUE_TEMPLATE/bug_report_zh.md +25 -0
- .github/ISSUE_TEMPLATE/proposal.md +14 -0
- .github/ISSUE_TEMPLATE/proposal_zh.md +14 -0
- .github/ISSUE_TEMPLATE/questions.md +14 -0
- .github/ISSUE_TEMPLATE/questions_zh.md +14 -0
- .gitignore +16 -0
- CODE_OF_CONDUCT.md +46 -0
- CONTRIBUTING.md +84 -0
- CONTRIBUTING_CN.md +84 -0
- DONATION.md +1 -0
- Dockerfile +30 -0
- LICENSE +201 -0
- Makefile +130 -0
- README.md +88 -10
- README_CN.md +83 -0
- SECURITY.md +5 -0
- adapter/adapter.go +196 -0
- adapter/beego/beego.go +170 -0
- adapter/beego2/beego2.go +138 -0
- adapter/buffalo/buffalo.go +214 -0
- adapter/chi/chi.go +230 -0
- adapter/echo/echo.go +179 -0
- adapter/fasthttp/fasthttp.go +246 -0
- adapter/gear/gear.go +206 -0
- adapter/gf/gf.go +186 -0
- adapter/gf2/gf2.go +153 -0
- adapter/gin/gin.go +173 -0
- adapter/gofiber/gofiber.go +230 -0
- adapter/gorilla/gorilla.go +207 -0
- adapter/iris/iris.go +177 -0
- context/context.go +781 -0
- context/context_test.go +72 -0
- context/trie.go +134 -0
- data/admin.db +0 -0
- data/admin.mssql +207 -0
- data/admin.pgsql +574 -0
- data/admin.sql +309 -0
- data/migrations/admin_2020_04_14_100427_ms.sql +10 -0
- data/migrations/admin_2020_04_14_100427_mysql.sql +10 -0
- data/migrations/admin_2020_04_14_100427_postgres.sql +72 -0
- data/migrations/admin_2020_04_14_100427_sqlite.sql +9 -0
- data/migrations/admin_2020_08_04_092427_ms.sql +3 -0
- data/migrations/admin_2020_08_04_092427_mysql.sql +3 -0
- data/migrations/admin_2020_08_04_092427_postgres.sql +3 -0
- data/migrations/admin_2020_08_04_092427_sqlite.sql +3 -0
.deepsource.toml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
version = 1
|
2 |
+
|
3 |
+
[[analyzers]]
|
4 |
+
name = "go"
|
5 |
+
enabled = true
|
6 |
+
|
7 |
+
[analyzers.meta]
|
8 |
+
import_paths = ["github.com/GoAdminGroup/go-admin"]
|
.drone.yml
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
kind: pipeline
|
3 |
+
type: docker
|
4 |
+
name: api_mysql
|
5 |
+
|
6 |
+
trigger:
|
7 |
+
event:
|
8 |
+
- pull_request
|
9 |
+
|
10 |
+
clone:
|
11 |
+
disable: true
|
12 |
+
|
13 |
+
services:
|
14 |
+
- name: db_mysql
|
15 |
+
image: mysql:5.7
|
16 |
+
environment:
|
17 |
+
MYSQL_ROOT_PASSWORD: root
|
18 |
+
MYSQL_DATABASE: go-admin-test
|
19 |
+
|
20 |
+
steps:
|
21 |
+
- name: api
|
22 |
+
image: chg80333/goadmin-test:v9
|
23 |
+
environment:
|
24 |
+
GO111MODULE: on
|
25 |
+
GOPROXY: https://goproxy.cn
|
26 |
+
commands:
|
27 |
+
- cd /go/src/github.com/GoAdminGroup/go-admin
|
28 |
+
- git pull
|
29 |
+
- git fetch origin pull/$DRONE_PULL_REQUEST/head:pr$DRONE_PULL_REQUEST
|
30 |
+
- git checkout pr$DRONE_PULL_REQUEST
|
31 |
+
- go version
|
32 |
+
- sleep 80
|
33 |
+
- GOPROXY=https://goproxy.cn make mysql-test
|
34 |
+
|
35 |
+
# ---
|
36 |
+
# kind: pipeline
|
37 |
+
# type: docker
|
38 |
+
# name: api_mssql
|
39 |
+
|
40 |
+
# trigger:
|
41 |
+
# event:
|
42 |
+
# - pull_request
|
43 |
+
|
44 |
+
# clone:
|
45 |
+
# disable: true
|
46 |
+
|
47 |
+
# volumes:
|
48 |
+
# - name: data
|
49 |
+
# temp: {}
|
50 |
+
|
51 |
+
# services:
|
52 |
+
# - name: db_mssql
|
53 |
+
# image: mcr.microsoft.com/mssql/server:2017-latest
|
54 |
+
# volumes:
|
55 |
+
# - name: data
|
56 |
+
# path: /home/data
|
57 |
+
# environment:
|
58 |
+
# ACCEPT_EULA: Y
|
59 |
+
# SA_PASSWORD: Aa123456
|
60 |
+
|
61 |
+
# steps:
|
62 |
+
# - name: api
|
63 |
+
# image: chg80333/goadmin-test:v9
|
64 |
+
# volumes:
|
65 |
+
# - name: data
|
66 |
+
# path: /go/src/github.com/GoAdminGroup/go-admin/tests/data
|
67 |
+
# environment:
|
68 |
+
# GO111MODULE: on
|
69 |
+
# GOPROXY: https://goproxy.cn
|
70 |
+
# commands:
|
71 |
+
# - cd /go/src/github.com/GoAdminGroup/go-admin
|
72 |
+
# - git pull
|
73 |
+
# - git fetch origin pull/$DRONE_PULL_REQUEST/head:pr$DRONE_PULL_REQUEST
|
74 |
+
# - git checkout pr$DRONE_PULL_REQUEST
|
75 |
+
# - go version
|
76 |
+
# - sleep 80
|
77 |
+
# - GOPROXY=https://goproxy.cn make ms-test
|
78 |
+
|
79 |
+
---
|
80 |
+
kind: pipeline
|
81 |
+
type: docker
|
82 |
+
name: api_postgres
|
83 |
+
|
84 |
+
trigger:
|
85 |
+
event:
|
86 |
+
- pull_request
|
87 |
+
|
88 |
+
clone:
|
89 |
+
disable: true
|
90 |
+
|
91 |
+
services:
|
92 |
+
- name: db_pgsql
|
93 |
+
image: postgres:10
|
94 |
+
environment:
|
95 |
+
POSTGRES_USER: postgres
|
96 |
+
POSTGRES_DB: go-admin-test
|
97 |
+
POSTGRES_PASSWORD: root
|
98 |
+
|
99 |
+
steps:
|
100 |
+
- name: api
|
101 |
+
image: chg80333/goadmin-test:v9
|
102 |
+
environment:
|
103 |
+
GO111MODULE: on
|
104 |
+
GOPROXY: https://goproxy.cn
|
105 |
+
commands:
|
106 |
+
- cd /go/src/github.com/GoAdminGroup/go-admin
|
107 |
+
- git pull
|
108 |
+
- git fetch origin pull/$DRONE_PULL_REQUEST/head:pr$DRONE_PULL_REQUEST
|
109 |
+
- git checkout pr$DRONE_PULL_REQUEST
|
110 |
+
- go version
|
111 |
+
- sleep 80
|
112 |
+
- GOPROXY=https://goproxy.cn make pg-test
|
113 |
+
|
114 |
+
---
|
115 |
+
kind: pipeline
|
116 |
+
type: docker
|
117 |
+
name: api_sqlite
|
118 |
+
|
119 |
+
trigger:
|
120 |
+
event:
|
121 |
+
- pull_request
|
122 |
+
|
123 |
+
clone:
|
124 |
+
disable: true
|
125 |
+
|
126 |
+
steps:
|
127 |
+
- name: api
|
128 |
+
image: chg80333/goadmin-test:v9
|
129 |
+
environment:
|
130 |
+
GO111MODULE: on
|
131 |
+
GOPROXY: https://goproxy.cn
|
132 |
+
commands:
|
133 |
+
- cd /go/src/github.com/GoAdminGroup/go-admin
|
134 |
+
- git pull
|
135 |
+
- git fetch origin pull/$DRONE_PULL_REQUEST/head:pr$DRONE_PULL_REQUEST
|
136 |
+
- git checkout pr$DRONE_PULL_REQUEST
|
137 |
+
- go version
|
138 |
+
- sleep 80
|
139 |
+
- GOPROXY=https://goproxy.cn make sqlite-test
|
140 |
+
|
141 |
+
---
|
142 |
+
kind: pipeline
|
143 |
+
type: docker
|
144 |
+
name: frontend
|
145 |
+
|
146 |
+
trigger:
|
147 |
+
event:
|
148 |
+
- pull_request
|
149 |
+
|
150 |
+
clone:
|
151 |
+
disable: true
|
152 |
+
|
153 |
+
services:
|
154 |
+
- name: db_mysql
|
155 |
+
image: mysql:5.7
|
156 |
+
environment:
|
157 |
+
MYSQL_ROOT_PASSWORD: root
|
158 |
+
MYSQL_DATABASE: go-admin-test
|
159 |
+
|
160 |
+
steps:
|
161 |
+
- name: chrome
|
162 |
+
image: chg80333/goadmin-test:v9
|
163 |
+
environment:
|
164 |
+
GO111MODULE: on
|
165 |
+
GOPROXY: https://goproxy.cn
|
166 |
+
commands:
|
167 |
+
- cd /go/src/github.com/GoAdminGroup/go-admin
|
168 |
+
- git pull
|
169 |
+
- git fetch origin pull/$DRONE_PULL_REQUEST/head:pr$DRONE_PULL_REQUEST
|
170 |
+
- git checkout pr$DRONE_PULL_REQUEST
|
171 |
+
- google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
|
172 |
+
- sleep 8
|
173 |
+
- GOPROXY=https://goproxy.cn make web-test
|
.gitattributes
CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
tests/data/admin_ms.bak filter=lfs diff=lfs merge=lfs -text
|
.github/FUNDING.yml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# These are supported funding model platforms
|
2 |
+
|
3 |
+
github:
|
4 |
+
patreon:
|
5 |
+
open_collective: go-admin
|
6 |
+
ko_fi:
|
7 |
+
tidelift:
|
8 |
+
community_bridge:
|
9 |
+
liberapay:
|
10 |
+
issuehunt:
|
11 |
+
otechie:
|
12 |
+
custom: ['https://www.paypal.me/cg80333']
|
.github/ISSUE_TEMPLATE/bug_report.md
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
name: Bug report
|
3 |
+
about: Create a report to help us improve
|
4 |
+
title: "[BUG]"
|
5 |
+
labels: "\U0001F41Bbug"
|
6 |
+
assignees: ''
|
7 |
+
|
8 |
+
---
|
9 |
+
|
10 |
+
### Bug Description [describe the bug in detail]
|
11 |
+
|
12 |
+
### How to reproduce [describe the steps how to reproduce the bug]
|
13 |
+
|
14 |
+
### Expect [describe your expect result]
|
15 |
+
|
16 |
+
### Reproduction code [here to show your codes or examples]
|
17 |
+
|
18 |
+
### Versions
|
19 |
+
|
20 |
+
- GoAdmin version: [e.g. 1.0.0]
|
21 |
+
- golang version
|
22 |
+
- Browser
|
23 |
+
- OS [e.g. mac OS]
|
24 |
+
|
25 |
+
### Others [screenshots or others info here]
|
.github/ISSUE_TEMPLATE/bug_report_zh.md
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
name: Bug 报告
|
3 |
+
about: 提交bug帮助我们修复
|
4 |
+
title: "[BUG]"
|
5 |
+
labels: "\U0001F41Bbug"
|
6 |
+
assignees: ''
|
7 |
+
|
8 |
+
---
|
9 |
+
|
10 |
+
### bug 描述 [详细地描述 bug,让大家都能理解]
|
11 |
+
|
12 |
+
### 复现步骤 [清晰描述复现步骤,让别人也能看到问题]
|
13 |
+
|
14 |
+
### 期望结果 [描述你原本期望看到的结果]
|
15 |
+
|
16 |
+
### 复现代码 [提供可复现的代码,仓库,或线上示例]
|
17 |
+
|
18 |
+
### 版本信息:
|
19 |
+
|
20 |
+
- GoAdmin 版本:
|
21 |
+
- golang 版本:
|
22 |
+
- 浏览器环境:
|
23 |
+
- 开发环境:
|
24 |
+
|
25 |
+
### 其他信息 [如截图等其他信息可以贴在这里]
|
.github/ISSUE_TEMPLATE/proposal.md
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
name: Proposal
|
3 |
+
about: Any advice for GoAdmin
|
4 |
+
title: "[Proposal]"
|
5 |
+
labels: ''
|
6 |
+
assignees: ''
|
7 |
+
|
8 |
+
---
|
9 |
+
|
10 |
+
### Description [describe your advice]
|
11 |
+
|
12 |
+
### Solution [if any solutions, describe here]
|
13 |
+
|
14 |
+
### Others [screenshots and other info]
|
.github/ISSUE_TEMPLATE/proposal_zh.md
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
name: 功能需求
|
3 |
+
about: 对 GoAdmin 的需求或建议
|
4 |
+
title: "[Proposal]"
|
5 |
+
labels: ''
|
6 |
+
assignees: ''
|
7 |
+
|
8 |
+
---
|
9 |
+
|
10 |
+
### 需求描述 [详细地描述需求,让大家都能理解]
|
11 |
+
|
12 |
+
### 解决方案 [如果你有解决方案,在这里清晰地阐述]
|
13 |
+
|
14 |
+
### 其他信息 [如截图等其他信息可以贴在这里]
|
.github/ISSUE_TEMPLATE/questions.md
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
name: Questions
|
3 |
+
about: Any questions when using GoAdmin
|
4 |
+
title: "[Question]"
|
5 |
+
labels: ''
|
6 |
+
assignees: ''
|
7 |
+
|
8 |
+
---
|
9 |
+
|
10 |
+
### Description [describe your questions]
|
11 |
+
|
12 |
+
### Example code [If you have any code info]
|
13 |
+
|
14 |
+
### Others [screenshots or other info]
|
.github/ISSUE_TEMPLATE/questions_zh.md
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
name: 疑问或需要帮助 ❓
|
3 |
+
about: 关于 GoAdmin 的问题
|
4 |
+
title: "[Question]"
|
5 |
+
labels: ''
|
6 |
+
assignees: ''
|
7 |
+
|
8 |
+
---
|
9 |
+
|
10 |
+
### 问题描述 [详细地描述问题,让大家都能理解]
|
11 |
+
|
12 |
+
### 示例代码 [如果有必要,展示代码,线上示例,或仓库]
|
13 |
+
|
14 |
+
### 其他信息 [如截图等其他信息可以贴在这里]
|
.gitignore
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.idea
|
2 |
+
.vscode
|
3 |
+
.DS_Store
|
4 |
+
demo/config.json
|
5 |
+
demo/config
|
6 |
+
demo/deploy.yml
|
7 |
+
demo/hosts
|
8 |
+
demo/go-admin
|
9 |
+
demo/Makefile
|
10 |
+
demo/deploy.retry
|
11 |
+
vendor/**
|
12 |
+
!vendor/vendor.json
|
13 |
+
logs
|
14 |
+
adm/build
|
15 |
+
template/login/assets/login
|
16 |
+
uploads
|
CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Contributor Covenant Code of Conduct
|
2 |
+
|
3 |
+
## Our Pledge
|
4 |
+
|
5 |
+
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
6 |
+
|
7 |
+
## Our Standards
|
8 |
+
|
9 |
+
Examples of behavior that contributes to creating a positive environment include:
|
10 |
+
|
11 |
+
- Using welcoming and inclusive language
|
12 |
+
- Being respectful of differing viewpoints and experiences
|
13 |
+
- Gracefully accepting constructive criticism
|
14 |
+
- Focusing on what is best for the community
|
15 |
+
- Showing empathy towards other community members
|
16 |
+
|
17 |
+
Examples of unacceptable behavior by participants include:
|
18 |
+
|
19 |
+
- The use of sexualized language or imagery and unwelcome sexual attention or advances
|
20 |
+
- Trolling, insulting/derogatory comments, and personal or political attacks
|
21 |
+
- Public or private harassment
|
22 |
+
- Publishing others' private information, such as a physical or electronic address, without explicit permission
|
23 |
+
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
24 |
+
|
25 |
+
## Our Responsibilities
|
26 |
+
|
27 |
+
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
28 |
+
|
29 |
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
30 |
+
|
31 |
+
## Scope
|
32 |
+
|
33 |
+
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
34 |
+
|
35 |
+
## Enforcement
|
36 |
+
|
37 |
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at chg80333@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
38 |
+
|
39 |
+
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
40 |
+
|
41 |
+
## Attribution
|
42 |
+
|
43 |
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
44 |
+
|
45 |
+
[homepage]: http://contributor-covenant.org
|
46 |
+
[version]: http://contributor-covenant.org/version/1/4/
|
CONTRIBUTING.md
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Contributing
|
2 |
+
|
3 |
+
If you want to contribute, but not sure what to do, here's a list of things that I always need help with:
|
4 |
+
|
5 |
+
* Translations
|
6 |
+
* README.md
|
7 |
+
* [docs](https://github.com/GoAdminGroup/docs/issues/1)
|
8 |
+
* Bug-hunting
|
9 |
+
* Finding security problems
|
10 |
+
* Themes and Plugins
|
11 |
+
|
12 |
+
See [manual](https://github.com/GoAdminGroup/go-admin/projects/3) for more information.
|
13 |
+
|
14 |
+
You can view all open issues on github, which is usually a good starting point if you want to start contributing:
|
15 |
+
|
16 |
+
https://github.com/search?q=org%3AGoAdminGroup+is%3Aopen+is%3Aissue+archived%3Afalse&type=Issues
|
17 |
+
|
18 |
+
## how to
|
19 |
+
|
20 |
+
GoAdmin uses GitHub to manage reviews of pull requests:
|
21 |
+
|
22 |
+
- If you have a trivial fix or improvement, go ahead and create a pull request.
|
23 |
+
- If you plan to do something more involved, discuss your ideas on the relevant GitHub issue.
|
24 |
+
|
25 |
+
For now, you need to add your fork as a remote on the original **\$GOPATH**/src/github.com/GoAdminGroup/go-admin clone, so:
|
26 |
+
|
27 |
+
```bash
|
28 |
+
|
29 |
+
$ go get github.com/GoAdminGroup/go-admin
|
30 |
+
$ cd $GOPATH/src/github.com/GoAdminGroup/go-admin # GOPATH is $HOME/go by default.
|
31 |
+
|
32 |
+
$ git remote add <FORK_NAME> <FORK_URL>
|
33 |
+
```
|
34 |
+
|
35 |
+
And before you commit, remember to execute the command:
|
36 |
+
|
37 |
+
```
|
38 |
+
make test
|
39 |
+
```
|
40 |
+
|
41 |
+
See the Makefile for more details.
|
42 |
+
|
43 |
+
Notice: `go get` return `package github.com/GoAdminGroup/go-admin: no Go files in /go/src/github.com/GoAdminGroup/go-admin` is normal.
|
44 |
+
|
45 |
+
### Dependency management
|
46 |
+
|
47 |
+
We uses [Go modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) to manage dependencies on external packages.
|
48 |
+
This requires a working Go environment with version 1.13 or greater and git installed.
|
49 |
+
|
50 |
+
To add or update a new dependency, use the `go get` command:
|
51 |
+
|
52 |
+
```bash
|
53 |
+
# Pick the latest tagged release.
|
54 |
+
go get example.com/some/module/pkg
|
55 |
+
|
56 |
+
# Pick a specific version.
|
57 |
+
go get example.com/some/module/pkg@vX.Y.Z
|
58 |
+
```
|
59 |
+
|
60 |
+
Tidy up the `go.mod` and `go.sum` files:
|
61 |
+
|
62 |
+
```bash
|
63 |
+
go mod tidy
|
64 |
+
go mod vendor
|
65 |
+
git add go.mod go.sum vendor
|
66 |
+
git commit
|
67 |
+
```
|
68 |
+
|
69 |
+
You have to commit the changes to `go.mod` and `go.sum` before submitting the pull request.
|
70 |
+
|
71 |
+
# Support
|
72 |
+
|
73 |
+
You can also donate or become a patreon, which helps out covering server costs and potentially make it possible to put out bounties:
|
74 |
+
|
75 |
+
* **Support on [Open Collective](https://opencollective.com/go-admin)**
|
76 |
+
* Donate via [PayPal](https://paypal.me/cg80333)
|
77 |
+
|
78 |
+
# Members
|
79 |
+
|
80 |
+
If you are a member of the official GoAdmin developer Team:
|
81 |
+
|
82 |
+
* [Discussions](http://forum.go-admin.cn)
|
83 |
+
* [Tasks](https://github.com/GoAdminGroup/go-admin/projects)
|
84 |
+
* [Chat](https://t.me/joinchat/NlyH6Bch2QARZkArithKvg)
|
CONTRIBUTING_CN.md
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# 贡献
|
2 |
+
|
3 |
+
如果你想要对项目作出贡献,却不知道怎么做,下面有一些帮助:
|
4 |
+
|
5 |
+
* 翻译
|
6 |
+
* README.md
|
7 |
+
* [docs](https://github.com/GoAdminGroup/docs/issues/1)
|
8 |
+
* 寻找BUG
|
9 |
+
* 寻找安全问题
|
10 |
+
* 主题和插件
|
11 |
+
|
12 |
+
在这里:[功能规划](https://github.com/GoAdminGroup/go-admin/projects/3) 可以获得更多信息。
|
13 |
+
|
14 |
+
你也可以看一下所有开放的issues,从这里去入手:
|
15 |
+
|
16 |
+
https://github.com/search?q=org%3AGoAdminGroup+is%3Aopen+is%3Aissue+archived%3Afalse&type=Issues
|
17 |
+
|
18 |
+
## 如何做贡献
|
19 |
+
|
20 |
+
GoAdmin 使用 GitHub 来管理项目代码:
|
21 |
+
|
22 |
+
- 如果你发现一些微不足道的fix或者功能增加,直接提pr即可;
|
23 |
+
- 如果你有一些提议,那么你可以先开一个issue进行讨论;
|
24 |
+
|
25 |
+
然后,你需要fork远程的master分支到你本地 **\$GOPATH**/src/github.com/GoAdminGroup/go-admin :
|
26 |
+
|
27 |
+
```bash
|
28 |
+
|
29 |
+
$ go get github.com/GoAdminGroup/go-admin
|
30 |
+
$ cd $GOPATH/src/github.com/GoAdminGroup/go-admin # GOPATH is $HOME/go by default.
|
31 |
+
|
32 |
+
$ git remote add <FORK_NAME> <FORK_URL>
|
33 |
+
```
|
34 |
+
|
35 |
+
在你提交代码之前,记得执行下面这个命令:
|
36 |
+
|
37 |
+
```
|
38 |
+
make test
|
39 |
+
```
|
40 |
+
|
41 |
+
看根目录下的```Makefile```获得更多信息。
|
42 |
+
|
43 |
+
注意了: `go get` 返回 `package github.com/GoAdminGroup/go-admin: no Go files in /go/src/github.com/GoAdminGroup/go-admin` 是正常的。
|
44 |
+
|
45 |
+
### 依赖管理
|
46 |
+
|
47 |
+
我们使用 [Go modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) 来管理依赖。
|
48 |
+
这需要 golang 版本大于1.11,以及安装了 git
|
49 |
+
|
50 |
+
要增加或更新依赖,就使用 `go get` 命令:
|
51 |
+
|
52 |
+
```bash
|
53 |
+
# Pick the latest tagged release.
|
54 |
+
go get example.com/some/module/pkg
|
55 |
+
|
56 |
+
# Pick a specific version.
|
57 |
+
go get example.com/some/module/pkg@vX.Y.Z
|
58 |
+
```
|
59 |
+
|
60 |
+
整理好 `go.mod` 和 `go.sum`:
|
61 |
+
|
62 |
+
```bash
|
63 |
+
go mod tidy
|
64 |
+
go mod vendor
|
65 |
+
git add go.mod go.sum vendor
|
66 |
+
git commit
|
67 |
+
```
|
68 |
+
|
69 |
+
直接提交 `go.mod` and `go.sum` 的修改。
|
70 |
+
|
71 |
+
# 赞助
|
72 |
+
|
73 |
+
你可以捐助或参与众筹来帮助我们维护服务器费用,以及提供一些奖金资助项目发展。
|
74 |
+
|
75 |
+
* **Support on [Open Collective](https://opencollective.com/go-admin)**
|
76 |
+
* Donate via [PayPal](https://paypal.me/cg80333)
|
77 |
+
|
78 |
+
# 成员
|
79 |
+
|
80 |
+
如果你已经是GoAdmin的官方开发组成员:
|
81 |
+
|
82 |
+
* [Discussions](http://forum.go-admin.cn)
|
83 |
+
* [Tasks](https://github.com/GoAdminGroup/go-admin/projects)
|
84 |
+
* [Chat](https://t.me/joinchat/NlyH6Bch2QARZkArithKvg)
|
DONATION.md
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
# Donation List 捐赠名单(排名不分先后)
|
Dockerfile
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This file describes the standard way to build GoAdmin develop env image, and using container
|
2 |
+
#
|
3 |
+
# Usage:
|
4 |
+
#
|
5 |
+
# # Assemble the code dev environment, get related database tools in docker-compose.yml, It is slow the first time.
|
6 |
+
# docker build -t goadmin:1.0 .
|
7 |
+
#
|
8 |
+
# # Mount your source code to container for quick developing:
|
9 |
+
# docker run -v `pwd`:/home/goadmin --name -d goadmin:1.0
|
10 |
+
# docker exec -it goadmin /bin/bash
|
11 |
+
# # if your local code has been changed ,you can restart the container to take effect
|
12 |
+
# docker restart goadmin
|
13 |
+
#
|
14 |
+
|
15 |
+
FROM golang:latest
|
16 |
+
MAINTAINER josingcjx
|
17 |
+
COPY . /home/goadmin
|
18 |
+
ENV GOPATH=$GOPATH:/home/goadmin/ GOPROXY=https://mirrors.aliyun.com/goproxy,https://goproxy.cn,direct
|
19 |
+
RUN apt-get update --fix-missing && \
|
20 |
+
apt-get install -y zip vim postgresql mysql-common default-mysql-server && \
|
21 |
+
tar -C / -xvf /home/goadmin/tools/godependacy.tgz
|
22 |
+
#if install dependacy tools failed, you can copy local's to remote
|
23 |
+
#mkdir -p /go/bin && \
|
24 |
+
#mv /home/goadmin/tools/{gotest,goimports,golint,golangci-lint,adm} /go/bin
|
25 |
+
#go get golang.org/x/tools/cmd/goimports && \
|
26 |
+
#go get github.com/rakyll/gotest && \
|
27 |
+
#go get -u golang.org/x/lint/golint && \
|
28 |
+
#go install github.com/GoAdminGroup/adm@latest && \
|
29 |
+
#go get -u github.com/golangci/golangci-lint/cmd/golangci-lint
|
30 |
+
WORKDIR /home/goadmin
|
LICENSE
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Apache License
|
2 |
+
Version 2.0, January 2004
|
3 |
+
http://www.apache.org/licenses/
|
4 |
+
|
5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
6 |
+
|
7 |
+
1. Definitions.
|
8 |
+
|
9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
11 |
+
|
12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
13 |
+
the copyright owner that is granting the License.
|
14 |
+
|
15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
16 |
+
other entities that control, are controlled by, or are under common
|
17 |
+
control with that entity. For the purposes of this definition,
|
18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
19 |
+
direction or management of such entity, whether by contract or
|
20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
22 |
+
|
23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
24 |
+
exercising permissions granted by this License.
|
25 |
+
|
26 |
+
"Source" form shall mean the preferred form for making modifications,
|
27 |
+
including but not limited to software source code, documentation
|
28 |
+
source, and configuration files.
|
29 |
+
|
30 |
+
"Object" form shall mean any form resulting from mechanical
|
31 |
+
transformation or translation of a Source form, including but
|
32 |
+
not limited to compiled object code, generated documentation,
|
33 |
+
and conversions to other media types.
|
34 |
+
|
35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
36 |
+
Object form, made available under the License, as indicated by a
|
37 |
+
copyright notice that is included in or attached to the work
|
38 |
+
(an example is provided in the Appendix below).
|
39 |
+
|
40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
41 |
+
form, that is based on (or derived from) the Work and for which the
|
42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
44 |
+
of this License, Derivative Works shall not include works that remain
|
45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
46 |
+
the Work and Derivative Works thereof.
|
47 |
+
|
48 |
+
"Contribution" shall mean any work of authorship, including
|
49 |
+
the original version of the Work and any modifications or additions
|
50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
51 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
54 |
+
means any form of electronic, verbal, or written communication sent
|
55 |
+
to the Licensor or its representatives, including but not limited to
|
56 |
+
communication on electronic mailing lists, source code control systems,
|
57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
59 |
+
excluding communication that is conspicuously marked or otherwise
|
60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
61 |
+
|
62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
63 |
+
on behalf of whom a Contribution has been received by Licensor and
|
64 |
+
subsequently incorporated within the Work.
|
65 |
+
|
66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
71 |
+
Work and such Derivative Works in Source or Object form.
|
72 |
+
|
73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
76 |
+
(except as stated in this section) patent license to make, have made,
|
77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
78 |
+
where such license applies only to those patent claims licensable
|
79 |
+
by such Contributor that are necessarily infringed by their
|
80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
82 |
+
institute patent litigation against any entity (including a
|
83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
84 |
+
or a Contribution incorporated within the Work constitutes direct
|
85 |
+
or contributory patent infringement, then any patent licenses
|
86 |
+
granted to You under this License for that Work shall terminate
|
87 |
+
as of the date such litigation is filed.
|
88 |
+
|
89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
90 |
+
Work or Derivative Works thereof in any medium, with or without
|
91 |
+
modifications, and in Source or Object form, provided that You
|
92 |
+
meet the following conditions:
|
93 |
+
|
94 |
+
(a) You must give any other recipients of the Work or
|
95 |
+
Derivative Works a copy of this License; and
|
96 |
+
|
97 |
+
(b) You must cause any modified files to carry prominent notices
|
98 |
+
stating that You changed the files; and
|
99 |
+
|
100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
101 |
+
that You distribute, all copyright, patent, trademark, and
|
102 |
+
attribution notices from the Source form of the Work,
|
103 |
+
excluding those notices that do not pertain to any part of
|
104 |
+
the Derivative Works; and
|
105 |
+
|
106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
107 |
+
distribution, then any Derivative Works that You distribute must
|
108 |
+
include a readable copy of the attribution notices contained
|
109 |
+
within such NOTICE file, excluding those notices that do not
|
110 |
+
pertain to any part of the Derivative Works, in at least one
|
111 |
+
of the following places: within a NOTICE text file distributed
|
112 |
+
as part of the Derivative Works; within the Source form or
|
113 |
+
documentation, if provided along with the Derivative Works; or,
|
114 |
+
within a display generated by the Derivative Works, if and
|
115 |
+
wherever such third-party notices normally appear. The contents
|
116 |
+
of the NOTICE file are for informational purposes only and
|
117 |
+
do not modify the License. You may add Your own attribution
|
118 |
+
notices within Derivative Works that You distribute, alongside
|
119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
120 |
+
that such additional attribution notices cannot be construed
|
121 |
+
as modifying the License.
|
122 |
+
|
123 |
+
You may add Your own copyright statement to Your modifications and
|
124 |
+
may provide additional or different license terms and conditions
|
125 |
+
for use, reproduction, or distribution of Your modifications, or
|
126 |
+
for any such Derivative Works as a whole, provided Your use,
|
127 |
+
reproduction, and distribution of the Work otherwise complies with
|
128 |
+
the conditions stated in this License.
|
129 |
+
|
130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
132 |
+
by You to the Licensor shall be under the terms and conditions of
|
133 |
+
this License, without any additional terms or conditions.
|
134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
135 |
+
the terms of any separate license agreement you may have executed
|
136 |
+
with Licensor regarding such Contributions.
|
137 |
+
|
138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
140 |
+
except as required for reasonable and customary use in describing the
|
141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
142 |
+
|
143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
144 |
+
agreed to in writing, Licensor provides the Work (and each
|
145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
147 |
+
implied, including, without limitation, any warranties or conditions
|
148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
150 |
+
appropriateness of using or redistributing the Work and assume any
|
151 |
+
risks associated with Your exercise of permissions under this License.
|
152 |
+
|
153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
154 |
+
whether in tort (including negligence), contract, or otherwise,
|
155 |
+
unless required by applicable law (such as deliberate and grossly
|
156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
157 |
+
liable to You for damages, including any direct, indirect, special,
|
158 |
+
incidental, or consequential damages of any character arising as a
|
159 |
+
result of this License or out of the use or inability to use the
|
160 |
+
Work (including but not limited to damages for loss of goodwill,
|
161 |
+
work stoppage, computer failure or malfunction, or any and all
|
162 |
+
other commercial damages or losses), even if such Contributor
|
163 |
+
has been advised of the possibility of such damages.
|
164 |
+
|
165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
168 |
+
or other liability obligations and/or rights consistent with this
|
169 |
+
License. However, in accepting such obligations, You may act only
|
170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
171 |
+
of any other Contributor, and only if You agree to indemnify,
|
172 |
+
defend, and hold each Contributor harmless for any liability
|
173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
174 |
+
of your accepting any such warranty or additional liability.
|
175 |
+
|
176 |
+
END OF TERMS AND CONDITIONS
|
177 |
+
|
178 |
+
APPENDIX: How to apply the Apache License to your work.
|
179 |
+
|
180 |
+
To apply the Apache License to your work, attach the following
|
181 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
182 |
+
replaced with your own identifying information. (Don't include
|
183 |
+
the brackets!) The text should be enclosed in the appropriate
|
184 |
+
comment syntax for the file format. We also recommend that a
|
185 |
+
file or class name and description of purpose be included on the
|
186 |
+
same "printed page" as the copyright notice for easier
|
187 |
+
identification within third-party archives.
|
188 |
+
|
189 |
+
Copyright [yyyy] [name of copyright owner]
|
190 |
+
|
191 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
192 |
+
you may not use this file except in compliance with the License.
|
193 |
+
You may obtain a copy of the License at
|
194 |
+
|
195 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
196 |
+
|
197 |
+
Unless required by applicable law or agreed to in writing, software
|
198 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
199 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
200 |
+
See the License for the specific language governing permissions and
|
201 |
+
limitations under the License.
|
Makefile
ADDED
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GOCMD = go
|
2 |
+
GOBUILD = $(GOCMD) build
|
3 |
+
|
4 |
+
TEST_CONFIG_PATH=./../../common/config.json
|
5 |
+
TEST_CONFIG_PQ_PATH=./../../common/config_pg.json
|
6 |
+
TEST_CONFIG_SQLITE_PATH=./../../common/config_sqlite.json
|
7 |
+
TEST_CONFIG_MS_PATH=./../../common/config_ms.json
|
8 |
+
TEST_FRAMEWORK_DIR=./tests/frameworks
|
9 |
+
|
10 |
+
## database configs
|
11 |
+
MYSQL_HOST = db_mysql
|
12 |
+
MYSQL_PORT = 3306
|
13 |
+
MYSQL_USER = root
|
14 |
+
MYSQL_PWD = root
|
15 |
+
|
16 |
+
POSTGRESSQL_HOST = db_pgsql
|
17 |
+
POSTGRESSQL_PORT = 5432
|
18 |
+
POSTGRESSQL_USER = postgres
|
19 |
+
POSTGRESSQL_PWD = root
|
20 |
+
|
21 |
+
TEST_DB = go-admin-test
|
22 |
+
|
23 |
+
all: test
|
24 |
+
|
25 |
+
## tests
|
26 |
+
|
27 |
+
test: cp-mod black-box-test web-test restore-mod
|
28 |
+
|
29 |
+
## tests: black box tests
|
30 |
+
|
31 |
+
black-box-test: mysql-test pg-test sqlite-test ms-test
|
32 |
+
|
33 |
+
mysql-test: $(TEST_FRAMEWORK_DIR)/*
|
34 |
+
go get github.com/ugorji/go/codec@none
|
35 |
+
for file in $^ ; do \
|
36 |
+
make import-mysql ; \
|
37 |
+
go test -mod=mod -gcflags=all=-l -v ./$${file}/... -args $(TEST_CONFIG_PATH) ; \
|
38 |
+
done
|
39 |
+
|
40 |
+
sqlite-test: $(TEST_FRAMEWORK_DIR)/*
|
41 |
+
for file in $^ ; do \
|
42 |
+
make import-sqlite ; \
|
43 |
+
go test -mod=mod -gcflags=all=-l ./$${file}/... -args $(TEST_CONFIG_SQLITE_PATH) ; \
|
44 |
+
done
|
45 |
+
|
46 |
+
pg-test: $(TEST_FRAMEWORK_DIR)/*
|
47 |
+
for file in $^ ; do \
|
48 |
+
make import-postgresql ; \
|
49 |
+
go test -mod=mod -gcflags=all=-l ./$${file}/... -args $(TEST_CONFIG_PQ_PATH) ; \
|
50 |
+
done
|
51 |
+
|
52 |
+
ms-test: $(TEST_FRAMEWORK_DIR)/*
|
53 |
+
for file in $^ ; do \
|
54 |
+
make import-mssql ; \
|
55 |
+
go test -mod=mod -gcflags=all=-l ./$${file}/... -args $(TEST_CONFIG_MS_PATH) ; \
|
56 |
+
done
|
57 |
+
|
58 |
+
## tests: user acceptance tests
|
59 |
+
|
60 |
+
web-test: import-mysql
|
61 |
+
go test -mod=mod ./tests/web/...
|
62 |
+
rm -rf ./tests/web/User*
|
63 |
+
|
64 |
+
web-test-debug: import-mysql
|
65 |
+
go test -mod=mod ./tests/web/... -args true
|
66 |
+
|
67 |
+
## tests: unit tests
|
68 |
+
|
69 |
+
unit-test:
|
70 |
+
go test -mod=mod ./adm/...
|
71 |
+
go test -mod=mod ./context/...
|
72 |
+
go test -mod=mod ./modules/...
|
73 |
+
go test -mod=mod ./plugins/admin/controller/...
|
74 |
+
go test -mod=mod ./plugins/admin/modules/parameter/...
|
75 |
+
go test -mod=mod ./plugins/admin/modules/table/...
|
76 |
+
go test -mod=mod ./plugins/admin/modules/...
|
77 |
+
|
78 |
+
## tests: helpers
|
79 |
+
|
80 |
+
import-sqlite:
|
81 |
+
rm -rf ./tests/common/admin.db
|
82 |
+
cp ./tests/data/admin.db ./tests/common/admin.db
|
83 |
+
|
84 |
+
import-mysql:
|
85 |
+
mysql -h$(MYSQL_HOST) -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PWD} -e "create database if not exists \`${TEST_DB}\`"
|
86 |
+
mysql -h$(MYSQL_HOST) -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PWD} ${TEST_DB} < ./tests/data/admin.sql
|
87 |
+
|
88 |
+
import-postgresql:
|
89 |
+
PGPASSWORD=${POSTGRESSQL_PWD} dropdb -h ${POSTGRESSQL_HOST} -p ${POSTGRESSQL_PORT} -U ${POSTGRESSQL_USER} ${TEST_DB}
|
90 |
+
PGPASSWORD=${POSTGRESSQL_PWD} createdb -h ${POSTGRESSQL_HOST} -p ${POSTGRESSQL_PORT} -U ${POSTGRESSQL_USER} ${TEST_DB}
|
91 |
+
PGPASSWORD=${POSTGRESSQL_PWD} psql -h ${POSTGRESSQL_HOST} -p ${POSTGRESSQL_PORT} -d ${TEST_DB} -U ${POSTGRESSQL_USER} -f ./tests/data/admin_pg.sql
|
92 |
+
|
93 |
+
import-mssql:
|
94 |
+
/opt/mssql-tools/bin/sqlcmd -S db_mssql -U SA -P Aa123456 -Q "RESTORE DATABASE [goadmin] FROM DISK = N'/home/data/admin_ms.bak' WITH FILE = 1, NOUNLOAD, REPLACE, RECOVERY, STATS = 5"
|
95 |
+
|
96 |
+
backup-mssql:
|
97 |
+
docker exec mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P Aa123456 -Q "BACKUP DATABASE [goadmin] TO DISK = N'/home/data/admin_ms.bak' WITH NOFORMAT, NOINIT, NAME = 'goadmin-full', SKIP, NOREWIND, NOUNLOAD, STATS = 10"
|
98 |
+
|
99 |
+
cp-mod:
|
100 |
+
cp go.mod go.mod.old
|
101 |
+
cp go.sum go.sum.old
|
102 |
+
|
103 |
+
restore-mod:
|
104 |
+
mv go.mod.old go.mod
|
105 |
+
mv go.sum.old go.sum
|
106 |
+
|
107 |
+
## code style check
|
108 |
+
|
109 |
+
lint: fmt golint govet cilint
|
110 |
+
|
111 |
+
fmt:
|
112 |
+
GO111MODULE=off go fmt ./...
|
113 |
+
GO111MODULE=off goimports -l -w .
|
114 |
+
|
115 |
+
govet:
|
116 |
+
GO111MODULE=off go vet ./...
|
117 |
+
|
118 |
+
cilint:
|
119 |
+
GO111MODULE=off golangci-lint run
|
120 |
+
|
121 |
+
golint:
|
122 |
+
GO111MODULE=off golint ./...
|
123 |
+
|
124 |
+
build-tmpl:
|
125 |
+
## form tmpl build
|
126 |
+
adm compile tpl --src ./template/types/tmpls/ --dist ./template/types/tmpl.go --package types --var tmpls
|
127 |
+
## generator tmpl build
|
128 |
+
adm compile tpl --src ./plugins/admin/modules/table/tmpl --dist ./plugins/admin/modules/table/tmpl.go --package table --var tmpls
|
129 |
+
|
130 |
+
.PHONY: all fmt golint govet cp-mod restore-mod test black-box-test mysql-test sqlite-test import-sqlite import-mysql import-postgresql pg-test lint cilint cli
|
README.md
CHANGED
@@ -1,10 +1,88 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<p align="center">
|
2 |
+
<a href="https://github.com/GoAdminGroup/go-admin">
|
3 |
+
<img width="48%" alt="go-admin" src="http://quick.go-admin.cn/official/assets/imgs/github_logo.png">
|
4 |
+
</a>
|
5 |
+
</p>
|
6 |
+
|
7 |
+
<p align="center">
|
8 |
+
the missing golang data admin panel builder tool.
|
9 |
+
</p>
|
10 |
+
|
11 |
+
<p align="center">
|
12 |
+
<a href="https://book.go-admin.cn/en">Documentation</a> |
|
13 |
+
<a href="http://doc.go-admin.cn/zh/">中文文档</a> |
|
14 |
+
<a href="./README_CN.md">中文介绍</a> |
|
15 |
+
<a href="https://demo.go-admin.com">DEMO</a> |
|
16 |
+
<a href="https://demo.go-admin.cn">中文DEMO</a> |
|
17 |
+
<a href="https://twitter.com/cg3365688034">Twitter</a> |
|
18 |
+
<a href="http://discuss.go-admin.com">Forum</a>
|
19 |
+
</p>
|
20 |
+
|
21 |
+
<p align="center">
|
22 |
+
<a href="http://drone.go-admin.com/GoAdminGroup/go-admin"><img alt="Build Status" src="http://drone.go-admin.com/api/badges/GoAdminGroup/go-admin/status.svg?ref=refs/heads/master"></a>
|
23 |
+
<a href="https://goreportcard.com/report/github.com/GoAdminGroup/go-admin"><img alt="Go Report Card" src="https://goreportcard.com/badge/github.com/GoAdminGroup/go-admin"></a>
|
24 |
+
<a href="https://goreportcard.com/report/github.com/GoAdminGroup/go-admin"><img alt="golang" src="https://img.shields.io/badge/awesome-golang-blue.svg"></a>
|
25 |
+
<a href="https://discord.gg/usAaEpCP"><img alt="discord" src="https://img.shields.io/badge/chat%20on-Discord-blue.svg"></a>
|
26 |
+
<a href="https://t.me/joinchat/NlyH6Bch2QARZkArithKvg" rel="nofollow"><img alt="telegram" src="https://img.shields.io/badge/chat%20on-telegram-blue" style="max-width:100%;"></a>
|
27 |
+
<a href="https://raw.githubusercontent.com/GoAdminGroup/go-admin/master/LICENSE" rel="nofollow"><img src="https://img.shields.io/badge/license-Apache2.0-blue.svg" alt="license" data-canonical-src="https://img.shields.io/badge/license-Apache2.0-blue.svg" style="max-width:100%;"></a>
|
28 |
+
</p>
|
29 |
+
|
30 |
+
<p align="center">
|
31 |
+
Inspired by <a href="https://github.com/z-song/laravel-admin" target="_blank">laravel-admin</a>
|
32 |
+
</p>
|
33 |
+
|
34 |
+
## Preface
|
35 |
+
|
36 |
+
GoAdmin is a toolkit to help you build a data visualization admin panel for your golang app.
|
37 |
+
|
38 |
+
Online demo: [https://demo.go-admin.com](https://demo.go-admin.com)
|
39 |
+
|
40 |
+
![interface](http://file.go-admin.cn/introduction/interface_en_3.png)
|
41 |
+
|
42 |
+
## Features
|
43 |
+
|
44 |
+
- 🚀 **Fast**: build a production admin panel app in **ten** minutes.
|
45 |
+
- 🎨 **Theming**: beautiful ui themes supported(default adminlte, more themes are coming.)
|
46 |
+
- 🔢 **Plugins**: many plugins to use(more useful and powerful plugins are coming.)
|
47 |
+
- ✅ **Rbac**: out of box rbac auth system.
|
48 |
+
- ⚙️ **Frameworks**: support most of the go web frameworks.
|
49 |
+
|
50 |
+
## Translation
|
51 |
+
We need your help: [https://github.com/GoAdminGroup/docs/issues/1](https://github.com/GoAdminGroup/docs/issues/1)
|
52 |
+
|
53 |
+
## Who is using
|
54 |
+
|
55 |
+
[Comment the issue to tell us](https://github.com/GoAdminGroup/go-admin/issues/71).
|
56 |
+
|
57 |
+
## How to
|
58 |
+
|
59 |
+
Following three steps to run it.
|
60 |
+
|
61 |
+
```shell
|
62 |
+
$ mkdir new_project && cd new_project
|
63 |
+
$ go install github.com/GoAdminGroup/adm@latest
|
64 |
+
$ adm init web
|
65 |
+
```
|
66 |
+
|
67 |
+
## Example
|
68 |
+
|
69 |
+
Quick follow up example:
|
70 |
+
|
71 |
+
- [pure golang](https://github.com/GoAdminGroup/example), simple and less dependency
|
72 |
+
- [golang with frontend template](https://github.com/GoAdminGroup/example_with_frontend), change template by yourself
|
73 |
+
- [golang with vue](https://github.com/GoAdminGroup/example_with_vue), if you have vue experience
|
74 |
+
|
75 |
+
See the [docs](https://book.go-admin.cn) for more details.
|
76 |
+
|
77 |
+
## Backers
|
78 |
+
|
79 |
+
Your support will help me do better! [[Become a backer](https://opencollective.com/go-admin#backer)]
|
80 |
+
<a href="https://opencollective.com/go-admin#backers" target="_blank"><img src="https://opencollective.com/go-admin/backers.svg?width=890"></a>
|
81 |
+
|
82 |
+
## Contribution
|
83 |
+
|
84 |
+
[here for contribution guide](CONTRIBUTING.md)
|
85 |
+
|
86 |
+
<strong>here to join into the develop team</strong>
|
87 |
+
|
88 |
+
[join telegram](https://t.me/joinchat/NlyH6Bch2QARZkArithKvg)
|
README_CN.md
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<p align="center">
|
2 |
+
<a href="https://github.com/GoAdminGroup/go-admin">
|
3 |
+
<img width="48%" alt="go-admin" src="http://quick.go-admin.cn/official/assets/imgs/github_logo.png">
|
4 |
+
</a>
|
5 |
+
</p>
|
6 |
+
<p align="center">
|
7 |
+
遗失的Golang编写的数据可视化与管理平台构建框架
|
8 |
+
</p>
|
9 |
+
<p align="center">
|
10 |
+
<a href="http://drone.go-admin.com/GoAdminGroup/go-admin"><img alt="Build Status" src="http://drone.go-admin.com/api/badges/GoAdminGroup/go-admin/status.svg?ref=refs/heads/master"></a>
|
11 |
+
<a href="https://goreportcard.com/report/github.com/GoAdminGroup/go-admin"><img alt="Go Report Card" src="https://goreportcard.com/badge/github.com/GoAdminGroup/go-admin"></a>
|
12 |
+
<a href="https://goreportcard.com/report/github.com/GoAdminGroup/go-admin"><img alt="golang" src="https://img.shields.io/badge/awesome-golang-blue.svg"></a>
|
13 |
+
<a href="https://discord.gg/usAaEpCP"><img alt="discord" src="https://img.shields.io/badge/chat%20on-Discord-blue.svg"></a>
|
14 |
+
<a href="https://t.me/joinchat/NlyH6Bch2QARZkArithKvg" rel="nofollow"><img alt="telegram" src="https://img.shields.io/badge/chat%20on-telegram-blue" style="max-width:100%;"></a>
|
15 |
+
<a href="https://raw.githubusercontent.com/GoAdminGroup/go-admin/master/LICENSE" rel="nofollow"><img src="https://img.shields.io/badge/license-Apache2.0-blue.svg" alt="license" data-canonical-src="https://img.shields.io/badge/license-Apache2.0-blue.svg" style="max-width:100%;"></a>
|
16 |
+
</p>
|
17 |
+
<p align="center">
|
18 |
+
由<a href="https://github.com/z-song/laravel-admin" target="_blank">laravel-admin</a>启发
|
19 |
+
</p>
|
20 |
+
|
21 |
+
## 前言
|
22 |
+
|
23 |
+
GoAdmin 可以帮助你的golang应用快速实现数据可视化,搭建一个数据管理平台。
|
24 |
+
|
25 |
+
[文档](http://doc.go-admin.cn/zh) | [论坛](http://discuss.go-admin.com) | [Demo](https://demo.go-admin.cn) | [上手例子](https://github.com/GoAdminGroup/example/blob/master/README_CN.md) | [GoAdmin+vue 例子](https://github.com/GoAdminGroup/goadmin-vue-example)
|
26 |
+
|
27 |
+
|
28 |
+
![](http://file.go-admin.cn/introduction/interface_3.png)
|
29 |
+
|
30 |
+
## 特征
|
31 |
+
|
32 |
+
- 🚀 **高生产效率**: 10分钟内做一个好看的管理后台
|
33 |
+
- 🎨 **主题**: 默认为adminlte,更多好看的主题正在制作中,欢迎给我们留言
|
34 |
+
- 🔢 **插件化**: 提供插件使用,真正实现一个插件解决不了问题,那就两个
|
35 |
+
- ✅ **认证**: 开箱即用的rbac认证系统
|
36 |
+
- ⚙️ **框架支持**: 支持大部分框架接入,让你更容易去上手和扩展
|
37 |
+
|
38 |
+
## 例子
|
39 |
+
|
40 |
+
- [纯golang](https://github.com/GoAdminGroup/example), 简单很少依赖
|
41 |
+
- [golang + 前端模版](https://github.com/GoAdminGroup/example_with_frontend), 你可以自己修改模版
|
42 |
+
- [golang + vue](https://github.com/GoAdminGroup/example_with_vue), 如果你会vue的话,不妨试试
|
43 |
+
|
44 |
+
## 翻译
|
45 |
+
我们需要您的帮忙: [https://github.com/GoAdminGroup/docs/issues/1](https://github.com/GoAdminGroup/docs/issues/1)
|
46 |
+
|
47 |
+
## 谁在使用GoAdmin
|
48 |
+
|
49 |
+
[评论这个issue告诉我们](https://github.com/GoAdminGroup/go-admin/issues/71).
|
50 |
+
|
51 |
+
## 使用
|
52 |
+
|
53 |
+
```shell
|
54 |
+
$ go install github.com/GoAdminGroup/adm@latest
|
55 |
+
$ mkdir new_project && cd new_project
|
56 |
+
$ adm init web -l cn
|
57 |
+
```
|
58 |
+
|
59 |
+
运行后将会启动一个网页安装程序,根据程序内容填写安装运行即可。
|
60 |
+
|
61 |
+
## 贡献
|
62 |
+
|
63 |
+
[这里有一份贡献指南](CONTRIBUTING_CN.md)
|
64 |
+
|
65 |
+
非常欢迎提pr,<strong>这里可以加入开发小组</strong>
|
66 |
+
|
67 |
+
<strong>QQ群</strong>:[874825430](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=f1LB6fiIKDi8hwR__CjB70pqylsbQsef&authKey=PsKZe803zC1VvhhFg10zbVBTAOzGbqMSU3%2BrA8mMwK3fhasaoilz9dFj7f%2FZyku6&noverify=0&group_code=874825430),记得备注加群来意
|
68 |
+
|
69 |
+
这里是[开发计划](https://github.com/GoAdminGroup/go-admin/projects)
|
70 |
+
|
71 |
+
<strong>[点击这里申请加微信群(记得备注加群)](http://quick.go-admin.cn/resource/wechat_qrcode_02.jpg)</strong>
|
72 |
+
|
73 |
+
<strong>注:在社区中如有问题提问,请务必清晰描述,包括但不限于问题详叙/问题代码/复现方法/已经尝试过的方法。</strong>
|
74 |
+
|
75 |
+
## 十分感谢
|
76 |
+
|
77 |
+
inspired by [laravel-admin](https://github.com/z-song/laravel-admin)
|
78 |
+
|
79 |
+
## 打赏
|
80 |
+
|
81 |
+
留下您的github/gitee用户名,我们将会展示在[捐赠名单](DONATION.md)中。
|
82 |
+
|
83 |
+
<img src="http://quick.go-admin.cn/official/assets/imgs/shoukuan.jpg" width="650" />
|
SECURITY.md
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Security Policy
|
2 |
+
|
3 |
+
## Reporting a Vulnerability
|
4 |
+
|
5 |
+
Please report security issues to `chg80333@gmail.com`
|
adapter/adapter.go
ADDED
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package adapter
|
6 |
+
|
7 |
+
import (
|
8 |
+
"bytes"
|
9 |
+
"fmt"
|
10 |
+
"net/http"
|
11 |
+
"net/url"
|
12 |
+
|
13 |
+
"github.com/GoAdminGroup/go-admin/context"
|
14 |
+
"github.com/GoAdminGroup/go-admin/modules/auth"
|
15 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
16 |
+
"github.com/GoAdminGroup/go-admin/modules/constant"
|
17 |
+
"github.com/GoAdminGroup/go-admin/modules/db"
|
18 |
+
"github.com/GoAdminGroup/go-admin/modules/errors"
|
19 |
+
"github.com/GoAdminGroup/go-admin/modules/logger"
|
20 |
+
"github.com/GoAdminGroup/go-admin/modules/menu"
|
21 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
22 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
23 |
+
"github.com/GoAdminGroup/go-admin/template"
|
24 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
25 |
+
)
|
26 |
+
|
27 |
+
// WebFrameWork is an interface which is used as an adapter of
|
28 |
+
// framework and goAdmin. It must implement two methods. Use registers
|
29 |
+
// the routes and the corresponding handlers. Content writes the
|
30 |
+
// response to the corresponding context of framework.
|
31 |
+
type WebFrameWork interface {
|
32 |
+
// Name return the web framework name.
|
33 |
+
Name() string
|
34 |
+
|
35 |
+
// Use method inject the plugins to the web framework engine which is the
|
36 |
+
// first parameter.
|
37 |
+
Use(app interface{}, plugins []plugins.Plugin) error
|
38 |
+
|
39 |
+
// Content add the panel html response of the given callback function to
|
40 |
+
// the web framework context which is the first parameter.
|
41 |
+
Content(ctx interface{}, fn types.GetPanelFn, fn2 context.NodeProcessor, navButtons ...types.Button)
|
42 |
+
|
43 |
+
// User get the auth user model from the given web framework context.
|
44 |
+
User(ctx interface{}) (models.UserModel, bool)
|
45 |
+
|
46 |
+
// AddHandler inject the route and handlers of GoAdmin to the web framework.
|
47 |
+
AddHandler(method, path string, handlers context.Handlers)
|
48 |
+
|
49 |
+
DisableLog()
|
50 |
+
|
51 |
+
Static(prefix, path string)
|
52 |
+
|
53 |
+
Run() error
|
54 |
+
|
55 |
+
// Helper functions
|
56 |
+
// ================================
|
57 |
+
|
58 |
+
SetApp(app interface{}) error
|
59 |
+
SetConnection(db.Connection)
|
60 |
+
GetConnection() db.Connection
|
61 |
+
SetContext(ctx interface{}) WebFrameWork
|
62 |
+
GetCookie() (string, error)
|
63 |
+
Lang() string
|
64 |
+
Path() string
|
65 |
+
Method() string
|
66 |
+
Request() *http.Request
|
67 |
+
FormParam() url.Values
|
68 |
+
Query() url.Values
|
69 |
+
IsPjax() bool
|
70 |
+
Redirect()
|
71 |
+
SetContentType()
|
72 |
+
Write(body []byte)
|
73 |
+
CookieKey() string
|
74 |
+
HTMLContentType() string
|
75 |
+
}
|
76 |
+
|
77 |
+
// BaseAdapter is a base adapter contains some helper functions.
|
78 |
+
type BaseAdapter struct {
|
79 |
+
db db.Connection
|
80 |
+
}
|
81 |
+
|
82 |
+
// SetConnection set the db connection.
|
83 |
+
func (base *BaseAdapter) SetConnection(conn db.Connection) {
|
84 |
+
base.db = conn
|
85 |
+
}
|
86 |
+
|
87 |
+
// GetConnection get the db connection.
|
88 |
+
func (base *BaseAdapter) GetConnection() db.Connection {
|
89 |
+
return base.db
|
90 |
+
}
|
91 |
+
|
92 |
+
// HTMLContentType return the default content type header.
|
93 |
+
func (*BaseAdapter) HTMLContentType() string {
|
94 |
+
return "text/html; charset=utf-8"
|
95 |
+
}
|
96 |
+
|
97 |
+
// CookieKey return the cookie key.
|
98 |
+
func (*BaseAdapter) CookieKey() string {
|
99 |
+
return auth.DefaultCookieKey
|
100 |
+
}
|
101 |
+
|
102 |
+
// GetUser is a helper function get the auth user model from the context.
|
103 |
+
func (*BaseAdapter) GetUser(ctx interface{}, wf WebFrameWork) (models.UserModel, bool) {
|
104 |
+
cookie, err := wf.SetContext(ctx).GetCookie()
|
105 |
+
|
106 |
+
if err != nil {
|
107 |
+
return models.UserModel{}, false
|
108 |
+
}
|
109 |
+
|
110 |
+
user, exist := auth.GetCurUser(cookie, wf.GetConnection())
|
111 |
+
return user.ReleaseConn(), exist
|
112 |
+
}
|
113 |
+
|
114 |
+
// GetUse is a helper function adds the plugins to the framework.
|
115 |
+
func (*BaseAdapter) GetUse(app interface{}, plugin []plugins.Plugin, wf WebFrameWork) error {
|
116 |
+
if err := wf.SetApp(app); err != nil {
|
117 |
+
return err
|
118 |
+
}
|
119 |
+
|
120 |
+
for _, plug := range plugin {
|
121 |
+
for path, handlers := range plug.GetHandler() {
|
122 |
+
if plug.Prefix() == "" {
|
123 |
+
wf.AddHandler(path.Method, path.URL, handlers)
|
124 |
+
} else {
|
125 |
+
wf.AddHandler(path.Method, config.Url("/"+plug.Prefix()+path.URL), handlers)
|
126 |
+
}
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
return nil
|
131 |
+
}
|
132 |
+
|
133 |
+
func (*BaseAdapter) Run() error { panic("not implement") }
|
134 |
+
func (*BaseAdapter) DisableLog() { panic("not implement") }
|
135 |
+
func (*BaseAdapter) Static(_, _ string) { panic("not implement") }
|
136 |
+
|
137 |
+
// GetContent is a helper function of adapter.Content
|
138 |
+
func (base *BaseAdapter) GetContent(ctx interface{}, getPanelFn types.GetPanelFn, wf WebFrameWork,
|
139 |
+
navButtons types.Buttons, fn context.NodeProcessor) {
|
140 |
+
|
141 |
+
var (
|
142 |
+
newBase = wf.SetContext(ctx)
|
143 |
+
cookie, hasError = newBase.GetCookie()
|
144 |
+
)
|
145 |
+
|
146 |
+
if hasError != nil || cookie == "" {
|
147 |
+
newBase.Redirect()
|
148 |
+
return
|
149 |
+
}
|
150 |
+
|
151 |
+
user, authSuccess := auth.GetCurUser(cookie, wf.GetConnection())
|
152 |
+
|
153 |
+
if !authSuccess {
|
154 |
+
newBase.Redirect()
|
155 |
+
return
|
156 |
+
}
|
157 |
+
|
158 |
+
var (
|
159 |
+
panel types.Panel
|
160 |
+
err error
|
161 |
+
)
|
162 |
+
|
163 |
+
gctx := context.NewContext(newBase.Request())
|
164 |
+
|
165 |
+
if !auth.CheckPermissions(user, newBase.Path(), newBase.Method(), newBase.FormParam()) {
|
166 |
+
panel = template.WarningPanel(gctx, errors.NoPermission, template.NoPermission403Page)
|
167 |
+
} else {
|
168 |
+
panel, err = getPanelFn(ctx)
|
169 |
+
if err != nil {
|
170 |
+
panel = template.WarningPanel(gctx, err.Error())
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
+
fn(panel.Callbacks...)
|
175 |
+
|
176 |
+
tmpl, tmplName := template.Default(gctx).GetTemplate(newBase.IsPjax())
|
177 |
+
|
178 |
+
buf := new(bytes.Buffer)
|
179 |
+
hasError = tmpl.ExecuteTemplate(buf, tmplName, types.NewPage(gctx, &types.NewPageParam{
|
180 |
+
User: user,
|
181 |
+
Menu: menu.GetGlobalMenu(user, wf.GetConnection(), newBase.Lang()).SetActiveClass(config.URLRemovePrefix(newBase.Path())),
|
182 |
+
Panel: panel.GetContent(config.IsProductionEnvironment()),
|
183 |
+
Assets: template.GetComponentAssetImportHTML(gctx),
|
184 |
+
Buttons: navButtons.CheckPermission(user),
|
185 |
+
TmplHeadHTML: template.Default(gctx).GetHeadHTML(),
|
186 |
+
TmplFootJS: template.Default(gctx).GetFootJS(),
|
187 |
+
Iframe: newBase.Query().Get(constant.IframeKey) == "true",
|
188 |
+
}))
|
189 |
+
|
190 |
+
if hasError != nil {
|
191 |
+
logger.Error(fmt.Sprintf("error: %s adapter content, ", newBase.Name()), hasError)
|
192 |
+
}
|
193 |
+
|
194 |
+
newBase.SetContentType()
|
195 |
+
newBase.Write(buf.Bytes())
|
196 |
+
}
|
adapter/beego/beego.go
ADDED
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package beego
|
6 |
+
|
7 |
+
import (
|
8 |
+
"bytes"
|
9 |
+
"errors"
|
10 |
+
"net/http"
|
11 |
+
"net/url"
|
12 |
+
"strings"
|
13 |
+
|
14 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
15 |
+
gctx "github.com/GoAdminGroup/go-admin/context"
|
16 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
17 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
18 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
19 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
20 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant"
|
21 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
22 |
+
"github.com/astaxie/beego"
|
23 |
+
"github.com/astaxie/beego/context"
|
24 |
+
)
|
25 |
+
|
26 |
+
// Beego structure value is a Beego GoAdmin adapter.
|
27 |
+
type Beego struct {
|
28 |
+
adapter.BaseAdapter
|
29 |
+
ctx *context.Context
|
30 |
+
app *beego.App
|
31 |
+
}
|
32 |
+
|
33 |
+
func init() {
|
34 |
+
engine.Register(new(Beego))
|
35 |
+
}
|
36 |
+
|
37 |
+
// User implements the method Adapter.User.
|
38 |
+
func (bee *Beego) User(ctx interface{}) (models.UserModel, bool) {
|
39 |
+
return bee.GetUser(ctx, bee)
|
40 |
+
}
|
41 |
+
|
42 |
+
// Use implements the method Adapter.Use.
|
43 |
+
func (bee *Beego) Use(app interface{}, plugs []plugins.Plugin) error {
|
44 |
+
return bee.GetUse(app, plugs, bee)
|
45 |
+
}
|
46 |
+
|
47 |
+
// Content implements the method Adapter.Content.
|
48 |
+
func (bee *Beego) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn gctx.NodeProcessor, navButtons ...types.Button) {
|
49 |
+
bee.GetContent(ctx, getPanelFn, bee, navButtons, fn)
|
50 |
+
}
|
51 |
+
|
52 |
+
type HandlerFunc func(ctx *context.Context) (types.Panel, error)
|
53 |
+
|
54 |
+
func Content(handler HandlerFunc) beego.FilterFunc {
|
55 |
+
return func(ctx *context.Context) {
|
56 |
+
engine.Content(ctx, func(ctx interface{}) (types.Panel, error) {
|
57 |
+
return handler(ctx.(*context.Context))
|
58 |
+
})
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
// SetApp implements the method Adapter.SetApp.
|
63 |
+
func (bee *Beego) SetApp(app interface{}) error {
|
64 |
+
var (
|
65 |
+
eng *beego.App
|
66 |
+
ok bool
|
67 |
+
)
|
68 |
+
if eng, ok = app.(*beego.App); !ok {
|
69 |
+
return errors.New("beego adapter SetApp: wrong parameter")
|
70 |
+
}
|
71 |
+
bee.app = eng
|
72 |
+
return nil
|
73 |
+
}
|
74 |
+
|
75 |
+
// AddHandler implements the method Adapter.AddHandler.
|
76 |
+
func (bee *Beego) AddHandler(method, path string, handlers gctx.Handlers) {
|
77 |
+
bee.app.Handlers.AddMethod(method, path, func(c *context.Context) {
|
78 |
+
for key, value := range c.Input.Params() {
|
79 |
+
if c.Request.URL.RawQuery == "" {
|
80 |
+
c.Request.URL.RawQuery += strings.ReplaceAll(key, ":", "") + "=" + value
|
81 |
+
} else {
|
82 |
+
c.Request.URL.RawQuery += "&" + strings.ReplaceAll(key, ":", "") + "=" + value
|
83 |
+
}
|
84 |
+
}
|
85 |
+
ctx := gctx.NewContext(c.Request)
|
86 |
+
ctx.SetHandlers(handlers).Next()
|
87 |
+
for key, head := range ctx.Response.Header {
|
88 |
+
c.ResponseWriter.Header().Add(key, head[0])
|
89 |
+
}
|
90 |
+
c.ResponseWriter.WriteHeader(ctx.Response.StatusCode)
|
91 |
+
if ctx.Response.Body != nil {
|
92 |
+
buf := new(bytes.Buffer)
|
93 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
94 |
+
c.WriteString(buf.String())
|
95 |
+
}
|
96 |
+
})
|
97 |
+
}
|
98 |
+
|
99 |
+
// Name implements the method Adapter.Name.
|
100 |
+
func (*Beego) Name() string {
|
101 |
+
return "beego"
|
102 |
+
}
|
103 |
+
|
104 |
+
// SetContext implements the method Adapter.SetContext.
|
105 |
+
func (*Beego) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
106 |
+
var (
|
107 |
+
ctx *context.Context
|
108 |
+
ok bool
|
109 |
+
)
|
110 |
+
if ctx, ok = contextInterface.(*context.Context); !ok {
|
111 |
+
panic("beego adapter SetContext: wrong parameter")
|
112 |
+
}
|
113 |
+
return &Beego{ctx: ctx}
|
114 |
+
}
|
115 |
+
|
116 |
+
// Redirect implements the method Adapter.Redirect.
|
117 |
+
func (bee *Beego) Redirect() {
|
118 |
+
bee.ctx.Redirect(http.StatusFound, config.Url(config.GetLoginUrl()))
|
119 |
+
}
|
120 |
+
|
121 |
+
// SetContentType implements the method Adapter.SetContentType.
|
122 |
+
func (bee *Beego) SetContentType() {
|
123 |
+
bee.ctx.ResponseWriter.Header().Set("Content-Type", bee.HTMLContentType())
|
124 |
+
}
|
125 |
+
|
126 |
+
// Write implements the method Adapter.Write.
|
127 |
+
func (bee *Beego) Write(body []byte) {
|
128 |
+
_, _ = bee.ctx.ResponseWriter.Write(body)
|
129 |
+
}
|
130 |
+
|
131 |
+
// GetCookie implements the method Adapter.GetCookie.
|
132 |
+
func (bee *Beego) GetCookie() (string, error) {
|
133 |
+
return bee.ctx.GetCookie(bee.CookieKey()), nil
|
134 |
+
}
|
135 |
+
|
136 |
+
// Lang implements the method Adapter.Lang.
|
137 |
+
func (bee *Beego) Lang() string {
|
138 |
+
return bee.ctx.Request.URL.Query().Get("__ga_lang")
|
139 |
+
}
|
140 |
+
|
141 |
+
// Path implements the method Adapter.Path.
|
142 |
+
func (bee *Beego) Path() string {
|
143 |
+
return bee.ctx.Request.URL.Path
|
144 |
+
}
|
145 |
+
|
146 |
+
// Method implements the method Adapter.Method.
|
147 |
+
func (bee *Beego) Method() string {
|
148 |
+
return bee.ctx.Request.Method
|
149 |
+
}
|
150 |
+
|
151 |
+
// FormParam implements the method Adapter.FormParam.
|
152 |
+
func (bee *Beego) FormParam() url.Values {
|
153 |
+
_ = bee.ctx.Request.ParseMultipartForm(32 << 20)
|
154 |
+
return bee.ctx.Request.PostForm
|
155 |
+
}
|
156 |
+
|
157 |
+
// IsPjax implements the method Adapter.IsPjax.
|
158 |
+
func (bee *Beego) IsPjax() bool {
|
159 |
+
return bee.ctx.Request.Header.Get(constant.PjaxHeader) == "true"
|
160 |
+
}
|
161 |
+
|
162 |
+
// Query implements the method Adapter.Query.
|
163 |
+
func (bee *Beego) Query() url.Values {
|
164 |
+
return bee.ctx.Request.URL.Query()
|
165 |
+
}
|
166 |
+
|
167 |
+
// Request implements the method Adapter.Request.
|
168 |
+
func (bee *Beego) Request() *http.Request {
|
169 |
+
return bee.ctx.Request
|
170 |
+
}
|
adapter/beego2/beego2.go
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package beego2
|
2 |
+
|
3 |
+
import (
|
4 |
+
"bytes"
|
5 |
+
"errors"
|
6 |
+
"net/http"
|
7 |
+
"net/url"
|
8 |
+
"strings"
|
9 |
+
|
10 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
11 |
+
gctx "github.com/GoAdminGroup/go-admin/context"
|
12 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
13 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
14 |
+
"github.com/GoAdminGroup/go-admin/modules/constant"
|
15 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
16 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
17 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
18 |
+
"github.com/beego/beego/v2/server/web"
|
19 |
+
"github.com/beego/beego/v2/server/web/context"
|
20 |
+
)
|
21 |
+
|
22 |
+
type Beego2 struct {
|
23 |
+
adapter.BaseAdapter
|
24 |
+
ctx *context.Context
|
25 |
+
app *web.HttpServer
|
26 |
+
}
|
27 |
+
|
28 |
+
func init() {
|
29 |
+
engine.Register(new(Beego2))
|
30 |
+
}
|
31 |
+
|
32 |
+
func (*Beego2) Name() string {
|
33 |
+
return "beego2"
|
34 |
+
}
|
35 |
+
|
36 |
+
func (bee2 *Beego2) Use(app interface{}, plugins []plugins.Plugin) error {
|
37 |
+
return bee2.GetUse(app, plugins, bee2)
|
38 |
+
}
|
39 |
+
|
40 |
+
func (bee2 *Beego2) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn gctx.NodeProcessor, navButtons ...types.Button) {
|
41 |
+
bee2.GetContent(ctx, getPanelFn, bee2, navButtons, fn)
|
42 |
+
}
|
43 |
+
|
44 |
+
func (bee2 *Beego2) User(ctx interface{}) (models.UserModel, bool) {
|
45 |
+
return bee2.GetUser(ctx, bee2)
|
46 |
+
}
|
47 |
+
|
48 |
+
func (bee2 *Beego2) AddHandler(method, path string, handlers gctx.Handlers) {
|
49 |
+
bee2.app.Handlers.AddMethod(method, path, func(c *context.Context) {
|
50 |
+
for key, value := range c.Input.Params() {
|
51 |
+
if c.Request.URL.RawQuery == "" {
|
52 |
+
c.Request.URL.RawQuery += strings.ReplaceAll(key, ":", "") + "=" + value
|
53 |
+
} else {
|
54 |
+
c.Request.URL.RawQuery += "&" + strings.ReplaceAll(key, ":", "") + "=" + value
|
55 |
+
}
|
56 |
+
}
|
57 |
+
ctx := gctx.NewContext(c.Request)
|
58 |
+
ctx.SetHandlers(handlers).Next()
|
59 |
+
for key, head := range ctx.Response.Header {
|
60 |
+
c.ResponseWriter.Header().Add(key, head[0])
|
61 |
+
}
|
62 |
+
c.ResponseWriter.WriteHeader(ctx.Response.StatusCode)
|
63 |
+
if ctx.Response.Body != nil {
|
64 |
+
buf := new(bytes.Buffer)
|
65 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
66 |
+
c.WriteString(buf.String())
|
67 |
+
}
|
68 |
+
})
|
69 |
+
}
|
70 |
+
|
71 |
+
func (bee2 *Beego2) SetApp(app interface{}) error {
|
72 |
+
var (
|
73 |
+
eng *web.HttpServer
|
74 |
+
ok bool
|
75 |
+
)
|
76 |
+
if eng, ok = app.(*web.HttpServer); !ok {
|
77 |
+
return errors.New("beego2 adapter SetApp: wrong parameter")
|
78 |
+
}
|
79 |
+
bee2.app = eng
|
80 |
+
return nil
|
81 |
+
}
|
82 |
+
|
83 |
+
func (*Beego2) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
84 |
+
var (
|
85 |
+
ctx *context.Context
|
86 |
+
ok bool
|
87 |
+
)
|
88 |
+
if ctx, ok = contextInterface.(*context.Context); !ok {
|
89 |
+
panic("beego2 adapter SetContext: wrong parameter")
|
90 |
+
}
|
91 |
+
return &Beego2{ctx: ctx}
|
92 |
+
}
|
93 |
+
|
94 |
+
func (bee2 *Beego2) GetCookie() (string, error) {
|
95 |
+
return bee2.ctx.GetCookie(bee2.CookieKey()), nil
|
96 |
+
}
|
97 |
+
|
98 |
+
func (bee2 *Beego2) Lang() string {
|
99 |
+
return bee2.ctx.Request.URL.Query().Get("__ga_lang")
|
100 |
+
}
|
101 |
+
|
102 |
+
func (bee2 *Beego2) Path() string {
|
103 |
+
return bee2.ctx.Request.URL.Path
|
104 |
+
}
|
105 |
+
|
106 |
+
func (bee2 *Beego2) Method() string {
|
107 |
+
return bee2.ctx.Request.Method
|
108 |
+
}
|
109 |
+
|
110 |
+
func (bee2 *Beego2) FormParam() url.Values {
|
111 |
+
_ = bee2.ctx.Request.ParseMultipartForm(32 << 20)
|
112 |
+
return bee2.ctx.Request.PostForm
|
113 |
+
}
|
114 |
+
|
115 |
+
func (bee2 *Beego2) Query() url.Values {
|
116 |
+
return bee2.ctx.Request.URL.Query()
|
117 |
+
}
|
118 |
+
|
119 |
+
func (bee2 *Beego2) IsPjax() bool {
|
120 |
+
return bee2.ctx.Request.Header.Get(constant.PjaxHeader) == "true"
|
121 |
+
}
|
122 |
+
|
123 |
+
func (bee2 *Beego2) Redirect() {
|
124 |
+
bee2.ctx.Redirect(http.StatusFound, config.Url(config.GetLoginUrl()))
|
125 |
+
}
|
126 |
+
|
127 |
+
func (bee2 *Beego2) SetContentType() {
|
128 |
+
bee2.ctx.ResponseWriter.Header().Set("Content-Type", bee2.HTMLContentType())
|
129 |
+
}
|
130 |
+
|
131 |
+
func (bee2 *Beego2) Write(body []byte) {
|
132 |
+
_, _ = bee2.ctx.ResponseWriter.Write(body)
|
133 |
+
}
|
134 |
+
|
135 |
+
// Request implements the method Adapter.Request.
|
136 |
+
func (bee2 *Beego2) Request() *http.Request {
|
137 |
+
return bee2.ctx.Request
|
138 |
+
}
|
adapter/buffalo/buffalo.go
ADDED
@@ -0,0 +1,214 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package buffalo
|
6 |
+
|
7 |
+
import (
|
8 |
+
"bytes"
|
9 |
+
"errors"
|
10 |
+
"net/http"
|
11 |
+
neturl "net/url"
|
12 |
+
"regexp"
|
13 |
+
"strings"
|
14 |
+
|
15 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
16 |
+
"github.com/GoAdminGroup/go-admin/context"
|
17 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
18 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
19 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
20 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
21 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant"
|
22 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
23 |
+
"github.com/gobuffalo/buffalo"
|
24 |
+
)
|
25 |
+
|
26 |
+
// Buffalo structure value is a Buffalo GoAdmin adapter.
|
27 |
+
type Buffalo struct {
|
28 |
+
adapter.BaseAdapter
|
29 |
+
ctx buffalo.Context
|
30 |
+
app *buffalo.App
|
31 |
+
}
|
32 |
+
|
33 |
+
func init() {
|
34 |
+
engine.Register(new(Buffalo))
|
35 |
+
}
|
36 |
+
|
37 |
+
// User implements the method Adapter.User.
|
38 |
+
func (bu *Buffalo) User(ctx interface{}) (models.UserModel, bool) {
|
39 |
+
return bu.GetUser(ctx, bu)
|
40 |
+
}
|
41 |
+
|
42 |
+
// Use implements the method Adapter.Use.
|
43 |
+
func (bu *Buffalo) Use(app interface{}, plugs []plugins.Plugin) error {
|
44 |
+
return bu.GetUse(app, plugs, bu)
|
45 |
+
}
|
46 |
+
|
47 |
+
// Content implements the method Adapter.Content.
|
48 |
+
func (bu *Buffalo) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) {
|
49 |
+
bu.GetContent(ctx, getPanelFn, bu, btns, fn)
|
50 |
+
}
|
51 |
+
|
52 |
+
type HandlerFunc func(ctx buffalo.Context) (types.Panel, error)
|
53 |
+
|
54 |
+
func Content(handler HandlerFunc) buffalo.Handler {
|
55 |
+
return func(ctx buffalo.Context) error {
|
56 |
+
engine.Content(ctx, func(ctx interface{}) (types.Panel, error) {
|
57 |
+
return handler(ctx.(buffalo.Context))
|
58 |
+
})
|
59 |
+
return nil
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
// SetApp implements the method Adapter.SetApp.
|
64 |
+
func (bu *Buffalo) SetApp(app interface{}) error {
|
65 |
+
var (
|
66 |
+
eng *buffalo.App
|
67 |
+
ok bool
|
68 |
+
)
|
69 |
+
if eng, ok = app.(*buffalo.App); !ok {
|
70 |
+
return errors.New("buffalo adapter SetApp: wrong parameter")
|
71 |
+
}
|
72 |
+
bu.app = eng
|
73 |
+
return nil
|
74 |
+
}
|
75 |
+
|
76 |
+
// AddHandler implements the method Adapter.AddHandler.
|
77 |
+
func (bu *Buffalo) AddHandler(method, path string, handlers context.Handlers) {
|
78 |
+
url := path
|
79 |
+
reg1 := regexp.MustCompile(":(.*?)/")
|
80 |
+
reg2 := regexp.MustCompile(":(.*?)$")
|
81 |
+
url = reg1.ReplaceAllString(url, "{$1}/")
|
82 |
+
url = reg2.ReplaceAllString(url, "{$1}")
|
83 |
+
|
84 |
+
getHandleFunc(bu.app, strings.ToUpper(method))(url, func(c buffalo.Context) error {
|
85 |
+
|
86 |
+
if c.Request().URL.Path[len(c.Request().URL.Path)-1] == '/' {
|
87 |
+
c.Request().URL.Path = c.Request().URL.Path[:len(c.Request().URL.Path)-1]
|
88 |
+
}
|
89 |
+
|
90 |
+
ctx := context.NewContext(c.Request())
|
91 |
+
|
92 |
+
params := c.Params().(neturl.Values)
|
93 |
+
|
94 |
+
for key, param := range params {
|
95 |
+
if c.Request().URL.RawQuery == "" {
|
96 |
+
c.Request().URL.RawQuery += strings.ReplaceAll(key, ":", "") + "=" + param[0]
|
97 |
+
} else {
|
98 |
+
c.Request().URL.RawQuery += "&" + strings.ReplaceAll(key, ":", "") + "=" + param[0]
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
ctx.SetHandlers(handlers).Next()
|
103 |
+
for key, head := range ctx.Response.Header {
|
104 |
+
c.Response().Header().Set(key, head[0])
|
105 |
+
}
|
106 |
+
if ctx.Response.Body != nil {
|
107 |
+
buf := new(bytes.Buffer)
|
108 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
109 |
+
c.Response().WriteHeader(ctx.Response.StatusCode)
|
110 |
+
_, _ = c.Response().Write(buf.Bytes())
|
111 |
+
} else {
|
112 |
+
c.Response().WriteHeader(ctx.Response.StatusCode)
|
113 |
+
}
|
114 |
+
return nil
|
115 |
+
})
|
116 |
+
}
|
117 |
+
|
118 |
+
// HandleFun is type of route methods of buffalo.
|
119 |
+
type HandleFun func(p string, h buffalo.Handler) *buffalo.RouteInfo
|
120 |
+
|
121 |
+
func getHandleFunc(eng *buffalo.App, method string) HandleFun {
|
122 |
+
switch method {
|
123 |
+
case "GET":
|
124 |
+
return eng.GET
|
125 |
+
case "POST":
|
126 |
+
return eng.POST
|
127 |
+
case "PUT":
|
128 |
+
return eng.PUT
|
129 |
+
case "DELETE":
|
130 |
+
return eng.DELETE
|
131 |
+
case "HEAD":
|
132 |
+
return eng.HEAD
|
133 |
+
case "OPTIONS":
|
134 |
+
return eng.OPTIONS
|
135 |
+
case "PATCH":
|
136 |
+
return eng.PATCH
|
137 |
+
default:
|
138 |
+
panic("wrong method")
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
// Name implements the method Adapter.Name.
|
143 |
+
func (*Buffalo) Name() string {
|
144 |
+
return "buffalo"
|
145 |
+
}
|
146 |
+
|
147 |
+
// SetContext implements the method Adapter.SetContext.
|
148 |
+
func (*Buffalo) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
149 |
+
var (
|
150 |
+
ctx buffalo.Context
|
151 |
+
ok bool
|
152 |
+
)
|
153 |
+
if ctx, ok = contextInterface.(buffalo.Context); !ok {
|
154 |
+
panic("buffalo adapter SetContext: wrong parameter")
|
155 |
+
}
|
156 |
+
return &Buffalo{ctx: ctx}
|
157 |
+
}
|
158 |
+
|
159 |
+
// Redirect implements the method Adapter.Redirect.
|
160 |
+
func (bu *Buffalo) Redirect() {
|
161 |
+
_ = bu.ctx.Redirect(http.StatusFound, config.Url(config.GetLoginUrl()))
|
162 |
+
}
|
163 |
+
|
164 |
+
// SetContentType implements the method Adapter.SetContentType.
|
165 |
+
func (bu *Buffalo) SetContentType() {
|
166 |
+
bu.ctx.Response().Header().Set("Content-Type", bu.HTMLContentType())
|
167 |
+
}
|
168 |
+
|
169 |
+
// Write implements the method Adapter.Write.
|
170 |
+
func (bu *Buffalo) Write(body []byte) {
|
171 |
+
bu.ctx.Response().WriteHeader(http.StatusOK)
|
172 |
+
_, _ = bu.ctx.Response().Write(body)
|
173 |
+
}
|
174 |
+
|
175 |
+
// GetCookie implements the method Adapter.GetCookie.
|
176 |
+
func (bu *Buffalo) GetCookie() (string, error) {
|
177 |
+
return bu.ctx.Cookies().Get(bu.CookieKey())
|
178 |
+
}
|
179 |
+
|
180 |
+
// Lang implements the method Adapter.Lang.
|
181 |
+
func (bu *Buffalo) Lang() string {
|
182 |
+
return bu.ctx.Request().URL.Query().Get("__ga_lang")
|
183 |
+
}
|
184 |
+
|
185 |
+
// Path implements the method Adapter.Path.
|
186 |
+
func (bu *Buffalo) Path() string {
|
187 |
+
return bu.ctx.Request().URL.Path
|
188 |
+
}
|
189 |
+
|
190 |
+
// Method implements the method Adapter.Method.
|
191 |
+
func (bu *Buffalo) Method() string {
|
192 |
+
return bu.ctx.Request().Method
|
193 |
+
}
|
194 |
+
|
195 |
+
// FormParam implements the method Adapter.FormParam.
|
196 |
+
func (bu *Buffalo) FormParam() neturl.Values {
|
197 |
+
_ = bu.ctx.Request().ParseMultipartForm(32 << 20)
|
198 |
+
return bu.ctx.Request().PostForm
|
199 |
+
}
|
200 |
+
|
201 |
+
// IsPjax implements the method Adapter.IsPjax.
|
202 |
+
func (bu *Buffalo) IsPjax() bool {
|
203 |
+
return bu.ctx.Request().Header.Get(constant.PjaxHeader) == "true"
|
204 |
+
}
|
205 |
+
|
206 |
+
// Query implements the method Adapter.Query.
|
207 |
+
func (bu *Buffalo) Query() neturl.Values {
|
208 |
+
return bu.ctx.Request().URL.Query()
|
209 |
+
}
|
210 |
+
|
211 |
+
// Request implements the method Adapter.Request.
|
212 |
+
func (bu *Buffalo) Request() *http.Request {
|
213 |
+
return bu.ctx.Request()
|
214 |
+
}
|
adapter/chi/chi.go
ADDED
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package chi
|
6 |
+
|
7 |
+
import (
|
8 |
+
"bytes"
|
9 |
+
"errors"
|
10 |
+
"net/http"
|
11 |
+
"net/url"
|
12 |
+
"regexp"
|
13 |
+
"strings"
|
14 |
+
|
15 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
16 |
+
"github.com/GoAdminGroup/go-admin/context"
|
17 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
18 |
+
cfg "github.com/GoAdminGroup/go-admin/modules/config"
|
19 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
20 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
21 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant"
|
22 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
23 |
+
"github.com/go-chi/chi"
|
24 |
+
)
|
25 |
+
|
26 |
+
// Chi structure value is a Chi GoAdmin adapter.
|
27 |
+
type Chi struct {
|
28 |
+
adapter.BaseAdapter
|
29 |
+
ctx Context
|
30 |
+
app *chi.Mux
|
31 |
+
}
|
32 |
+
|
33 |
+
func init() {
|
34 |
+
engine.Register(new(Chi))
|
35 |
+
}
|
36 |
+
|
37 |
+
// User implements the method Adapter.User.
|
38 |
+
func (ch *Chi) User(ctx interface{}) (models.UserModel, bool) {
|
39 |
+
return ch.GetUser(ctx, ch)
|
40 |
+
}
|
41 |
+
|
42 |
+
// Use implements the method Adapter.Use.
|
43 |
+
func (ch *Chi) Use(app interface{}, plugs []plugins.Plugin) error {
|
44 |
+
return ch.GetUse(app, plugs, ch)
|
45 |
+
}
|
46 |
+
|
47 |
+
// Content implements the method Adapter.Content.
|
48 |
+
func (ch *Chi) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) {
|
49 |
+
ch.GetContent(ctx, getPanelFn, ch, btns, fn)
|
50 |
+
}
|
51 |
+
|
52 |
+
type HandlerFunc func(ctx Context) (types.Panel, error)
|
53 |
+
|
54 |
+
func Content(handler HandlerFunc) http.HandlerFunc {
|
55 |
+
return func(writer http.ResponseWriter, request *http.Request) {
|
56 |
+
ctx := Context{
|
57 |
+
Request: request,
|
58 |
+
Response: writer,
|
59 |
+
}
|
60 |
+
engine.Content(ctx, func(ctx interface{}) (types.Panel, error) {
|
61 |
+
return handler(ctx.(Context))
|
62 |
+
})
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
// SetApp implements the method Adapter.SetApp.
|
67 |
+
func (ch *Chi) SetApp(app interface{}) error {
|
68 |
+
var (
|
69 |
+
eng *chi.Mux
|
70 |
+
ok bool
|
71 |
+
)
|
72 |
+
if eng, ok = app.(*chi.Mux); !ok {
|
73 |
+
return errors.New("chi adapter SetApp: wrong parameter")
|
74 |
+
}
|
75 |
+
ch.app = eng
|
76 |
+
return nil
|
77 |
+
}
|
78 |
+
|
79 |
+
// AddHandler implements the method Adapter.AddHandler.
|
80 |
+
func (ch *Chi) AddHandler(method, path string, handlers context.Handlers) {
|
81 |
+
url := path
|
82 |
+
reg1 := regexp.MustCompile(":(.*?)/")
|
83 |
+
reg2 := regexp.MustCompile(":(.*?)$")
|
84 |
+
url = reg1.ReplaceAllString(url, "{$1}/")
|
85 |
+
url = reg2.ReplaceAllString(url, "{$1}")
|
86 |
+
|
87 |
+
if len(url) > 1 && url[0] == '/' && url[1] == '/' {
|
88 |
+
url = url[1:]
|
89 |
+
}
|
90 |
+
|
91 |
+
getHandleFunc(ch.app, strings.ToUpper(method))(url, func(w http.ResponseWriter, r *http.Request) {
|
92 |
+
|
93 |
+
if r.URL.Path[len(r.URL.Path)-1] == '/' {
|
94 |
+
r.URL.Path = r.URL.Path[:len(r.URL.Path)-1]
|
95 |
+
}
|
96 |
+
|
97 |
+
ctx := context.NewContext(r)
|
98 |
+
|
99 |
+
params := chi.RouteContext(r.Context()).URLParams
|
100 |
+
|
101 |
+
for i := 0; i < len(params.Values); i++ {
|
102 |
+
if r.URL.RawQuery == "" {
|
103 |
+
r.URL.RawQuery += strings.ReplaceAll(params.Keys[i], ":", "") + "=" + params.Values[i]
|
104 |
+
} else {
|
105 |
+
r.URL.RawQuery += "&" + strings.ReplaceAll(params.Keys[i], ":", "") + "=" + params.Values[i]
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
ctx.SetHandlers(handlers).Next()
|
110 |
+
for key, head := range ctx.Response.Header {
|
111 |
+
w.Header().Set(key, head[0])
|
112 |
+
}
|
113 |
+
if ctx.Response.Body != nil {
|
114 |
+
buf := new(bytes.Buffer)
|
115 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
116 |
+
w.WriteHeader(ctx.Response.StatusCode)
|
117 |
+
_, _ = w.Write(buf.Bytes())
|
118 |
+
} else {
|
119 |
+
w.WriteHeader(ctx.Response.StatusCode)
|
120 |
+
}
|
121 |
+
})
|
122 |
+
}
|
123 |
+
|
124 |
+
// HandleFun is type of route methods of chi.
|
125 |
+
type HandleFun func(pattern string, handlerFn http.HandlerFunc)
|
126 |
+
|
127 |
+
func getHandleFunc(eng *chi.Mux, method string) HandleFun {
|
128 |
+
switch method {
|
129 |
+
case "GET":
|
130 |
+
return eng.Get
|
131 |
+
case "POST":
|
132 |
+
return eng.Post
|
133 |
+
case "PUT":
|
134 |
+
return eng.Put
|
135 |
+
case "DELETE":
|
136 |
+
return eng.Delete
|
137 |
+
case "HEAD":
|
138 |
+
return eng.Head
|
139 |
+
case "OPTIONS":
|
140 |
+
return eng.Options
|
141 |
+
case "PATCH":
|
142 |
+
return eng.Patch
|
143 |
+
default:
|
144 |
+
panic("wrong method")
|
145 |
+
}
|
146 |
+
}
|
147 |
+
|
148 |
+
// Context wraps the Request and Response object of Chi.
|
149 |
+
type Context struct {
|
150 |
+
Request *http.Request
|
151 |
+
Response http.ResponseWriter
|
152 |
+
}
|
153 |
+
|
154 |
+
// SetContext implements the method Adapter.SetContext.
|
155 |
+
func (*Chi) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
156 |
+
var (
|
157 |
+
ctx Context
|
158 |
+
ok bool
|
159 |
+
)
|
160 |
+
if ctx, ok = contextInterface.(Context); !ok {
|
161 |
+
panic("chi adapter SetContext: wrong parameter")
|
162 |
+
}
|
163 |
+
return &Chi{ctx: ctx}
|
164 |
+
}
|
165 |
+
|
166 |
+
// Name implements the method Adapter.Name.
|
167 |
+
func (*Chi) Name() string {
|
168 |
+
return "chi"
|
169 |
+
}
|
170 |
+
|
171 |
+
// Redirect implements the method Adapter.Redirect.
|
172 |
+
func (ch *Chi) Redirect() {
|
173 |
+
http.Redirect(ch.ctx.Response, ch.ctx.Request, cfg.Url(cfg.GetLoginUrl()), http.StatusFound)
|
174 |
+
}
|
175 |
+
|
176 |
+
// SetContentType implements the method Adapter.SetContentType.
|
177 |
+
func (ch *Chi) SetContentType() {
|
178 |
+
ch.ctx.Response.Header().Set("Content-Type", ch.HTMLContentType())
|
179 |
+
}
|
180 |
+
|
181 |
+
// Write implements the method Adapter.Write.
|
182 |
+
func (ch *Chi) Write(body []byte) {
|
183 |
+
ch.ctx.Response.WriteHeader(http.StatusOK)
|
184 |
+
_, _ = ch.ctx.Response.Write(body)
|
185 |
+
}
|
186 |
+
|
187 |
+
// GetCookie implements the method Adapter.GetCookie.
|
188 |
+
func (ch *Chi) GetCookie() (string, error) {
|
189 |
+
cookie, err := ch.ctx.Request.Cookie(ch.CookieKey())
|
190 |
+
if err != nil {
|
191 |
+
return "", err
|
192 |
+
}
|
193 |
+
return cookie.Value, err
|
194 |
+
}
|
195 |
+
|
196 |
+
// Lang implements the method Adapter.Lang.
|
197 |
+
func (ch *Chi) Lang() string {
|
198 |
+
return ch.ctx.Request.URL.Query().Get("__ga_lang")
|
199 |
+
}
|
200 |
+
|
201 |
+
// Path implements the method Adapter.Path.
|
202 |
+
func (ch *Chi) Path() string {
|
203 |
+
return ch.ctx.Request.URL.Path
|
204 |
+
}
|
205 |
+
|
206 |
+
// Method implements the method Adapter.Method.
|
207 |
+
func (ch *Chi) Method() string {
|
208 |
+
return ch.ctx.Request.Method
|
209 |
+
}
|
210 |
+
|
211 |
+
// FormParam implements the method Adapter.FormParam.
|
212 |
+
func (ch *Chi) FormParam() url.Values {
|
213 |
+
_ = ch.ctx.Request.ParseMultipartForm(32 << 20)
|
214 |
+
return ch.ctx.Request.PostForm
|
215 |
+
}
|
216 |
+
|
217 |
+
// IsPjax implements the method Adapter.IsPjax.
|
218 |
+
func (ch *Chi) IsPjax() bool {
|
219 |
+
return ch.ctx.Request.Header.Get(constant.PjaxHeader) == "true"
|
220 |
+
}
|
221 |
+
|
222 |
+
// Query implements the method Adapter.Query.
|
223 |
+
func (ch *Chi) Query() url.Values {
|
224 |
+
return ch.ctx.Request.URL.Query()
|
225 |
+
}
|
226 |
+
|
227 |
+
// Request implements the method Adapter.Request.
|
228 |
+
func (ch *Chi) Request() *http.Request {
|
229 |
+
return ch.ctx.Request
|
230 |
+
}
|
adapter/echo/echo.go
ADDED
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package echo
|
6 |
+
|
7 |
+
import (
|
8 |
+
"bytes"
|
9 |
+
"errors"
|
10 |
+
"net/http"
|
11 |
+
"net/url"
|
12 |
+
"strings"
|
13 |
+
|
14 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
15 |
+
"github.com/GoAdminGroup/go-admin/context"
|
16 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
17 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
18 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
19 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
20 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant"
|
21 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
22 |
+
"github.com/labstack/echo/v4"
|
23 |
+
)
|
24 |
+
|
25 |
+
// Echo structure value is an Echo GoAdmin adapter.
|
26 |
+
type Echo struct {
|
27 |
+
adapter.BaseAdapter
|
28 |
+
ctx echo.Context
|
29 |
+
app *echo.Echo
|
30 |
+
}
|
31 |
+
|
32 |
+
func init() {
|
33 |
+
engine.Register(new(Echo))
|
34 |
+
}
|
35 |
+
|
36 |
+
// User implements the method Adapter.User.
|
37 |
+
func (e *Echo) User(ctx interface{}) (models.UserModel, bool) {
|
38 |
+
return e.GetUser(ctx, e)
|
39 |
+
}
|
40 |
+
|
41 |
+
// Use implements the method Adapter.Use.
|
42 |
+
func (e *Echo) Use(app interface{}, plugs []plugins.Plugin) error {
|
43 |
+
return e.GetUse(app, plugs, e)
|
44 |
+
}
|
45 |
+
|
46 |
+
// Content implements the method Adapter.Content.
|
47 |
+
func (e *Echo) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) {
|
48 |
+
e.GetContent(ctx, getPanelFn, e, btns, fn)
|
49 |
+
}
|
50 |
+
|
51 |
+
type HandlerFunc func(ctx echo.Context) (types.Panel, error)
|
52 |
+
|
53 |
+
func Content(handler HandlerFunc) echo.HandlerFunc {
|
54 |
+
return func(ctx echo.Context) error {
|
55 |
+
engine.Content(ctx, func(ctx interface{}) (types.Panel, error) {
|
56 |
+
return handler(ctx.(echo.Context))
|
57 |
+
})
|
58 |
+
return nil
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
// SetApp implements the method Adapter.SetApp.
|
63 |
+
func (e *Echo) SetApp(app interface{}) error {
|
64 |
+
var (
|
65 |
+
eng *echo.Echo
|
66 |
+
ok bool
|
67 |
+
)
|
68 |
+
if eng, ok = app.(*echo.Echo); !ok {
|
69 |
+
return errors.New("echo adapter SetApp: wrong parameter")
|
70 |
+
}
|
71 |
+
e.app = eng
|
72 |
+
return nil
|
73 |
+
}
|
74 |
+
|
75 |
+
// AddHandler implements the method Adapter.AddHandler.
|
76 |
+
func (e *Echo) AddHandler(method, path string, handlers context.Handlers) {
|
77 |
+
e.app.Add(strings.ToUpper(method), path, func(c echo.Context) error {
|
78 |
+
ctx := context.NewContext(c.Request())
|
79 |
+
|
80 |
+
for _, key := range c.ParamNames() {
|
81 |
+
if c.Request().URL.RawQuery == "" {
|
82 |
+
c.Request().URL.RawQuery += strings.ReplaceAll(key, ":", "") + "=" + c.Param(key)
|
83 |
+
} else {
|
84 |
+
c.Request().URL.RawQuery += "&" + strings.ReplaceAll(key, ":", "") + "=" + c.Param(key)
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
ctx.SetHandlers(handlers).Next()
|
89 |
+
for key, head := range ctx.Response.Header {
|
90 |
+
c.Response().Header().Set(key, head[0])
|
91 |
+
}
|
92 |
+
if ctx.Response.Body != nil {
|
93 |
+
buf := new(bytes.Buffer)
|
94 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
95 |
+
_ = c.String(ctx.Response.StatusCode, buf.String())
|
96 |
+
} else {
|
97 |
+
c.Response().WriteHeader(ctx.Response.StatusCode)
|
98 |
+
}
|
99 |
+
return nil
|
100 |
+
})
|
101 |
+
}
|
102 |
+
|
103 |
+
// Name implements the method Adapter.Name.
|
104 |
+
func (*Echo) Name() string {
|
105 |
+
return "echo"
|
106 |
+
}
|
107 |
+
|
108 |
+
// SetContext implements the method Adapter.SetContext.
|
109 |
+
func (*Echo) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
110 |
+
var (
|
111 |
+
ctx echo.Context
|
112 |
+
ok bool
|
113 |
+
)
|
114 |
+
if ctx, ok = contextInterface.(echo.Context); !ok {
|
115 |
+
panic("echo adapter SetContext: wrong parameter")
|
116 |
+
}
|
117 |
+
return &Echo{ctx: ctx}
|
118 |
+
}
|
119 |
+
|
120 |
+
// Redirect implements the method Adapter.Redirect.
|
121 |
+
func (e *Echo) Redirect() {
|
122 |
+
_ = e.ctx.Redirect(http.StatusFound, config.Url(config.GetLoginUrl()))
|
123 |
+
}
|
124 |
+
|
125 |
+
// SetContentType implements the method Adapter.SetContentType.
|
126 |
+
func (e *Echo) SetContentType() {
|
127 |
+
e.ctx.Response().Header().Set("Content-Type", e.HTMLContentType())
|
128 |
+
}
|
129 |
+
|
130 |
+
// Write implements the method Adapter.Write.
|
131 |
+
func (e *Echo) Write(body []byte) {
|
132 |
+
e.ctx.Response().WriteHeader(http.StatusOK)
|
133 |
+
_, _ = e.ctx.Response().Write(body)
|
134 |
+
}
|
135 |
+
|
136 |
+
// GetCookie implements the method Adapter.GetCookie.
|
137 |
+
func (e *Echo) GetCookie() (string, error) {
|
138 |
+
cookie, err := e.ctx.Cookie(e.CookieKey())
|
139 |
+
if err != nil {
|
140 |
+
return "", err
|
141 |
+
}
|
142 |
+
return cookie.Value, err
|
143 |
+
}
|
144 |
+
|
145 |
+
// Lang implements the method Adapter.Lang.
|
146 |
+
func (e *Echo) Lang() string {
|
147 |
+
return e.ctx.Request().URL.Query().Get("__ga_lang")
|
148 |
+
}
|
149 |
+
|
150 |
+
// Path implements the method Adapter.Path.
|
151 |
+
func (e *Echo) Path() string {
|
152 |
+
return e.ctx.Request().URL.Path
|
153 |
+
}
|
154 |
+
|
155 |
+
// Method implements the method Adapter.Method.
|
156 |
+
func (e *Echo) Method() string {
|
157 |
+
return e.ctx.Request().Method
|
158 |
+
}
|
159 |
+
|
160 |
+
// FormParam implements the method Adapter.FormParam.
|
161 |
+
func (e *Echo) FormParam() url.Values {
|
162 |
+
_ = e.ctx.Request().ParseMultipartForm(32 << 20)
|
163 |
+
return e.ctx.Request().PostForm
|
164 |
+
}
|
165 |
+
|
166 |
+
// IsPjax implements the method Adapter.IsPjax.
|
167 |
+
func (e *Echo) IsPjax() bool {
|
168 |
+
return e.ctx.Request().Header.Get(constant.PjaxHeader) == "true"
|
169 |
+
}
|
170 |
+
|
171 |
+
// Query implements the method Adapter.Query.
|
172 |
+
func (e *Echo) Query() url.Values {
|
173 |
+
return e.ctx.Request().URL.Query()
|
174 |
+
}
|
175 |
+
|
176 |
+
// Request implements the method Adapter.Request.
|
177 |
+
func (e *Echo) Request() *http.Request {
|
178 |
+
return e.ctx.Request()
|
179 |
+
}
|
adapter/fasthttp/fasthttp.go
ADDED
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package fasthttp
|
6 |
+
|
7 |
+
import (
|
8 |
+
"bytes"
|
9 |
+
"errors"
|
10 |
+
"io"
|
11 |
+
"net/http"
|
12 |
+
"net/url"
|
13 |
+
"strings"
|
14 |
+
|
15 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
16 |
+
"github.com/GoAdminGroup/go-admin/context"
|
17 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
18 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
19 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
20 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
21 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant"
|
22 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
23 |
+
"github.com/buaazp/fasthttprouter"
|
24 |
+
"github.com/valyala/fasthttp"
|
25 |
+
)
|
26 |
+
|
27 |
+
// Fasthttp structure value is a Fasthttp GoAdmin adapter.
|
28 |
+
type Fasthttp struct {
|
29 |
+
adapter.BaseAdapter
|
30 |
+
ctx *fasthttp.RequestCtx
|
31 |
+
app *fasthttprouter.Router
|
32 |
+
}
|
33 |
+
|
34 |
+
func init() {
|
35 |
+
engine.Register(new(Fasthttp))
|
36 |
+
}
|
37 |
+
|
38 |
+
// User implements the method Adapter.User.
|
39 |
+
func (fast *Fasthttp) User(ctx interface{}) (models.UserModel, bool) {
|
40 |
+
return fast.GetUser(ctx, fast)
|
41 |
+
}
|
42 |
+
|
43 |
+
// Use implements the method Adapter.Use.
|
44 |
+
func (fast *Fasthttp) Use(app interface{}, plugs []plugins.Plugin) error {
|
45 |
+
return fast.GetUse(app, plugs, fast)
|
46 |
+
}
|
47 |
+
|
48 |
+
// Content implements the method Adapter.Content.
|
49 |
+
func (fast *Fasthttp) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) {
|
50 |
+
fast.GetContent(ctx, getPanelFn, fast, btns, fn)
|
51 |
+
}
|
52 |
+
|
53 |
+
type HandlerFunc func(ctx *fasthttp.RequestCtx) (types.Panel, error)
|
54 |
+
|
55 |
+
func Content(handler HandlerFunc) fasthttp.RequestHandler {
|
56 |
+
return func(ctx *fasthttp.RequestCtx) {
|
57 |
+
engine.Content(ctx, func(ctx interface{}) (types.Panel, error) {
|
58 |
+
return handler(ctx.(*fasthttp.RequestCtx))
|
59 |
+
})
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
// SetApp implements the method Adapter.SetApp.
|
64 |
+
func (fast *Fasthttp) SetApp(app interface{}) error {
|
65 |
+
var (
|
66 |
+
eng *fasthttprouter.Router
|
67 |
+
ok bool
|
68 |
+
)
|
69 |
+
if eng, ok = app.(*fasthttprouter.Router); !ok {
|
70 |
+
return errors.New("fasthttp adapter SetApp: wrong parameter")
|
71 |
+
}
|
72 |
+
|
73 |
+
fast.app = eng
|
74 |
+
return nil
|
75 |
+
}
|
76 |
+
|
77 |
+
// AddHandler implements the method Adapter.AddHandler.
|
78 |
+
func (fast *Fasthttp) AddHandler(method, path string, handlers context.Handlers) {
|
79 |
+
fast.app.Handle(strings.ToUpper(method), path, func(c *fasthttp.RequestCtx) {
|
80 |
+
httpreq := convertCtx(c)
|
81 |
+
ctx := context.NewContext(httpreq)
|
82 |
+
|
83 |
+
var params = make(map[string]string)
|
84 |
+
c.VisitUserValues(func(i []byte, i2 interface{}) {
|
85 |
+
if value, ok := i2.(string); ok {
|
86 |
+
params[string(i)] = value
|
87 |
+
}
|
88 |
+
})
|
89 |
+
|
90 |
+
for key, value := range params {
|
91 |
+
if httpreq.URL.RawQuery == "" {
|
92 |
+
httpreq.URL.RawQuery += strings.ReplaceAll(key, ":", "") + "=" + value
|
93 |
+
} else {
|
94 |
+
httpreq.URL.RawQuery += "&" + strings.ReplaceAll(key, ":", "") + "=" + value
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
ctx.SetHandlers(handlers).Next()
|
99 |
+
for key, head := range ctx.Response.Header {
|
100 |
+
c.Response.Header.Set(key, head[0])
|
101 |
+
}
|
102 |
+
if ctx.Response.Body != nil {
|
103 |
+
buf := new(bytes.Buffer)
|
104 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
105 |
+
_, _ = c.WriteString(buf.String())
|
106 |
+
}
|
107 |
+
c.Response.SetStatusCode(ctx.Response.StatusCode)
|
108 |
+
})
|
109 |
+
}
|
110 |
+
|
111 |
+
func convertCtx(ctx *fasthttp.RequestCtx) *http.Request {
|
112 |
+
var r http.Request
|
113 |
+
|
114 |
+
body := ctx.PostBody()
|
115 |
+
r.Method = string(ctx.Method())
|
116 |
+
r.Proto = "HTTP/1.1"
|
117 |
+
r.ProtoMajor = 1
|
118 |
+
r.ProtoMinor = 1
|
119 |
+
r.RequestURI = string(ctx.RequestURI())
|
120 |
+
r.ContentLength = int64(len(body))
|
121 |
+
r.Host = string(ctx.Host())
|
122 |
+
r.RemoteAddr = ctx.RemoteAddr().String()
|
123 |
+
|
124 |
+
hdr := make(http.Header)
|
125 |
+
ctx.Request.Header.VisitAll(func(k, v []byte) {
|
126 |
+
sk := string(k)
|
127 |
+
sv := string(v)
|
128 |
+
switch sk {
|
129 |
+
case "Transfer-Encoding":
|
130 |
+
r.TransferEncoding = append(r.TransferEncoding, sv)
|
131 |
+
default:
|
132 |
+
hdr.Set(sk, sv)
|
133 |
+
}
|
134 |
+
})
|
135 |
+
r.Header = hdr
|
136 |
+
r.Body = &netHTTPBody{body}
|
137 |
+
rURL, err := url.ParseRequestURI(r.RequestURI)
|
138 |
+
if err != nil {
|
139 |
+
ctx.Logger().Printf("cannot parse requestURI %q: %s", r.RequestURI, err)
|
140 |
+
ctx.Error("Internal Server Error", fasthttp.StatusInternalServerError)
|
141 |
+
return &r
|
142 |
+
}
|
143 |
+
r.URL = rURL
|
144 |
+
return &r
|
145 |
+
}
|
146 |
+
|
147 |
+
type netHTTPBody struct {
|
148 |
+
b []byte
|
149 |
+
}
|
150 |
+
|
151 |
+
func (r *netHTTPBody) Read(p []byte) (int, error) {
|
152 |
+
if len(r.b) == 0 {
|
153 |
+
return 0, io.EOF
|
154 |
+
}
|
155 |
+
n := copy(p, r.b)
|
156 |
+
r.b = r.b[n:]
|
157 |
+
return n, nil
|
158 |
+
}
|
159 |
+
|
160 |
+
func (r *netHTTPBody) Close() error {
|
161 |
+
r.b = r.b[:0]
|
162 |
+
return nil
|
163 |
+
}
|
164 |
+
|
165 |
+
// Name implements the method Adapter.Name.
|
166 |
+
func (*Fasthttp) Name() string {
|
167 |
+
return "fasthttp"
|
168 |
+
}
|
169 |
+
|
170 |
+
// SetContext implements the method Adapter.SetContext.
|
171 |
+
func (*Fasthttp) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
172 |
+
var (
|
173 |
+
ctx *fasthttp.RequestCtx
|
174 |
+
ok bool
|
175 |
+
)
|
176 |
+
if ctx, ok = contextInterface.(*fasthttp.RequestCtx); !ok {
|
177 |
+
panic("fasthttp adapter SetContext: wrong parameter")
|
178 |
+
}
|
179 |
+
return &Fasthttp{ctx: ctx}
|
180 |
+
}
|
181 |
+
|
182 |
+
// Redirect implements the method Adapter.Redirect.
|
183 |
+
func (fast *Fasthttp) Redirect() {
|
184 |
+
fast.ctx.Redirect(config.Url(config.GetLoginUrl()), http.StatusFound)
|
185 |
+
}
|
186 |
+
|
187 |
+
// SetContentType implements the method Adapter.SetContentType.
|
188 |
+
func (fast *Fasthttp) SetContentType() {
|
189 |
+
fast.ctx.Response.Header.Set("Content-Type", fast.HTMLContentType())
|
190 |
+
}
|
191 |
+
|
192 |
+
// Write implements the method Adapter.Write.
|
193 |
+
func (fast *Fasthttp) Write(body []byte) {
|
194 |
+
_, _ = fast.ctx.Write(body)
|
195 |
+
}
|
196 |
+
|
197 |
+
// GetCookie implements the method Adapter.GetCookie.
|
198 |
+
func (fast *Fasthttp) GetCookie() (string, error) {
|
199 |
+
return string(fast.ctx.Request.Header.Cookie(fast.CookieKey())), nil
|
200 |
+
}
|
201 |
+
|
202 |
+
// Lang implements the method Adapter.Lang.
|
203 |
+
func (fast *Fasthttp) Lang() string {
|
204 |
+
return string(fast.ctx.Request.URI().QueryArgs().Peek("__ga_lang"))
|
205 |
+
}
|
206 |
+
|
207 |
+
// Path implements the method Adapter.Path.
|
208 |
+
func (fast *Fasthttp) Path() string {
|
209 |
+
return string(fast.ctx.Path())
|
210 |
+
}
|
211 |
+
|
212 |
+
// Method implements the method Adapter.Method.
|
213 |
+
func (fast *Fasthttp) Method() string {
|
214 |
+
return string(fast.ctx.Method())
|
215 |
+
}
|
216 |
+
|
217 |
+
// FormParam implements the method Adapter.FormParam.
|
218 |
+
func (fast *Fasthttp) FormParam() url.Values {
|
219 |
+
f, _ := fast.ctx.MultipartForm()
|
220 |
+
if f != nil {
|
221 |
+
return f.Value
|
222 |
+
}
|
223 |
+
return url.Values{}
|
224 |
+
}
|
225 |
+
|
226 |
+
// IsPjax implements the method Adapter.IsPjax.
|
227 |
+
func (fast *Fasthttp) IsPjax() bool {
|
228 |
+
return string(fast.ctx.Request.Header.Peek(constant.PjaxHeader)) == "true"
|
229 |
+
}
|
230 |
+
|
231 |
+
// Query implements the method Adapter.Query.
|
232 |
+
func (fast *Fasthttp) Query() url.Values {
|
233 |
+
queryStr := fast.ctx.URI().QueryString()
|
234 |
+
queryObj, err := url.Parse(string(queryStr))
|
235 |
+
|
236 |
+
if err != nil {
|
237 |
+
return url.Values{}
|
238 |
+
}
|
239 |
+
|
240 |
+
return queryObj.Query()
|
241 |
+
}
|
242 |
+
|
243 |
+
// Request implements the method Adapter.Request.
|
244 |
+
func (fast *Fasthttp) Request() *http.Request {
|
245 |
+
return convertCtx(fast.ctx)
|
246 |
+
}
|
adapter/gear/gear.go
ADDED
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/***
|
2 |
+
# File Name: ../../adapter/gear/gear.go
|
3 |
+
# Author: eavesmy
|
4 |
+
# Email: eavesmy@gmail.com
|
5 |
+
# Created Time: 2021年06月03日 星期四 19时05分06秒
|
6 |
+
***/
|
7 |
+
|
8 |
+
package gear
|
9 |
+
|
10 |
+
import (
|
11 |
+
"bytes"
|
12 |
+
"errors"
|
13 |
+
"net/http"
|
14 |
+
"net/url"
|
15 |
+
"regexp"
|
16 |
+
"strings"
|
17 |
+
|
18 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
19 |
+
"github.com/GoAdminGroup/go-admin/context"
|
20 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
21 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
22 |
+
"github.com/GoAdminGroup/go-admin/modules/utils"
|
23 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
24 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
25 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant"
|
26 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
27 |
+
"github.com/teambition/gear"
|
28 |
+
)
|
29 |
+
|
30 |
+
// Gear structure value is a Gin GoAdmin adapter.
|
31 |
+
type Gear struct {
|
32 |
+
adapter.BaseAdapter
|
33 |
+
ctx *gear.Context
|
34 |
+
app *gear.App
|
35 |
+
router *gear.Router
|
36 |
+
}
|
37 |
+
|
38 |
+
func init() {
|
39 |
+
engine.Register(new(Gear))
|
40 |
+
}
|
41 |
+
|
42 |
+
// User implements the method Adapter.User.
|
43 |
+
func (gears *Gear) User(ctx interface{}) (models.UserModel, bool) {
|
44 |
+
return gears.GetUser(ctx, gears)
|
45 |
+
}
|
46 |
+
|
47 |
+
// Use implements the method Adapter.Use.
|
48 |
+
func (gears *Gear) Use(app interface{}, plugs []plugins.Plugin) error {
|
49 |
+
return gears.GetUse(app, plugs, gears)
|
50 |
+
}
|
51 |
+
|
52 |
+
// Content implements the method Adapter.Content.
|
53 |
+
func (gears *Gear) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) {
|
54 |
+
gears.GetContent(ctx, getPanelFn, gears, btns, fn)
|
55 |
+
}
|
56 |
+
|
57 |
+
type HandlerFunc func(ctx *gear.Context) (types.Panel, error)
|
58 |
+
|
59 |
+
func Content(handler HandlerFunc) gear.Middleware {
|
60 |
+
return func(ctx *gear.Context) error {
|
61 |
+
engine.Content(ctx, func(ctx interface{}) (types.Panel, error) {
|
62 |
+
return handler(ctx.(*gear.Context))
|
63 |
+
})
|
64 |
+
return nil
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
// SetApp implements the method Adapter.SetApp.
|
69 |
+
func (gears *Gear) SetApp(app interface{}) error {
|
70 |
+
gears.app = app.(*gear.App)
|
71 |
+
gears.router = gear.NewRouter()
|
72 |
+
var (
|
73 |
+
eng *gear.App
|
74 |
+
ok bool
|
75 |
+
)
|
76 |
+
if eng, ok = app.(*gear.App); !ok {
|
77 |
+
return errors.New("beego adapter SetApp: wrong parameter")
|
78 |
+
}
|
79 |
+
gears.app = eng
|
80 |
+
return nil
|
81 |
+
}
|
82 |
+
|
83 |
+
// AddHandler implements the method Adapter.AddHandler.
|
84 |
+
func (gears *Gear) AddHandler(method, path string, handlers context.Handlers) {
|
85 |
+
|
86 |
+
if gears.router == nil {
|
87 |
+
gears.router = gear.NewRouter()
|
88 |
+
}
|
89 |
+
|
90 |
+
gears.router.Handle(strings.ToUpper(method), path, func(c *gear.Context) error {
|
91 |
+
|
92 |
+
ctx := context.NewContext(c.Req)
|
93 |
+
|
94 |
+
newPath := path
|
95 |
+
|
96 |
+
reg1 := regexp.MustCompile(":(.*?)/")
|
97 |
+
reg2 := regexp.MustCompile(":(.*?)$")
|
98 |
+
|
99 |
+
params := reg1.FindAllString(newPath, -1)
|
100 |
+
newPath = reg1.ReplaceAllString(newPath, "")
|
101 |
+
params = append(params, reg2.FindAllString(newPath, -1)...)
|
102 |
+
|
103 |
+
for _, param := range params {
|
104 |
+
p := utils.ReplaceAll(param, ":", "", "/", "")
|
105 |
+
|
106 |
+
if c.Req.URL.RawQuery == "" {
|
107 |
+
c.Req.URL.RawQuery += p + "=" + c.Param(p)
|
108 |
+
} else {
|
109 |
+
c.Req.URL.RawQuery += "&" + p + "=" + c.Param(p)
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
ctx.SetHandlers(handlers).Next()
|
114 |
+
|
115 |
+
for key, head := range ctx.Response.Header {
|
116 |
+
c.Res.Header().Add(key, head[0])
|
117 |
+
}
|
118 |
+
|
119 |
+
if ctx.Response.Body != nil {
|
120 |
+
buf := new(bytes.Buffer)
|
121 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
122 |
+
|
123 |
+
return c.End(ctx.Response.StatusCode, buf.Bytes())
|
124 |
+
}
|
125 |
+
|
126 |
+
c.Status(ctx.Response.StatusCode)
|
127 |
+
return nil
|
128 |
+
})
|
129 |
+
|
130 |
+
gears.app.UseHandler(gears.router)
|
131 |
+
}
|
132 |
+
|
133 |
+
// Name implements the method Adapter.Name.
|
134 |
+
func (*Gear) Name() string {
|
135 |
+
return "gear"
|
136 |
+
}
|
137 |
+
|
138 |
+
// SetContext implements the method Adapter.SetContext.
|
139 |
+
func (*Gear) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
140 |
+
var (
|
141 |
+
ctx *gear.Context
|
142 |
+
ok bool
|
143 |
+
)
|
144 |
+
|
145 |
+
if ctx, ok = contextInterface.(*gear.Context); !ok {
|
146 |
+
panic("gear adapter SetContext: wrong parameter")
|
147 |
+
}
|
148 |
+
|
149 |
+
return &Gear{ctx: ctx}
|
150 |
+
}
|
151 |
+
|
152 |
+
// Redirect implements the method Adapter.Redirect.
|
153 |
+
func (gears *Gear) Redirect() {
|
154 |
+
gears.ctx.Redirect(config.Url(config.GetLoginUrl()))
|
155 |
+
}
|
156 |
+
|
157 |
+
// SetContentType implements the method Adapter.SetContentType.
|
158 |
+
func (gears *Gear) SetContentType() {
|
159 |
+
gears.ctx.Res.Header().Set("Content-Type", gears.HTMLContentType())
|
160 |
+
}
|
161 |
+
|
162 |
+
// Write implements the method Adapter.Write.
|
163 |
+
func (gears *Gear) Write(body []byte) {
|
164 |
+
gears.ctx.End(http.StatusOK, body)
|
165 |
+
}
|
166 |
+
|
167 |
+
// GetCookie implements the method Adapter.GetCookie.
|
168 |
+
func (gears *Gear) GetCookie() (string, error) {
|
169 |
+
return gears.ctx.Cookies.Get(gears.CookieKey())
|
170 |
+
}
|
171 |
+
|
172 |
+
// Lang implements the method Adapter.Lang.
|
173 |
+
func (gears *Gear) Lang() string {
|
174 |
+
return gears.ctx.Req.URL.Query().Get("__ga_lang")
|
175 |
+
}
|
176 |
+
|
177 |
+
// Path implements the method Adapter.Path.
|
178 |
+
func (gears *Gear) Path() string {
|
179 |
+
return gears.ctx.Req.URL.Path
|
180 |
+
}
|
181 |
+
|
182 |
+
// Method implements the method Adapter.Method.
|
183 |
+
func (gears *Gear) Method() string {
|
184 |
+
return gears.ctx.Req.Method
|
185 |
+
}
|
186 |
+
|
187 |
+
// FormParam implements the method Adapter.FormParam.
|
188 |
+
func (gears *Gear) FormParam() url.Values {
|
189 |
+
_ = gears.ctx.Req.ParseMultipartForm(32 << 20)
|
190 |
+
return gears.ctx.Req.PostForm
|
191 |
+
}
|
192 |
+
|
193 |
+
// IsPjax implements the method Adapter.IsPjax.
|
194 |
+
func (gears *Gear) IsPjax() bool {
|
195 |
+
return gears.ctx.Req.Header.Get(constant.PjaxHeader) == "true"
|
196 |
+
}
|
197 |
+
|
198 |
+
// Query implements the method Adapter.Query.
|
199 |
+
func (gears *Gear) Query() url.Values {
|
200 |
+
return gears.ctx.Req.URL.Query()
|
201 |
+
}
|
202 |
+
|
203 |
+
// Request implements the method Adapter.Request.
|
204 |
+
func (gears *Gear) Request() *http.Request {
|
205 |
+
return gears.ctx.Req
|
206 |
+
}
|
adapter/gf/gf.go
ADDED
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package gf
|
6 |
+
|
7 |
+
import (
|
8 |
+
"bytes"
|
9 |
+
"errors"
|
10 |
+
"net/http"
|
11 |
+
"net/url"
|
12 |
+
"regexp"
|
13 |
+
"strings"
|
14 |
+
|
15 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
16 |
+
"github.com/GoAdminGroup/go-admin/context"
|
17 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
18 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
19 |
+
"github.com/GoAdminGroup/go-admin/modules/utils"
|
20 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
21 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
22 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant"
|
23 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
24 |
+
"github.com/gogf/gf/net/ghttp"
|
25 |
+
)
|
26 |
+
|
27 |
+
// Gf structure value is a Gf GoAdmin adapter.
|
28 |
+
type Gf struct {
|
29 |
+
adapter.BaseAdapter
|
30 |
+
ctx *ghttp.Request
|
31 |
+
app *ghttp.Server
|
32 |
+
}
|
33 |
+
|
34 |
+
func init() {
|
35 |
+
engine.Register(new(Gf))
|
36 |
+
}
|
37 |
+
|
38 |
+
// User implements the method Adapter.User.
|
39 |
+
func (gf *Gf) User(ctx interface{}) (models.UserModel, bool) {
|
40 |
+
return gf.GetUser(ctx, gf)
|
41 |
+
}
|
42 |
+
|
43 |
+
// Use implements the method Adapter.Use.
|
44 |
+
func (gf *Gf) Use(app interface{}, plugs []plugins.Plugin) error {
|
45 |
+
return gf.GetUse(app, plugs, gf)
|
46 |
+
}
|
47 |
+
|
48 |
+
// Content implements the method Adapter.Content.
|
49 |
+
func (gf *Gf) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) {
|
50 |
+
gf.GetContent(ctx, getPanelFn, gf, btns, fn)
|
51 |
+
}
|
52 |
+
|
53 |
+
type HandlerFunc func(ctx *ghttp.Request) (types.Panel, error)
|
54 |
+
|
55 |
+
func Content(handler HandlerFunc) ghttp.HandlerFunc {
|
56 |
+
return func(ctx *ghttp.Request) {
|
57 |
+
engine.Content(ctx, func(ctx interface{}) (types.Panel, error) {
|
58 |
+
return handler(ctx.(*ghttp.Request))
|
59 |
+
})
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
// SetApp implements the method Adapter.SetApp.
|
64 |
+
func (gf *Gf) SetApp(app interface{}) error {
|
65 |
+
var (
|
66 |
+
eng *ghttp.Server
|
67 |
+
ok bool
|
68 |
+
)
|
69 |
+
if eng, ok = app.(*ghttp.Server); !ok {
|
70 |
+
return errors.New("gf adapter SetApp: wrong parameter")
|
71 |
+
}
|
72 |
+
gf.app = eng
|
73 |
+
return nil
|
74 |
+
}
|
75 |
+
|
76 |
+
// AddHandler implements the method Adapter.AddHandler.
|
77 |
+
func (gf *Gf) AddHandler(method, path string, handlers context.Handlers) {
|
78 |
+
gf.app.BindHandler(strings.ToUpper(method)+":"+path, func(c *ghttp.Request) {
|
79 |
+
ctx := context.NewContext(c.Request)
|
80 |
+
|
81 |
+
newPath := path
|
82 |
+
|
83 |
+
reg1 := regexp.MustCompile(":(.*?)/")
|
84 |
+
reg2 := regexp.MustCompile(":(.*?)$")
|
85 |
+
|
86 |
+
params := reg1.FindAllString(newPath, -1)
|
87 |
+
newPath = reg1.ReplaceAllString(newPath, "")
|
88 |
+
params = append(params, reg2.FindAllString(newPath, -1)...)
|
89 |
+
|
90 |
+
for _, param := range params {
|
91 |
+
p := utils.ReplaceAll(param, ":", "", "/", "")
|
92 |
+
|
93 |
+
if c.Request.URL.RawQuery == "" {
|
94 |
+
c.Request.URL.RawQuery += p + "=" + c.GetRequestString(p)
|
95 |
+
} else {
|
96 |
+
c.Request.URL.RawQuery += "&" + p + "=" + c.GetRequestString(p)
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
ctx.SetHandlers(handlers).Next()
|
101 |
+
for key, head := range ctx.Response.Header {
|
102 |
+
c.Response.Header().Add(key, head[0])
|
103 |
+
}
|
104 |
+
|
105 |
+
if ctx.Response.Body != nil {
|
106 |
+
buf := new(bytes.Buffer)
|
107 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
108 |
+
c.Response.WriteStatus(ctx.Response.StatusCode, buf.Bytes())
|
109 |
+
} else {
|
110 |
+
c.Response.WriteStatus(ctx.Response.StatusCode)
|
111 |
+
}
|
112 |
+
})
|
113 |
+
}
|
114 |
+
|
115 |
+
// Name implements the method Adapter.Name.
|
116 |
+
func (*Gf) Name() string {
|
117 |
+
return "gf"
|
118 |
+
}
|
119 |
+
|
120 |
+
// SetContext implements the method Adapter.SetContext.
|
121 |
+
func (*Gf) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
122 |
+
var (
|
123 |
+
ctx *ghttp.Request
|
124 |
+
ok bool
|
125 |
+
)
|
126 |
+
|
127 |
+
if ctx, ok = contextInterface.(*ghttp.Request); !ok {
|
128 |
+
panic("gf adapter SetContext: wrong parameter")
|
129 |
+
}
|
130 |
+
return &Gf{ctx: ctx}
|
131 |
+
}
|
132 |
+
|
133 |
+
// Redirect implements the method Adapter.Redirect.
|
134 |
+
func (gf *Gf) Redirect() {
|
135 |
+
gf.ctx.Response.RedirectTo(config.Url(config.GetLoginUrl()))
|
136 |
+
}
|
137 |
+
|
138 |
+
// SetContentType implements the method Adapter.SetContentType.
|
139 |
+
func (gf *Gf) SetContentType() {
|
140 |
+
gf.ctx.Response.Header().Add("Content-Type", gf.HTMLContentType())
|
141 |
+
}
|
142 |
+
|
143 |
+
// Write implements the method Adapter.Write.
|
144 |
+
func (gf *Gf) Write(body []byte) {
|
145 |
+
gf.ctx.Response.WriteStatus(http.StatusOK, body)
|
146 |
+
}
|
147 |
+
|
148 |
+
// GetCookie implements the method Adapter.GetCookie.
|
149 |
+
func (gf *Gf) GetCookie() (string, error) {
|
150 |
+
return gf.ctx.Cookie.Get(gf.CookieKey()), nil
|
151 |
+
}
|
152 |
+
|
153 |
+
// Lang implements the method Adapter.Lang.
|
154 |
+
func (gf *Gf) Lang() string {
|
155 |
+
return gf.ctx.Request.URL.Query().Get("__ga_lang")
|
156 |
+
}
|
157 |
+
|
158 |
+
// Path implements the method Adapter.Path.
|
159 |
+
func (gf *Gf) Path() string {
|
160 |
+
return gf.ctx.URL.Path
|
161 |
+
}
|
162 |
+
|
163 |
+
// Method implements the method Adapter.Method.
|
164 |
+
func (gf *Gf) Method() string {
|
165 |
+
return gf.ctx.Method
|
166 |
+
}
|
167 |
+
|
168 |
+
// FormParam implements the method Adapter.FormParam.
|
169 |
+
func (gf *Gf) FormParam() url.Values {
|
170 |
+
return gf.ctx.Form
|
171 |
+
}
|
172 |
+
|
173 |
+
// IsPjax implements the method Adapter.IsPjax.
|
174 |
+
func (gf *Gf) IsPjax() bool {
|
175 |
+
return gf.ctx.Header.Get(constant.PjaxHeader) == "true"
|
176 |
+
}
|
177 |
+
|
178 |
+
// Query implements the method Adapter.Query.
|
179 |
+
func (gf *Gf) Query() url.Values {
|
180 |
+
return gf.ctx.Request.URL.Query()
|
181 |
+
}
|
182 |
+
|
183 |
+
// Request implements the method Adapter.Request.
|
184 |
+
func (gf *Gf) Request() *http.Request {
|
185 |
+
return gf.ctx.Request
|
186 |
+
}
|
adapter/gf2/gf2.go
ADDED
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package gf2
|
2 |
+
|
3 |
+
import (
|
4 |
+
"bytes"
|
5 |
+
"errors"
|
6 |
+
"net/http"
|
7 |
+
"net/url"
|
8 |
+
"regexp"
|
9 |
+
"strings"
|
10 |
+
|
11 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
12 |
+
"github.com/GoAdminGroup/go-admin/context"
|
13 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
14 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
15 |
+
"github.com/GoAdminGroup/go-admin/modules/constant"
|
16 |
+
"github.com/GoAdminGroup/go-admin/modules/utils"
|
17 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
18 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
19 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
20 |
+
"github.com/gogf/gf/v2/net/ghttp"
|
21 |
+
)
|
22 |
+
|
23 |
+
type GF2 struct {
|
24 |
+
adapter.BaseAdapter
|
25 |
+
ctx *ghttp.Request
|
26 |
+
app *ghttp.Server
|
27 |
+
}
|
28 |
+
|
29 |
+
func init() {
|
30 |
+
engine.Register(new(GF2))
|
31 |
+
}
|
32 |
+
|
33 |
+
func (*GF2) Name() string {
|
34 |
+
return "gf2"
|
35 |
+
}
|
36 |
+
|
37 |
+
func (gf2 *GF2) Use(app interface{}, plugins []plugins.Plugin) error {
|
38 |
+
return gf2.GetUse(app, plugins, gf2)
|
39 |
+
}
|
40 |
+
|
41 |
+
func (gf2 *GF2) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) {
|
42 |
+
gf2.GetContent(ctx, getPanelFn, gf2, btns, fn)
|
43 |
+
}
|
44 |
+
|
45 |
+
func (gf2 *GF2) User(ctx interface{}) (models.UserModel, bool) {
|
46 |
+
return gf2.GetUser(ctx, gf2)
|
47 |
+
}
|
48 |
+
|
49 |
+
func (gf2 *GF2) AddHandler(method, path string, handlers context.Handlers) {
|
50 |
+
gf2.app.BindHandler(strings.ToUpper(method)+":"+path, func(c *ghttp.Request) {
|
51 |
+
ctx := context.NewContext(c.Request)
|
52 |
+
|
53 |
+
newPath := path
|
54 |
+
|
55 |
+
reg1 := regexp.MustCompile(":(.*?)/")
|
56 |
+
reg2 := regexp.MustCompile(":(.*?)$")
|
57 |
+
|
58 |
+
params := reg1.FindAllString(newPath, -1)
|
59 |
+
newPath = reg1.ReplaceAllString(newPath, "")
|
60 |
+
params = append(params, reg2.FindAllString(newPath, -1)...)
|
61 |
+
|
62 |
+
for _, param := range params {
|
63 |
+
p := utils.ReplaceAll(param, ":", "", "/", "")
|
64 |
+
|
65 |
+
if c.Request.URL.RawQuery == "" {
|
66 |
+
c.Request.URL.RawQuery += p + "=" + c.GetRequest(p).String()
|
67 |
+
} else {
|
68 |
+
c.Request.URL.RawQuery += "&" + p + "=" + c.GetRequest(p).String()
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
ctx.SetHandlers(handlers).Next()
|
73 |
+
for key, head := range ctx.Response.Header {
|
74 |
+
c.Response.Header().Add(key, head[0])
|
75 |
+
}
|
76 |
+
|
77 |
+
if ctx.Response.Body != nil {
|
78 |
+
buf := new(bytes.Buffer)
|
79 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
80 |
+
c.Response.WriteStatus(ctx.Response.StatusCode, buf.Bytes())
|
81 |
+
} else {
|
82 |
+
c.Response.WriteStatus(ctx.Response.StatusCode)
|
83 |
+
}
|
84 |
+
})
|
85 |
+
}
|
86 |
+
|
87 |
+
func (gf2 *GF2) SetApp(app interface{}) error {
|
88 |
+
var (
|
89 |
+
eng *ghttp.Server
|
90 |
+
ok bool
|
91 |
+
)
|
92 |
+
if eng, ok = app.(*ghttp.Server); !ok {
|
93 |
+
return errors.New("gf2 adapter SetApp: wrong parameter")
|
94 |
+
}
|
95 |
+
gf2.app = eng
|
96 |
+
return nil
|
97 |
+
}
|
98 |
+
|
99 |
+
func (*GF2) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
100 |
+
var (
|
101 |
+
ctx *ghttp.Request
|
102 |
+
ok bool
|
103 |
+
)
|
104 |
+
if ctx, ok = contextInterface.(*ghttp.Request); !ok {
|
105 |
+
panic("gf2 adapter SetContext: wrong parameter")
|
106 |
+
}
|
107 |
+
return &GF2{ctx: ctx}
|
108 |
+
}
|
109 |
+
|
110 |
+
func (gf2 *GF2) GetCookie() (string, error) {
|
111 |
+
return gf2.ctx.Cookie.Get(gf2.CookieKey()).String(), nil
|
112 |
+
}
|
113 |
+
|
114 |
+
func (gf2 *GF2) Lang() string {
|
115 |
+
return gf2.ctx.Request.URL.Query().Get("__ga_lang")
|
116 |
+
}
|
117 |
+
|
118 |
+
func (gf2 *GF2) Path() string {
|
119 |
+
return gf2.ctx.URL.Path
|
120 |
+
}
|
121 |
+
|
122 |
+
func (gf2 *GF2) Method() string {
|
123 |
+
return gf2.ctx.Method
|
124 |
+
}
|
125 |
+
|
126 |
+
func (gf2 *GF2) FormParam() url.Values {
|
127 |
+
return gf2.ctx.Form
|
128 |
+
}
|
129 |
+
|
130 |
+
func (gf2 *GF2) Query() url.Values {
|
131 |
+
return gf2.ctx.Request.URL.Query()
|
132 |
+
}
|
133 |
+
|
134 |
+
func (gf2 *GF2) IsPjax() bool {
|
135 |
+
return gf2.ctx.Header.Get(constant.PjaxHeader) == "true"
|
136 |
+
}
|
137 |
+
|
138 |
+
func (gf2 *GF2) Redirect() {
|
139 |
+
gf2.ctx.Response.RedirectTo(config.Url(config.GetLoginUrl()))
|
140 |
+
}
|
141 |
+
|
142 |
+
func (gf2 *GF2) SetContentType() {
|
143 |
+
gf2.ctx.Response.Header().Add("Content-Type", gf2.HTMLContentType())
|
144 |
+
}
|
145 |
+
|
146 |
+
func (gf2 *GF2) Write(body []byte) {
|
147 |
+
gf2.ctx.Response.WriteStatus(http.StatusOK, body)
|
148 |
+
}
|
149 |
+
|
150 |
+
// Request implements the method Adapter.Request.
|
151 |
+
func (gf2 *GF2) Request() *http.Request {
|
152 |
+
return gf2.ctx.Request
|
153 |
+
}
|
adapter/gin/gin.go
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package gin
|
6 |
+
|
7 |
+
import (
|
8 |
+
"bytes"
|
9 |
+
"errors"
|
10 |
+
"net/http"
|
11 |
+
"net/url"
|
12 |
+
"strings"
|
13 |
+
|
14 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
15 |
+
"github.com/GoAdminGroup/go-admin/context"
|
16 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
17 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
18 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
19 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
20 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant"
|
21 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
22 |
+
"github.com/gin-gonic/gin"
|
23 |
+
)
|
24 |
+
|
25 |
+
// Gin structure value is a Gin GoAdmin adapter.
|
26 |
+
type Gin struct {
|
27 |
+
adapter.BaseAdapter
|
28 |
+
ctx *gin.Context
|
29 |
+
app *gin.Engine
|
30 |
+
}
|
31 |
+
|
32 |
+
func init() {
|
33 |
+
engine.Register(new(Gin))
|
34 |
+
}
|
35 |
+
|
36 |
+
// User implements the method Adapter.User.
|
37 |
+
func (gins *Gin) User(ctx interface{}) (models.UserModel, bool) {
|
38 |
+
return gins.GetUser(ctx, gins)
|
39 |
+
}
|
40 |
+
|
41 |
+
// Use implements the method Adapter.Use.
|
42 |
+
func (gins *Gin) Use(app interface{}, plugs []plugins.Plugin) error {
|
43 |
+
return gins.GetUse(app, plugs, gins)
|
44 |
+
}
|
45 |
+
|
46 |
+
// Content implements the method Adapter.Content.
|
47 |
+
func (gins *Gin) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) {
|
48 |
+
gins.GetContent(ctx, getPanelFn, gins, btns, fn)
|
49 |
+
}
|
50 |
+
|
51 |
+
type HandlerFunc func(ctx *gin.Context) (types.Panel, error)
|
52 |
+
|
53 |
+
func Content(handler HandlerFunc) gin.HandlerFunc {
|
54 |
+
return func(ctx *gin.Context) {
|
55 |
+
engine.Content(ctx, func(ctx interface{}) (types.Panel, error) {
|
56 |
+
return handler(ctx.(*gin.Context))
|
57 |
+
})
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
// SetApp implements the method Adapter.SetApp.
|
62 |
+
func (gins *Gin) SetApp(app interface{}) error {
|
63 |
+
var (
|
64 |
+
eng *gin.Engine
|
65 |
+
ok bool
|
66 |
+
)
|
67 |
+
if eng, ok = app.(*gin.Engine); !ok {
|
68 |
+
return errors.New("gin adapter SetApp: wrong parameter")
|
69 |
+
}
|
70 |
+
gins.app = eng
|
71 |
+
return nil
|
72 |
+
}
|
73 |
+
|
74 |
+
// AddHandler implements the method Adapter.AddHandler.
|
75 |
+
func (gins *Gin) AddHandler(method, path string, handlers context.Handlers) {
|
76 |
+
gins.app.Handle(strings.ToUpper(method), path, func(c *gin.Context) {
|
77 |
+
ctx := context.NewContext(c.Request)
|
78 |
+
|
79 |
+
for _, param := range c.Params {
|
80 |
+
if c.Request.URL.RawQuery == "" {
|
81 |
+
c.Request.URL.RawQuery += strings.ReplaceAll(param.Key, ":", "") + "=" + param.Value
|
82 |
+
} else {
|
83 |
+
c.Request.URL.RawQuery += "&" + strings.ReplaceAll(param.Key, ":", "") + "=" + param.Value
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
ctx.SetHandlers(handlers).Next()
|
88 |
+
for key, head := range ctx.Response.Header {
|
89 |
+
c.Header(key, head[0])
|
90 |
+
}
|
91 |
+
if ctx.Response.Body != nil {
|
92 |
+
buf := new(bytes.Buffer)
|
93 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
94 |
+
c.String(ctx.Response.StatusCode, buf.String())
|
95 |
+
} else {
|
96 |
+
c.Status(ctx.Response.StatusCode)
|
97 |
+
}
|
98 |
+
})
|
99 |
+
}
|
100 |
+
|
101 |
+
// Name implements the method Adapter.Name.
|
102 |
+
func (*Gin) Name() string {
|
103 |
+
return "gin"
|
104 |
+
}
|
105 |
+
|
106 |
+
// SetContext implements the method Adapter.SetContext.
|
107 |
+
func (*Gin) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
108 |
+
var (
|
109 |
+
ctx *gin.Context
|
110 |
+
ok bool
|
111 |
+
)
|
112 |
+
|
113 |
+
if ctx, ok = contextInterface.(*gin.Context); !ok {
|
114 |
+
panic("gin adapter SetContext: wrong parameter")
|
115 |
+
}
|
116 |
+
|
117 |
+
return &Gin{ctx: ctx}
|
118 |
+
}
|
119 |
+
|
120 |
+
// Redirect implements the method Adapter.Redirect.
|
121 |
+
func (gins *Gin) Redirect() {
|
122 |
+
gins.ctx.Redirect(http.StatusFound, config.Url(config.GetLoginUrl()))
|
123 |
+
gins.ctx.Abort()
|
124 |
+
}
|
125 |
+
|
126 |
+
// SetContentType implements the method Adapter.SetContentType.
|
127 |
+
func (*Gin) SetContentType() {}
|
128 |
+
|
129 |
+
// Write implements the method Adapter.Write.
|
130 |
+
func (gins *Gin) Write(body []byte) {
|
131 |
+
gins.ctx.Data(http.StatusOK, gins.HTMLContentType(), body)
|
132 |
+
}
|
133 |
+
|
134 |
+
// GetCookie implements the method Adapter.GetCookie.
|
135 |
+
func (gins *Gin) GetCookie() (string, error) {
|
136 |
+
return gins.ctx.Cookie(gins.CookieKey())
|
137 |
+
}
|
138 |
+
|
139 |
+
// Lang implements the method Adapter.Lang.
|
140 |
+
func (gins *Gin) Lang() string {
|
141 |
+
return gins.ctx.Request.URL.Query().Get("__ga_lang")
|
142 |
+
}
|
143 |
+
|
144 |
+
// Path implements the method Adapter.Path.
|
145 |
+
func (gins *Gin) Path() string {
|
146 |
+
return gins.ctx.Request.URL.Path
|
147 |
+
}
|
148 |
+
|
149 |
+
// Method implements the method Adapter.Method.
|
150 |
+
func (gins *Gin) Method() string {
|
151 |
+
return gins.ctx.Request.Method
|
152 |
+
}
|
153 |
+
|
154 |
+
// FormParam implements the method Adapter.FormParam.
|
155 |
+
func (gins *Gin) FormParam() url.Values {
|
156 |
+
_ = gins.ctx.Request.ParseMultipartForm(32 << 20)
|
157 |
+
return gins.ctx.Request.PostForm
|
158 |
+
}
|
159 |
+
|
160 |
+
// IsPjax implements the method Adapter.IsPjax.
|
161 |
+
func (gins *Gin) IsPjax() bool {
|
162 |
+
return gins.ctx.Request.Header.Get(constant.PjaxHeader) == "true"
|
163 |
+
}
|
164 |
+
|
165 |
+
// Query implements the method Adapter.Query.
|
166 |
+
func (gins *Gin) Query() url.Values {
|
167 |
+
return gins.ctx.Request.URL.Query()
|
168 |
+
}
|
169 |
+
|
170 |
+
// Request implements the method Adapter.Request.
|
171 |
+
func (gins *Gin) Request() *http.Request {
|
172 |
+
return gins.ctx.Request
|
173 |
+
}
|
adapter/gofiber/gofiber.go
ADDED
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package gofiber
|
6 |
+
|
7 |
+
import (
|
8 |
+
"errors"
|
9 |
+
"io"
|
10 |
+
"net/http"
|
11 |
+
"net/url"
|
12 |
+
"strings"
|
13 |
+
|
14 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
15 |
+
"github.com/GoAdminGroup/go-admin/context"
|
16 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
17 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
18 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
19 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
20 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant"
|
21 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
22 |
+
"github.com/gofiber/fiber/v2"
|
23 |
+
"github.com/valyala/fasthttp"
|
24 |
+
)
|
25 |
+
|
26 |
+
// Fasthttp structure value is a Fasthttp GoAdmin adapter.
|
27 |
+
type Gofiber struct {
|
28 |
+
adapter.BaseAdapter
|
29 |
+
ctx *fiber.Ctx
|
30 |
+
app *fiber.App
|
31 |
+
}
|
32 |
+
|
33 |
+
func init() {
|
34 |
+
engine.Register(new(Gofiber))
|
35 |
+
}
|
36 |
+
|
37 |
+
// User implements the method Adapter.User.
|
38 |
+
func (gof *Gofiber) User(ctx interface{}) (models.UserModel, bool) {
|
39 |
+
return gof.GetUser(ctx, gof)
|
40 |
+
}
|
41 |
+
|
42 |
+
// Use implements the method Adapter.Use.
|
43 |
+
func (gof *Gofiber) Use(app interface{}, plugs []plugins.Plugin) error {
|
44 |
+
return gof.GetUse(app, plugs, gof)
|
45 |
+
}
|
46 |
+
|
47 |
+
// Content implements the method Adapter.Content.
|
48 |
+
func (gof *Gofiber) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) {
|
49 |
+
gof.GetContent(ctx, getPanelFn, gof, btns, fn)
|
50 |
+
}
|
51 |
+
|
52 |
+
// SetApp implements the method Adapter.SetApp.
|
53 |
+
func (gof *Gofiber) SetApp(app interface{}) error {
|
54 |
+
var (
|
55 |
+
eng *fiber.App
|
56 |
+
ok bool
|
57 |
+
)
|
58 |
+
if eng, ok = app.(*fiber.App); !ok {
|
59 |
+
return errors.New("fiber.App adapter SetApp: wrong parameter")
|
60 |
+
}
|
61 |
+
|
62 |
+
gof.app = eng
|
63 |
+
return nil
|
64 |
+
}
|
65 |
+
|
66 |
+
// AddHandler implements the method Adapter.AddHandler.
|
67 |
+
func (gof *Gofiber) AddHandler(method, path string, handlers context.Handlers) {
|
68 |
+
|
69 |
+
gof.app.Add(strings.ToUpper(method), path, func(c *fiber.Ctx) error {
|
70 |
+
|
71 |
+
httpreq := convertCtx(c.Context())
|
72 |
+
ctx := context.NewContext(httpreq)
|
73 |
+
|
74 |
+
for _, key := range c.Route().Params {
|
75 |
+
if httpreq.URL.RawQuery == "" {
|
76 |
+
httpreq.URL.RawQuery += strings.ReplaceAll(key, ":", "") + "=" + c.Params(key)
|
77 |
+
} else {
|
78 |
+
httpreq.URL.RawQuery += "&" + strings.ReplaceAll(key, ":", "") + "=" + c.Params(key)
|
79 |
+
}
|
80 |
+
|
81 |
+
}
|
82 |
+
|
83 |
+
ctx.SetHandlers(handlers).Next()
|
84 |
+
for key, head := range ctx.Response.Header {
|
85 |
+
c.Set(key, head[0])
|
86 |
+
|
87 |
+
}
|
88 |
+
|
89 |
+
return c.Status(ctx.Response.StatusCode).SendStream(ctx.Response.Body)
|
90 |
+
|
91 |
+
})
|
92 |
+
|
93 |
+
}
|
94 |
+
|
95 |
+
func convertCtx(ctx *fasthttp.RequestCtx) *http.Request {
|
96 |
+
var r http.Request
|
97 |
+
|
98 |
+
body := ctx.PostBody()
|
99 |
+
r.Method = string(ctx.Method())
|
100 |
+
r.Proto = "HTTP/1.1"
|
101 |
+
r.ProtoMajor = 1
|
102 |
+
r.ProtoMinor = 1
|
103 |
+
r.RequestURI = string(ctx.RequestURI())
|
104 |
+
r.ContentLength = int64(len(body))
|
105 |
+
r.Host = string(ctx.Host())
|
106 |
+
r.RemoteAddr = ctx.RemoteAddr().String()
|
107 |
+
|
108 |
+
hdr := make(http.Header)
|
109 |
+
ctx.Request.Header.VisitAll(func(k, v []byte) {
|
110 |
+
sk := string(k)
|
111 |
+
sv := string(v)
|
112 |
+
switch sk {
|
113 |
+
case "Transfer-Encoding":
|
114 |
+
r.TransferEncoding = append(r.TransferEncoding, sv)
|
115 |
+
default:
|
116 |
+
hdr.Set(sk, sv)
|
117 |
+
}
|
118 |
+
})
|
119 |
+
r.Header = hdr
|
120 |
+
r.Body = &netHTTPBody{body}
|
121 |
+
rURL, err := url.ParseRequestURI(r.RequestURI)
|
122 |
+
if err != nil {
|
123 |
+
ctx.Logger().Printf("cannot parse requestURI %q: %s", r.RequestURI, err)
|
124 |
+
ctx.Error("Internal Server Error", fasthttp.StatusInternalServerError)
|
125 |
+
return &r
|
126 |
+
}
|
127 |
+
r.URL = rURL
|
128 |
+
return &r
|
129 |
+
}
|
130 |
+
|
131 |
+
type netHTTPBody struct {
|
132 |
+
b []byte
|
133 |
+
}
|
134 |
+
|
135 |
+
func (r *netHTTPBody) Read(p []byte) (int, error) {
|
136 |
+
if len(r.b) == 0 {
|
137 |
+
return 0, io.EOF
|
138 |
+
}
|
139 |
+
n := copy(p, r.b)
|
140 |
+
r.b = r.b[n:]
|
141 |
+
return n, nil
|
142 |
+
}
|
143 |
+
|
144 |
+
func (r *netHTTPBody) Close() error {
|
145 |
+
r.b = r.b[:0]
|
146 |
+
return nil
|
147 |
+
}
|
148 |
+
|
149 |
+
// Name implements the method Adapter.Name.
|
150 |
+
func (*Gofiber) Name() string {
|
151 |
+
return "gofiber"
|
152 |
+
}
|
153 |
+
|
154 |
+
// SetContext implements the method Adapter.SetContext.
|
155 |
+
func (*Gofiber) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
156 |
+
var (
|
157 |
+
ctx *fiber.Ctx
|
158 |
+
ok bool
|
159 |
+
)
|
160 |
+
if ctx, ok = contextInterface.(*fiber.Ctx); !ok {
|
161 |
+
panic("gofiber adapter SetContext: wrong parameter")
|
162 |
+
}
|
163 |
+
return &Gofiber{ctx: ctx}
|
164 |
+
}
|
165 |
+
|
166 |
+
// Redirect implements the method Adapter.Redirect.
|
167 |
+
func (gof *Gofiber) Redirect() {
|
168 |
+
_ = gof.ctx.Redirect(config.Url(config.GetLoginUrl()), http.StatusFound)
|
169 |
+
}
|
170 |
+
|
171 |
+
// SetContentType implements the method Adapter.SetContentType.
|
172 |
+
func (gof *Gofiber) SetContentType() {
|
173 |
+
gof.ctx.Response().Header.Set("Content-Type", gof.HTMLContentType())
|
174 |
+
}
|
175 |
+
|
176 |
+
// Write implements the method Adapter.Write.
|
177 |
+
func (gof *Gofiber) Write(body []byte) {
|
178 |
+
_, _ = gof.ctx.Write(body)
|
179 |
+
}
|
180 |
+
|
181 |
+
// GetCookie implements the method Adapter.GetCookie.
|
182 |
+
func (gof *Gofiber) GetCookie() (string, error) {
|
183 |
+
return string(gof.ctx.Cookies(gof.CookieKey())), nil
|
184 |
+
}
|
185 |
+
|
186 |
+
// Lang implements the method Adapter.Lang.
|
187 |
+
func (gof *Gofiber) Lang() string {
|
188 |
+
return string(gof.ctx.Request().URI().QueryArgs().Peek("__ga_lang"))
|
189 |
+
}
|
190 |
+
|
191 |
+
// Path implements the method Adapter.Path.
|
192 |
+
func (gof *Gofiber) Path() string {
|
193 |
+
return string(gof.ctx.Path())
|
194 |
+
}
|
195 |
+
|
196 |
+
// Method implements the method Adapter.Method.
|
197 |
+
func (gof *Gofiber) Method() string {
|
198 |
+
return string(gof.ctx.Method())
|
199 |
+
}
|
200 |
+
|
201 |
+
// FormParam implements the method Adapter.FormParam.
|
202 |
+
func (gof *Gofiber) FormParam() url.Values {
|
203 |
+
f, _ := gof.ctx.MultipartForm()
|
204 |
+
if f != nil {
|
205 |
+
return f.Value
|
206 |
+
}
|
207 |
+
return url.Values{}
|
208 |
+
}
|
209 |
+
|
210 |
+
// IsPjax implements the method Adapter.IsPjax.
|
211 |
+
func (gof *Gofiber) IsPjax() bool {
|
212 |
+
return string(gof.ctx.Request().Header.Peek(constant.PjaxHeader)) == "true"
|
213 |
+
}
|
214 |
+
|
215 |
+
// Query implements the method Adapter.Query.
|
216 |
+
func (gof *Gofiber) Query() url.Values {
|
217 |
+
queryStr := gof.ctx.Context().QueryArgs().QueryString()
|
218 |
+
queryObj, err := url.Parse(string(queryStr))
|
219 |
+
|
220 |
+
if err != nil {
|
221 |
+
return url.Values{}
|
222 |
+
}
|
223 |
+
|
224 |
+
return queryObj.Query()
|
225 |
+
}
|
226 |
+
|
227 |
+
// Request implements the method Adapter.Request.
|
228 |
+
func (gof *Gofiber) Request() *http.Request {
|
229 |
+
return convertCtx(gof.ctx.Context())
|
230 |
+
}
|
adapter/gorilla/gorilla.go
ADDED
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package gorilla
|
6 |
+
|
7 |
+
import (
|
8 |
+
"bytes"
|
9 |
+
"errors"
|
10 |
+
"net/http"
|
11 |
+
"net/url"
|
12 |
+
"regexp"
|
13 |
+
"strings"
|
14 |
+
|
15 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
16 |
+
"github.com/GoAdminGroup/go-admin/context"
|
17 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
18 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
19 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
20 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
21 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant"
|
22 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
23 |
+
"github.com/gorilla/mux"
|
24 |
+
)
|
25 |
+
|
26 |
+
// Gorilla structure value is a Gorilla GoAdmin adapter.
|
27 |
+
type Gorilla struct {
|
28 |
+
adapter.BaseAdapter
|
29 |
+
ctx Context
|
30 |
+
app *mux.Router
|
31 |
+
}
|
32 |
+
|
33 |
+
func init() {
|
34 |
+
engine.Register(new(Gorilla))
|
35 |
+
}
|
36 |
+
|
37 |
+
// User implements the method Adapter.User.
|
38 |
+
func (g *Gorilla) User(ctx interface{}) (models.UserModel, bool) {
|
39 |
+
return g.GetUser(ctx, g)
|
40 |
+
}
|
41 |
+
|
42 |
+
// Use implements the method Adapter.Use.
|
43 |
+
func (g *Gorilla) Use(app interface{}, plugs []plugins.Plugin) error {
|
44 |
+
return g.GetUse(app, plugs, g)
|
45 |
+
}
|
46 |
+
|
47 |
+
// Content implements the method Adapter.Content.
|
48 |
+
func (g *Gorilla) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) {
|
49 |
+
g.GetContent(ctx, getPanelFn, g, btns, fn)
|
50 |
+
}
|
51 |
+
|
52 |
+
type HandlerFunc func(ctx Context) (types.Panel, error)
|
53 |
+
|
54 |
+
func Content(handler HandlerFunc) http.HandlerFunc {
|
55 |
+
return func(writer http.ResponseWriter, request *http.Request) {
|
56 |
+
ctx := Context{
|
57 |
+
Request: request,
|
58 |
+
Response: writer,
|
59 |
+
}
|
60 |
+
engine.Content(ctx, func(ctx interface{}) (types.Panel, error) {
|
61 |
+
return handler(ctx.(Context))
|
62 |
+
})
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
// SetApp implements the method Adapter.SetApp.
|
67 |
+
func (g *Gorilla) SetApp(app interface{}) error {
|
68 |
+
var (
|
69 |
+
eng *mux.Router
|
70 |
+
ok bool
|
71 |
+
)
|
72 |
+
if eng, ok = app.(*mux.Router); !ok {
|
73 |
+
return errors.New("gorilla adapter SetApp: wrong parameter")
|
74 |
+
}
|
75 |
+
g.app = eng
|
76 |
+
return nil
|
77 |
+
}
|
78 |
+
|
79 |
+
// AddHandler implements the method Adapter.AddHandler.
|
80 |
+
func (g *Gorilla) AddHandler(method, path string, handlers context.Handlers) {
|
81 |
+
|
82 |
+
reg1 := regexp.MustCompile(":(.*?)/")
|
83 |
+
reg2 := regexp.MustCompile(":(.*?)$")
|
84 |
+
|
85 |
+
u := path
|
86 |
+
u = reg1.ReplaceAllString(u, "{$1}/")
|
87 |
+
u = reg2.ReplaceAllString(u, "{$1}")
|
88 |
+
|
89 |
+
g.app.HandleFunc(u, func(w http.ResponseWriter, r *http.Request) {
|
90 |
+
ctx := context.NewContext(r)
|
91 |
+
|
92 |
+
params := mux.Vars(r)
|
93 |
+
|
94 |
+
for key, param := range params {
|
95 |
+
if r.URL.RawQuery == "" {
|
96 |
+
r.URL.RawQuery += strings.ReplaceAll(key, ":", "") + "=" + param
|
97 |
+
} else {
|
98 |
+
r.URL.RawQuery += "&" + strings.ReplaceAll(key, ":", "") + "=" + param
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
ctx.SetHandlers(handlers).Next()
|
103 |
+
for key, head := range ctx.Response.Header {
|
104 |
+
w.Header().Add(key, head[0])
|
105 |
+
}
|
106 |
+
|
107 |
+
if ctx.Response.Body == nil {
|
108 |
+
w.WriteHeader(ctx.Response.StatusCode)
|
109 |
+
return
|
110 |
+
}
|
111 |
+
|
112 |
+
w.WriteHeader(ctx.Response.StatusCode)
|
113 |
+
|
114 |
+
buf := new(bytes.Buffer)
|
115 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
116 |
+
|
117 |
+
_, err := w.Write(buf.Bytes())
|
118 |
+
if err != nil {
|
119 |
+
w.WriteHeader(http.StatusInternalServerError)
|
120 |
+
return
|
121 |
+
}
|
122 |
+
}).Methods(strings.ToUpper(method))
|
123 |
+
}
|
124 |
+
|
125 |
+
// Context wraps the Request and Response object of Gorilla.
|
126 |
+
type Context struct {
|
127 |
+
Request *http.Request
|
128 |
+
Response http.ResponseWriter
|
129 |
+
}
|
130 |
+
|
131 |
+
// Name implements the method Adapter.Name.
|
132 |
+
func (*Gorilla) Name() string {
|
133 |
+
return "gorilla"
|
134 |
+
}
|
135 |
+
|
136 |
+
// SetContext implements the method Adapter.SetContext.
|
137 |
+
func (*Gorilla) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
138 |
+
var (
|
139 |
+
ctx Context
|
140 |
+
ok bool
|
141 |
+
)
|
142 |
+
if ctx, ok = contextInterface.(Context); !ok {
|
143 |
+
panic("gorilla adapter SetContext: wrong parameter")
|
144 |
+
}
|
145 |
+
|
146 |
+
return &Gorilla{ctx: ctx}
|
147 |
+
}
|
148 |
+
|
149 |
+
// Redirect implements the method Adapter.Redirect.
|
150 |
+
func (g *Gorilla) Redirect() {
|
151 |
+
http.Redirect(g.ctx.Response, g.ctx.Request, config.Url(config.GetLoginUrl()), http.StatusFound)
|
152 |
+
}
|
153 |
+
|
154 |
+
// SetContentType implements the method Adapter.SetContentType.
|
155 |
+
func (g *Gorilla) SetContentType() {
|
156 |
+
g.ctx.Response.Header().Set("Content-Type", g.HTMLContentType())
|
157 |
+
}
|
158 |
+
|
159 |
+
// Write implements the method Adapter.Write.
|
160 |
+
func (g *Gorilla) Write(body []byte) {
|
161 |
+
_, _ = g.ctx.Response.Write(body)
|
162 |
+
}
|
163 |
+
|
164 |
+
// GetCookie implements the method Adapter.GetCookie.
|
165 |
+
func (g *Gorilla) GetCookie() (string, error) {
|
166 |
+
cookie, err := g.ctx.Request.Cookie(g.CookieKey())
|
167 |
+
if err != nil {
|
168 |
+
return "", err
|
169 |
+
}
|
170 |
+
return cookie.Value, err
|
171 |
+
}
|
172 |
+
|
173 |
+
// Lang implements the method Adapter.Lang.
|
174 |
+
func (g *Gorilla) Lang() string {
|
175 |
+
return g.ctx.Request.URL.Query().Get("__ga_lang")
|
176 |
+
}
|
177 |
+
|
178 |
+
// Path implements the method Adapter.Path.
|
179 |
+
func (g *Gorilla) Path() string {
|
180 |
+
return g.ctx.Request.RequestURI
|
181 |
+
}
|
182 |
+
|
183 |
+
// Method implements the method Adapter.Method.
|
184 |
+
func (g *Gorilla) Method() string {
|
185 |
+
return g.ctx.Request.Method
|
186 |
+
}
|
187 |
+
|
188 |
+
// FormParam implements the method Adapter.FormParam.
|
189 |
+
func (g *Gorilla) FormParam() url.Values {
|
190 |
+
_ = g.ctx.Request.ParseMultipartForm(32 << 20)
|
191 |
+
return g.ctx.Request.PostForm
|
192 |
+
}
|
193 |
+
|
194 |
+
// IsPjax implements the method Adapter.IsPjax.
|
195 |
+
func (g *Gorilla) IsPjax() bool {
|
196 |
+
return g.ctx.Request.Header.Get(constant.PjaxHeader) == "true"
|
197 |
+
}
|
198 |
+
|
199 |
+
// Query implements the method Adapter.Query.
|
200 |
+
func (g *Gorilla) Query() url.Values {
|
201 |
+
return g.ctx.Request.URL.Query()
|
202 |
+
}
|
203 |
+
|
204 |
+
// Request implements the method Adapter.Request.
|
205 |
+
func (g *Gorilla) Request() *http.Request {
|
206 |
+
return g.ctx.Request
|
207 |
+
}
|
adapter/iris/iris.go
ADDED
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package iris
|
6 |
+
|
7 |
+
import (
|
8 |
+
"bytes"
|
9 |
+
"errors"
|
10 |
+
"net/http"
|
11 |
+
"net/url"
|
12 |
+
"strings"
|
13 |
+
|
14 |
+
"github.com/GoAdminGroup/go-admin/adapter"
|
15 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/models"
|
16 |
+
"github.com/GoAdminGroup/go-admin/template/types"
|
17 |
+
"github.com/kataras/iris/v12"
|
18 |
+
|
19 |
+
"github.com/GoAdminGroup/go-admin/context"
|
20 |
+
"github.com/GoAdminGroup/go-admin/engine"
|
21 |
+
"github.com/GoAdminGroup/go-admin/modules/config"
|
22 |
+
"github.com/GoAdminGroup/go-admin/plugins"
|
23 |
+
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant"
|
24 |
+
)
|
25 |
+
|
26 |
+
// Iris structure value is an Iris GoAdmin adapter.
|
27 |
+
type Iris struct {
|
28 |
+
adapter.BaseAdapter
|
29 |
+
ctx iris.Context
|
30 |
+
app *iris.Application
|
31 |
+
}
|
32 |
+
|
33 |
+
func init() {
|
34 |
+
engine.Register(new(Iris))
|
35 |
+
}
|
36 |
+
|
37 |
+
// User implements the method Adapter.User.
|
38 |
+
func (is *Iris) User(ctx interface{}) (models.UserModel, bool) {
|
39 |
+
return is.GetUser(ctx, is)
|
40 |
+
}
|
41 |
+
|
42 |
+
// Use implements the method Adapter.Use.
|
43 |
+
func (is *Iris) Use(app interface{}, plugs []plugins.Plugin) error {
|
44 |
+
return is.GetUse(app, plugs, is)
|
45 |
+
}
|
46 |
+
|
47 |
+
// Content implements the method Adapter.Content.
|
48 |
+
func (is *Iris) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) {
|
49 |
+
is.GetContent(ctx, getPanelFn, is, btns, fn)
|
50 |
+
}
|
51 |
+
|
52 |
+
type HandlerFunc func(ctx iris.Context) (types.Panel, error)
|
53 |
+
|
54 |
+
func Content(handler HandlerFunc) iris.Handler {
|
55 |
+
return func(ctx iris.Context) {
|
56 |
+
engine.Content(ctx, func(ctx interface{}) (types.Panel, error) {
|
57 |
+
return handler(ctx.(iris.Context))
|
58 |
+
})
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
// SetApp implements the method Adapter.SetApp.
|
63 |
+
func (is *Iris) SetApp(app interface{}) error {
|
64 |
+
var (
|
65 |
+
eng *iris.Application
|
66 |
+
ok bool
|
67 |
+
)
|
68 |
+
if eng, ok = app.(*iris.Application); !ok {
|
69 |
+
return errors.New("iris adapter SetApp: wrong parameter")
|
70 |
+
}
|
71 |
+
is.app = eng
|
72 |
+
return nil
|
73 |
+
}
|
74 |
+
|
75 |
+
// AddHandler implements the method Adapter.AddHandler.
|
76 |
+
func (is *Iris) AddHandler(method, path string, handlers context.Handlers) {
|
77 |
+
is.app.Handle(strings.ToUpper(method), path, func(c iris.Context) {
|
78 |
+
ctx := context.NewContext(c.Request())
|
79 |
+
|
80 |
+
var params = map[string]string{}
|
81 |
+
c.Params().Visit(func(key string, value string) {
|
82 |
+
params[key] = value
|
83 |
+
})
|
84 |
+
|
85 |
+
for key, value := range params {
|
86 |
+
if c.Request().URL.RawQuery == "" {
|
87 |
+
c.Request().URL.RawQuery += strings.ReplaceAll(key, ":", "") + "=" + value
|
88 |
+
} else {
|
89 |
+
c.Request().URL.RawQuery += "&" + strings.ReplaceAll(key, ":", "") + "=" + value
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
ctx.SetHandlers(handlers).Next()
|
94 |
+
for key, head := range ctx.Response.Header {
|
95 |
+
c.Header(key, head[0])
|
96 |
+
}
|
97 |
+
c.StatusCode(ctx.Response.StatusCode)
|
98 |
+
if ctx.Response.Body != nil {
|
99 |
+
buf := new(bytes.Buffer)
|
100 |
+
_, _ = buf.ReadFrom(ctx.Response.Body)
|
101 |
+
_, _ = c.WriteString(buf.String())
|
102 |
+
}
|
103 |
+
})
|
104 |
+
}
|
105 |
+
|
106 |
+
// Name implements the method Adapter.Name.
|
107 |
+
func (*Iris) Name() string {
|
108 |
+
return "iris"
|
109 |
+
}
|
110 |
+
|
111 |
+
// SetContext implements the method Adapter.SetContext.
|
112 |
+
func (*Iris) SetContext(contextInterface interface{}) adapter.WebFrameWork {
|
113 |
+
var (
|
114 |
+
ctx iris.Context
|
115 |
+
ok bool
|
116 |
+
)
|
117 |
+
if ctx, ok = contextInterface.(iris.Context); !ok {
|
118 |
+
panic("iris adapter SetContext: wrong parameter")
|
119 |
+
}
|
120 |
+
|
121 |
+
return &Iris{ctx: ctx}
|
122 |
+
}
|
123 |
+
|
124 |
+
// Redirect implements the method Adapter.Redirect.
|
125 |
+
func (is *Iris) Redirect() {
|
126 |
+
is.ctx.Redirect(config.Url(config.GetLoginUrl()), http.StatusFound)
|
127 |
+
}
|
128 |
+
|
129 |
+
// SetContentType implements the method Adapter.SetContentType.
|
130 |
+
func (is *Iris) SetContentType() {
|
131 |
+
is.ctx.Header("Content-Type", is.HTMLContentType())
|
132 |
+
}
|
133 |
+
|
134 |
+
// Write implements the method Adapter.Write.
|
135 |
+
func (is *Iris) Write(body []byte) {
|
136 |
+
_, _ = is.ctx.Write(body)
|
137 |
+
}
|
138 |
+
|
139 |
+
// GetCookie implements the method Adapter.GetCookie.
|
140 |
+
func (is *Iris) GetCookie() (string, error) {
|
141 |
+
return is.ctx.GetCookie(is.CookieKey()), nil
|
142 |
+
}
|
143 |
+
|
144 |
+
// Lang implements the method Adapter.Lang.
|
145 |
+
func (is *Iris) Lang() string {
|
146 |
+
return is.ctx.Request().URL.Query().Get("__ga_lang")
|
147 |
+
}
|
148 |
+
|
149 |
+
// Path implements the method Adapter.Path.
|
150 |
+
func (is *Iris) Path() string {
|
151 |
+
return is.ctx.Path()
|
152 |
+
}
|
153 |
+
|
154 |
+
// Method implements the method Adapter.Method.
|
155 |
+
func (is *Iris) Method() string {
|
156 |
+
return is.ctx.Method()
|
157 |
+
}
|
158 |
+
|
159 |
+
// FormParam implements the method Adapter.FormParam.
|
160 |
+
func (is *Iris) FormParam() url.Values {
|
161 |
+
return is.ctx.FormValues()
|
162 |
+
}
|
163 |
+
|
164 |
+
// IsPjax implements the method Adapter.IsPjax.
|
165 |
+
func (is *Iris) IsPjax() bool {
|
166 |
+
return is.ctx.GetHeader(constant.PjaxHeader) == "true"
|
167 |
+
}
|
168 |
+
|
169 |
+
// Query implements the method Adapter.Query.
|
170 |
+
func (is *Iris) Query() url.Values {
|
171 |
+
return is.ctx.Request().URL.Query()
|
172 |
+
}
|
173 |
+
|
174 |
+
// Request implements the method Adapter.Request.
|
175 |
+
func (is *Iris) Request() *http.Request {
|
176 |
+
return is.ctx.Request()
|
177 |
+
}
|
context/context.go
ADDED
@@ -0,0 +1,781 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package context
|
6 |
+
|
7 |
+
import (
|
8 |
+
"bytes"
|
9 |
+
"encoding/json"
|
10 |
+
"errors"
|
11 |
+
"fmt"
|
12 |
+
"io"
|
13 |
+
"math"
|
14 |
+
"net"
|
15 |
+
"net/http"
|
16 |
+
"net/url"
|
17 |
+
"os"
|
18 |
+
"path"
|
19 |
+
"strings"
|
20 |
+
"time"
|
21 |
+
|
22 |
+
"github.com/GoAdminGroup/go-admin/modules/constant"
|
23 |
+
)
|
24 |
+
|
25 |
+
const abortIndex int8 = math.MaxInt8 / 2
|
26 |
+
|
27 |
+
// Context is the simplify version of web framework context.
|
28 |
+
// But it is important which will be used in plugins to custom
|
29 |
+
// the request and response. And adapter will help to transform
|
30 |
+
// the Context to the web framework`s context. It has three attributes.
|
31 |
+
// Request and response are belongs to net/http package. UserValue
|
32 |
+
// is the custom key-value store of context.
|
33 |
+
type Context struct {
|
34 |
+
Request *http.Request
|
35 |
+
Response *http.Response
|
36 |
+
UserValue map[string]interface{}
|
37 |
+
index int8
|
38 |
+
handlers Handlers
|
39 |
+
}
|
40 |
+
|
41 |
+
// Path is used in the matching of request and response. Url stores the
|
42 |
+
// raw register url. RegUrl contains the wildcard which on behalf of
|
43 |
+
// the route params.
|
44 |
+
type Path struct {
|
45 |
+
URL string
|
46 |
+
Method string
|
47 |
+
}
|
48 |
+
|
49 |
+
type RouterMap map[string]Router
|
50 |
+
|
51 |
+
func (r RouterMap) Get(name string) Router {
|
52 |
+
return r[name]
|
53 |
+
}
|
54 |
+
|
55 |
+
type Router struct {
|
56 |
+
Methods []string
|
57 |
+
Patten string
|
58 |
+
}
|
59 |
+
|
60 |
+
func (r Router) Method() string {
|
61 |
+
return r.Methods[0]
|
62 |
+
}
|
63 |
+
|
64 |
+
func (r Router) GetURL(value ...string) string {
|
65 |
+
u := r.Patten
|
66 |
+
for i := 0; i < len(value); i += 2 {
|
67 |
+
u = strings.ReplaceAll(u, ":__"+value[i], value[i+1])
|
68 |
+
}
|
69 |
+
return u
|
70 |
+
}
|
71 |
+
|
72 |
+
type NodeProcessor func(...Node)
|
73 |
+
|
74 |
+
type Node struct {
|
75 |
+
Path string
|
76 |
+
Method string
|
77 |
+
Handlers []Handler
|
78 |
+
Value map[string]interface{}
|
79 |
+
}
|
80 |
+
|
81 |
+
// SetUserValue set the value of user context.
|
82 |
+
func (ctx *Context) SetUserValue(key string, value interface{}) {
|
83 |
+
ctx.UserValue[key] = value
|
84 |
+
}
|
85 |
+
|
86 |
+
// GetUserValue get the value of key.
|
87 |
+
func (ctx *Context) GetUserValue(key string) interface{} {
|
88 |
+
return ctx.UserValue[key]
|
89 |
+
}
|
90 |
+
|
91 |
+
// Path return the url path.
|
92 |
+
func (ctx *Context) Path() string {
|
93 |
+
return ctx.Request.URL.Path
|
94 |
+
}
|
95 |
+
|
96 |
+
// Abort abort the context.
|
97 |
+
func (ctx *Context) Abort() {
|
98 |
+
ctx.index = abortIndex
|
99 |
+
}
|
100 |
+
|
101 |
+
// Next should be used only inside middleware.
|
102 |
+
func (ctx *Context) Next() {
|
103 |
+
ctx.index++
|
104 |
+
for s := int8(len(ctx.handlers)); ctx.index < s; ctx.index++ {
|
105 |
+
ctx.handlers[ctx.index](ctx)
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
// SetHandlers set the handlers of Context.
|
110 |
+
func (ctx *Context) SetHandlers(handlers Handlers) *Context {
|
111 |
+
ctx.handlers = handlers
|
112 |
+
return ctx
|
113 |
+
}
|
114 |
+
|
115 |
+
// Method return the request method.
|
116 |
+
func (ctx *Context) Method() string {
|
117 |
+
return ctx.Request.Method
|
118 |
+
}
|
119 |
+
|
120 |
+
// NewContext used in adapter which return a Context with request
|
121 |
+
// and slice of UserValue and a default Response.
|
122 |
+
func NewContext(req *http.Request) *Context {
|
123 |
+
|
124 |
+
return &Context{
|
125 |
+
Request: req,
|
126 |
+
UserValue: make(map[string]interface{}),
|
127 |
+
Response: &http.Response{
|
128 |
+
StatusCode: http.StatusOK,
|
129 |
+
Header: make(http.Header),
|
130 |
+
},
|
131 |
+
index: -1,
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
const (
|
136 |
+
HeaderContentType = "Content-Type"
|
137 |
+
|
138 |
+
HeaderLastModified = "Last-Modified"
|
139 |
+
HeaderIfModifiedSince = "If-Modified-Since"
|
140 |
+
HeaderCacheControl = "Cache-Control"
|
141 |
+
HeaderETag = "ETag"
|
142 |
+
|
143 |
+
HeaderContentDisposition = "Content-Disposition"
|
144 |
+
HeaderContentLength = "Content-Length"
|
145 |
+
HeaderContentEncoding = "Content-Encoding"
|
146 |
+
|
147 |
+
GzipHeaderValue = "gzip"
|
148 |
+
HeaderAcceptEncoding = "Accept-Encoding"
|
149 |
+
HeaderVary = "Vary"
|
150 |
+
|
151 |
+
ThemeKey = "__ga_theme"
|
152 |
+
)
|
153 |
+
|
154 |
+
func (ctx *Context) BindJSON(data interface{}) error {
|
155 |
+
if ctx.Request.Body != nil {
|
156 |
+
b, err := io.ReadAll(ctx.Request.Body)
|
157 |
+
if err == nil {
|
158 |
+
return json.Unmarshal(b, data)
|
159 |
+
}
|
160 |
+
return err
|
161 |
+
}
|
162 |
+
return errors.New("empty request body")
|
163 |
+
}
|
164 |
+
|
165 |
+
func (ctx *Context) MustBindJSON(data interface{}) {
|
166 |
+
if ctx.Request.Body != nil {
|
167 |
+
b, err := io.ReadAll(ctx.Request.Body)
|
168 |
+
if err != nil {
|
169 |
+
panic(err)
|
170 |
+
}
|
171 |
+
err = json.Unmarshal(b, data)
|
172 |
+
if err != nil {
|
173 |
+
panic(err)
|
174 |
+
}
|
175 |
+
}
|
176 |
+
panic("empty request body")
|
177 |
+
}
|
178 |
+
|
179 |
+
// Write save the given status code, headers and body string into the response.
|
180 |
+
func (ctx *Context) Write(code int, header map[string]string, Body string) {
|
181 |
+
ctx.Response.StatusCode = code
|
182 |
+
for key, head := range header {
|
183 |
+
ctx.AddHeader(key, head)
|
184 |
+
}
|
185 |
+
ctx.Response.Body = io.NopCloser(strings.NewReader(Body))
|
186 |
+
}
|
187 |
+
|
188 |
+
// JSON serializes the given struct as JSON into the response body.
|
189 |
+
// It also sets the Content-Type as "application/json".
|
190 |
+
func (ctx *Context) JSON(code int, Body map[string]interface{}) {
|
191 |
+
ctx.Response.StatusCode = code
|
192 |
+
ctx.SetContentType("application/json")
|
193 |
+
BodyStr, err := json.Marshal(Body)
|
194 |
+
if err != nil {
|
195 |
+
panic(err)
|
196 |
+
}
|
197 |
+
ctx.Response.Body = io.NopCloser(bytes.NewReader(BodyStr))
|
198 |
+
}
|
199 |
+
|
200 |
+
// DataWithHeaders save the given status code, headers and body data into the response.
|
201 |
+
func (ctx *Context) DataWithHeaders(code int, header map[string]string, data []byte) {
|
202 |
+
ctx.Response.StatusCode = code
|
203 |
+
for key, head := range header {
|
204 |
+
ctx.AddHeader(key, head)
|
205 |
+
}
|
206 |
+
ctx.Response.Body = io.NopCloser(bytes.NewBuffer(data))
|
207 |
+
}
|
208 |
+
|
209 |
+
// Data writes some data into the body stream and updates the HTTP code.
|
210 |
+
func (ctx *Context) Data(code int, contentType string, data []byte) {
|
211 |
+
ctx.Response.StatusCode = code
|
212 |
+
ctx.SetContentType(contentType)
|
213 |
+
ctx.Response.Body = io.NopCloser(bytes.NewBuffer(data))
|
214 |
+
}
|
215 |
+
|
216 |
+
// Redirect add redirect url to header.
|
217 |
+
func (ctx *Context) Redirect(path string) {
|
218 |
+
ctx.Response.StatusCode = http.StatusFound
|
219 |
+
ctx.SetContentType("text/html; charset=utf-8")
|
220 |
+
ctx.AddHeader("Location", path)
|
221 |
+
}
|
222 |
+
|
223 |
+
// HTML output html response.
|
224 |
+
func (ctx *Context) HTML(code int, body string) {
|
225 |
+
ctx.SetContentType("text/html; charset=utf-8")
|
226 |
+
ctx.SetStatusCode(code)
|
227 |
+
ctx.WriteString(body)
|
228 |
+
}
|
229 |
+
|
230 |
+
// HTMLByte output html response.
|
231 |
+
func (ctx *Context) HTMLByte(code int, body []byte) {
|
232 |
+
ctx.SetContentType("text/html; charset=utf-8")
|
233 |
+
ctx.SetStatusCode(code)
|
234 |
+
ctx.Response.Body = io.NopCloser(bytes.NewBuffer(body))
|
235 |
+
}
|
236 |
+
|
237 |
+
// WriteString save the given body string into the response.
|
238 |
+
func (ctx *Context) WriteString(body string) {
|
239 |
+
ctx.Response.Body = io.NopCloser(strings.NewReader(body))
|
240 |
+
}
|
241 |
+
|
242 |
+
// SetStatusCode save the given status code into the response.
|
243 |
+
func (ctx *Context) SetStatusCode(code int) {
|
244 |
+
ctx.Response.StatusCode = code
|
245 |
+
}
|
246 |
+
|
247 |
+
// SetContentType save the given content type header into the response header.
|
248 |
+
func (ctx *Context) SetContentType(contentType string) {
|
249 |
+
ctx.AddHeader(HeaderContentType, contentType)
|
250 |
+
}
|
251 |
+
|
252 |
+
func (ctx *Context) SetLastModified(modtime time.Time) {
|
253 |
+
if !IsZeroTime(modtime) {
|
254 |
+
ctx.AddHeader(HeaderLastModified, modtime.UTC().Format(http.TimeFormat)) // or modtime.UTC()?
|
255 |
+
}
|
256 |
+
}
|
257 |
+
|
258 |
+
var unixEpochTime = time.Unix(0, 0)
|
259 |
+
|
260 |
+
// IsZeroTime reports whether t is obviously unspecified (either zero or Unix()=0).
|
261 |
+
func IsZeroTime(t time.Time) bool {
|
262 |
+
return t.IsZero() || t.Equal(unixEpochTime)
|
263 |
+
}
|
264 |
+
|
265 |
+
// ParseTime parses a time header (such as the Date: header),
|
266 |
+
// trying each forth formats
|
267 |
+
// that are allowed by HTTP/1.1:
|
268 |
+
// time.RFC850, and time.ANSIC.
|
269 |
+
var ParseTime = func(text string) (t time.Time, err error) {
|
270 |
+
t, err = time.Parse(http.TimeFormat, text)
|
271 |
+
if err != nil {
|
272 |
+
return http.ParseTime(text)
|
273 |
+
}
|
274 |
+
|
275 |
+
return
|
276 |
+
}
|
277 |
+
|
278 |
+
func (ctx *Context) WriteNotModified() {
|
279 |
+
// RFC 7232 section 4.1:
|
280 |
+
// a sender SHOULD NOT generate representation metadata other than the
|
281 |
+
// above listed fields unless said metadata exists for the purpose of
|
282 |
+
// guiding cache updates (e.g.," Last-Modified" might be useful if the
|
283 |
+
// response does not have an ETag field).
|
284 |
+
delete(ctx.Response.Header, HeaderContentType)
|
285 |
+
delete(ctx.Response.Header, HeaderContentLength)
|
286 |
+
if ctx.Headers(HeaderETag) != "" {
|
287 |
+
delete(ctx.Response.Header, HeaderLastModified)
|
288 |
+
}
|
289 |
+
ctx.SetStatusCode(http.StatusNotModified)
|
290 |
+
}
|
291 |
+
|
292 |
+
func (ctx *Context) CheckIfModifiedSince(modtime time.Time) (bool, error) {
|
293 |
+
if method := ctx.Method(); method != http.MethodGet && method != http.MethodHead {
|
294 |
+
return false, errors.New("skip: method")
|
295 |
+
}
|
296 |
+
ims := ctx.Headers(HeaderIfModifiedSince)
|
297 |
+
if ims == "" || IsZeroTime(modtime) {
|
298 |
+
return false, errors.New("skip: zero time")
|
299 |
+
}
|
300 |
+
t, err := ParseTime(ims)
|
301 |
+
if err != nil {
|
302 |
+
return false, errors.New("skip: " + err.Error())
|
303 |
+
}
|
304 |
+
// sub-second precision, so
|
305 |
+
// use mtime < t+1s instead of mtime <= t to check for unmodified.
|
306 |
+
if modtime.UTC().Before(t.Add(1 * time.Second)) {
|
307 |
+
return false, nil
|
308 |
+
}
|
309 |
+
return true, nil
|
310 |
+
}
|
311 |
+
|
312 |
+
// LocalIP return the request client ip.
|
313 |
+
func (ctx *Context) LocalIP() string {
|
314 |
+
xForwardedFor := ctx.Request.Header.Get("X-Forwarded-For")
|
315 |
+
ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
|
316 |
+
if ip != "" {
|
317 |
+
return ip
|
318 |
+
}
|
319 |
+
|
320 |
+
ip = strings.TrimSpace(ctx.Request.Header.Get("X-Real-Ip"))
|
321 |
+
if ip != "" {
|
322 |
+
return ip
|
323 |
+
}
|
324 |
+
|
325 |
+
if ip, _, err := net.SplitHostPort(strings.TrimSpace(ctx.Request.RemoteAddr)); err == nil {
|
326 |
+
return ip
|
327 |
+
}
|
328 |
+
|
329 |
+
return "127.0.0.1"
|
330 |
+
}
|
331 |
+
|
332 |
+
// SetCookie save the given cookie obj into the response Set-Cookie header.
|
333 |
+
func (ctx *Context) SetCookie(cookie *http.Cookie) {
|
334 |
+
if v := cookie.String(); v != "" {
|
335 |
+
ctx.AddHeader("Set-Cookie", v)
|
336 |
+
}
|
337 |
+
}
|
338 |
+
|
339 |
+
// Query get the query parameter of url.
|
340 |
+
func (ctx *Context) Query(key string) string {
|
341 |
+
return ctx.Request.URL.Query().Get(key)
|
342 |
+
}
|
343 |
+
|
344 |
+
// QueryAll get the query parameters of url.
|
345 |
+
func (ctx *Context) QueryAll(key string) []string {
|
346 |
+
return ctx.Request.URL.Query()[key]
|
347 |
+
}
|
348 |
+
|
349 |
+
// QueryDefault get the query parameter of url. If it is empty, return the default.
|
350 |
+
func (ctx *Context) QueryDefault(key, def string) string {
|
351 |
+
value := ctx.Query(key)
|
352 |
+
if value == "" {
|
353 |
+
return def
|
354 |
+
}
|
355 |
+
return value
|
356 |
+
}
|
357 |
+
|
358 |
+
// Lang get the query parameter of url with given key __ga_lang.
|
359 |
+
func (ctx *Context) Lang() string {
|
360 |
+
return ctx.Query("__ga_lang")
|
361 |
+
}
|
362 |
+
|
363 |
+
// Theme get the request theme with given key __ga_theme.
|
364 |
+
func (ctx *Context) Theme() string {
|
365 |
+
queryTheme := ctx.Query(ThemeKey)
|
366 |
+
if queryTheme != "" {
|
367 |
+
return queryTheme
|
368 |
+
}
|
369 |
+
cookieTheme := ctx.Cookie(ThemeKey)
|
370 |
+
if cookieTheme != "" {
|
371 |
+
return cookieTheme
|
372 |
+
}
|
373 |
+
return ctx.RefererQuery(ThemeKey)
|
374 |
+
}
|
375 |
+
|
376 |
+
// Headers get the value of request headers key.
|
377 |
+
func (ctx *Context) Headers(key string) string {
|
378 |
+
return ctx.Request.Header.Get(key)
|
379 |
+
}
|
380 |
+
|
381 |
+
// Referer get the url string of request header Referer.
|
382 |
+
func (ctx *Context) Referer() string {
|
383 |
+
return ctx.Headers("Referer")
|
384 |
+
}
|
385 |
+
|
386 |
+
// RefererURL get the url.URL object of request header Referer.
|
387 |
+
func (ctx *Context) RefererURL() *url.URL {
|
388 |
+
ref := ctx.Headers("Referer")
|
389 |
+
if ref == "" {
|
390 |
+
return nil
|
391 |
+
}
|
392 |
+
u, err := url.Parse(ref)
|
393 |
+
if err != nil {
|
394 |
+
return nil
|
395 |
+
}
|
396 |
+
return u
|
397 |
+
}
|
398 |
+
|
399 |
+
// RefererQuery retrieve the value of given key from url.URL object of request header Referer.
|
400 |
+
func (ctx *Context) RefererQuery(key string) string {
|
401 |
+
if u := ctx.RefererURL(); u != nil {
|
402 |
+
return u.Query().Get(key)
|
403 |
+
}
|
404 |
+
return ""
|
405 |
+
}
|
406 |
+
|
407 |
+
// FormValue get the value of request form key.
|
408 |
+
func (ctx *Context) FormValue(key string) string {
|
409 |
+
return ctx.Request.FormValue(key)
|
410 |
+
}
|
411 |
+
|
412 |
+
// PostForm get the values of request form.
|
413 |
+
func (ctx *Context) PostForm() url.Values {
|
414 |
+
_ = ctx.Request.ParseMultipartForm(32 << 20)
|
415 |
+
return ctx.Request.PostForm
|
416 |
+
}
|
417 |
+
|
418 |
+
func (ctx *Context) WantHTML() bool {
|
419 |
+
return ctx.Method() == "GET" && strings.Contains(ctx.Headers("Accept"), "html")
|
420 |
+
}
|
421 |
+
|
422 |
+
func (ctx *Context) WantJSON() bool {
|
423 |
+
return strings.Contains(ctx.Headers("Accept"), "json")
|
424 |
+
}
|
425 |
+
|
426 |
+
// AddHeader adds the key, value pair to the header.
|
427 |
+
func (ctx *Context) AddHeader(key, value string) {
|
428 |
+
ctx.Response.Header.Add(key, value)
|
429 |
+
}
|
430 |
+
|
431 |
+
// PjaxUrl add pjax url header.
|
432 |
+
func (ctx *Context) PjaxUrl(url string) {
|
433 |
+
ctx.Response.Header.Add(constant.PjaxUrlHeader, url)
|
434 |
+
}
|
435 |
+
|
436 |
+
// IsPjax check request is pjax or not.
|
437 |
+
func (ctx *Context) IsPjax() bool {
|
438 |
+
return ctx.Headers(constant.PjaxHeader) == "true"
|
439 |
+
}
|
440 |
+
|
441 |
+
// IsIframe check request is iframe or not.
|
442 |
+
func (ctx *Context) IsIframe() bool {
|
443 |
+
return ctx.Query(constant.IframeKey) == "true" || ctx.Headers(constant.IframeKey) == "true"
|
444 |
+
}
|
445 |
+
|
446 |
+
// SetHeader set the key, value pair to the header.
|
447 |
+
func (ctx *Context) SetHeader(key, value string) {
|
448 |
+
ctx.Response.Header.Set(key, value)
|
449 |
+
}
|
450 |
+
|
451 |
+
func (ctx *Context) GetContentType() string {
|
452 |
+
return ctx.Request.Header.Get("Content-Type")
|
453 |
+
}
|
454 |
+
|
455 |
+
func (ctx *Context) Cookie(name string) string {
|
456 |
+
for _, ck := range ctx.Request.Cookies() {
|
457 |
+
if ck.Name == name {
|
458 |
+
return ck.Value
|
459 |
+
}
|
460 |
+
}
|
461 |
+
return ""
|
462 |
+
}
|
463 |
+
|
464 |
+
// User return the current login user.
|
465 |
+
func (ctx *Context) User() interface{} {
|
466 |
+
return ctx.UserValue["user"]
|
467 |
+
}
|
468 |
+
|
469 |
+
// ServeContent serves content, headers are autoset
|
470 |
+
// receives three parameters, it's low-level function, instead you can use .ServeFile(string,bool)/SendFile(string,string)
|
471 |
+
//
|
472 |
+
// You can define your own "Content-Type" header also, after this function call
|
473 |
+
// Doesn't implements resuming (by range), use ctx.SendFile instead
|
474 |
+
func (ctx *Context) ServeContent(content io.ReadSeeker, filename string, modtime time.Time, gzipCompression bool) error {
|
475 |
+
if modified, err := ctx.CheckIfModifiedSince(modtime); !modified && err == nil {
|
476 |
+
ctx.WriteNotModified()
|
477 |
+
return nil
|
478 |
+
}
|
479 |
+
|
480 |
+
if ctx.GetContentType() == "" {
|
481 |
+
ctx.SetContentType(filename)
|
482 |
+
}
|
483 |
+
|
484 |
+
buf, _ := io.ReadAll(content)
|
485 |
+
ctx.Response.Body = io.NopCloser(bytes.NewBuffer(buf))
|
486 |
+
return nil
|
487 |
+
}
|
488 |
+
|
489 |
+
// ServeFile serves a view file, to send a file ( zip for example) to the client you should use the SendFile(serverfilename,clientfilename)
|
490 |
+
func (ctx *Context) ServeFile(filename string, gzipCompression bool) error {
|
491 |
+
f, err := os.Open(filename)
|
492 |
+
if err != nil {
|
493 |
+
return fmt.Errorf("%d", http.StatusNotFound)
|
494 |
+
}
|
495 |
+
defer func() {
|
496 |
+
_ = f.Close()
|
497 |
+
}()
|
498 |
+
fi, _ := f.Stat()
|
499 |
+
if fi.IsDir() {
|
500 |
+
return ctx.ServeFile(path.Join(filename, "index.html"), gzipCompression)
|
501 |
+
}
|
502 |
+
|
503 |
+
return ctx.ServeContent(f, fi.Name(), fi.ModTime(), gzipCompression)
|
504 |
+
}
|
505 |
+
|
506 |
+
type HandlerMap map[Path]Handlers
|
507 |
+
|
508 |
+
// App is the key struct of the package. App as a member of plugin
|
509 |
+
// entity contains the request and the corresponding handler. Prefix
|
510 |
+
// is the url prefix and MiddlewareList is for control flow.
|
511 |
+
type App struct {
|
512 |
+
Requests []Path
|
513 |
+
Handlers HandlerMap
|
514 |
+
Middlewares Handlers
|
515 |
+
Prefix string
|
516 |
+
|
517 |
+
Routers RouterMap
|
518 |
+
routeIndex int
|
519 |
+
routeANY bool
|
520 |
+
}
|
521 |
+
|
522 |
+
// NewApp return an empty app.
|
523 |
+
func NewApp() *App {
|
524 |
+
return &App{
|
525 |
+
Requests: make([]Path, 0),
|
526 |
+
Handlers: make(HandlerMap),
|
527 |
+
Prefix: "/",
|
528 |
+
Middlewares: make([]Handler, 0),
|
529 |
+
routeIndex: -1,
|
530 |
+
Routers: make(RouterMap),
|
531 |
+
}
|
532 |
+
}
|
533 |
+
|
534 |
+
// Handler defines the handler used by the middleware as return value.
|
535 |
+
type Handler func(ctx *Context)
|
536 |
+
|
537 |
+
// Handlers is the array of Handler
|
538 |
+
type Handlers []Handler
|
539 |
+
|
540 |
+
// AppendReqAndResp stores the request info and handle into app.
|
541 |
+
// support the route parameter. The route parameter will be recognized as
|
542 |
+
// wildcard store into the RegUrl of Path struct. For example:
|
543 |
+
//
|
544 |
+
// /user/:id => /user/(.*)
|
545 |
+
// /user/:id/info => /user/(.*?)/info
|
546 |
+
//
|
547 |
+
// The RegUrl will be used to recognize the incoming path and find
|
548 |
+
// the handler.
|
549 |
+
func (app *App) AppendReqAndResp(url, method string, handler []Handler) {
|
550 |
+
|
551 |
+
app.Requests = append(app.Requests, Path{
|
552 |
+
URL: join(app.Prefix, url),
|
553 |
+
Method: method,
|
554 |
+
})
|
555 |
+
app.routeIndex++
|
556 |
+
|
557 |
+
app.Handlers[Path{
|
558 |
+
URL: join(app.Prefix, url),
|
559 |
+
Method: method,
|
560 |
+
}] = append(app.Middlewares, handler...)
|
561 |
+
}
|
562 |
+
|
563 |
+
// Find is public helper method for findPath of tree.
|
564 |
+
func (app *App) Find(url, method string) []Handler {
|
565 |
+
app.routeANY = false
|
566 |
+
return app.Handlers[Path{URL: url, Method: method}]
|
567 |
+
}
|
568 |
+
|
569 |
+
// POST is a shortcut for app.AppendReqAndResp(url, "post", handler).
|
570 |
+
func (app *App) POST(url string, handler ...Handler) *App {
|
571 |
+
app.routeANY = false
|
572 |
+
app.AppendReqAndResp(url, "post", handler)
|
573 |
+
return app
|
574 |
+
}
|
575 |
+
|
576 |
+
// GET is a shortcut for app.AppendReqAndResp(url, "get", handler).
|
577 |
+
func (app *App) GET(url string, handler ...Handler) *App {
|
578 |
+
app.routeANY = false
|
579 |
+
app.AppendReqAndResp(url, "get", handler)
|
580 |
+
return app
|
581 |
+
}
|
582 |
+
|
583 |
+
// DELETE is a shortcut for app.AppendReqAndResp(url, "delete", handler).
|
584 |
+
func (app *App) DELETE(url string, handler ...Handler) *App {
|
585 |
+
app.routeANY = false
|
586 |
+
app.AppendReqAndResp(url, "delete", handler)
|
587 |
+
return app
|
588 |
+
}
|
589 |
+
|
590 |
+
// PUT is a shortcut for app.AppendReqAndResp(url, "put", handler).
|
591 |
+
func (app *App) PUT(url string, handler ...Handler) *App {
|
592 |
+
app.routeANY = false
|
593 |
+
app.AppendReqAndResp(url, "put", handler)
|
594 |
+
return app
|
595 |
+
}
|
596 |
+
|
597 |
+
// OPTIONS is a shortcut for app.AppendReqAndResp(url, "options", handler).
|
598 |
+
func (app *App) OPTIONS(url string, handler ...Handler) *App {
|
599 |
+
app.routeANY = false
|
600 |
+
app.AppendReqAndResp(url, "options", handler)
|
601 |
+
return app
|
602 |
+
}
|
603 |
+
|
604 |
+
// HEAD is a shortcut for app.AppendReqAndResp(url, "head", handler).
|
605 |
+
func (app *App) HEAD(url string, handler ...Handler) *App {
|
606 |
+
app.routeANY = false
|
607 |
+
app.AppendReqAndResp(url, "head", handler)
|
608 |
+
return app
|
609 |
+
}
|
610 |
+
|
611 |
+
// ANY registers a route that matches all the HTTP methods.
|
612 |
+
// GET, POST, PUT, HEAD, OPTIONS, DELETE.
|
613 |
+
func (app *App) ANY(url string, handler ...Handler) *App {
|
614 |
+
app.routeANY = true
|
615 |
+
app.AppendReqAndResp(url, "post", handler)
|
616 |
+
app.AppendReqAndResp(url, "get", handler)
|
617 |
+
app.AppendReqAndResp(url, "delete", handler)
|
618 |
+
app.AppendReqAndResp(url, "put", handler)
|
619 |
+
app.AppendReqAndResp(url, "options", handler)
|
620 |
+
app.AppendReqAndResp(url, "head", handler)
|
621 |
+
return app
|
622 |
+
}
|
623 |
+
|
624 |
+
func (app *App) Name(name string) {
|
625 |
+
if app.routeANY {
|
626 |
+
app.Routers[name] = Router{
|
627 |
+
Methods: []string{"POST", "GET", "DELETE", "PUT", "OPTIONS", "HEAD"},
|
628 |
+
Patten: app.Requests[app.routeIndex].URL,
|
629 |
+
}
|
630 |
+
} else {
|
631 |
+
app.Routers[name] = Router{
|
632 |
+
Methods: []string{app.Requests[app.routeIndex].Method},
|
633 |
+
Patten: app.Requests[app.routeIndex].URL,
|
634 |
+
}
|
635 |
+
}
|
636 |
+
}
|
637 |
+
|
638 |
+
// Group add middlewares and prefix for App.
|
639 |
+
func (app *App) Group(prefix string, middleware ...Handler) *RouterGroup {
|
640 |
+
return &RouterGroup{
|
641 |
+
app: app,
|
642 |
+
Middlewares: append(app.Middlewares, middleware...),
|
643 |
+
Prefix: slash(prefix),
|
644 |
+
}
|
645 |
+
}
|
646 |
+
|
647 |
+
// RouterGroup is a group of routes.
|
648 |
+
type RouterGroup struct {
|
649 |
+
app *App
|
650 |
+
Middlewares Handlers
|
651 |
+
Prefix string
|
652 |
+
}
|
653 |
+
|
654 |
+
// AppendReqAndResp stores the request info and handle into app.
|
655 |
+
// support the route parameter. The route parameter will be recognized as
|
656 |
+
// wildcard store into the RegUrl of Path struct. For example:
|
657 |
+
//
|
658 |
+
// /user/:id => /user/(.*)
|
659 |
+
// /user/:id/info => /user/(.*?)/info
|
660 |
+
//
|
661 |
+
// The RegUrl will be used to recognize the incoming path and find
|
662 |
+
// the handler.
|
663 |
+
func (g *RouterGroup) AppendReqAndResp(url, method string, handler []Handler) {
|
664 |
+
|
665 |
+
g.app.Requests = append(g.app.Requests, Path{
|
666 |
+
URL: join(g.Prefix, url),
|
667 |
+
Method: method,
|
668 |
+
})
|
669 |
+
g.app.routeIndex++
|
670 |
+
|
671 |
+
var h = make([]Handler, len(g.Middlewares))
|
672 |
+
copy(h, g.Middlewares)
|
673 |
+
|
674 |
+
g.app.Handlers[Path{
|
675 |
+
URL: join(g.Prefix, url),
|
676 |
+
Method: method,
|
677 |
+
}] = append(h, handler...)
|
678 |
+
}
|
679 |
+
|
680 |
+
// POST is a shortcut for app.AppendReqAndResp(url, "post", handler).
|
681 |
+
func (g *RouterGroup) POST(url string, handler ...Handler) *RouterGroup {
|
682 |
+
g.app.routeANY = false
|
683 |
+
g.AppendReqAndResp(url, "post", handler)
|
684 |
+
return g
|
685 |
+
}
|
686 |
+
|
687 |
+
// GET is a shortcut for app.AppendReqAndResp(url, "get", handler).
|
688 |
+
func (g *RouterGroup) GET(url string, handler ...Handler) *RouterGroup {
|
689 |
+
g.app.routeANY = false
|
690 |
+
g.AppendReqAndResp(url, "get", handler)
|
691 |
+
return g
|
692 |
+
}
|
693 |
+
|
694 |
+
// DELETE is a shortcut for app.AppendReqAndResp(url, "delete", handler).
|
695 |
+
func (g *RouterGroup) DELETE(url string, handler ...Handler) *RouterGroup {
|
696 |
+
g.app.routeANY = false
|
697 |
+
g.AppendReqAndResp(url, "delete", handler)
|
698 |
+
return g
|
699 |
+
}
|
700 |
+
|
701 |
+
// PUT is a shortcut for app.AppendReqAndResp(url, "put", handler).
|
702 |
+
func (g *RouterGroup) PUT(url string, handler ...Handler) *RouterGroup {
|
703 |
+
g.app.routeANY = false
|
704 |
+
g.AppendReqAndResp(url, "put", handler)
|
705 |
+
return g
|
706 |
+
}
|
707 |
+
|
708 |
+
// OPTIONS is a shortcut for app.AppendReqAndResp(url, "options", handler).
|
709 |
+
func (g *RouterGroup) OPTIONS(url string, handler ...Handler) *RouterGroup {
|
710 |
+
g.app.routeANY = false
|
711 |
+
g.AppendReqAndResp(url, "options", handler)
|
712 |
+
return g
|
713 |
+
}
|
714 |
+
|
715 |
+
// HEAD is a shortcut for app.AppendReqAndResp(url, "head", handler).
|
716 |
+
func (g *RouterGroup) HEAD(url string, handler ...Handler) *RouterGroup {
|
717 |
+
g.app.routeANY = false
|
718 |
+
g.AppendReqAndResp(url, "head", handler)
|
719 |
+
return g
|
720 |
+
}
|
721 |
+
|
722 |
+
// ANY registers a route that matches all the HTTP methods.
|
723 |
+
// GET, POST, PUT, HEAD, OPTIONS, DELETE.
|
724 |
+
func (g *RouterGroup) ANY(url string, handler ...Handler) *RouterGroup {
|
725 |
+
g.app.routeANY = true
|
726 |
+
g.AppendReqAndResp(url, "post", handler)
|
727 |
+
g.AppendReqAndResp(url, "get", handler)
|
728 |
+
g.AppendReqAndResp(url, "delete", handler)
|
729 |
+
g.AppendReqAndResp(url, "put", handler)
|
730 |
+
g.AppendReqAndResp(url, "options", handler)
|
731 |
+
g.AppendReqAndResp(url, "head", handler)
|
732 |
+
return g
|
733 |
+
}
|
734 |
+
|
735 |
+
func (g *RouterGroup) Name(name string) {
|
736 |
+
g.app.Name(name)
|
737 |
+
}
|
738 |
+
|
739 |
+
// Group add middlewares and prefix for RouterGroup.
|
740 |
+
func (g *RouterGroup) Group(prefix string, middleware ...Handler) *RouterGroup {
|
741 |
+
return &RouterGroup{
|
742 |
+
app: g.app,
|
743 |
+
Middlewares: append(g.Middlewares, middleware...),
|
744 |
+
Prefix: join(slash(g.Prefix), slash(prefix)),
|
745 |
+
}
|
746 |
+
}
|
747 |
+
|
748 |
+
// slash fix the path which has wrong format problem.
|
749 |
+
//
|
750 |
+
// "" => "/"
|
751 |
+
// "abc/" => "/abc"
|
752 |
+
// "/abc/" => "/abc"
|
753 |
+
// "/abc" => "/abc"
|
754 |
+
// "/" => "/"
|
755 |
+
func slash(prefix string) string {
|
756 |
+
prefix = strings.TrimSpace(prefix)
|
757 |
+
if prefix == "" || prefix == "/" {
|
758 |
+
return "/"
|
759 |
+
}
|
760 |
+
if prefix[0] != '/' {
|
761 |
+
if prefix[len(prefix)-1] == '/' {
|
762 |
+
return "/" + prefix[:len(prefix)-1]
|
763 |
+
}
|
764 |
+
return "/" + prefix
|
765 |
+
}
|
766 |
+
if prefix[len(prefix)-1] == '/' {
|
767 |
+
return prefix[:len(prefix)-1]
|
768 |
+
}
|
769 |
+
return prefix
|
770 |
+
}
|
771 |
+
|
772 |
+
// join join the path.
|
773 |
+
func join(prefix, suffix string) string {
|
774 |
+
if prefix == "/" {
|
775 |
+
return suffix
|
776 |
+
}
|
777 |
+
if suffix == "/" {
|
778 |
+
return prefix
|
779 |
+
}
|
780 |
+
return prefix + suffix
|
781 |
+
}
|
context/context_test.go
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package context
|
2 |
+
|
3 |
+
import (
|
4 |
+
"fmt"
|
5 |
+
"testing"
|
6 |
+
|
7 |
+
"github.com/magiconair/properties/assert"
|
8 |
+
)
|
9 |
+
|
10 |
+
func TestSlash(t *testing.T) {
|
11 |
+
assert.Equal(t, "/abc", slash("/abc"))
|
12 |
+
assert.Equal(t, "/", slash(""))
|
13 |
+
assert.Equal(t, "/abc", slash("abc/"))
|
14 |
+
assert.Equal(t, "/", slash("/"))
|
15 |
+
assert.Equal(t, "/abc", slash("/abc/"))
|
16 |
+
assert.Equal(t, "/", slash("//"))
|
17 |
+
}
|
18 |
+
|
19 |
+
func TestJoin(t *testing.T) {
|
20 |
+
assert.Equal(t, "/abc/abc", join(slash("/abc"), slash("/abc")))
|
21 |
+
assert.Equal(t, "/", join(slash("/"), slash("/")))
|
22 |
+
assert.Equal(t, "/abc", join(slash("/"), slash("/abc")))
|
23 |
+
assert.Equal(t, "/abc", join(slash("abc/"), slash("/")))
|
24 |
+
assert.Equal(t, "/abc", join(slash("/abc/"), slash("/")))
|
25 |
+
}
|
26 |
+
|
27 |
+
func TestTree(t *testing.T) {
|
28 |
+
tree := tree()
|
29 |
+
tree.addPath(stringToArr("/adm"), "GET", []Handler{func(ctx *Context) { fmt.Println(1) }})
|
30 |
+
tree.addPath(stringToArr("/admi"), "GET", []Handler{func(ctx *Context) { fmt.Println(1) }})
|
31 |
+
tree.addPath(stringToArr("/admin"), "GET", []Handler{func(ctx *Context) { fmt.Println(1) }})
|
32 |
+
tree.addPath(stringToArr("/admin/menu/new"), "POST", []Handler{func(ctx *Context) { fmt.Println(1) }})
|
33 |
+
tree.addPath(stringToArr("/admin/menu/new"), "GET", []Handler{func(ctx *Context) { fmt.Println(1) }})
|
34 |
+
tree.addPath(stringToArr("/admin/info/:__prefix"), "GET", []Handler{
|
35 |
+
func(ctx *Context) { fmt.Println("auth") },
|
36 |
+
func(ctx *Context) { fmt.Println("init") },
|
37 |
+
func(ctx *Context) { fmt.Println("info") },
|
38 |
+
})
|
39 |
+
tree.addPath(stringToArr("/admin/info/:__prefix/detail"), "GET", []Handler{
|
40 |
+
func(ctx *Context) { fmt.Println("auth") },
|
41 |
+
func(ctx *Context) { fmt.Println("detail") },
|
42 |
+
})
|
43 |
+
|
44 |
+
fmt.Println("/admin/menu/new", "GET")
|
45 |
+
h := tree.findPath(stringToArr("/admin/menu/new"), "GET")
|
46 |
+
assert.Equal(t, h != nil, true)
|
47 |
+
printHandler(h)
|
48 |
+
fmt.Println("/admin/menu/new", "POST")
|
49 |
+
h = tree.findPath(stringToArr("/admin/menu/new"), "POST")
|
50 |
+
assert.Equal(t, h != nil, true)
|
51 |
+
printHandler(h)
|
52 |
+
fmt.Println("/admin/me/new", "POST")
|
53 |
+
h = tree.findPath(stringToArr("/admin/me/new"), "POST")
|
54 |
+
assert.Equal(t, h == nil, true)
|
55 |
+
printHandler(h)
|
56 |
+
fmt.Println("/admin/info/user", "GET")
|
57 |
+
h = tree.findPath(stringToArr("/admin/info/user"), "GET")
|
58 |
+
assert.Equal(t, h != nil, true)
|
59 |
+
printHandler(h)
|
60 |
+
fmt.Println("/admin/info/user/detail", "GET")
|
61 |
+
h = tree.findPath(stringToArr("/admin/info/user/detail"), "GET")
|
62 |
+
assert.Equal(t, h != nil, true)
|
63 |
+
printHandler(h)
|
64 |
+
fmt.Println("=========== printChildren ===========")
|
65 |
+
tree.printChildren()
|
66 |
+
}
|
67 |
+
|
68 |
+
func printHandler(h []Handler) {
|
69 |
+
for _, value := range h {
|
70 |
+
value(&Context{})
|
71 |
+
}
|
72 |
+
}
|
context/trie.go
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Copyright 2019 GoAdmin Core Team. All rights reserved.
|
2 |
+
// Use of this source code is governed by a Apache-2.0 style
|
3 |
+
// license that can be found in the LICENSE file.
|
4 |
+
|
5 |
+
package context
|
6 |
+
|
7 |
+
import "fmt"
|
8 |
+
|
9 |
+
type node struct {
|
10 |
+
children []*node
|
11 |
+
value string
|
12 |
+
method []string
|
13 |
+
handle [][]Handler
|
14 |
+
}
|
15 |
+
|
16 |
+
func tree() *node {
|
17 |
+
return &node{
|
18 |
+
children: make([]*node, 0),
|
19 |
+
value: "/",
|
20 |
+
handle: nil,
|
21 |
+
}
|
22 |
+
}
|
23 |
+
|
24 |
+
func (n *node) hasMethod(method string) int {
|
25 |
+
for k, m := range n.method {
|
26 |
+
if m == method {
|
27 |
+
return k
|
28 |
+
}
|
29 |
+
}
|
30 |
+
return -1
|
31 |
+
}
|
32 |
+
|
33 |
+
func (n *node) addMethodAndHandler(method string, handler []Handler) {
|
34 |
+
n.method = append(n.method, method)
|
35 |
+
n.handle = append(n.handle, handler)
|
36 |
+
}
|
37 |
+
|
38 |
+
func (n *node) addChild(child *node) {
|
39 |
+
n.children = append(n.children, child)
|
40 |
+
}
|
41 |
+
|
42 |
+
func (n *node) addContent(value string) *node {
|
43 |
+
var child = n.search(value)
|
44 |
+
if child == nil {
|
45 |
+
child = &node{
|
46 |
+
children: make([]*node, 0),
|
47 |
+
value: value,
|
48 |
+
}
|
49 |
+
n.addChild(child)
|
50 |
+
}
|
51 |
+
return child
|
52 |
+
}
|
53 |
+
|
54 |
+
func (n *node) search(value string) *node {
|
55 |
+
for _, child := range n.children {
|
56 |
+
if child.value == value || child.value == "*" {
|
57 |
+
return child
|
58 |
+
}
|
59 |
+
}
|
60 |
+
return nil
|
61 |
+
}
|
62 |
+
|
63 |
+
func (n *node) addPath(paths []string, method string, handler []Handler) {
|
64 |
+
child := n
|
65 |
+
for i := 0; i < len(paths); i++ {
|
66 |
+
child = child.addContent(paths[i])
|
67 |
+
}
|
68 |
+
child.addMethodAndHandler(method, handler)
|
69 |
+
}
|
70 |
+
|
71 |
+
func (n *node) findPath(paths []string, method string) []Handler {
|
72 |
+
child := n
|
73 |
+
for i := 0; i < len(paths); i++ {
|
74 |
+
child = child.search(paths[i])
|
75 |
+
if child == nil {
|
76 |
+
return nil
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
methodIndex := child.hasMethod(method)
|
81 |
+
if methodIndex == -1 {
|
82 |
+
return nil
|
83 |
+
}
|
84 |
+
|
85 |
+
return child.handle[methodIndex]
|
86 |
+
}
|
87 |
+
|
88 |
+
func (n *node) print() {
|
89 |
+
fmt.Println(n)
|
90 |
+
}
|
91 |
+
|
92 |
+
func (n *node) printChildren() {
|
93 |
+
n.print()
|
94 |
+
for _, child := range n.children {
|
95 |
+
child.printChildren()
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
func stringToArr(path string) []string {
|
100 |
+
var (
|
101 |
+
paths = make([]string, 0)
|
102 |
+
start = 0
|
103 |
+
end int
|
104 |
+
isWildcard = false
|
105 |
+
)
|
106 |
+
for i := 0; i < len(path); i++ {
|
107 |
+
if i == 0 && path[0] == '/' {
|
108 |
+
start = 1
|
109 |
+
continue
|
110 |
+
}
|
111 |
+
if path[i] == ':' {
|
112 |
+
isWildcard = true
|
113 |
+
}
|
114 |
+
if i == len(path)-1 {
|
115 |
+
end = i + 1
|
116 |
+
if isWildcard {
|
117 |
+
paths = append(paths, "*")
|
118 |
+
} else {
|
119 |
+
paths = append(paths, path[start:end])
|
120 |
+
}
|
121 |
+
}
|
122 |
+
if path[i] == '/' {
|
123 |
+
end = i
|
124 |
+
if isWildcard {
|
125 |
+
paths = append(paths, "*")
|
126 |
+
} else {
|
127 |
+
paths = append(paths, path[start:end])
|
128 |
+
}
|
129 |
+
start = i + 1
|
130 |
+
isWildcard = false
|
131 |
+
}
|
132 |
+
}
|
133 |
+
return paths
|
134 |
+
}
|
data/admin.db
ADDED
Binary file (397 kB). View file
|
|
data/admin.mssql
ADDED
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
|
3 |
+
CREATE TABLE [goadmin_menu] (
|
4 |
+
[id] int identity(1,1) ,
|
5 |
+
[parent_id] int NOT NULL DEFAULT 0,
|
6 |
+
[type] tinyint NOT NULL DEFAULT 0,
|
7 |
+
[order] int NOT NULL DEFAULT '0',
|
8 |
+
[title] varchar(50) NOT NULL,
|
9 |
+
[icon] varchar(50) NOT NULL,
|
10 |
+
[uri] varchar(3000) NOT NULL DEFAULT '',
|
11 |
+
[header] varchar(150) DEFAULT NULL,
|
12 |
+
[uuid] varchar(150) DEFAULT NULL,
|
13 |
+
[plugin_name] varchar(150) NOT NULL DEFAULT '',
|
14 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
15 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
16 |
+
PRIMARY KEY ([id]),
|
17 |
+
)
|
18 |
+
set IDENTITY_INSERT [goadmin_menu] ON
|
19 |
+
INSERT INTO[goadmin_menu] ([id],[parent_id],[type],[order],[title],[icon],[uri],[header],[created_at],[updated_at])
|
20 |
+
VALUES
|
21 |
+
(1,0,1,2,'Admin','fa-tasks','',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
22 |
+
(2,1,1,2,'Users','fa-users','/info/manager',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
23 |
+
(3,1,1,3,'Roles','fa-user','/info/roles',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
24 |
+
(4,1,1,4,'Permission','fa-ban','/info/permission',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
25 |
+
(5,1,1,5,'Menu','fa-bars','/menu',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
26 |
+
(6,1,1,6,'Operation log','fa-history','/info/op',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
27 |
+
(7,0,1,1,'Dashboard','fa-bar-chart','/',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00');
|
28 |
+
set IDENTITY_INSERT [goadmin_menu] OFF
|
29 |
+
|
30 |
+
|
31 |
+
|
32 |
+
|
33 |
+
CREATE TABLE[goadmin_operation_log] (
|
34 |
+
[id] int identity(1,1) ,
|
35 |
+
[user_id] int NOT NULL,
|
36 |
+
[path] varchar(255) NOT NULL,
|
37 |
+
[method] varchar(10) NOT NULL,
|
38 |
+
[ip] varchar(15) NOT NULL,
|
39 |
+
[input] text NOT NULL,
|
40 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
41 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
42 |
+
PRIMARY KEY ([id]),
|
43 |
+
)
|
44 |
+
|
45 |
+
|
46 |
+
CREATE TABLE[goadmin_site] (
|
47 |
+
[id] int identity(1,1) ,
|
48 |
+
[key] varchar(100) NOT NULL,
|
49 |
+
[value] text NOT NULL,
|
50 |
+
[state] tinyint NOT NULL DEFAULT 0,
|
51 |
+
[description] varchar(3000) DEFAULT NULL,
|
52 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
53 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
54 |
+
PRIMARY KEY ([id]),
|
55 |
+
)
|
56 |
+
|
57 |
+
|
58 |
+
CREATE TABLE[goadmin_permissions] (
|
59 |
+
[id] int identity(1,1) ,
|
60 |
+
[name] varchar(50) NOT NULL,
|
61 |
+
[slug] varchar(50) NOT NULL,
|
62 |
+
[http_method] varchar(255) DEFAULT NULL,
|
63 |
+
[http_path] text NOT NULL,
|
64 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
65 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
66 |
+
PRIMARY KEY ([id]),
|
67 |
+
)
|
68 |
+
|
69 |
+
set IDENTITY_INSERT [goadmin_permissions] ON
|
70 |
+
|
71 |
+
INSERT INTO[goadmin_permissions] ([id],[name],[slug],[http_method],[http_path],[created_at],[updated_at])
|
72 |
+
VALUES
|
73 |
+
(1,'All permission','*','','*','2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
74 |
+
(2,'Dashboard','dashboard','GET,PUT,POST,DELETE','/','2019-09-10 00:00:00','2019-09-10 00:00:00');
|
75 |
+
|
76 |
+
set IDENTITY_INSERT [goadmin_permissions] OFF
|
77 |
+
|
78 |
+
|
79 |
+
|
80 |
+
|
81 |
+
CREATE TABLE[goadmin_role_menu] (
|
82 |
+
[role_id] int NOT NULL,
|
83 |
+
[menu_id] int NOT NULL,
|
84 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
85 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
86 |
+
PRIMARY KEY([role_id],[menu_id])
|
87 |
+
)
|
88 |
+
|
89 |
+
|
90 |
+
|
91 |
+
INSERT INTO[goadmin_role_menu] ([role_id],[menu_id],[created_at],[updated_at])
|
92 |
+
VALUES
|
93 |
+
(1,1,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
94 |
+
(1,7,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
95 |
+
(2,7,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
96 |
+
(1,8,'2019-09-11 10:20:55','2019-09-11 10:20:55'),
|
97 |
+
(2,8,'2019-09-11 10:20:55','2019-09-11 10:20:55');
|
98 |
+
|
99 |
+
|
100 |
+
|
101 |
+
|
102 |
+
|
103 |
+
CREATE TABLE[goadmin_role_permissions] (
|
104 |
+
[role_id] int NOT NULL,
|
105 |
+
[permission_id] int NOT NULL,
|
106 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
107 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
108 |
+
PRIMARY KEY ([role_id],[permission_id])
|
109 |
+
)
|
110 |
+
|
111 |
+
|
112 |
+
INSERT INTO[goadmin_role_permissions] ([role_id],[permission_id],[created_at],[updated_at])
|
113 |
+
VALUES
|
114 |
+
(1,1,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
115 |
+
(1,2,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
116 |
+
(2,2,'2019-09-10 00:00:00','2019-09-10 00:00:00');
|
117 |
+
|
118 |
+
|
119 |
+
|
120 |
+
|
121 |
+
CREATE TABLE[goadmin_role_users] (
|
122 |
+
[role_id] int NOT NULL,
|
123 |
+
[user_id] int NOT NULL,
|
124 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
125 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
126 |
+
PRIMARY KEY ([role_id],[user_id])
|
127 |
+
)
|
128 |
+
|
129 |
+
|
130 |
+
INSERT INTO[goadmin_role_users] ([role_id],[user_id],[created_at],[updated_at])
|
131 |
+
VALUES
|
132 |
+
(1,1,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
133 |
+
(2,2,'2019-09-10 00:00:00','2019-09-10 00:00:00');
|
134 |
+
|
135 |
+
|
136 |
+
|
137 |
+
|
138 |
+
CREATE TABLE[goadmin_roles] (
|
139 |
+
[id] int identity(1,1) ,
|
140 |
+
[name] varchar(50) NOT NULL UNIQUE,
|
141 |
+
[slug] varchar(50) NOT NULL,
|
142 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
143 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
144 |
+
PRIMARY KEY ([id]),
|
145 |
+
)
|
146 |
+
|
147 |
+
set IDENTITY_INSERT [goadmin_roles] ON
|
148 |
+
|
149 |
+
INSERT INTO[goadmin_roles] ([id],[name],[slug],[created_at],[updated_at])
|
150 |
+
VALUES
|
151 |
+
(1,'Administrator','administrator','2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
152 |
+
(2,'Operator','operator','2019-09-10 00:00:00','2019-09-10 00:00:00');
|
153 |
+
|
154 |
+
set IDENTITY_INSERT [goadmin_roles] OFF
|
155 |
+
|
156 |
+
|
157 |
+
CREATE TABLE[goadmin_session] (
|
158 |
+
[id] int identity(1,1) ,
|
159 |
+
[sid] varchar(50) DEFAULT '',
|
160 |
+
[values] varchar(3000) DEFAULT '',
|
161 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
162 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
163 |
+
PRIMARY KEY ([id])
|
164 |
+
)
|
165 |
+
|
166 |
+
|
167 |
+
|
168 |
+
|
169 |
+
CREATE TABLE[goadmin_user_permissions] (
|
170 |
+
[user_id] int NOT NULL,
|
171 |
+
[permission_id] int NOT NULL,
|
172 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
173 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
174 |
+
PRIMARY KEY ([user_id],[permission_id])
|
175 |
+
)
|
176 |
+
|
177 |
+
|
178 |
+
INSERT INTO[goadmin_user_permissions] ([user_id],[permission_id],[created_at],[updated_at])
|
179 |
+
VALUES
|
180 |
+
(1,1,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
181 |
+
(2,2,'2019-09-10 00:00:00','2019-09-10 00:00:00');
|
182 |
+
|
183 |
+
|
184 |
+
|
185 |
+
|
186 |
+
|
187 |
+
CREATE TABLE[goadmin_users] (
|
188 |
+
[id] int identity(1,1) ,
|
189 |
+
[username] varchar(100) NOT NULL UNIQUE,
|
190 |
+
[password] varchar(100) NOT NULL DEFAULT '',
|
191 |
+
[name] varchar(100) NOT NULL,
|
192 |
+
[avatar] varchar(255) DEFAULT NULL,
|
193 |
+
[remember_token] varchar(100) DEFAULT NULL,
|
194 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
195 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
196 |
+
PRIMARY KEY ([id]),
|
197 |
+
)
|
198 |
+
|
199 |
+
set IDENTITY_INSERT [goadmin_users] ON
|
200 |
+
|
201 |
+
INSERT INTO[goadmin_users] ([id],[username],[password],[name],[avatar],[remember_token],[created_at],[updated_at])
|
202 |
+
VALUES
|
203 |
+
(1,'admin','$2a$10$U3F/NSaf2kaVbyXTBp7ppOn0jZFyRqXRnYXB.AMioCjXl3Ciaj4oy','admin','','tlNcBVK9AvfYH7WEnwB1RKvocJu8FfRy4um3DJtwdHuJy0dwFsLOgAc0xUfh','2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
204 |
+
(2,'operator','$2a$10$rVqkOzHjN2MdlEprRflb1eGP0oZXuSrbJLOmJagFsCd81YZm0bsh.','Operator','',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00');
|
205 |
+
set IDENTITY_INSERT [goadmin_users] OFF
|
206 |
+
|
207 |
+
|
data/admin.pgsql
ADDED
@@ -0,0 +1,574 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
--
|
2 |
+
-- PostgreSQL database dump
|
3 |
+
--
|
4 |
+
|
5 |
+
-- Dumped from database version 9.5.14
|
6 |
+
-- Dumped by pg_dump version 10.5
|
7 |
+
|
8 |
+
SET statement_timeout = 0;
|
9 |
+
SET lock_timeout = 0;
|
10 |
+
SET idle_in_transaction_session_timeout = 0;
|
11 |
+
SET client_encoding = 'UTF8';
|
12 |
+
SET standard_conforming_strings = on;
|
13 |
+
SELECT pg_catalog.set_config('search_path', '', false);
|
14 |
+
SET check_function_bodies = false;
|
15 |
+
SET client_min_messages = warning;
|
16 |
+
SET row_security = off;
|
17 |
+
|
18 |
+
--
|
19 |
+
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner:
|
20 |
+
--
|
21 |
+
|
22 |
+
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
|
23 |
+
|
24 |
+
|
25 |
+
--
|
26 |
+
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner:
|
27 |
+
--
|
28 |
+
|
29 |
+
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
|
30 |
+
|
31 |
+
|
32 |
+
--
|
33 |
+
-- Name: goadmin_menu_myid_seq; Type: SEQUENCE; Schema: public; Owner: postgres
|
34 |
+
--
|
35 |
+
|
36 |
+
CREATE SEQUENCE public.goadmin_menu_myid_seq
|
37 |
+
START WITH 1
|
38 |
+
INCREMENT BY 1
|
39 |
+
NO MINVALUE
|
40 |
+
MAXVALUE 99999999
|
41 |
+
CACHE 1;
|
42 |
+
|
43 |
+
|
44 |
+
ALTER TABLE public.goadmin_menu_myid_seq OWNER TO postgres;
|
45 |
+
|
46 |
+
SET default_tablespace = '';
|
47 |
+
|
48 |
+
SET default_with_oids = false;
|
49 |
+
|
50 |
+
--
|
51 |
+
-- Name: goadmin_menu; Type: TABLE; Schema: public; Owner: postgres
|
52 |
+
--
|
53 |
+
|
54 |
+
CREATE TABLE public.goadmin_menu (
|
55 |
+
id integer DEFAULT nextval('public.goadmin_menu_myid_seq'::regclass) NOT NULL,
|
56 |
+
parent_id integer DEFAULT 0 NOT NULL,
|
57 |
+
type integer DEFAULT 0,
|
58 |
+
"order" integer DEFAULT 0 NOT NULL,
|
59 |
+
title character varying(50) NOT NULL,
|
60 |
+
header character varying(100),
|
61 |
+
plugin_name character varying(100) NOT NULL,
|
62 |
+
icon character varying(50) NOT NULL,
|
63 |
+
uri character varying(3000) NOT NULL,
|
64 |
+
uuid character varying(100),
|
65 |
+
created_at timestamp without time zone DEFAULT now(),
|
66 |
+
updated_at timestamp without time zone DEFAULT now()
|
67 |
+
);
|
68 |
+
|
69 |
+
|
70 |
+
ALTER TABLE public.goadmin_menu OWNER TO postgres;
|
71 |
+
|
72 |
+
--
|
73 |
+
-- Name: goadmin_operation_log_myid_seq; Type: SEQUENCE; Schema: public; Owner: postgres
|
74 |
+
--
|
75 |
+
|
76 |
+
CREATE SEQUENCE public.goadmin_operation_log_myid_seq
|
77 |
+
START WITH 1
|
78 |
+
INCREMENT BY 1
|
79 |
+
NO MINVALUE
|
80 |
+
MAXVALUE 99999999
|
81 |
+
CACHE 1;
|
82 |
+
|
83 |
+
|
84 |
+
ALTER TABLE public.goadmin_operation_log_myid_seq OWNER TO postgres;
|
85 |
+
|
86 |
+
--
|
87 |
+
-- Name: goadmin_operation_log; Type: TABLE; Schema: public; Owner: postgres
|
88 |
+
--
|
89 |
+
|
90 |
+
CREATE TABLE public.goadmin_operation_log (
|
91 |
+
id integer DEFAULT nextval('public.goadmin_operation_log_myid_seq'::regclass) NOT NULL,
|
92 |
+
user_id integer NOT NULL,
|
93 |
+
path character varying(255) NOT NULL,
|
94 |
+
method character varying(10) NOT NULL,
|
95 |
+
ip character varying(15) NOT NULL,
|
96 |
+
input text NOT NULL,
|
97 |
+
created_at timestamp without time zone DEFAULT now(),
|
98 |
+
updated_at timestamp without time zone DEFAULT now()
|
99 |
+
);
|
100 |
+
|
101 |
+
|
102 |
+
ALTER TABLE public.goadmin_operation_log OWNER TO postgres;
|
103 |
+
|
104 |
+
--
|
105 |
+
-- Name: goadmin_site_myid_seq; Type: SEQUENCE; Schema: public; Owner: postgres
|
106 |
+
--
|
107 |
+
|
108 |
+
CREATE SEQUENCE public.goadmin_site_myid_seq
|
109 |
+
START WITH 1
|
110 |
+
INCREMENT BY 1
|
111 |
+
NO MINVALUE
|
112 |
+
MAXVALUE 99999999
|
113 |
+
CACHE 1;
|
114 |
+
|
115 |
+
|
116 |
+
ALTER TABLE public.goadmin_site_myid_seq OWNER TO postgres;
|
117 |
+
|
118 |
+
--
|
119 |
+
-- Name: goadmin_site; Type: TABLE; Schema: public; Owner: postgres
|
120 |
+
--
|
121 |
+
|
122 |
+
CREATE TABLE public.goadmin_site (
|
123 |
+
id integer DEFAULT nextval('public.goadmin_site_myid_seq'::regclass) NOT NULL,
|
124 |
+
key character varying(100) NOT NULL,
|
125 |
+
value text NOT NULL,
|
126 |
+
type integer DEFAULT 0,
|
127 |
+
description character varying(3000),
|
128 |
+
state integer DEFAULT 0,
|
129 |
+
created_at timestamp without time zone DEFAULT now(),
|
130 |
+
updated_at timestamp without time zone DEFAULT now()
|
131 |
+
);
|
132 |
+
|
133 |
+
|
134 |
+
ALTER TABLE public.goadmin_site OWNER TO postgres;
|
135 |
+
|
136 |
+
--
|
137 |
+
-- Name: goadmin_permissions_myid_seq; Type: SEQUENCE; Schema: public; Owner: postgres
|
138 |
+
--
|
139 |
+
|
140 |
+
CREATE SEQUENCE public.goadmin_permissions_myid_seq
|
141 |
+
START WITH 1
|
142 |
+
INCREMENT BY 1
|
143 |
+
NO MINVALUE
|
144 |
+
MAXVALUE 99999999
|
145 |
+
CACHE 1;
|
146 |
+
|
147 |
+
|
148 |
+
ALTER TABLE public.goadmin_permissions_myid_seq OWNER TO postgres;
|
149 |
+
|
150 |
+
--
|
151 |
+
-- Name: goadmin_permissions; Type: TABLE; Schema: public; Owner: postgres
|
152 |
+
--
|
153 |
+
|
154 |
+
CREATE TABLE public.goadmin_permissions (
|
155 |
+
id integer DEFAULT nextval('public.goadmin_permissions_myid_seq'::regclass) NOT NULL,
|
156 |
+
name character varying(50) NOT NULL,
|
157 |
+
slug character varying(50) NOT NULL,
|
158 |
+
http_method character varying(255),
|
159 |
+
http_path text NOT NULL,
|
160 |
+
created_at timestamp without time zone DEFAULT now(),
|
161 |
+
updated_at timestamp without time zone DEFAULT now()
|
162 |
+
);
|
163 |
+
|
164 |
+
|
165 |
+
ALTER TABLE public.goadmin_permissions OWNER TO postgres;
|
166 |
+
|
167 |
+
--
|
168 |
+
-- Name: goadmin_role_menu; Type: TABLE; Schema: public; Owner: postgres
|
169 |
+
--
|
170 |
+
|
171 |
+
CREATE TABLE public.goadmin_role_menu (
|
172 |
+
role_id integer NOT NULL,
|
173 |
+
menu_id integer NOT NULL,
|
174 |
+
created_at timestamp without time zone DEFAULT now(),
|
175 |
+
updated_at timestamp without time zone DEFAULT now()
|
176 |
+
);
|
177 |
+
|
178 |
+
|
179 |
+
ALTER TABLE public.goadmin_role_menu OWNER TO postgres;
|
180 |
+
|
181 |
+
--
|
182 |
+
-- Name: goadmin_role_permissions; Type: TABLE; Schema: public; Owner: postgres
|
183 |
+
--
|
184 |
+
|
185 |
+
CREATE TABLE public.goadmin_role_permissions (
|
186 |
+
role_id integer NOT NULL,
|
187 |
+
permission_id integer NOT NULL,
|
188 |
+
created_at timestamp without time zone DEFAULT now(),
|
189 |
+
updated_at timestamp without time zone DEFAULT now()
|
190 |
+
);
|
191 |
+
|
192 |
+
|
193 |
+
ALTER TABLE public.goadmin_role_permissions OWNER TO postgres;
|
194 |
+
|
195 |
+
--
|
196 |
+
-- Name: goadmin_role_users; Type: TABLE; Schema: public; Owner: postgres
|
197 |
+
--
|
198 |
+
|
199 |
+
CREATE TABLE public.goadmin_role_users (
|
200 |
+
role_id integer NOT NULL,
|
201 |
+
user_id integer NOT NULL,
|
202 |
+
created_at timestamp without time zone DEFAULT now(),
|
203 |
+
updated_at timestamp without time zone DEFAULT now()
|
204 |
+
);
|
205 |
+
|
206 |
+
|
207 |
+
ALTER TABLE public.goadmin_role_users OWNER TO postgres;
|
208 |
+
|
209 |
+
--
|
210 |
+
-- Name: goadmin_roles_myid_seq; Type: SEQUENCE; Schema: public; Owner: postgres
|
211 |
+
--
|
212 |
+
|
213 |
+
CREATE SEQUENCE public.goadmin_roles_myid_seq
|
214 |
+
START WITH 1
|
215 |
+
INCREMENT BY 1
|
216 |
+
NO MINVALUE
|
217 |
+
MAXVALUE 99999999
|
218 |
+
CACHE 1;
|
219 |
+
|
220 |
+
|
221 |
+
ALTER TABLE public.goadmin_roles_myid_seq OWNER TO postgres;
|
222 |
+
|
223 |
+
--
|
224 |
+
-- Name: goadmin_roles; Type: TABLE; Schema: public; Owner: postgres
|
225 |
+
--
|
226 |
+
|
227 |
+
CREATE TABLE public.goadmin_roles (
|
228 |
+
id integer DEFAULT nextval('public.goadmin_roles_myid_seq'::regclass) NOT NULL,
|
229 |
+
name character varying NOT NULL,
|
230 |
+
slug character varying NOT NULL,
|
231 |
+
created_at timestamp without time zone DEFAULT now(),
|
232 |
+
updated_at timestamp without time zone DEFAULT now()
|
233 |
+
);
|
234 |
+
|
235 |
+
|
236 |
+
ALTER TABLE public.goadmin_roles OWNER TO postgres;
|
237 |
+
|
238 |
+
--
|
239 |
+
-- Name: goadmin_session_myid_seq; Type: SEQUENCE; Schema: public; Owner: postgres
|
240 |
+
--
|
241 |
+
|
242 |
+
CREATE SEQUENCE public.goadmin_session_myid_seq
|
243 |
+
START WITH 1
|
244 |
+
INCREMENT BY 1
|
245 |
+
NO MINVALUE
|
246 |
+
MAXVALUE 99999999
|
247 |
+
CACHE 1;
|
248 |
+
|
249 |
+
|
250 |
+
ALTER TABLE public.goadmin_session_myid_seq OWNER TO postgres;
|
251 |
+
|
252 |
+
--
|
253 |
+
-- Name: goadmin_session; Type: TABLE; Schema: public; Owner: postgres
|
254 |
+
--
|
255 |
+
|
256 |
+
CREATE TABLE public.goadmin_session (
|
257 |
+
id integer DEFAULT nextval('public.goadmin_session_myid_seq'::regclass) NOT NULL,
|
258 |
+
sid character varying(50) NOT NULL,
|
259 |
+
"values" character varying(3000) NOT NULL,
|
260 |
+
created_at timestamp without time zone DEFAULT now(),
|
261 |
+
updated_at timestamp without time zone DEFAULT now()
|
262 |
+
);
|
263 |
+
|
264 |
+
|
265 |
+
ALTER TABLE public.goadmin_session OWNER TO postgres;
|
266 |
+
|
267 |
+
--
|
268 |
+
-- Name: goadmin_user_permissions; Type: TABLE; Schema: public; Owner: postgres
|
269 |
+
--
|
270 |
+
|
271 |
+
CREATE TABLE public.goadmin_user_permissions (
|
272 |
+
user_id integer NOT NULL,
|
273 |
+
permission_id integer NOT NULL,
|
274 |
+
created_at timestamp without time zone DEFAULT now(),
|
275 |
+
updated_at timestamp without time zone DEFAULT now()
|
276 |
+
);
|
277 |
+
|
278 |
+
|
279 |
+
ALTER TABLE public.goadmin_user_permissions OWNER TO postgres;
|
280 |
+
|
281 |
+
--
|
282 |
+
-- Name: goadmin_users_myid_seq; Type: SEQUENCE; Schema: public; Owner: postgres
|
283 |
+
--
|
284 |
+
|
285 |
+
CREATE SEQUENCE public.goadmin_users_myid_seq
|
286 |
+
START WITH 1
|
287 |
+
INCREMENT BY 1
|
288 |
+
NO MINVALUE
|
289 |
+
MAXVALUE 99999999
|
290 |
+
CACHE 1;
|
291 |
+
|
292 |
+
|
293 |
+
ALTER TABLE public.goadmin_users_myid_seq OWNER TO postgres;
|
294 |
+
|
295 |
+
--
|
296 |
+
-- Name: goadmin_users; Type: TABLE; Schema: public; Owner: postgres
|
297 |
+
--
|
298 |
+
|
299 |
+
CREATE TABLE public.goadmin_users (
|
300 |
+
id integer DEFAULT nextval('public.goadmin_users_myid_seq'::regclass) NOT NULL,
|
301 |
+
username character varying(100) NOT NULL,
|
302 |
+
password character varying(100) NOT NULL,
|
303 |
+
name character varying(100) NOT NULL,
|
304 |
+
avatar character varying(255),
|
305 |
+
remember_token character varying(100),
|
306 |
+
created_at timestamp without time zone DEFAULT now(),
|
307 |
+
updated_at timestamp without time zone DEFAULT now()
|
308 |
+
);
|
309 |
+
|
310 |
+
|
311 |
+
ALTER TABLE public.goadmin_users OWNER TO postgres;
|
312 |
+
|
313 |
+
--
|
314 |
+
-- Data for Name: goadmin_menu; Type: TABLE DATA; Schema: public; Owner: postgres
|
315 |
+
--
|
316 |
+
|
317 |
+
COPY public.goadmin_menu (id, parent_id, type, "order", title, plugin_name, header, icon, uri, created_at, updated_at) FROM stdin;
|
318 |
+
1 0 1 2 Admin \N fa-tasks 2019-09-10 00:00:00 2019-09-10 00:00:00
|
319 |
+
2 1 1 2 Users \N fa-users /info/manager 2019-09-10 00:00:00 2019-09-10 00:00:00
|
320 |
+
3 1 1 3 Roles \N fa-user /info/roles 2019-09-10 00:00:00 2019-09-10 00:00:00
|
321 |
+
4 1 1 4 Permission \N fa-ban /info/permission 2019-09-10 00:00:00 2019-09-10 00:00:00
|
322 |
+
5 1 1 5 Menu \N fa-bars /menu 2019-09-10 00:00:00 2019-09-10 00:00:00
|
323 |
+
6 1 1 6 Operation log \N fa-history /info/op 2019-09-10 00:00:00 2019-09-10 00:00:00
|
324 |
+
7 0 1 1 Dashboard \N fa-bar-chart / 2019-09-10 00:00:00 2019-09-10 00:00:00
|
325 |
+
\.
|
326 |
+
|
327 |
+
|
328 |
+
--
|
329 |
+
-- Data for Name: goadmin_operation_log; Type: TABLE DATA; Schema: public; Owner: postgres
|
330 |
+
--
|
331 |
+
|
332 |
+
COPY public.goadmin_operation_log (id, user_id, path, method, ip, input, created_at, updated_at) FROM stdin;
|
333 |
+
\.
|
334 |
+
|
335 |
+
|
336 |
+
--
|
337 |
+
-- Data for Name: goadmin_site; Type: TABLE DATA; Schema: public; Owner: postgres
|
338 |
+
--
|
339 |
+
|
340 |
+
COPY public.goadmin_site (id, key, value, description, state, created_at, updated_at) FROM stdin;
|
341 |
+
\.
|
342 |
+
|
343 |
+
|
344 |
+
--
|
345 |
+
-- Data for Name: goadmin_permissions; Type: TABLE DATA; Schema: public; Owner: postgres
|
346 |
+
--
|
347 |
+
|
348 |
+
COPY public.goadmin_permissions (id, name, slug, http_method, http_path, created_at, updated_at) FROM stdin;
|
349 |
+
1 All permission * * 2019-09-10 00:00:00 2019-09-10 00:00:00
|
350 |
+
2 Dashboard dashboard GET,PUT,POST,DELETE / 2019-09-10 00:00:00 2019-09-10 00:00:00
|
351 |
+
\.
|
352 |
+
|
353 |
+
|
354 |
+
--
|
355 |
+
-- Data for Name: goadmin_role_menu; Type: TABLE DATA; Schema: public; Owner: postgres
|
356 |
+
--
|
357 |
+
|
358 |
+
COPY public.goadmin_role_menu (role_id, menu_id, created_at, updated_at) FROM stdin;
|
359 |
+
1 1 2019-09-10 00:00:00 2019-09-10 00:00:00
|
360 |
+
1 7 2019-09-10 00:00:00 2019-09-10 00:00:00
|
361 |
+
2 7 2019-09-10 00:00:00 2019-09-10 00:00:00
|
362 |
+
\.
|
363 |
+
|
364 |
+
|
365 |
+
--
|
366 |
+
-- Data for Name: goadmin_role_permissions; Type: TABLE DATA; Schema: public; Owner: postgres
|
367 |
+
--
|
368 |
+
|
369 |
+
COPY public.goadmin_role_permissions (role_id, permission_id, created_at, updated_at) FROM stdin;
|
370 |
+
1 1 2019-09-10 00:00:00 2019-09-10 00:00:00
|
371 |
+
1 2 2019-09-10 00:00:00 2019-09-10 00:00:00
|
372 |
+
2 2 2019-09-10 00:00:00 2019-09-10 00:00:00
|
373 |
+
0 3 \N \N
|
374 |
+
0 3 \N \N
|
375 |
+
0 3 \N \N
|
376 |
+
0 3 \N \N
|
377 |
+
0 3 \N \N
|
378 |
+
0 3 \N \N
|
379 |
+
0 3 \N \N
|
380 |
+
0 3 \N \N
|
381 |
+
0 3 \N \N
|
382 |
+
0 3 \N \N
|
383 |
+
0 3 \N \N
|
384 |
+
0 3 \N \N
|
385 |
+
0 3 \N \N
|
386 |
+
0 3 \N \N
|
387 |
+
0 3 \N \N
|
388 |
+
0 3 \N \N
|
389 |
+
\.
|
390 |
+
|
391 |
+
|
392 |
+
--
|
393 |
+
-- Data for Name: goadmin_role_users; Type: TABLE DATA; Schema: public; Owner: postgres
|
394 |
+
--
|
395 |
+
|
396 |
+
COPY public.goadmin_role_users (role_id, user_id, created_at, updated_at) FROM stdin;
|
397 |
+
1 1 2019-09-10 00:00:00 2019-09-10 00:00:00
|
398 |
+
2 2 2019-09-10 00:00:00 2019-09-10 00:00:00
|
399 |
+
\.
|
400 |
+
|
401 |
+
|
402 |
+
--
|
403 |
+
-- Data for Name: goadmin_roles; Type: TABLE DATA; Schema: public; Owner: postgres
|
404 |
+
--
|
405 |
+
|
406 |
+
COPY public.goadmin_roles (id, name, slug, created_at, updated_at) FROM stdin;
|
407 |
+
1 Administrator administrator 2019-09-10 00:00:00 2019-09-10 00:00:00
|
408 |
+
2 Operator operator 2019-09-10 00:00:00 2019-09-10 00:00:00
|
409 |
+
\.
|
410 |
+
|
411 |
+
|
412 |
+
--
|
413 |
+
-- Data for Name: goadmin_session; Type: TABLE DATA; Schema: public; Owner: postgres
|
414 |
+
--
|
415 |
+
|
416 |
+
COPY public.goadmin_session (id, sid, "values", created_at, updated_at) FROM stdin;
|
417 |
+
\.
|
418 |
+
|
419 |
+
|
420 |
+
--
|
421 |
+
-- Data for Name: goadmin_user_permissions; Type: TABLE DATA; Schema: public; Owner: postgres
|
422 |
+
--
|
423 |
+
|
424 |
+
COPY public.goadmin_user_permissions (user_id, permission_id, created_at, updated_at) FROM stdin;
|
425 |
+
1 1 2019-09-10 00:00:00 2019-09-10 00:00:00
|
426 |
+
2 2 2019-09-10 00:00:00 2019-09-10 00:00:00
|
427 |
+
0 1 \N \N
|
428 |
+
0 1 \N \N
|
429 |
+
0 1 \N \N
|
430 |
+
0 1 \N \N
|
431 |
+
0 1 \N \N
|
432 |
+
0 1 \N \N
|
433 |
+
0 1 \N \N
|
434 |
+
0 1 \N \N
|
435 |
+
0 1 \N \N
|
436 |
+
0 1 \N \N
|
437 |
+
0 1 \N \N
|
438 |
+
0 1 \N \N
|
439 |
+
0 1 \N \N
|
440 |
+
0 1 \N \N
|
441 |
+
0 1 \N \N
|
442 |
+
0 1 \N \N
|
443 |
+
\.
|
444 |
+
|
445 |
+
|
446 |
+
--
|
447 |
+
-- Data for Name: goadmin_users; Type: TABLE DATA; Schema: public; Owner: postgres
|
448 |
+
--
|
449 |
+
|
450 |
+
COPY public.goadmin_users (id, username, password, name, avatar, remember_token, created_at, updated_at) FROM stdin;
|
451 |
+
1 admin $2a$10$OxWYJJGTP2gi00l2x06QuOWqw5VR47MQCJ0vNKnbMYfrutij10Hwe admin tlNcBVK9AvfYH7WEnwB1RKvocJu8FfRy4um3DJtwdHuJy0dwFsLOgAc0xUfh 2019-09-10 00:00:00 2019-09-10 00:00:00
|
452 |
+
2 operator $2a$10$rVqkOzHjN2MdlEprRflb1eGP0oZXuSrbJLOmJagFsCd81YZm0bsh. Operator \N 2019-09-10 00:00:00 2019-09-10 00:00:00
|
453 |
+
\.
|
454 |
+
|
455 |
+
|
456 |
+
--
|
457 |
+
-- Name: goadmin_menu_myid_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
|
458 |
+
--
|
459 |
+
|
460 |
+
SELECT pg_catalog.setval('public.goadmin_menu_myid_seq', 7, true);
|
461 |
+
|
462 |
+
|
463 |
+
--
|
464 |
+
-- Name: goadmin_operation_log_myid_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
|
465 |
+
--
|
466 |
+
|
467 |
+
SELECT pg_catalog.setval('public.goadmin_operation_log_myid_seq', 1, true);
|
468 |
+
|
469 |
+
|
470 |
+
--
|
471 |
+
-- Name: goadmin_permissions_myid_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
|
472 |
+
--
|
473 |
+
|
474 |
+
SELECT pg_catalog.setval('public.goadmin_permissions_myid_seq', 2, true);
|
475 |
+
|
476 |
+
|
477 |
+
--
|
478 |
+
-- Name: goadmin_roles_myid_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
|
479 |
+
--
|
480 |
+
|
481 |
+
SELECT pg_catalog.setval('public.goadmin_roles_myid_seq', 2, true);
|
482 |
+
|
483 |
+
|
484 |
+
--
|
485 |
+
-- Name: goadmin_site_myid_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
|
486 |
+
--
|
487 |
+
|
488 |
+
SELECT pg_catalog.setval('public.goadmin_site_myid_seq', 1, true);
|
489 |
+
|
490 |
+
|
491 |
+
--
|
492 |
+
-- Name: goadmin_session_myid_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
|
493 |
+
--
|
494 |
+
|
495 |
+
SELECT pg_catalog.setval('public.goadmin_session_myid_seq', 1, true);
|
496 |
+
|
497 |
+
|
498 |
+
--
|
499 |
+
-- Name: goadmin_users_myid_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
|
500 |
+
--
|
501 |
+
|
502 |
+
SELECT pg_catalog.setval('public.goadmin_users_myid_seq', 2, true);
|
503 |
+
|
504 |
+
|
505 |
+
--
|
506 |
+
-- Name: goadmin_menu goadmin_menu_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
|
507 |
+
--
|
508 |
+
|
509 |
+
ALTER TABLE ONLY public.goadmin_menu
|
510 |
+
ADD CONSTRAINT goadmin_menu_pkey PRIMARY KEY (id);
|
511 |
+
|
512 |
+
|
513 |
+
--
|
514 |
+
-- Name: goadmin_operation_log goadmin_operation_log_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
|
515 |
+
--
|
516 |
+
|
517 |
+
ALTER TABLE ONLY public.goadmin_operation_log
|
518 |
+
ADD CONSTRAINT goadmin_operation_log_pkey PRIMARY KEY (id);
|
519 |
+
|
520 |
+
|
521 |
+
--
|
522 |
+
-- Name: goadmin_permissions goadmin_permissions_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
|
523 |
+
--
|
524 |
+
|
525 |
+
ALTER TABLE ONLY public.goadmin_permissions
|
526 |
+
ADD CONSTRAINT goadmin_permissions_pkey PRIMARY KEY (id);
|
527 |
+
|
528 |
+
|
529 |
+
--
|
530 |
+
-- Name: goadmin_roles goadmin_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
|
531 |
+
--
|
532 |
+
|
533 |
+
ALTER TABLE ONLY public.goadmin_roles
|
534 |
+
ADD CONSTRAINT goadmin_roles_pkey PRIMARY KEY (id);
|
535 |
+
|
536 |
+
|
537 |
+
--
|
538 |
+
-- Name: goadmin_site goadmin_site_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
|
539 |
+
--
|
540 |
+
|
541 |
+
ALTER TABLE ONLY public.goadmin_site
|
542 |
+
ADD CONSTRAINT goadmin_site_pkey PRIMARY KEY (id);
|
543 |
+
|
544 |
+
|
545 |
+
--
|
546 |
+
-- Name: goadmin_session goadmin_session_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
|
547 |
+
--
|
548 |
+
|
549 |
+
ALTER TABLE ONLY public.goadmin_session
|
550 |
+
ADD CONSTRAINT goadmin_session_pkey PRIMARY KEY (id);
|
551 |
+
|
552 |
+
|
553 |
+
--
|
554 |
+
-- Name: goadmin_users goadmin_users_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
|
555 |
+
--
|
556 |
+
|
557 |
+
ALTER TABLE ONLY public.goadmin_users
|
558 |
+
ADD CONSTRAINT goadmin_users_pkey PRIMARY KEY (id);
|
559 |
+
|
560 |
+
|
561 |
+
--
|
562 |
+
-- Name: SCHEMA public; Type: ACL; Schema: -; Owner: postgres
|
563 |
+
--
|
564 |
+
|
565 |
+
REVOKE ALL ON SCHEMA public FROM PUBLIC;
|
566 |
+
REVOKE ALL ON SCHEMA public FROM postgres;
|
567 |
+
GRANT ALL ON SCHEMA public TO postgres;
|
568 |
+
GRANT ALL ON SCHEMA public TO PUBLIC;
|
569 |
+
|
570 |
+
|
571 |
+
--
|
572 |
+
-- PostgreSQL database dump complete
|
573 |
+
--
|
574 |
+
|
data/admin.sql
ADDED
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# ************************************************************
|
2 |
+
# Sequel Pro SQL dump
|
3 |
+
# Version 4468
|
4 |
+
#
|
5 |
+
# http://www.sequelpro.com/
|
6 |
+
# https://github.com/sequelpro/sequelpro
|
7 |
+
#
|
8 |
+
# Host: 127.0.0.1 (MySQL 5.7.19)
|
9 |
+
# Database: godmin
|
10 |
+
# Generation Time: 2019-09-12 04:16:47 +0000
|
11 |
+
# ************************************************************
|
12 |
+
|
13 |
+
|
14 |
+
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
15 |
+
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
16 |
+
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
17 |
+
/*!40101 SET NAMES utf8 */;
|
18 |
+
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
19 |
+
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
20 |
+
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
21 |
+
|
22 |
+
|
23 |
+
# Dump of table goadmin_menu
|
24 |
+
# ------------------------------------------------------------
|
25 |
+
|
26 |
+
DROP TABLE IF EXISTS `goadmin_menu`;
|
27 |
+
|
28 |
+
CREATE TABLE `goadmin_menu` (
|
29 |
+
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
30 |
+
`parent_id` int(11) unsigned NOT NULL DEFAULT '0',
|
31 |
+
`type` tinyint(4) unsigned NOT NULL DEFAULT '0',
|
32 |
+
`order` int(11) unsigned NOT NULL DEFAULT '0',
|
33 |
+
`title` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
34 |
+
`icon` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
35 |
+
`uri` varchar(3000) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
|
36 |
+
`header` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
37 |
+
`plugin_name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
|
38 |
+
`uuid` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
39 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
40 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
41 |
+
PRIMARY KEY (`id`)
|
42 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
43 |
+
|
44 |
+
LOCK TABLES `goadmin_menu` WRITE;
|
45 |
+
/*!40000 ALTER TABLE `goadmin_menu` DISABLE KEYS */;
|
46 |
+
|
47 |
+
INSERT INTO `goadmin_menu` (`id`, `parent_id`, `type`, `order`, `title`, `icon`, `uri`, `plugin_name`, `header`, `created_at`, `updated_at`)
|
48 |
+
VALUES
|
49 |
+
(1,0,1,2,'Admin','fa-tasks','','',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
50 |
+
(2,1,1,2,'Users','fa-users','/info/manager','',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
51 |
+
(3,1,1,3,'Roles','fa-user','/info/roles','',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
52 |
+
(4,1,1,4,'Permission','fa-ban','/info/permission','',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
53 |
+
(5,1,1,5,'Menu','fa-bars','/menu','',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
54 |
+
(6,1,1,6,'Operation log','fa-history','/info/op','',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
55 |
+
(7,0,1,1,'Dashboard','fa-bar-chart','/','',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00');
|
56 |
+
|
57 |
+
/*!40000 ALTER TABLE `goadmin_menu` ENABLE KEYS */;
|
58 |
+
UNLOCK TABLES;
|
59 |
+
|
60 |
+
|
61 |
+
# Dump of table goadmin_operation_log
|
62 |
+
# ------------------------------------------------------------
|
63 |
+
|
64 |
+
DROP TABLE IF EXISTS `goadmin_operation_log`;
|
65 |
+
|
66 |
+
CREATE TABLE `goadmin_operation_log` (
|
67 |
+
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
68 |
+
`user_id` int(11) unsigned NOT NULL,
|
69 |
+
`path` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
70 |
+
`method` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
|
71 |
+
`ip` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL,
|
72 |
+
`input` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
73 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
74 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
75 |
+
PRIMARY KEY (`id`),
|
76 |
+
KEY `admin_operation_log_user_id_index` (`user_id`)
|
77 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
78 |
+
|
79 |
+
|
80 |
+
# Dump of table goadmin_site
|
81 |
+
# ------------------------------------------------------------
|
82 |
+
|
83 |
+
DROP TABLE IF EXISTS `goadmin_site`;
|
84 |
+
|
85 |
+
CREATE TABLE `goadmin_site` (
|
86 |
+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
87 |
+
`key` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
88 |
+
`value` longtext COLLATE utf8mb4_unicode_ci,
|
89 |
+
`description` varchar(3000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
90 |
+
`state` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
91 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
92 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
93 |
+
PRIMARY KEY (`id`)
|
94 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
95 |
+
|
96 |
+
|
97 |
+
# Dump of table goadmin_permissions
|
98 |
+
# ------------------------------------------------------------
|
99 |
+
|
100 |
+
DROP TABLE IF EXISTS `goadmin_permissions`;
|
101 |
+
|
102 |
+
CREATE TABLE `goadmin_permissions` (
|
103 |
+
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
104 |
+
`name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
105 |
+
`slug` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
106 |
+
`http_method` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
107 |
+
`http_path` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
108 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
109 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
110 |
+
PRIMARY KEY (`id`),
|
111 |
+
UNIQUE KEY `admin_permissions_name_unique` (`name`)
|
112 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
113 |
+
|
114 |
+
LOCK TABLES `goadmin_permissions` WRITE;
|
115 |
+
/*!40000 ALTER TABLE `goadmin_permissions` DISABLE KEYS */;
|
116 |
+
|
117 |
+
INSERT INTO `goadmin_permissions` (`id`, `name`, `slug`, `http_method`, `http_path`, `created_at`, `updated_at`)
|
118 |
+
VALUES
|
119 |
+
(1,'All permission','*','','*','2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
120 |
+
(2,'Dashboard','dashboard','GET,PUT,POST,DELETE','/','2019-09-10 00:00:00','2019-09-10 00:00:00');
|
121 |
+
|
122 |
+
/*!40000 ALTER TABLE `goadmin_permissions` ENABLE KEYS */;
|
123 |
+
UNLOCK TABLES;
|
124 |
+
|
125 |
+
|
126 |
+
# Dump of table goadmin_role_menu
|
127 |
+
# ------------------------------------------------------------
|
128 |
+
|
129 |
+
DROP TABLE IF EXISTS `goadmin_role_menu`;
|
130 |
+
|
131 |
+
CREATE TABLE `goadmin_role_menu` (
|
132 |
+
`role_id` int(11) unsigned NOT NULL,
|
133 |
+
`menu_id` int(11) unsigned NOT NULL,
|
134 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
135 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
136 |
+
KEY `admin_role_menu_role_id_menu_id_index` (`role_id`,`menu_id`)
|
137 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
138 |
+
|
139 |
+
LOCK TABLES `goadmin_role_menu` WRITE;
|
140 |
+
/*!40000 ALTER TABLE `goadmin_role_menu` DISABLE KEYS */;
|
141 |
+
|
142 |
+
INSERT INTO `goadmin_role_menu` (`role_id`, `menu_id`, `created_at`, `updated_at`)
|
143 |
+
VALUES
|
144 |
+
(1,1,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
145 |
+
(1,7,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
146 |
+
(2,7,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
147 |
+
(1,8,'2019-09-11 10:20:55','2019-09-11 10:20:55'),
|
148 |
+
(2,8,'2019-09-11 10:20:55','2019-09-11 10:20:55');
|
149 |
+
|
150 |
+
/*!40000 ALTER TABLE `goadmin_role_menu` ENABLE KEYS */;
|
151 |
+
UNLOCK TABLES;
|
152 |
+
|
153 |
+
|
154 |
+
# Dump of table goadmin_role_permissions
|
155 |
+
# ------------------------------------------------------------
|
156 |
+
|
157 |
+
DROP TABLE IF EXISTS `goadmin_role_permissions`;
|
158 |
+
|
159 |
+
CREATE TABLE `goadmin_role_permissions` (
|
160 |
+
`role_id` int(11) unsigned NOT NULL,
|
161 |
+
`permission_id` int(11) unsigned NOT NULL,
|
162 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
163 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
164 |
+
UNIQUE KEY `admin_role_permissions` (`role_id`,`permission_id`)
|
165 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
166 |
+
|
167 |
+
LOCK TABLES `goadmin_role_permissions` WRITE;
|
168 |
+
/*!40000 ALTER TABLE `goadmin_role_permissions` DISABLE KEYS */;
|
169 |
+
|
170 |
+
INSERT INTO `goadmin_role_permissions` (`role_id`, `permission_id`, `created_at`, `updated_at`)
|
171 |
+
VALUES
|
172 |
+
(1,1,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
173 |
+
(1,2,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
174 |
+
(2,2,'2019-09-10 00:00:00','2019-09-10 00:00:00');
|
175 |
+
|
176 |
+
/*!40000 ALTER TABLE `goadmin_role_permissions` ENABLE KEYS */;
|
177 |
+
UNLOCK TABLES;
|
178 |
+
|
179 |
+
|
180 |
+
# Dump of table goadmin_role_users
|
181 |
+
# ------------------------------------------------------------
|
182 |
+
|
183 |
+
DROP TABLE IF EXISTS `goadmin_role_users`;
|
184 |
+
|
185 |
+
CREATE TABLE `goadmin_role_users` (
|
186 |
+
`role_id` int(11) unsigned NOT NULL,
|
187 |
+
`user_id` int(11) unsigned NOT NULL,
|
188 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
189 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
190 |
+
UNIQUE KEY `admin_user_roles` (`role_id`,`user_id`)
|
191 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
192 |
+
|
193 |
+
LOCK TABLES `goadmin_role_users` WRITE;
|
194 |
+
/*!40000 ALTER TABLE `goadmin_role_users` DISABLE KEYS */;
|
195 |
+
|
196 |
+
INSERT INTO `goadmin_role_users` (`role_id`, `user_id`, `created_at`, `updated_at`)
|
197 |
+
VALUES
|
198 |
+
(1,1,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
199 |
+
(2,2,'2019-09-10 00:00:00','2019-09-10 00:00:00');
|
200 |
+
|
201 |
+
/*!40000 ALTER TABLE `goadmin_role_users` ENABLE KEYS */;
|
202 |
+
UNLOCK TABLES;
|
203 |
+
|
204 |
+
|
205 |
+
# Dump of table goadmin_roles
|
206 |
+
# ------------------------------------------------------------
|
207 |
+
|
208 |
+
DROP TABLE IF EXISTS `goadmin_roles`;
|
209 |
+
|
210 |
+
CREATE TABLE `goadmin_roles` (
|
211 |
+
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
212 |
+
`name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
213 |
+
`slug` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
214 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
215 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
216 |
+
PRIMARY KEY (`id`),
|
217 |
+
UNIQUE KEY `admin_roles_name_unique` (`name`)
|
218 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
219 |
+
|
220 |
+
LOCK TABLES `goadmin_roles` WRITE;
|
221 |
+
/*!40000 ALTER TABLE `goadmin_roles` DISABLE KEYS */;
|
222 |
+
|
223 |
+
INSERT INTO `goadmin_roles` (`id`, `name`, `slug`, `created_at`, `updated_at`)
|
224 |
+
VALUES
|
225 |
+
(1,'Administrator','administrator','2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
226 |
+
(2,'Operator','operator','2019-09-10 00:00:00','2019-09-10 00:00:00');
|
227 |
+
|
228 |
+
/*!40000 ALTER TABLE `goadmin_roles` ENABLE KEYS */;
|
229 |
+
UNLOCK TABLES;
|
230 |
+
|
231 |
+
|
232 |
+
# Dump of table goadmin_session
|
233 |
+
# ------------------------------------------------------------
|
234 |
+
|
235 |
+
DROP TABLE IF EXISTS `goadmin_session`;
|
236 |
+
|
237 |
+
CREATE TABLE `goadmin_session` (
|
238 |
+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
239 |
+
`sid` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
|
240 |
+
`values` varchar(3000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
|
241 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
242 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
243 |
+
PRIMARY KEY (`id`)
|
244 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
245 |
+
|
246 |
+
|
247 |
+
|
248 |
+
# Dump of table goadmin_user_permissions
|
249 |
+
# ------------------------------------------------------------
|
250 |
+
|
251 |
+
DROP TABLE IF EXISTS `goadmin_user_permissions`;
|
252 |
+
|
253 |
+
CREATE TABLE `goadmin_user_permissions` (
|
254 |
+
`user_id` int(11) unsigned NOT NULL,
|
255 |
+
`permission_id` int(11) unsigned NOT NULL,
|
256 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
257 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
258 |
+
UNIQUE KEY `admin_user_permissions` (`user_id`,`permission_id`)
|
259 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
260 |
+
|
261 |
+
LOCK TABLES `goadmin_user_permissions` WRITE;
|
262 |
+
/*!40000 ALTER TABLE `goadmin_user_permissions` DISABLE KEYS */;
|
263 |
+
|
264 |
+
INSERT INTO `goadmin_user_permissions` (`user_id`, `permission_id`, `created_at`, `updated_at`)
|
265 |
+
VALUES
|
266 |
+
(1,1,'2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
267 |
+
(2,2,'2019-09-10 00:00:00','2019-09-10 00:00:00');
|
268 |
+
|
269 |
+
/*!40000 ALTER TABLE `goadmin_user_permissions` ENABLE KEYS */;
|
270 |
+
UNLOCK TABLES;
|
271 |
+
|
272 |
+
|
273 |
+
# Dump of table goadmin_users
|
274 |
+
# ------------------------------------------------------------
|
275 |
+
|
276 |
+
DROP TABLE IF EXISTS `goadmin_users`;
|
277 |
+
|
278 |
+
CREATE TABLE `goadmin_users` (
|
279 |
+
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
280 |
+
`username` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
|
281 |
+
`password` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
|
282 |
+
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
|
283 |
+
`avatar` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
284 |
+
`remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
285 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
286 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
287 |
+
PRIMARY KEY (`id`),
|
288 |
+
UNIQUE KEY `admin_users_username_unique` (`username`)
|
289 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
290 |
+
|
291 |
+
LOCK TABLES `goadmin_users` WRITE;
|
292 |
+
/*!40000 ALTER TABLE `goadmin_users` DISABLE KEYS */;
|
293 |
+
|
294 |
+
INSERT INTO `goadmin_users` (`id`, `username`, `password`, `name`, `avatar`, `remember_token`, `created_at`, `updated_at`)
|
295 |
+
VALUES
|
296 |
+
(1,'admin','$2a$10$U3F/NSaf2kaVbyXTBp7ppOn0jZFyRqXRnYXB.AMioCjXl3Ciaj4oy','admin','','tlNcBVK9AvfYH7WEnwB1RKvocJu8FfRy4um3DJtwdHuJy0dwFsLOgAc0xUfh','2019-09-10 00:00:00','2019-09-10 00:00:00'),
|
297 |
+
(2,'operator','$2a$10$rVqkOzHjN2MdlEprRflb1eGP0oZXuSrbJLOmJagFsCd81YZm0bsh.','Operator','',NULL,'2019-09-10 00:00:00','2019-09-10 00:00:00');
|
298 |
+
|
299 |
+
/*!40000 ALTER TABLE `goadmin_users` ENABLE KEYS */;
|
300 |
+
UNLOCK TABLES;
|
301 |
+
|
302 |
+
|
303 |
+
|
304 |
+
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
305 |
+
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
306 |
+
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
307 |
+
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
308 |
+
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
309 |
+
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
data/migrations/admin_2020_04_14_100427_ms.sql
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CREATE TABLE[goadmin_site] (
|
2 |
+
[id] int identity(1,1) ,
|
3 |
+
[key] varchar(100) NOT NULL,
|
4 |
+
[value] text NOT NULL,
|
5 |
+
[state] tinyint NOT NULL DEFAULT 0,
|
6 |
+
[description] varchar(3000) NOT NULL,
|
7 |
+
[created_at] datetime NULL DEFAULT GETDATE(),
|
8 |
+
[updated_at] datetime NULL DEFAULT GETDATE(),
|
9 |
+
PRIMARY KEY ([id]),
|
10 |
+
)
|
data/migrations/admin_2020_04_14_100427_mysql.sql
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CREATE TABLE `goadmin_site` (
|
2 |
+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
3 |
+
`key` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
4 |
+
`value` longtext COLLATE utf8mb4_unicode_ci,
|
5 |
+
`description` varchar(3000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
6 |
+
`state` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
7 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
8 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
9 |
+
PRIMARY KEY (`id`)
|
10 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
data/migrations/admin_2020_04_14_100427_postgres.sql
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
--
|
2 |
+
-- PostgreSQL database dump
|
3 |
+
--
|
4 |
+
|
5 |
+
-- Dumped from database version 9.5.14
|
6 |
+
-- Dumped by pg_dump version 10.5
|
7 |
+
|
8 |
+
SET statement_timeout = 0;
|
9 |
+
SET lock_timeout = 0;
|
10 |
+
SET idle_in_transaction_session_timeout = 0;
|
11 |
+
SET client_encoding = 'EUC_CN';
|
12 |
+
SET standard_conforming_strings = on;
|
13 |
+
SELECT pg_catalog.set_config('search_path', '', false);
|
14 |
+
SET check_function_bodies = false;
|
15 |
+
SET client_min_messages = warning;
|
16 |
+
SET row_security = off;
|
17 |
+
|
18 |
+
SET default_tablespace = '';
|
19 |
+
|
20 |
+
SET default_with_oids = false;
|
21 |
+
|
22 |
+
--
|
23 |
+
-- Name: goadmin_site_myid_seq; Type: SEQUENCE; Schema: public; Owner: postgres
|
24 |
+
--
|
25 |
+
|
26 |
+
CREATE SEQUENCE public.goadmin_site_myid_seq
|
27 |
+
START WITH 1
|
28 |
+
INCREMENT BY 1
|
29 |
+
NO MINVALUE
|
30 |
+
MAXVALUE 99999999
|
31 |
+
CACHE 1;
|
32 |
+
|
33 |
+
ALTER TABLE public.goadmin_site_myid_seq OWNER TO postgres;
|
34 |
+
|
35 |
+
--
|
36 |
+
-- Name: goadmin_site; Type: TABLE; Schema: public; Owner: postgres
|
37 |
+
--
|
38 |
+
|
39 |
+
CREATE TABLE public.goadmin_site (
|
40 |
+
id integer DEFAULT nextval('public.goadmin_site_myid_seq'::regclass) NOT NULL,
|
41 |
+
key character varying(100) NOT NULL,
|
42 |
+
value text NOT NULL,
|
43 |
+
type integer DEFAULT 0,
|
44 |
+
description character varying(3000),
|
45 |
+
state integer DEFAULT 0,
|
46 |
+
created_at timestamp without time zone DEFAULT now(),
|
47 |
+
updated_at timestamp without time zone DEFAULT now()
|
48 |
+
);
|
49 |
+
|
50 |
+
|
51 |
+
ALTER TABLE public.goadmin_site OWNER TO postgres;
|
52 |
+
|
53 |
+
--
|
54 |
+
-- Data for Name: goadmin_site; Type: TABLE DATA; Schema: public; Owner: postgres
|
55 |
+
--
|
56 |
+
|
57 |
+
COPY public.goadmin_site (id, key, value, type, description, state, created_at, updated_at) FROM stdin;
|
58 |
+
\.
|
59 |
+
|
60 |
+
|
61 |
+
--
|
62 |
+
-- Name: goadmin_site goadmin_site_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
|
63 |
+
--
|
64 |
+
|
65 |
+
ALTER TABLE ONLY public.goadmin_site
|
66 |
+
ADD CONSTRAINT goadmin_site_pkey PRIMARY KEY (id);
|
67 |
+
|
68 |
+
|
69 |
+
--
|
70 |
+
-- PostgreSQL database dump complete
|
71 |
+
--
|
72 |
+
|
data/migrations/admin_2020_04_14_100427_sqlite.sql
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CREATE TABLE IF NOT EXISTS "goadmin_site" (
|
2 |
+
`id` integer PRIMARY KEY autoincrement,
|
3 |
+
`key` CHAR(100) COLLATE NOCASE NOT NULL,
|
4 |
+
`value` text COLLATE NOCASE NOT NULL,
|
5 |
+
`state` INT NOT NULL DEFAULT '0',
|
6 |
+
`description` CHAR(3000) COLLATE NOCASE,
|
7 |
+
`created_at` TIMESTAMP default CURRENT_TIMESTAMP,
|
8 |
+
`updated_at` TIMESTAMP default CURRENT_TIMESTAMP
|
9 |
+
);
|
data/migrations/admin_2020_08_04_092427_ms.sql
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
ALTER TABLE goadmin_menu
|
2 |
+
ADD plugin_name varchar(150) NOT NULL DEFAULT '',
|
3 |
+
ADD uuid varchar(150) NOT NULL DEFAULT '';
|
data/migrations/admin_2020_08_04_092427_mysql.sql
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
ALTER TABLE goadmin_menu
|
2 |
+
ADD COLUMN `uuid` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
|
3 |
+
ADD COLUMN `plugin_name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '';
|
data/migrations/admin_2020_08_04_092427_postgres.sql
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
ALTER TABLE goadmin_menu
|
2 |
+
ADD COLUMN plugin_name character varying(150) NOT NULL DEFAULT '',
|
3 |
+
ADD COLUMN uuid character varying(150) NOT NULL DEFAULT '';
|
data/migrations/admin_2020_08_04_092427_sqlite.sql
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
ALTER TABLE goadmin_menu
|
2 |
+
ADD COLUMN `uuid` varchar(150) NOT NULL DEFAULT '',
|
3 |
+
ADD COLUMN `plugin_name` varchar(150) NOT NULL DEFAULT '';
|