├── .gitignore
├── Dockerfile
├── Makefile
├── README.md
├── README_CN.md
├── adm_config.ini
├── admin.db
├── bootstrap.go
├── config.yml
├── deploy
├── README.md
├── apache.conf
└── nginx.conf
├── go.mod
├── go.sum
├── html
└── hello.tmpl
├── logs
└── .gitkeep
├── main.go
├── main_test.go
├── models
├── base.go
└── statistics.go
├── pages
├── form.go
├── index.go
└── table.go
├── project.db
├── tables
├── authors.go
├── external.go
├── posts.go
├── profile.go
├── tables.go
└── users.go
└── uploads
└── a.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .vscode
3 | build
4 | vendor/**
5 | !vendor/vendor.json
6 | local.mk
7 | build
8 | logs/**
9 | !.gitkeep
10 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:latest
2 |
3 | WORKDIR /go/src/app
4 | COPY . .
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | GOCMD = go
2 | GOBUILD = $(GOCMD) build
3 | GOINSTALL = $(GOCMD) install
4 | GOTEST = $(GOCMD) test
5 | BINARY_NAME = goadmin
6 | CLI = adm
7 |
8 | all: serve
9 |
10 | serve:
11 | $(GOCMD) run .
12 |
13 | build:
14 | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -o ./build/$(BINARY_NAME) -v ./
15 |
16 | generate:
17 | $(GOINSTALL) github.com/GoAdminGroup/go-admin/adm
18 | $(CLI) generate -c adm_config.ini
19 |
20 | test: black-box-test user-acceptance-test
21 |
22 | black-box-test: ready-for-data
23 | $(GOTEST) -v -test.run=TestExampleBlackBox
24 | make clean
25 |
26 | user-acceptance-test: ready-for-data
27 | $(GOTEST) -v -test.run=TestExampleUserAcceptance
28 | make clean
29 |
30 | ready-for-data:
31 | cp admin.db admin_test.db
32 |
33 | clean:
34 | rm admin_test.db
35 |
36 | .PHONY: all serve build generate test black-box-test user-acceptance-test ready-for-data clean
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GoAdmin Example
2 |
3 | [中文说明](./README_CN.md)
4 |
5 | A example show how to run go-admin. Just for reference, [here](http://www.go-admin.cn/en) to know more.
6 |
7 | Following three ways to run the code.
8 |
9 | If you are Windows user, [go-sqlite-dirver](https://github.com/mattn/go-sqlite3) require to download the gcc to make it work.
10 |
11 | ## use go module
12 |
13 | To use go module, you should set GO111MODULE=on first.
14 |
15 | ### step 1
16 |
17 | ```shell
18 | git clone https://github.com/GoAdminGroup/example.git
19 | ```
20 |
21 | ### step 2
22 |
23 | ```shell
24 | cd example
25 | GO111MODULE=on go run .
26 | ```
27 |
28 | visit: [http://localhost:9033/admin](http://localhost:9033/admin)
29 |
30 | ## use docker
31 |
32 | ### step 1
33 |
34 | ```shell
35 | git clone https://github.com/GoAdminGroup/example.git
36 | ```
37 |
38 | ### step 2
39 |
40 | ```shell
41 | cd example
42 | docker build -t go-admin-example .
43 | ```
44 |
45 | ### step 3
46 |
47 | ```shell
48 | docker attach $(docker run -p 9033:9033 -it -d go-admin-example /bin/bash -c "cd /go/src/app && GOPROXY=http://goproxy.cn GO111MODULE=on go run .")
49 | ```
50 |
51 | visit: [http://localhost:9033/admin](http://localhost:9033/admin)
--------------------------------------------------------------------------------
/README_CN.md:
--------------------------------------------------------------------------------
1 | # GoAdmin 上手例子
2 |
3 | 一个运行go-admin的例子。仅供参考,在[这里](http://www.go-admin.cn)了解更多。
4 |
5 | 以下三种方法。建议go版本大于1.11使用模块加载,同时设置环境变量```GOPROXY=http://goproxy.cn```,版本低于1.11的盆友使用第二种方法。如果本机没有golang环境,可以使用docker。
6 |
7 | **如果你没有golang基础,是golang新手的话,建议花几分钟了解一下[golang的依赖包管理机制](https://ms.logger.im/search?q=golang%20%E4%BE%9D%E8%B5%96%E7%AE%A1%E7%90%86)**
8 |
9 | 如果你是windows用户,那么你需要下载gcc,因为本例子使用的是sqlite数据库,如果你不想使用sqlite数据库,你可以换成mysql,则不需要下载gcc。
10 |
11 | 劝退:没有计算机基础或基础比较差的请谨慎使用或不要使用orz。
12 |
13 | ## 安装与运行
14 |
15 | ### 使用模块go module加载依赖
16 |
17 | 使用 go module的话,需要先设置环境变量```GO111MODULE```为```on```
18 |
19 | #### 第一步
20 |
21 | ```shell
22 | git clone https://github.com/GoAdminGroup/example.git
23 | ```
24 |
25 | #### 第二步
26 |
27 | ```shell
28 | cd example
29 | GOPROXY=https://goproxy.cn GO111MODULE=on go run .
30 | ```
31 |
32 | 访问: [http://localhost:9033/admin](http://localhost:9033/admin)
33 |
34 | ### use docker 使用docker
35 |
36 | #### 第一步
37 |
38 | ```shell
39 | git clone https://github.com/GoAdminGroup/example.git
40 | ```
41 |
42 | #### 第二步
43 |
44 | ```shell
45 | cd example
46 | docker build -t go-admin-example .
47 | ```
48 |
49 | #### 第三步
50 |
51 | ```shell
52 | docker attach $(docker run -p 9033:9033 -it -d go-admin-example /bin/bash -c "cd /go/src/app && GOPROXY=http://goproxy.cn GO111MODULE=on go run .")
53 | ```
54 |
55 | 访问: [http://localhost:9033/admin](http://localhost:9033/admin)
56 |
57 | ## 文件夹介绍
58 |
59 | ```
60 | .
61 | ├── Dockerfile Dockerfile
62 | ├── Makefile Makefile命令
63 | ├── adm_config.ini adm配置文件
64 | ├── admin.db 数据库文件
65 | ├── build 二进制构建目标文件夹
66 | ├── config.json 配置文件
67 | ├── deploy 部署命令说明
68 | ├── go.mod go.mod
69 | ├── go.sum go.sum
70 | ├── html 前端html文件
71 | ├── logs 日志存放文件夹
72 | ├── main.go main文件
73 | ├── main_test.go CI测试文件
74 | ├── models ORM模型文件
75 | ├── pages 页面控制器
76 | ├── tables 数据模型表格文件
77 | ├── uploads 图片等上传文件夹
78 | └── vendor 第三方依赖
79 | ```
80 |
81 | ## 开发与部署流程
82 |
83 | ### 第一步
84 |
85 | #### 1. 新建表格
86 |
87 | 数据库新建表格后,通过执行```make generate```生成数据表格模型文件,修改数据表格模型文件。
88 |
89 | #### 2. 新建页面
90 |
91 | pages文件夹新建页面控制器文件,如果需要更大程度定制可以html文件夹下新建一个golang tmpl模板文件,然后在main.go中载入。
92 |
93 | ### 第二步
94 |
95 | 本地执行```make serve```,查看效果。并增加菜单,与对应权限角色。
96 |
97 | ### 第三步
98 |
99 | 编写main_test.go测试文件,本地执行```make test```,测试所有API与页面UI逻辑。
100 |
101 | ### 第四步
102 |
103 | 通过git等版本控制软件发布到线上测试环境,触发CI测试。
104 |
105 | ### 第五步
106 |
107 | 测试没问题后,将```make build```编译出的二进制文件,发布到生产环境。
108 |
109 |
110 | **注意:以上windows用户请自行将makefile命令转换为windows下命令**
111 |
--------------------------------------------------------------------------------
/adm_config.ini:
--------------------------------------------------------------------------------
1 | ; default database config 默认数据库配置
2 | [database]
3 | driver = sqlite
4 | file = ./admin.db
5 | database = goadmin
6 | ; Here are new tables to generate. 新的待转换的表格
7 | tables = new_table1,new_table2
8 |
9 | ; specified connection database config 指定数据库配置
10 | ; for example, database config which connection name is mydb.
11 | ;[database.mydb]
12 |
13 | ; table model config 数据模型设置
14 | [model]
15 | package = main
16 | connection = default
17 | output = ./tables
--------------------------------------------------------------------------------
/admin.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoAdminGroup/example/956d61425a561b823fa00bc7c9a5098882411f42/admin.db
--------------------------------------------------------------------------------
/bootstrap.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/config.yml:
--------------------------------------------------------------------------------
1 |
2 | # 配置将在应用第一次启动时写入到数据库的数据表 goadmin_site 中。后续启动将优先从 goadmin_site
3 | # 中进行加载配置,如果希望修改,可以点击网站右上角配置中心入口进入修改。
4 |
5 | # 数据库设置,支持配置多个数据库,目前支持的数据库驱动为:sqlite/mssql/mysql/postgresql
6 | # 默认数据库连接名为default,框架中可以通过自定义的数据库连接名获取到该连接对象。
7 | # 在数据表模型中也可以通过指定对应的连接名来获取对应数据。
8 | database:
9 | default:
10 | driver: sqlite
11 | file: ./admin.db
12 |
13 | # params为驱动需要的额外的传参
14 | # params:
15 | # character: utf8mb4
16 |
17 | # 如果设置了DSN,那么以上配置除了Driver都将失效而以配置的DSN为准
18 | # dsn: ""
19 | bookstore:
20 | driver: sqlite
21 | file: ./project.db
22 |
23 | # 本应用的唯一ID
24 | app_id: F5sDriver1Ox9segP
25 |
26 | # 定义的网站域名,用于cookie认证进行域名限制
27 | # domain:
28 | # 网站语言
29 | language: cn
30 | # 全局路由前缀
31 | prefix: admin
32 | # UI主题
33 | theme: sword
34 | # 文件存储设置,设置上传文件的存储路径以及路由前缀
35 | store:
36 | path: ./uploads
37 | prefix: uploads
38 |
39 | # 网站标题
40 | title: GoAdmin
41 | # 网站LOGO文字,将显示在登录页面以及侧边栏上方,可以为自定义HTML
42 | logo: GoAdmin
43 | # 网站LOGO缩小文字,将显示缩小的侧边栏上方,可以为自定义HTML
44 | mini_logo: GA
45 | # 首页路由
46 | index: /
47 | # 登录路由
48 | login_url: /login
49 |
50 | # 是否为调试模式
51 | debug: true
52 | # 开发环境:本地 EnvLocal / 测试 EnvTest / 生产 EnvProd
53 | env: local
54 |
55 | # info日志本地存储路径
56 | info_log: ./logs/info.log
57 | # error日志本地存储路径
58 | error_log: ./logs/error.log
59 | # access日志本地存储路径
60 | access_log: ./logs/access.log
61 |
62 | # 是否关闭资源访问日志
63 | # access_assets_log_off: false
64 | # 是否关闭sql日志
65 | # sql_log: false
66 | # 是否关闭access日志
67 | # access_log_off: false
68 | # 是否关闭info日志
69 | # info_log_off: false
70 | # 是否关闭error日志
71 | # error_log_off: false
72 |
73 | # 颜色主题,当框架主题为adminlte时生效
74 | # color_scheme:
75 |
76 | # session的时长,单位为秒,默认为两小时。连续不登两小时后需要重新登录。
77 | session_life_time: 7200
78 |
79 | # 资源路由,当使用CDN时,此配置生效
80 | # asset_url:
81 |
82 | # 文件上传引擎
83 | file_upload_engine:
84 | name: local
85 |
86 | # 自定义头部HTML
87 | # custom_head_html:
88 | # 自定义底部HTML
89 | # custom_foot_html:
90 | # 自定义底部信息
91 | # footer_info:
92 |
93 | # 登录页标题
94 | # login_title: GoAdmin
95 | # 登录页Logo
96 | # login_logo: GoAdmin
97 |
98 | # 自定义的用户表
99 | # auth_user_table: goadmin_users
100 |
101 | # 是否不限制多IP登录,如果需要多浏览器登录,请设置为true
102 | # no_limit_login_ip: false
103 |
104 | # 是否关闭网站
105 | # site_off: false
106 |
107 | # 是否隐藏配置中心入口
108 | # hide_config_center_entrance: false
109 | # 是否禁止配置修改
110 | # prohibit_config_modification: false
111 | # 是否隐藏应用中心入口
112 | # hide_app_info_entrance: false
113 | # 是否隐藏工具入口
114 | # hide_tool_entrance: false
115 | # 是否隐藏插件中心入口
116 | # hide_plugin_entrance: false
117 |
118 | # 自定义404页面HTML
119 | # custom_404_html:
120 | # 自定义403页面HTML
121 | # custom_403_html:
122 | # 自定义500页面HTML
123 | # custom_500_html:
124 |
125 | # 是否开放admin api
126 | # open_admin_api: false
127 | # 是否隐藏用户中心入口
128 | # hide_visitor_user_center_entrance: false
129 |
130 | # 排除的需要加载的主题组件
131 | # exclude_theme_components:
132 | # - ""
133 |
134 | # 引导文件的本地路径
135 | bootstrap_file_path: ./bootstrap.go
136 | # go.mod文件的本地路径
137 | go_mod_file_path: ./go.mod
138 |
139 | # 是否允许删除操作日志
140 | allow_del_operation_log: false
141 | # 是否关闭操作日志
142 | operation_log_off: false
143 |
144 | # 资源文件的本地路径
145 | # 当选择资源文件分离的主题模式时候需要设置此配置项。
146 | asset_root_path: ./public/
147 |
148 | # URL格式
149 | # url_format:
150 | # info: /info/:__prefix
151 | # detail: /info/:__prefix/detail
152 | # create: /new/:__prefix
153 | # delete: /delete/:__prefix
154 | # export: /export/:__prefix
155 | # edit: /edit/:__prefix
156 | # show_edit: /info/:__prefix/edit
157 | # show_create: /info/:__prefix/new
158 | # update: /update/:__prefix
159 |
160 | # Logger配置用于设置日志记录器的行为和设置。
161 | # 更多细节:https://pkg.go.dev/go.uber.org/zap
162 | logger:
163 | # Encoder配置用于设置日志编码器的行为和设置。
164 | encoder:
165 | # 时间键
166 | time_key: ts
167 | # 级别键
168 | level_key: level
169 | # 名称键
170 | name_key: logger
171 | # 调用者键
172 | caller_key: caller
173 | # 消息键
174 | message_key: msg
175 | # 堆栈跟踪键
176 | stacktrace_key: stacktrace
177 | # 级别格式
178 | level: capitalColor
179 | # 时间格式
180 | time: ISO8601
181 | # 间隔
182 | duration: seconds
183 | # 调用者格式
184 | caller: short
185 | # 编码格式 console/json
186 | encoding: console
187 |
188 | # Rotate配置用于设置日志轮转的行为和设置。
189 | rotate:
190 | # 最大保存时间
191 | max_age: 10
192 | # 最大保存数量
193 | max_backups: 5
194 | # 最大大小
195 | max_size: 30
196 | # 压缩
197 | compress: false
198 |
199 |
--------------------------------------------------------------------------------
/deploy/README.md:
--------------------------------------------------------------------------------
1 | # Deploy GoAdmin Example / 部署GoAdmin Example
2 |
3 | ## Load balancing 负载均衡
4 |
5 | - nginx
6 | - apache
7 | - docker
8 |
9 | ## CICD 持续集成
10 |
11 | - jenkins
12 | - drone
--------------------------------------------------------------------------------
/deploy/apache.conf:
--------------------------------------------------------------------------------
1 | NameVirtualHost *:80
2 |
3 | ServerName xxxx.com
4 | ProxyRequests Off
5 |
6 | Order deny,allow
7 | Allow from all
8 |
9 | ProxyPass / http://127.0.0.1:9033/
10 | ProxyPassReverse / http://127.0.0.1:9033/
11 |
--------------------------------------------------------------------------------
/deploy/nginx.conf:
--------------------------------------------------------------------------------
1 | worker_processes 1;
2 |
3 | events {
4 | worker_connections 1024;
5 | }
6 |
7 | http {
8 | include mime.types;
9 | default_type application/octet-stream;
10 |
11 | sendfile on;
12 | keepalive_timeout 65;
13 |
14 | upstream api.blog.com {
15 | server 127.0.0.1:9033;
16 | }
17 |
18 | server {
19 | listen 80;
20 | server_name xxxxx.com;
21 |
22 | location / {
23 | proxy_pass http://xxxxx.com/;
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoAdminGroup/example
2 |
3 | go 1.21.5
4 |
5 | require (
6 | github.com/GoAdminGroup/go-admin v1.2.26
7 | github.com/GoAdminGroup/themes v0.0.47
8 | github.com/gavv/httpexpect v2.0.0+incompatible
9 | github.com/gin-gonic/gin v1.5.0
10 | github.com/jinzhu/gorm v1.9.12
11 | )
12 |
13 | require (
14 | filippo.io/edwards25519 v1.1.0 // indirect
15 | github.com/360EntSecGroup-Skylar/excelize v1.4.1 // indirect
16 | github.com/GoAdminGroup/html v0.0.1 // indirect
17 | github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e // indirect
18 | github.com/ajg/form v1.5.1 // indirect
19 | github.com/andybalholm/brotli v1.1.0 // indirect
20 | github.com/buaazp/fasthttprouter v0.1.1 // indirect
21 | github.com/davecgh/go-spew v1.1.1 // indirect
22 | github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e // indirect
23 | github.com/fatih/structs v1.1.0 // indirect
24 | github.com/gin-contrib/sse v0.1.0 // indirect
25 | github.com/go-playground/locales v0.12.1 // indirect
26 | github.com/go-playground/universal-translator v0.16.0 // indirect
27 | github.com/go-sql-driver/mysql v1.8.1 // indirect
28 | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
29 | github.com/golang/protobuf v1.5.3 // indirect
30 | github.com/golang/snappy v0.0.4 // indirect
31 | github.com/google/go-cmp v0.6.0 // indirect
32 | github.com/google/go-querystring v1.1.0 // indirect
33 | github.com/google/uuid v1.6.0 // indirect
34 | github.com/gopherjs/gopherjs v1.17.2 // indirect
35 | github.com/gorilla/websocket v1.5.1 // indirect
36 | github.com/imkira/go-interpol v1.1.0 // indirect
37 | github.com/jinzhu/inflection v1.0.0 // indirect
38 | github.com/json-iterator/go v1.1.12 // indirect
39 | github.com/jtolds/gls v4.20.0+incompatible // indirect
40 | github.com/klauspost/compress v1.17.6 // indirect
41 | github.com/kr/pretty v0.3.1 // indirect
42 | github.com/leodido/go-urn v1.1.0 // indirect
43 | github.com/lib/pq v1.10.5 // indirect
44 | github.com/mattn/go-colorable v0.1.13 // indirect
45 | github.com/mattn/go-isatty v0.0.20 // indirect
46 | github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
47 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
48 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
49 | github.com/modern-go/reflect2 v1.0.2 // indirect
50 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
51 | github.com/moul/http2curl v1.0.0 // indirect
52 | github.com/nxadm/tail v1.4.11 // indirect
53 | github.com/onsi/ginkgo v1.16.5 // indirect
54 | github.com/onsi/gomega v1.27.10 // indirect
55 | github.com/pkg/errors v0.9.1 // indirect
56 | github.com/pmezard/go-difflib v1.0.0 // indirect
57 | github.com/sclevine/agouti v3.0.0+incompatible // indirect
58 | github.com/sergi/go-diff v1.2.0 // indirect
59 | github.com/smarty/assertions v1.15.0 // indirect
60 | github.com/stretchr/testify v1.9.0 // indirect
61 | github.com/syndtr/goleveldb v1.0.0 // indirect
62 | github.com/ugorji/go/codec v1.2.12 // indirect
63 | github.com/valyala/bytebufferpool v1.0.0 // indirect
64 | github.com/valyala/fasthttp v1.52.0 // indirect
65 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
66 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
67 | github.com/xeipuuv/gojsonschema v1.2.0 // indirect
68 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
69 | github.com/yudai/gojsondiff v1.0.0 // indirect
70 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
71 | go.uber.org/atomic v1.9.0 // indirect
72 | go.uber.org/multierr v1.7.0 // indirect
73 | go.uber.org/zap v1.19.1 // indirect
74 | golang.org/x/crypto v0.20.0 // indirect
75 | golang.org/x/net v0.21.0 // indirect
76 | golang.org/x/sys v0.17.0 // indirect
77 | golang.org/x/text v0.14.0 // indirect
78 | google.golang.org/protobuf v1.32.0 // indirect
79 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
80 | gopkg.in/go-playground/validator.v9 v9.29.1 // indirect
81 | gopkg.in/ini.v1 v1.67.0 // indirect
82 | gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
83 | gopkg.in/yaml.v2 v2.4.0 // indirect
84 | gopkg.in/yaml.v3 v3.0.1 // indirect
85 | xorm.io/builder v0.3.7 // indirect
86 | xorm.io/xorm v1.0.2 // indirect
87 | )
88 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3 | cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
4 | filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
5 | filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
6 | gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
7 | gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
8 | github.com/360EntSecGroup-Skylar/excelize v1.4.1 h1:l55mJb6rkkaUzOpSsgEeKYtS6/0gHwBYyfo5Jcjv/Ks=
9 | github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE=
10 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
11 | github.com/GoAdminGroup/go-admin v1.2.26 h1:kk18rVrteLcrzH7iMM5p/13jghDC5n3DJG/7zAnbnEU=
12 | github.com/GoAdminGroup/go-admin v1.2.26/go.mod h1:QXj94ZrDclKzqwZnAGUWaK3qY1Wfr6/Qy5GnRGeXR+k=
13 | github.com/GoAdminGroup/html v0.0.1 h1:SdWNWl4OKPsvDk2GDp5ZKD6ceWoN8n4Pj6cUYxavUd0=
14 | github.com/GoAdminGroup/html v0.0.1/go.mod h1:A1laTJaOx8sQ64p2dE8IqtstDeCNBHEazrEp7hR5VvM=
15 | github.com/GoAdminGroup/themes v0.0.47 h1:e9xQXbDdjJhypvWvj5tUVFT8r56XHWoZQhIkV72EZXo=
16 | github.com/GoAdminGroup/themes v0.0.47/go.mod h1:w/5P0WCmM8iv7DYE5scIT8AODYMoo6zj/bVlzAbgOaU=
17 | github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e h1:n+DcnTNkQnHlwpsrHoQtkrJIO7CBx029fw6oR4vIob4=
18 | github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e/go.mod h1:Bdzq+51GR4/0DIhaICZEOm+OHvXGwwB2trKZ8B4Y6eQ=
19 | github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
20 | github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
21 | github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
22 | github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
23 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
24 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
25 | github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
26 | github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
27 | github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
28 | github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
29 | github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
30 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
31 | github.com/buaazp/fasthttprouter v0.1.1 h1:4oAnN0C3xZjylvZJdP35cxfclyn4TYkW6Y+DSvS+h8Q=
32 | github.com/buaazp/fasthttprouter v0.1.1/go.mod h1:h/Ap5oRVLeItGKTVBb+heQPks+HdIUtGmI4H5WCYijM=
33 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
34 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
35 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
36 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
37 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
38 | github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
39 | github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
40 | github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e h1:LzwWXEScfcTu7vUZNlDDWDARoSGEtvlDKK2BYHowNeE=
41 | github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
42 | github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
43 | github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
44 | github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
45 | github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
46 | github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
47 | github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 h1:DddqAaWDpywytcG8w/qoQ5sAN8X12d3Z3koB0C3Rxsc=
48 | github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
49 | github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
50 | github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
51 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
52 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
53 | github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
54 | github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
55 | github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
56 | github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8=
57 | github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
58 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
59 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
60 | github.com/gin-gonic/gin v1.5.0 h1:fi+bqFAx/oLK54somfCtEZs9HeH1LHVoEPUgARpTqyc=
61 | github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
62 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
63 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
64 | github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
65 | github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
66 | github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM=
67 | github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
68 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
69 | github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
70 | github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
71 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
72 | github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
73 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
74 | github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
75 | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
76 | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
77 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
78 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
79 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
80 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
81 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
82 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
83 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
84 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
85 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
86 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
87 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
88 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
89 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
90 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
91 | github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
92 | github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
93 | github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
94 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
95 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
96 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
97 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
98 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
99 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
100 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
101 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
102 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
103 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
104 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
105 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
106 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
107 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
108 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
109 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
110 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
111 | github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
112 | github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
113 | github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
114 | github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
115 | github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
116 | github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
117 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
118 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
119 | github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
120 | github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
121 | github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
122 | github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
123 | github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
124 | github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
125 | github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
126 | github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
127 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
128 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
129 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
130 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
131 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
132 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
133 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
134 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
135 | github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI=
136 | github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
137 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
138 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
139 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
140 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
141 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
142 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
143 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
144 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
145 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
146 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
147 | github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
148 | github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
149 | github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
150 | github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
151 | github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ=
152 | github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
153 | github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
154 | github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
155 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
156 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
157 | github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
158 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
159 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
160 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
161 | github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
162 | github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
163 | github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
164 | github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
165 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
166 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
167 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
168 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
169 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
170 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
171 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
172 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
173 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
174 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
175 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
176 | github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
177 | github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
178 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
179 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
180 | github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
181 | github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
182 | github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
183 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
184 | github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
185 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
186 | github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
187 | github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
188 | github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
189 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
190 | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
191 | github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
192 | github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
193 | github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
194 | github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
195 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
196 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
197 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
198 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
199 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
200 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
201 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
202 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
203 | github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
204 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
205 | github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
206 | github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
207 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
208 | github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
209 | github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
210 | github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
211 | github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
212 | github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
213 | github.com/sclevine/agouti v3.0.0+incompatible h1:8IBJS6PWz3uTlMP3YBIR5f+KAldcGuOeFkFbUWfBgK4=
214 | github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
215 | github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
216 | github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
217 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
218 | github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
219 | github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
220 | github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
221 | github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
222 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
223 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
224 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
225 | github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
226 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
227 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
228 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
229 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
230 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
231 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
232 | github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
233 | github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
234 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
235 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
236 | github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
237 | github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
238 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
239 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
240 | github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0=
241 | github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ=
242 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
243 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
244 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
245 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
246 | github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
247 | github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
248 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY=
249 | github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
250 | github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
251 | github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
252 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M=
253 | github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
254 | github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI=
255 | github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
256 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
257 | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
258 | github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
259 | go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
260 | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
261 | go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
262 | go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
263 | go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
264 | go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
265 | go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
266 | go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
267 | go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
268 | go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
269 | go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
270 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
271 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
272 | golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
273 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
274 | golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
275 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
276 | golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
277 | golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
278 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
279 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
280 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
281 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
282 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
283 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
284 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
285 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
286 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
287 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
288 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
289 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
290 | golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
291 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
292 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
293 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
294 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
295 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
296 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
297 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
298 | golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
299 | golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
300 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
301 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
302 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
303 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
304 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
305 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
306 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
307 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
308 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
309 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
310 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
311 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
312 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
313 | golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
314 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
315 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
316 | golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
317 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
318 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
319 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
320 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
321 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
322 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
323 | golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
324 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
325 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
326 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
327 | golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
328 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
329 | golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
330 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
331 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
332 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
333 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
334 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
335 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
336 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
337 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
338 | golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
339 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
340 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
341 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
342 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
343 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
344 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
345 | golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
346 | golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
347 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
348 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
349 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
350 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
351 | google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
352 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
353 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
354 | google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
355 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
356 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
357 | google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
358 | google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
359 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
360 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
361 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
362 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
363 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
364 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
365 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
366 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
367 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
368 | google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
369 | google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
370 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
371 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
372 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
373 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
374 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
375 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
376 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
377 | gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
378 | gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
379 | gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
380 | gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
381 | gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
382 | gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
383 | gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
384 | gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
385 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
386 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
387 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
388 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
389 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
390 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
391 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
392 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
393 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
394 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
395 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
396 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
397 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
398 | honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
399 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
400 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
401 | xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI=
402 | xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
403 | xorm.io/xorm v1.0.2 h1:kZlCh9rqd1AzGwWitcrEEqHE1h1eaZE/ujU5/2tWEtg=
404 | xorm.io/xorm v1.0.2/go.mod h1:o4vnEsQ5V2F1/WK6w4XTwmiWJeGj82tqjAnHe44wVHY=
405 |
--------------------------------------------------------------------------------
/html/hello.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
{{index . "msg"}}
3 |
4 |
5 |
12 |
--------------------------------------------------------------------------------
/logs/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoAdminGroup/example/956d61425a561b823fa00bc7c9a5098882411f42/logs/.gitkeep
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "io/ioutil"
6 | "log"
7 | "net/http"
8 | "os"
9 | "os/signal"
10 | "time"
11 |
12 | _ "github.com/GoAdminGroup/go-admin/adapter/gin" // web framework adapter
13 | _ "github.com/GoAdminGroup/go-admin/modules/db/drivers/sqlite" // sql driver
14 | _ "github.com/GoAdminGroup/themes/sword" // ui theme
15 |
16 | "github.com/GoAdminGroup/example/models"
17 | "github.com/GoAdminGroup/example/pages"
18 | "github.com/GoAdminGroup/example/tables"
19 | "github.com/GoAdminGroup/go-admin/engine"
20 | "github.com/GoAdminGroup/go-admin/template"
21 | "github.com/GoAdminGroup/go-admin/template/chartjs"
22 | "github.com/gin-gonic/gin"
23 | )
24 |
25 | func main() {
26 | startServer()
27 | }
28 |
29 | func startServer() {
30 | gin.SetMode(gin.ReleaseMode)
31 | gin.DefaultWriter = ioutil.Discard
32 |
33 | r := gin.Default()
34 |
35 | eng := engine.Default()
36 |
37 | template.AddComp(chartjs.NewChart())
38 |
39 | //cfg := config.Config{
40 | // Databases: config.DatabaseList{
41 | // "default": {
42 | // Host: "127.0.0.1",
43 | // Port: "3306",
44 | // User: "root",
45 | // Pwd: "root",
46 | // Name: "go-admin",
47 | // MaxIdleCon: 50,
48 | // MaxOpenCon: 150,
49 | // Driver: db.DriverMysql,
50 | // },
51 | // },
52 | // UrlPrefix: "admin",
53 | // IndexUrl: "/",
54 | // Debug: true,
55 | // Language: language.CN,
56 | //}
57 |
58 | if err := eng.AddConfigFromYAML("./config.yml").
59 | AddGenerators(tables.Generators).
60 | AddGenerator("external", tables.GetExternalTable).
61 | Use(r); err != nil {
62 | panic(err)
63 | }
64 |
65 | models.Init(eng.SqliteConnection())
66 |
67 | r.Static("/uploads", "./uploads")
68 |
69 | eng.HTML("GET", "/admin", pages.DashboardPage)
70 | eng.HTML("GET", "/admin/form", pages.GetFormContent)
71 | eng.HTML("GET", "/admin/table", pages.GetTableContent)
72 | eng.HTMLFile("GET", "/admin/hello", "./html/hello.tmpl", map[string]interface{}{
73 | "msg": "Hello world",
74 | })
75 |
76 | srv := &http.Server{
77 | Addr: ":9033",
78 | Handler: r,
79 | }
80 |
81 | go func() {
82 | if err := srv.ListenAndServe(); err != nil {
83 | log.Printf("listen: %s\n", err)
84 | }
85 | }()
86 |
87 | quit := make(chan os.Signal)
88 | signal.Notify(quit, os.Interrupt)
89 | <-quit
90 |
91 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
92 | defer cancel()
93 | if err := srv.Shutdown(ctx); err != nil {
94 | log.Fatal("Server Shutdown:", err)
95 | }
96 | log.Println("Server exiting")
97 | }
98 |
--------------------------------------------------------------------------------
/main_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "testing"
6 |
7 | "github.com/GoAdminGroup/example/tables"
8 | "github.com/GoAdminGroup/go-admin/modules/config"
9 | "github.com/GoAdminGroup/go-admin/tests"
10 | "github.com/GoAdminGroup/go-admin/tests/common"
11 | "github.com/GoAdminGroup/go-admin/tests/frameworks/gin"
12 | "github.com/GoAdminGroup/go-admin/tests/web"
13 | "github.com/gavv/httpexpect"
14 | )
15 |
16 | // Black box testing
17 | func TestExampleBlackBox(t *testing.T) {
18 | tests.BlackBoxTestSuit(t, gin.NewHandler, config.DatabaseList{
19 | "default": config.Database{
20 | File: "./admin_test.db",
21 | Driver: "sqlite",
22 | },
23 | }, tables.Generators, func(cfg config.DatabaseList) {
24 | // Data cleaner of the framework
25 | tests.Cleaner(cfg)
26 | // Clean your own data:
27 | // ...
28 | }, func(e *httpexpect.Expect) {
29 | // Test cases of the framework
30 | common.Test(e)
31 | // Write your own API test, for example:
32 | // More usages: https://github.com/gavv/httpexpect
33 | // e.POST("/signin").Expect().Status(http.StatusOK)
34 | })
35 | }
36 |
37 | // User acceptance testing
38 | func TestExampleUserAcceptance(t *testing.T) {
39 | web.UserAcceptanceTestSuit(t, func(t *testing.T, page *web.Page) {
40 | // Write test case base on chromedriver, for example:
41 | // More usages: https://github.com/sclevine/agouti
42 | page.NavigateTo("http://127.0.0.1:9033/admin")
43 | //page.Contain("username")
44 | //page.Click("")
45 | }, func(quit chan struct{}) {
46 | // start the server:
47 | // ....
48 | go startServer()
49 | <-quit
50 | log.Print("test quit")
51 | }, true) // if local parameter is true, it will not be headless, and window not close when finishing tests.
52 | }
53 |
--------------------------------------------------------------------------------
/models/base.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "github.com/GoAdminGroup/go-admin/modules/db"
5 | "github.com/jinzhu/gorm"
6 | )
7 |
8 | var (
9 | orm *gorm.DB
10 | err error
11 | )
12 |
13 | func Init(c db.Connection) {
14 | orm, err = gorm.Open("sqlite3", c.GetDB("default"))
15 |
16 | if err != nil {
17 | panic("initialize orm failed")
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/models/statistics.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "html/template"
5 | "strconv"
6 | "time"
7 | )
8 |
9 | type Statistics struct {
10 | ID uint `gorm:"primary_key,column:cpu"`
11 | CPU uint `gorm:"column:cpu"`
12 | Likes uint `gorm:"column:likes"`
13 | Sales uint `gorm:"column:sales"`
14 | NewMembers uint `gorm:"column:new_members"`
15 |
16 | CreatedAt time.Time
17 | UpdatedAt time.Time
18 | }
19 |
20 | func FirstStatics() *Statistics {
21 | s := new(Statistics)
22 | orm.First(s)
23 | return s
24 | }
25 |
26 | func (s *Statistics) CPUTmpl() template.HTML {
27 | return template.HTML(strconv.Itoa(int(s.CPU)))
28 | }
29 |
30 | func (s *Statistics) LikesTmpl() template.HTML {
31 | return template.HTML(strconv.Itoa(int(s.Likes)))
32 | }
33 |
34 | func (s *Statistics) SalesTmpl() template.HTML {
35 | return template.HTML(strconv.Itoa(int(s.Sales)))
36 | }
37 |
38 | func (s *Statistics) NewMembersTmpl() template.HTML {
39 | return template.HTML(strconv.Itoa(int(s.NewMembers)))
40 | }
41 |
--------------------------------------------------------------------------------
/pages/form.go:
--------------------------------------------------------------------------------
1 | package pages
2 |
3 | import (
4 | "github.com/GoAdminGroup/go-admin/context"
5 | "github.com/GoAdminGroup/go-admin/modules/config"
6 | "github.com/GoAdminGroup/go-admin/modules/db"
7 | "github.com/GoAdminGroup/go-admin/modules/language"
8 | form2 "github.com/GoAdminGroup/go-admin/plugins/admin/modules/form"
9 | template2 "github.com/GoAdminGroup/go-admin/template"
10 | "github.com/GoAdminGroup/go-admin/template/icon"
11 | "github.com/GoAdminGroup/go-admin/template/types"
12 | "github.com/GoAdminGroup/go-admin/template/types/form"
13 | )
14 |
15 | func GetFormContent(ctx *context.Context) (types.Panel, error) {
16 |
17 | components := template2.Get(ctx, config.GetTheme())
18 |
19 | col1 := components.Col().GetContent()
20 | btn1 := components.Button().SetType("submit").
21 | SetContent(language.GetFromHtml("Save")).
22 | SetThemePrimary().
23 | SetOrientationRight().
24 | SetLoadingText(icon.Icon("fa-spinner fa-spin", 2) + `Save`).
25 | GetContent()
26 | btn2 := components.Button().SetType("reset").
27 | SetContent(language.GetFromHtml("Reset")).
28 | SetThemeWarning().
29 | SetOrientationLeft().
30 | GetContent()
31 | col2 := components.Col().SetSize(types.SizeMD(8)).
32 | SetContent(btn1 + btn2).GetContent()
33 |
34 | var panel = types.NewFormPanel()
35 | panel.AddField("Name", "name", db.Varchar, form.Text)
36 | panel.AddField("Age", "age", db.Int, form.Number)
37 | panel.AddField("HomePage", "homepage", db.Varchar, form.Url).FieldDefault("http://google.com")
38 | panel.AddField("Email", "email", db.Varchar, form.Email).FieldDefault("xxxx@xxx.com")
39 | panel.AddField("Birthday", "birthday", db.Varchar, form.Date).FieldDefault("2010-09-03 18:09:05")
40 | panel.AddField("Time", "time", db.Varchar, form.Datetime).FieldDefault("2010-09-05")
41 | panel.AddField("Time Range", "time_range", db.Varchar, form.DatetimeRange)
42 | panel.AddField("Date Range", "date_range", db.Varchar, form.DateRange)
43 | panel.AddField("Password", "password", db.Varchar, form.Password).FieldDivider("Divider line")
44 | panel.AddField("IP", "ip", db.Varchar, form.Ip)
45 | panel.AddField("Certificate", "certificate", db.Varchar, form.Multifile).FieldOptionExt(map[string]interface{}{
46 | "maxFileCount": 10,
47 | })
48 | panel.AddField("Money", "currency", db.Int, form.Currency)
49 | panel.AddField("Rate", "rate", db.Int, form.Rate)
50 | panel.AddField("Reward", "reward", db.Int, form.Slider).FieldOptionExt(map[string]interface{}{
51 | "max": 1000,
52 | "min": 1,
53 | "step": 1,
54 | "postfix": "$",
55 | })
56 | panel.AddField("Content", "content", db.Text, form.RichText).
57 | FieldDefault(`343434
34344433434
- 23234
- 2342342342
- asdfads
343434
434434433434
`).
58 | FieldDivider("Divider line No2")
59 | panel.AddField("Code", "code", db.Text, form.Code).FieldDefault(`package main
60 |
61 | import "fmt"
62 |
63 | func main() {
64 | fmt.Println("hello GoAdmin!")
65 | }
66 | `)
67 | panel.AddField("Website", "website", db.Tinyint, form.Switch).
68 | FieldHelpMsg("The Website will not be able to access after closing, the admin system still can login").
69 | FieldOptions(types.FieldOptions{
70 | {Value: "0"},
71 | {Value: "1"},
72 | })
73 | panel.AddField("Fruit", "fruit", db.Varchar, form.SelectBox).
74 | FieldOptions(types.FieldOptions{
75 | {Text: "Apple", Value: "apple"},
76 | {Text: "Banana", Value: "banana"},
77 | {Text: "Watermelon", Value: "watermelon"},
78 | {Text: "Pear", Value: "pear"},
79 | }).
80 | FieldDisplay(func(value types.FieldModel) interface{} {
81 | return []string{"Pear"}
82 | })
83 | panel.AddField("Gender", "gender", db.Tinyint, form.Radio).
84 | FieldOptions(types.FieldOptions{
85 | {Text: "Men", Value: "0"},
86 | {Text: "Women", Value: "1"},
87 | })
88 | panel.AddField("Drink", "drink", db.Tinyint, form.Select).
89 | FieldOptions(types.FieldOptions{
90 | {Text: "Beer", Value: "beer"},
91 | {Text: "Juice", Value: "juice"},
92 | {Text: "Water", Value: "water"},
93 | {Text: "Red Bull", Value: "red bull"},
94 | }).FieldDefault("beer")
95 | panel.AddField("Work Experience", "experience", db.Tinyint, form.SelectSingle).
96 | FieldOptions(types.FieldOptions{
97 | {Text: "two years", Value: "0"},
98 | {Text: "three years", Value: "1"},
99 | {Text: "four years", Value: "2"},
100 | {Text: "five years", Value: "3"},
101 | }).FieldDefault("beer")
102 | panel.AddField("Snacks", "snacks", db.Varchar, form.Checkbox).
103 | FieldOptions(types.FieldOptions{
104 | {Text: "cereal", Value: "0"},
105 | {Text: "chips", Value: "1"},
106 | {Text: "spicy strip", Value: "2"},
107 | {Text: "ice cream", Value: "3"},
108 | })
109 | panel.AddField("Cat", "cat", db.Varchar, form.CheckboxStacked).
110 | FieldOptions(types.FieldOptions{
111 | {Text: "Garfield", Value: "0"},
112 | {Text: "British Shorthair", Value: "1"},
113 | {Text: "American Shorthair", Value: "2"},
114 | })
115 | panel.AddRow(func(pa *types.FormPanel) {
116 | panel.AddField("Province", "province", db.Tinyint, form.SelectSingle).
117 | FieldOptions(types.FieldOptions{
118 | {Text: "Beijing", Value: "0"},
119 | {Text: "Shanghai", Value: "1"},
120 | {Text: "GuangDong", Value: "2"},
121 | {Text: "ChongQing", Value: "3"},
122 | }).FieldRowWidth(2)
123 | panel.AddField("City", "city", db.Tinyint, form.SelectSingle).
124 | FieldOptions(types.FieldOptions{
125 | {Text: "Beijing", Value: "0"},
126 | {Text: "Shanghai", Value: "1"},
127 | {Text: "GuangZhou", Value: "2"},
128 | {Text: "ShenZhen", Value: "3"},
129 | }).FieldRowWidth(3).FieldHeadWidth(2).FieldInputWidth(10)
130 | panel.AddField("District", "district", db.Tinyint, form.SelectSingle).
131 | FieldOptions(types.FieldOptions{
132 | {Text: "ChaoYang", Value: "0"},
133 | {Text: "HaiZhu", Value: "1"},
134 | {Text: "PuDong", Value: "2"},
135 | {Text: "BaoAn", Value: "3"},
136 | }).FieldRowWidth(3).FieldHeadWidth(2).FieldInputWidth(9)
137 | })
138 | panel.AddField("Employee", "employee", db.Varchar, form.Array)
139 | panel.AddTable("Setting", "setting", func(panel *types.FormPanel) {
140 | panel.AddField("Key", "key", db.Varchar, form.Text).FieldHideLabel()
141 | panel.AddField("Value", "value", db.Varchar, form.Text).FieldHideLabel()
142 | })
143 | panel.SetTabGroups(types.TabGroups{
144 | {"name", "age", "homepage", "email", "birthday", "time", "time_range", "date_range", "password", "ip",
145 | "certificate", "currency", "rate", "reward", "content", "code"},
146 | {"website", "snacks", "fruit", "gender", "cat", "drink", "province", "city", "district", "experience"},
147 | {"employee", "setting"},
148 | })
149 | panel.SetTabHeaders("input", "select", "multi")
150 |
151 | fields, headers := panel.GroupField()
152 |
153 | aform := components.Form().
154 | SetTabHeaders(headers).
155 | SetTabContents(fields).
156 | SetPrefix(config.PrefixFixSlash()).
157 | SetUrl("/admin/form/update").
158 | SetTitle("Form").
159 | SetHiddenFields(map[string]string{
160 | form2.PreviousKey: "/admin",
161 | }).
162 | SetOperationFooter(col1 + col2)
163 |
164 | return types.Panel{
165 | Content: components.Box().
166 | SetHeader(aform.GetDefaultBoxHeader(true)).
167 | WithHeadBorder().
168 | SetBody(aform.GetContent()).
169 | GetContent(),
170 | Title: "Form",
171 | Callbacks: panel.Callbacks,
172 | Description: "form example",
173 | }, nil
174 | }
175 |
--------------------------------------------------------------------------------
/pages/index.go:
--------------------------------------------------------------------------------
1 | package pages
2 |
3 | import (
4 | "html/template"
5 |
6 | "github.com/GoAdminGroup/example/models"
7 | "github.com/GoAdminGroup/go-admin/context"
8 | tmpl "github.com/GoAdminGroup/go-admin/template"
9 | "github.com/GoAdminGroup/go-admin/template/chartjs"
10 | "github.com/GoAdminGroup/go-admin/template/color"
11 | "github.com/GoAdminGroup/go-admin/template/icon"
12 | "github.com/GoAdminGroup/go-admin/template/types"
13 | "github.com/GoAdminGroup/themes/adminlte/components/chart_legend"
14 | "github.com/GoAdminGroup/themes/adminlte/components/description"
15 | "github.com/GoAdminGroup/themes/adminlte/components/infobox"
16 | "github.com/GoAdminGroup/themes/adminlte/components/productlist"
17 | "github.com/GoAdminGroup/themes/adminlte/components/progress_group"
18 | "github.com/GoAdminGroup/themes/adminlte/components/smallbox"
19 | )
20 |
21 | // GetContent return the content of index page.
22 | func DashboardPage(ctx *context.Context) (types.Panel, error) {
23 |
24 | components := tmpl.Default()
25 | colComp := components.Col()
26 |
27 | statics := models.FirstStatics()
28 |
29 | /**************************
30 | * Info Box
31 | /**************************/
32 |
33 | infobox1 := infobox.New().
34 | SetText("CPU TRAFFIC").
35 | SetColor(color.Aqua).
36 | SetNumber(statics.CPUTmpl()).
37 | SetIcon("ion-ios-gear-outline").
38 | GetContent()
39 |
40 | infobox2 := infobox.New().
41 | SetText("Likes").
42 | SetColor(color.Red).
43 | SetNumber(statics.LikesTmpl() + "$").
44 | SetIcon(icon.GooglePlus).
45 | GetContent()
46 |
47 | infobox3 := infobox.New().
48 | SetText("Sales").
49 | SetColor(color.Green).
50 | SetNumber(statics.SalesTmpl()).
51 | SetIcon("ion-ios-cart-outline").
52 | GetContent()
53 |
54 | infobox4 := infobox.New().
55 | SetText("New Members").
56 | SetColor(color.Yellow).
57 | SetNumber(statics.NewMembersTmpl()).
58 | SetIcon("ion-ios-people-outline").
59 | GetContent()
60 |
61 | var size = types.SizeMD(3).SM(6).XS(12)
62 | infoboxCol1 := colComp.SetSize(size).SetContent(infobox1).GetContent()
63 | infoboxCol2 := colComp.SetSize(size).SetContent(infobox2).GetContent()
64 | infoboxCol3 := colComp.SetSize(size).SetContent(infobox3).GetContent()
65 | infoboxCol4 := colComp.SetSize(size).SetContent(infobox4).GetContent()
66 | row1 := components.Row().SetContent(infoboxCol1 + infoboxCol2 + infoboxCol3 + infoboxCol4).GetContent()
67 |
68 | /**************************
69 | * Box
70 | /**************************/
71 |
72 | table := components.Table().SetType("table").SetInfoList([]map[string]types.InfoItem{
73 | {
74 | "Order ID": {Content: "OR9842"},
75 | "Item": {Content: "Call of Duty IV"},
76 | "Status": {Content: "shipped"},
77 | "Popularity": {Content: "90%"},
78 | }, {
79 | "Order ID": {Content: "OR9842"},
80 | "Item": {Content: "Call of Duty IV"},
81 | "Status": {Content: "shipped"},
82 | "Popularity": {Content: "90%"},
83 | }, {
84 | "Order ID": {Content: "OR9842"},
85 | "Item": {Content: "Call of Duty IV"},
86 | "Status": {Content: "shipped"},
87 | "Popularity": {Content: "90%"},
88 | }, {
89 | "Order ID": {Content: "OR9842"},
90 | "Item": {Content: "Call of Duty IV"},
91 | "Status": {Content: "shipped"},
92 | "Popularity": {Content: "90%"},
93 | },
94 | }).SetThead(types.Thead{
95 | {Head: "Order ID"},
96 | {Head: "Item"},
97 | {Head: "Status"},
98 | {Head: "Popularity"},
99 | }).GetContent()
100 |
101 | boxInfo := components.Box().
102 | WithHeadBorder().
103 | SetHeader("Latest Orders").
104 | SetHeadColor("#f7f7f7").
105 | SetBody(table).
106 | SetFooter(``).
107 | GetContent()
108 |
109 | tableCol := colComp.SetSize(types.SizeMD(8)).SetContent(row1 + boxInfo).GetContent()
110 |
111 | /**************************
112 | * Product List
113 | /**************************/
114 |
115 | productList := productlist.New().SetData([]map[string]string{
116 | {
117 | "img": "//adminlte.io/themes/AdminLTE/dist/img/default-50x50.gif",
118 | "title": "GoAdmin",
119 | "has_tabel": "true",
120 | "labeltype": "warning",
121 | "label": "free",
122 | "description": `a framework help you build the dataviz system`,
123 | }, {
124 | "img": "//adminlte.io/themes/AdminLTE/dist/img/default-50x50.gif",
125 | "title": "GoAdmin",
126 | "has_tabel": "true",
127 | "labeltype": "warning",
128 | "label": "free",
129 | "description": `a framework help you build the dataviz system`,
130 | }, {
131 | "img": "//adminlte.io/themes/AdminLTE/dist/img/default-50x50.gif",
132 | "title": "GoAdmin",
133 | "has_tabel": "true",
134 | "labeltype": "warning",
135 | "label": "free",
136 | "description": `a framework help you build the dataviz system`,
137 | }, {
138 | "img": "//adminlte.io/themes/AdminLTE/dist/img/default-50x50.gif",
139 | "title": "GoAdmin",
140 | "has_tabel": "true",
141 | "labeltype": "warning",
142 | "label": "free",
143 | "description": `a framework help you build the dataviz system`,
144 | },
145 | }).GetContent()
146 |
147 | boxWarning := components.Box().SetTheme("warning").WithHeadBorder().SetHeader("Recently Added Products").
148 | SetBody(productList).
149 | SetFooter(`View All Products`).
150 | GetContent()
151 |
152 | newsCol := colComp.SetSize(types.SizeMD(4)).SetContent(boxWarning).GetContent()
153 |
154 | row5 := components.Row().SetContent(tableCol + newsCol).GetContent()
155 |
156 | /**************************
157 | * Box
158 | /**************************/
159 |
160 | line := chartjs.Line()
161 |
162 | lineChart := line.
163 | SetID("salechart").
164 | SetHeight(180).
165 | SetTitle("Sales: 1 Jan, 2019 - 30 Jul, 2019").
166 | SetLabels([]string{"January", "February", "March", "April", "May", "June", "July"}).
167 | AddDataSet("Electronics").
168 | DSData([]float64{65, 59, 80, 81, 56, 55, 40}).
169 | DSFill(false).
170 | DSBorderColor("rgb(210, 214, 222)").
171 | DSLineTension(0.1).
172 | AddDataSet("Digital Goods").
173 | DSData([]float64{28, 48, 40, 19, 86, 27, 90}).
174 | DSFill(false).
175 | DSBorderColor("rgba(60,141,188,1)").
176 | DSLineTension(0.1).
177 | GetContent()
178 |
179 | title := `Goal Completion
`
180 | progressGroup := progress_group.New().
181 | SetTitle("Add Products to Cart").
182 | SetColor("#76b2d4").
183 | SetDenominator(200).
184 | SetMolecular(160).
185 | SetPercent(80).
186 | GetContent()
187 |
188 | progressGroup1 := progress_group.New().
189 | SetTitle("Complete Purchase").
190 | SetColor("#f17c6e").
191 | SetDenominator(400).
192 | SetMolecular(310).
193 | SetPercent(80).
194 | GetContent()
195 |
196 | progressGroup2 := progress_group.New().
197 | SetTitle("Visit Premium Page").
198 | SetColor("#ace0ae").
199 | SetDenominator(800).
200 | SetMolecular(490).
201 | SetPercent(80).
202 | GetContent()
203 |
204 | progressGroup3 := progress_group.New().
205 | SetTitle("Send Inquiries").
206 | SetColor("#fdd698").
207 | SetDenominator(500).
208 | SetMolecular(250).
209 | SetPercent(50).
210 | GetContent()
211 |
212 | boxInternalCol1 := colComp.SetContent(lineChart).SetSize(types.SizeMD(8)).GetContent()
213 | boxInternalCol2 := colComp.
214 | SetContent(template.HTML(title) + progressGroup + progressGroup1 + progressGroup2 + progressGroup3).
215 | SetSize(types.SizeMD(4)).
216 | GetContent()
217 |
218 | boxInternalRow := components.Row().SetContent(boxInternalCol1 + boxInternalCol2).GetContent()
219 |
220 | description1 := description.New().
221 | SetPercent("17").
222 | SetNumber("¥140,100").
223 | SetTitle("TOTAL REVENUE").
224 | SetArrow("up").
225 | SetColor("green").
226 | SetBorder("right").
227 | GetContent()
228 |
229 | description2 := description.New().
230 | SetPercent("2").
231 | SetNumber("440,560").
232 | SetTitle("TOTAL REVENUE").
233 | SetArrow("down").
234 | SetColor("red").
235 | SetBorder("right").
236 | GetContent()
237 |
238 | description3 := description.New().
239 | SetPercent("12").
240 | SetNumber("¥140,050").
241 | SetTitle("TOTAL REVENUE").
242 | SetArrow("up").
243 | SetColor("green").
244 | SetBorder("right").
245 | GetContent()
246 |
247 | description4 := description.New().
248 | SetPercent("1").
249 | SetNumber("30943").
250 | SetTitle("TOTAL REVENUE").
251 | SetArrow("up").
252 | SetColor("green").
253 | GetContent()
254 |
255 | size2 := types.SizeSM(3).XS(6)
256 | boxInternalCol3 := colComp.SetContent(description1).SetSize(size2).GetContent()
257 | boxInternalCol4 := colComp.SetContent(description2).SetSize(size2).GetContent()
258 | boxInternalCol5 := colComp.SetContent(description3).SetSize(size2).GetContent()
259 | boxInternalCol6 := colComp.SetContent(description4).SetSize(size2).GetContent()
260 |
261 | boxInternalRow2 := components.Row().SetContent(boxInternalCol3 + boxInternalCol4 + boxInternalCol5 + boxInternalCol6).GetContent()
262 |
263 | box := components.Box().WithHeadBorder().SetHeader("Monthly Recap Report").
264 | SetBody(boxInternalRow).
265 | SetFooter(boxInternalRow2).
266 | GetContent()
267 |
268 | boxcol := colComp.SetContent(box).SetSize(types.SizeMD(12)).GetContent()
269 | row2 := components.Row().SetContent(boxcol).GetContent()
270 |
271 | /**************************
272 | * Small Box
273 | /**************************/
274 |
275 | smallbox1 := smallbox.New().SetColor("blue").SetIcon("ion-ios-gear-outline").SetUrl("/").SetTitle("new users").SetValue("345¥").GetContent()
276 | smallbox2 := smallbox.New().SetColor("yellow").SetIcon("ion-ios-cart-outline").SetUrl("/").SetTitle("new users").SetValue("80%").GetContent()
277 | smallbox3 := smallbox.New().SetColor("red").SetIcon("fa-user").SetUrl("/").SetTitle("new users").SetValue("645¥").GetContent()
278 | smallbox4 := smallbox.New().SetColor("green").SetIcon("ion-ios-cart-outline").SetUrl("/").SetTitle("new users").SetValue("889¥").GetContent()
279 |
280 | col1 := colComp.SetSize(size).SetContent(smallbox1).GetContent()
281 | col2 := colComp.SetSize(size).SetContent(smallbox2).GetContent()
282 | col3 := colComp.SetSize(size).SetContent(smallbox3).GetContent()
283 | col4 := colComp.SetSize(size).SetContent(smallbox4).GetContent()
284 |
285 | row3 := components.Row().SetContent(col1 + col2 + col3 + col4).GetContent()
286 |
287 | /**************************
288 | * Pie Chart
289 | /**************************/
290 |
291 | pie := chartjs.Pie().
292 | SetHeight(170).
293 | SetLabels([]string{"Navigator", "Opera", "Safari", "FireFox", "IE", "Chrome"}).
294 | SetID("pieChart").
295 | AddDataSet("Chrome").
296 | DSData([]float64{100, 300, 600, 400, 500, 700}).
297 | DSBackgroundColor([]chartjs.Color{
298 | "rgb(255, 205, 86)", "rgb(54, 162, 235)", "rgb(255, 99, 132)", "rgb(255, 205, 86)", "rgb(54, 162, 235)", "rgb(255, 99, 132)",
299 | }).
300 | GetContent()
301 |
302 | legend := chart_legend.New().SetData([]map[string]string{
303 | {
304 | "label": " Chrome",
305 | "color": "red",
306 | }, {
307 | "label": " IE",
308 | "color": "Green",
309 | }, {
310 | "label": " FireFox",
311 | "color": "yellow",
312 | }, {
313 | "label": " Sarafri",
314 | "color": "blue",
315 | }, {
316 | "label": " Opera",
317 | "color": "light-blue",
318 | }, {
319 | "label": " Navigator",
320 | "color": "gray",
321 | },
322 | }).GetContent()
323 |
324 | boxDanger := components.Box().SetTheme("danger").WithHeadBorder().SetHeader("Browser Usage").
325 | SetBody(components.Row().
326 | SetContent(colComp.SetSize(types.SizeMD(8)).
327 | SetContent(pie).
328 | GetContent() + colComp.SetSize(types.SizeMD(4)).
329 | SetContent(legend).
330 | GetContent()).GetContent()).
331 | SetFooter(`View All Users
`).
332 | GetContent()
333 |
334 | tabs := components.Tabs().SetData([]map[string]template.HTML{
335 | {
336 | "title": "tabs1",
337 | "content": template.HTML(`How to use:
338 |
339 | Exactly like the original bootstrap tabs except you should use
340 | the custom wrapper .nav-tabs-custom
to achieve this style.
341 | A wonderful serenity has taken possession of my entire soul,
342 | like these sweet mornings of spring which I enjoy with my whole heart.
343 | I am alone, and feel the charm of existence in this spot,
344 | which was created for the bliss of souls like mine. I am so happy,
345 | my dear friend, so absorbed in the exquisite sense of mere tranquil existence,
346 | that I neglect my talents. I should be incapable of drawing a single stroke
347 | at the present moment; and yet I feel that I never was a greater artist than now.`),
348 | }, {
349 | "title": "tabs2",
350 | "content": template.HTML(`
351 | The European languages are members of the same family. Their separate existence is a myth.
352 | For science, music, sport, etc, Europe uses the same vocabulary. The languages only differ
353 | in their grammar, their pronunciation and their most common words. Everyone realizes why a
354 | new common language would be desirable: one could refuse to pay expensive translators. To
355 | achieve this, it would be necessary to have uniform grammar, pronunciation and more common
356 | words. If several languages coalesce, the grammar of the resulting language is more simple
357 | and regular than that of the individual languages.
358 | `),
359 | }, {
360 | "title": "tabs3",
361 | "content": template.HTML(`
362 | Lorem Ipsum is simply dummy text of the printing and typesetting industry.
363 | Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
364 | when an unknown printer took a galley of type and scrambled it to make a type specimen book.
365 | It has survived not only five centuries, but also the leap into electronic typesetting,
366 | remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset
367 | sheets containing Lorem Ipsum passages, and more recently with desktop publishing software
368 | like Aldus PageMaker including versions of Lorem Ipsum.
369 | `),
370 | },
371 | }).GetContent()
372 |
373 | buttonTest := ``
374 | popupForm := ``
384 | popup := components.Popup().SetID("exampleModal").
385 | SetFooter("Save Change").
386 | SetTitle("this is a popup").
387 | SetBody(template.HTML(popupForm)).
388 | GetContent()
389 |
390 | col5 := colComp.SetSize(types.SizeMD(8)).SetContent(tabs + template.HTML(buttonTest)).GetContent()
391 | col6 := colComp.SetSize(types.SizeMD(4)).SetContent(boxDanger + popup).GetContent()
392 |
393 | row4 := components.Row().SetContent(col5 + col6).GetContent()
394 |
395 | return types.Panel{
396 | Content: row3 + row2 + row5 + row4,
397 | Title: "Dashboard",
398 | Description: "dashboard example",
399 | }, nil
400 | }
401 |
--------------------------------------------------------------------------------
/pages/table.go:
--------------------------------------------------------------------------------
1 | package pages
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/GoAdminGroup/go-admin/context"
7 | "github.com/GoAdminGroup/go-admin/modules/config"
8 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/paginator"
9 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/parameter"
10 | "github.com/GoAdminGroup/go-admin/template"
11 | "github.com/GoAdminGroup/go-admin/template/icon"
12 | "github.com/GoAdminGroup/go-admin/template/types"
13 | "github.com/GoAdminGroup/go-admin/template/types/action"
14 | )
15 |
16 | func GetTableContent(ctx *context.Context) (types.Panel, error) {
17 |
18 | comp := template.Get(ctx, config.GetTheme())
19 |
20 | table := comp.DataTable().
21 | SetInfoList([]map[string]types.InfoItem{
22 | {
23 | "id": {Content: "0"},
24 | "name": {Content: "Jack"},
25 | "gender": {Content: "men"},
26 | "age": {Content: "20"},
27 | },
28 | {
29 | "id": {Content: "1"},
30 | "name": {Content: "Jane"},
31 | "gender": {Content: "women"},
32 | "age": {Content: "23"},
33 | },
34 | }).
35 | SetPrimaryKey("id").
36 | SetThead(types.Thead{
37 | {Head: "ID", Field: "id"},
38 | {Head: "Name", Field: "name"},
39 | {Head: "Gender", Field: "gender"},
40 | {Head: "Age", Field: "age"},
41 | })
42 |
43 | allBtns := make(types.Buttons, 0)
44 |
45 | // Add a ajax button action
46 | allBtns = append(allBtns, types.GetDefaultButton("Click me", icon.ArrowLeft, action.Ajax("ajax_id",
47 | func(ctx *context.Context) (success bool, msg string, data interface{}) {
48 | fmt.Println("ctx request", ctx.FormValue("id"))
49 | return true, "ok", nil
50 | })))
51 |
52 | btns, btnsJs := allBtns.Content(ctx)
53 | table = table.SetButtons(btns).SetActionJs(btnsJs)
54 |
55 | cbs := make(types.Callbacks, 0)
56 | for _, btn := range allBtns {
57 | cbs = append(cbs, btn.GetAction().GetCallbacks())
58 | }
59 |
60 | body := table.GetContent()
61 |
62 | return types.Panel{
63 | Content: comp.Box().
64 | SetBody(body).
65 | SetNoPadding().
66 | SetHeader(table.GetDataTableHeader()).
67 | WithHeadBorder().
68 | SetFooter(paginator.Get(ctx, paginator.Config{
69 | Size: 50,
70 | PageSizeList: []string{"10", "20", "30", "50"},
71 | Param: parameter.GetParam(ctx.Request.URL, 10),
72 | }).GetContent()).
73 | GetContent(),
74 | Title: "Table",
75 | Description: "table example",
76 | Callbacks: cbs,
77 | }, nil
78 | }
79 |
--------------------------------------------------------------------------------
/project.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoAdminGroup/example/956d61425a561b823fa00bc7c9a5098882411f42/project.db
--------------------------------------------------------------------------------
/tables/authors.go:
--------------------------------------------------------------------------------
1 | package tables
2 |
3 | import (
4 | "github.com/GoAdminGroup/go-admin/context"
5 | "github.com/GoAdminGroup/go-admin/modules/db"
6 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
7 | "github.com/GoAdminGroup/go-admin/template/icon"
8 | "github.com/GoAdminGroup/go-admin/template/types"
9 | "github.com/GoAdminGroup/go-admin/template/types/action"
10 | "github.com/GoAdminGroup/go-admin/template/types/form"
11 | )
12 |
13 | // GetAuthorsTable return the model of table author.
14 | func GetAuthorsTable(ctx *context.Context) (authorsTable table.Table) {
15 |
16 | authorsTable = table.NewDefaultTable(ctx, table.DefaultConfigWithDriver("sqlite"))
17 |
18 | // connect your custom connection
19 | // authorsTable = table.NewDefaultTable(ctx, table.DefaultConfigWithDriverAndConnection("mysql", "admin"))
20 |
21 | info := authorsTable.GetInfo().SetFilterFormLayout(form.LayoutFilter)
22 | info.AddField("ID", "id", db.Int).FieldSortable()
23 | info.AddField("First Name", "first_name", db.Varchar).FieldHide()
24 | info.AddField("Last Name", "last_name", db.Varchar).FieldHide()
25 | info.AddField("Name", "name", db.Varchar).FieldDisplay(func(value types.FieldModel) interface{} {
26 | first, _ := value.Row["first_name"].(string)
27 | last, _ := value.Row["last_name"].(string)
28 | return first + " " + last
29 | })
30 | info.AddField("Email", "email", db.Varchar)
31 | info.AddField("Birthdate", "birthdate", db.Date)
32 | info.AddField("Added", "added", db.Timestamp)
33 |
34 | info.AddButton(ctx, "Articles", icon.Tv,
35 | action.PopUpWithIframe("/authors/list", "文章", action.IframeData{Src: "/admin/info/posts"}, "900px", "560px"))
36 | info.SetTable("authors").SetTitle("Authors").SetDescription("Authors")
37 |
38 | formList := authorsTable.GetForm()
39 | formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowEdit().FieldNotAllowAdd()
40 | formList.AddField("First Name", "first_name", db.Varchar, form.Text)
41 | formList.AddField("Last Name", "last_name", db.Varchar, form.Text)
42 | formList.AddField("Email", "email", db.Varchar, form.Text)
43 | formList.AddField("Birthdate", "birthdate", db.Date, form.Text)
44 | formList.AddField("Added", "added", db.Timestamp, form.Text)
45 |
46 | formList.SetTable("authors").SetTitle("Authors").SetDescription("Authors")
47 |
48 | return
49 | }
50 |
--------------------------------------------------------------------------------
/tables/external.go:
--------------------------------------------------------------------------------
1 | package tables
2 |
3 | import (
4 | "github.com/GoAdminGroup/go-admin/context"
5 | "github.com/GoAdminGroup/go-admin/modules/db"
6 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/parameter"
7 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
8 | "github.com/GoAdminGroup/go-admin/template/types/form"
9 | )
10 |
11 | // GetExternalTable return the model from external data source.
12 | func GetExternalTable(ctx *context.Context) (externalTable table.Table) {
13 |
14 | externalTable = table.NewDefaultTable(ctx, table.DefaultConfig())
15 |
16 | info := externalTable.GetInfo().SetFilterFormLayout(form.LayoutFilter)
17 | info.AddField("ID", "id", db.Int).FieldSortable()
18 | info.AddField("Title", "title", db.Varchar)
19 |
20 | info.SetTable("external").
21 | SetTitle("Externals").
22 | SetDescription("Externals").
23 | SetGetDataFn(func(param parameter.Parameters) ([]map[string]interface{}, int) {
24 | return []map[string]interface{}{
25 | {
26 | "id": 10,
27 | "title": "this is a title",
28 | }, {
29 | "id": 11,
30 | "title": "this is a title2",
31 | }, {
32 | "id": 12,
33 | "title": "this is a title3",
34 | }, {
35 | "id": 13,
36 | "title": "this is a title4",
37 | },
38 | }, 10
39 | })
40 |
41 | formList := externalTable.GetForm()
42 | formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowEdit().FieldNotAllowAdd()
43 | formList.AddField("Title", "title", db.Varchar, form.Text)
44 |
45 | formList.SetTable("external").SetTitle("Externals").SetDescription("Externals")
46 |
47 | detail := externalTable.GetDetail()
48 |
49 | detail.SetTable("external").
50 | SetTitle("Externals").
51 | SetDescription("Externals").
52 | SetGetDataFn(func(param parameter.Parameters) ([]map[string]interface{}, int) {
53 | return []map[string]interface{}{
54 | {
55 | "id": 10,
56 | "title": "this is a title",
57 | },
58 | }, 1
59 | })
60 |
61 | return
62 | }
63 |
--------------------------------------------------------------------------------
/tables/posts.go:
--------------------------------------------------------------------------------
1 | package tables
2 |
3 | import (
4 | "github.com/GoAdminGroup/go-admin/context"
5 | "github.com/GoAdminGroup/go-admin/modules/db"
6 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
7 | "github.com/GoAdminGroup/go-admin/template"
8 | "github.com/GoAdminGroup/go-admin/template/types"
9 | "github.com/GoAdminGroup/go-admin/template/types/form"
10 | editType "github.com/GoAdminGroup/go-admin/template/types/table"
11 | )
12 |
13 | // GetPostsTable return the model of table posts.
14 | func GetPostsTable(ctx *context.Context) (postsTable table.Table) {
15 |
16 | postsTable = table.NewDefaultTable(ctx, table.DefaultConfigWithDriver("sqlite"))
17 |
18 | info := postsTable.GetInfo().SetFilterFormLayout(form.LayoutFilter)
19 | info.AddField("ID", "id", db.Int).FieldSortable()
20 | info.AddField("Title", "title", db.Varchar)
21 | info.AddField("AuthorID", "author_id", db.Int).FieldDisplay(func(value types.FieldModel) interface{} {
22 | return template.Default().
23 | Link().
24 | SetURL("/admin/info/authors/detail?__goadmin_detail_pk=" + value.Value).
25 | SetContent(template.HTML(value.Value)).
26 | OpenInNewTab().
27 | SetTabTitle(template.HTML("Author Detail(" + value.Value + ")")).
28 | GetContent()
29 | })
30 | info.AddField("AuthorName", "name", db.Varchar).FieldDisplay(func(value types.FieldModel) interface{} {
31 | first, _ := value.Row["authors_goadmin_join_first_name"].(string)
32 | last, _ := value.Row["authors_goadmin_join_last_name"].(string)
33 | return first + " " + last
34 | })
35 | info.AddField("AuthorFirstName", "first_name", db.Varchar).FieldJoin(types.Join{
36 | Field: "author_id",
37 | JoinField: "id",
38 | Table: "authors",
39 | }).FieldHide()
40 | info.AddField("AuthorLastName", "last_name", db.Varchar).FieldJoin(types.Join{
41 | Field: "author_id",
42 | JoinField: "id",
43 | Table: "authors",
44 | }).FieldHide()
45 | info.AddField("Description", "description", db.Varchar)
46 | info.AddField("Content", "content", db.Varchar).FieldEditAble(editType.Textarea)
47 | info.AddField("Date", "date", db.Varchar)
48 |
49 | info.SetTable("posts").SetTitle("Posts").SetDescription("Posts")
50 |
51 | formList := postsTable.GetForm()
52 | formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowEdit().FieldNotAllowAdd()
53 | formList.AddField("Title", "title", db.Varchar, form.Text)
54 | formList.AddField("Description", "description", db.Varchar, form.Text)
55 | formList.AddField("Content", "content", db.Varchar, form.RichText).FieldEnableFileUpload()
56 | formList.AddField("Date", "date", db.Varchar, form.Datetime)
57 |
58 | formList.EnableAjax("Success", "Fail")
59 |
60 | formList.SetTable("posts").SetTitle("Posts").SetDescription("Posts")
61 |
62 | return
63 | }
64 |
--------------------------------------------------------------------------------
/tables/profile.go:
--------------------------------------------------------------------------------
1 | package tables
2 |
3 | import (
4 | "path/filepath"
5 | "strings"
6 |
7 | "github.com/GoAdminGroup/go-admin/context"
8 | "github.com/GoAdminGroup/go-admin/modules/db"
9 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
10 | "github.com/GoAdminGroup/go-admin/template/types"
11 | "github.com/GoAdminGroup/go-admin/template/types/form"
12 | )
13 |
14 | func GetProfileTable(ctx *context.Context) table.Table {
15 |
16 | profile := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver("sqlite"))
17 |
18 | info := profile.GetInfo().HideFilterArea().SetFilterFormLayout(form.LayoutFilter)
19 | info.AddField("ID", "id", db.Int).FieldFilterable()
20 | info.AddField("UUID", "uuid", db.Varchar).FieldCopyable()
21 | info.AddField("Pass", "pass", db.Tinyint).FieldBool("1", "0")
22 | info.AddField("Photos", "photos", db.Varchar).FieldCarousel(func(value string) []string {
23 | return strings.Split(value, ",")
24 | }, 150, 100)
25 | info.AddField("Finish State", "finish_state", db.Tinyint).
26 | FieldDisplay(func(value types.FieldModel) interface{} {
27 | if value.Value == "0" {
28 | return "Step 1"
29 | }
30 | if value.Value == "1" {
31 | return "Step 2"
32 | }
33 | if value.Value == "2" {
34 | return "Step 3"
35 | }
36 | return "Unknown"
37 | }).
38 | FieldDot(map[string]types.FieldDotColor{
39 | "Step 1": types.FieldDotColorDanger,
40 | "Step 2": types.FieldDotColorInfo,
41 | "Step 3": types.FieldDotColorPrimary,
42 | }, types.FieldDotColorDanger)
43 | info.AddField("Progress", "finish_progress", db.Int).FieldProgressBar()
44 | info.AddField("Resume", "resume", db.Varchar).
45 | FieldDisplay(func(value types.FieldModel) interface{} {
46 | return filepath.Base(value.Value)
47 | }).
48 | FieldDownLoadable("http://yinyanghu.github.io/files/")
49 | info.AddField("FileSize", "resume_size", db.Int).FieldFileSize()
50 |
51 | info.SetTable("profile").SetTitle("Profile").SetDescription("Profile")
52 |
53 | formList := profile.GetForm()
54 | formList.AddField("UUID", "uuid", db.Varchar, form.Text)
55 | formList.AddField("Photos", "photos", db.Varchar, form.Text)
56 | formList.AddField("Resume", "resume", db.Varchar, form.Text)
57 | formList.AddField("FileSize", "resume_size", db.Int, form.Number)
58 | formList.AddField("Finish State", "finish_state", db.Tinyint, form.Number)
59 | formList.AddField("Progress", "finish_progress", db.Int, form.Number)
60 | formList.AddField("Pass", "pass", db.Tinyint, form.Number)
61 |
62 | formList.SetTable("profile").SetTitle("Profile").SetDescription("Profile")
63 |
64 | return profile
65 | }
66 |
--------------------------------------------------------------------------------
/tables/tables.go:
--------------------------------------------------------------------------------
1 | package tables
2 |
3 | import "github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
4 |
5 | // generators is a map of table models.
6 | //
7 | // The key of generators is the prefix of table info url.
8 | // The corresponding value is the Form and TableName data.
9 | //
10 | // http://{{config.Domain}}:{{Port}}/{{config.Prefix}}/info/{{key}}
11 | //
12 | // example:
13 | //
14 | // "users" => http://localhost:9033/admin/info/users
15 | // "posts" => http://localhost:9033/admin/info/posts
16 | // "authors" => http://localhost:9033/admin/info/authors
17 | //
18 | var Generators = map[string]table.Generator{
19 | "posts": GetPostsTable,
20 | "users": GetUserTable,
21 | "authors": GetAuthorsTable,
22 | "profile": GetProfileTable,
23 | }
24 |
--------------------------------------------------------------------------------
/tables/users.go:
--------------------------------------------------------------------------------
1 | package tables
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/GoAdminGroup/go-admin/context"
7 | "github.com/GoAdminGroup/go-admin/modules/db"
8 | form2 "github.com/GoAdminGroup/go-admin/plugins/admin/modules/form"
9 | "github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
10 | "github.com/GoAdminGroup/go-admin/template"
11 | "github.com/GoAdminGroup/go-admin/template/icon"
12 | "github.com/GoAdminGroup/go-admin/template/types"
13 | "github.com/GoAdminGroup/go-admin/template/types/action"
14 | "github.com/GoAdminGroup/go-admin/template/types/form"
15 | selection "github.com/GoAdminGroup/go-admin/template/types/form/select"
16 | editType "github.com/GoAdminGroup/go-admin/template/types/table"
17 | )
18 |
19 | // GetUserTable return the model of table user.
20 | func GetUserTable(ctx *context.Context) (userTable table.Table) {
21 |
22 | userTable = table.NewDefaultTable(ctx, table.Config{
23 | Driver: db.DriverSqlite,
24 | CanAdd: true,
25 | Editable: true,
26 | Deletable: true,
27 | Exportable: true,
28 | Connection: table.DefaultConnectionName,
29 | PrimaryKey: table.PrimaryKey{
30 | Type: db.Int,
31 | Name: table.DefaultPrimaryKeyName,
32 | },
33 | })
34 |
35 | info := userTable.GetInfo().SetFilterFormLayout(form.LayoutFilter)
36 | info.AddField("ID", "id", db.Int).FieldSortable()
37 | info.AddField("Name", "name", db.Varchar).FieldEditAble(editType.Text).
38 | FieldFilterable(types.FilterType{Operator: types.FilterOperatorLike})
39 | info.AddField("Gender", "gender", db.Tinyint).FieldDisplay(func(model types.FieldModel) interface{} {
40 | if model.Value == "0" {
41 | return "men"
42 | }
43 | if model.Value == "1" {
44 | return "women"
45 | }
46 | return "unknown"
47 | }).FieldEditAble(editType.Switch).FieldEditOptions(types.FieldOptions{
48 | {Value: "0", Text: "👨"},
49 | {Value: "1", Text: "👩"},
50 | }).FieldFilterable(types.FilterType{FormType: form.SelectSingle}).FieldFilterOptions(types.FieldOptions{
51 | {Value: "0", Text: "men"},
52 | {Value: "1", Text: "women"},
53 | })
54 | info.AddColumn("personality", func(value types.FieldModel) interface{} {
55 | return "handsome"
56 | })
57 | info.AddColumnButtons(ctx, "see more", types.GetColumnButton("more", icon.Info,
58 | action.PopUp("/see/more/example", "Detail", func(ctx *context.Context) (success bool, msg string, data interface{}) {
59 | return true, "ok", "Detail
balabala
this feature will be released in v1.2.7
"
60 | })))
61 | info.AddField("Phone", "phone", db.Varchar).FieldFilterable()
62 | info.AddField("City", "city", db.Varchar).FieldFilterable()
63 | info.AddField("Avatar", "avatar", db.Varchar).FieldDisplay(func(value types.FieldModel) interface{} {
64 | return template.Default().Image().
65 | SetSrc(`//quick.go-admin.cn/demo/assets/dist/img/gopher_avatar.png`).
66 | SetHeight("120").SetWidth("120").WithModal().GetContent()
67 | })
68 | info.AddField("CreatedAt", "created_at", db.Timestamp).
69 | FieldFilterable(types.FilterType{FormType: form.DatetimeRange})
70 | info.AddField("UpdatedAt", "updated_at", db.Timestamp).FieldEditAble(editType.Datetime)
71 |
72 | info.AddActionButton(ctx, "google", action.Jump("https://google.com"))
73 | info.AddActionButton(ctx, "audit", action.Ajax("/admin/audit",
74 | func(ctx *context.Context) (success bool, msg string, data interface{}) {
75 | return true, "success", ""
76 | }))
77 | info.AddActionButton(ctx, "Preview", action.PopUp("/admin/preview", "Preview",
78 | func(ctx *context.Context) (success bool, msg string, data interface{}) {
79 | return true, "", "hello world
"
80 | }))
81 | info.AddButton(ctx, "google", icon.Google, action.Jump("https://google.com"))
82 | info.AddButton(ctx, "popup", icon.Terminal, action.PopUp("/admin/popup", "Popup Example",
83 | func(ctx *context.Context) (success bool, msg string, data interface{}) {
84 | return true, "", "hello world
"
85 | }))
86 | info.AddButton(ctx, "iframe", icon.Tv, action.PopUpWithIframe("/admin/iframe", "Iframe Example",
87 | action.IframeData{Src: "/admin/info/profile/new"}, "900px", "480px"))
88 | info.AddButton(ctx, "ajax", icon.Android, action.Ajax("/admin/ajax",
89 | func(ctx *context.Context) (success bool, msg string, data interface{}) {
90 | return true, "success", ""
91 | }))
92 | info.AddSelectBox(ctx, "gender", types.FieldOptions{
93 | {Value: "0", Text: "men"},
94 | {Value: "1", Text: "women"},
95 | }, action.FieldFilter("gender"))
96 |
97 | info.SetTable("users").SetTitle("Users").SetDescription("Users")
98 |
99 | formList := userTable.GetForm()
100 | formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowEdit().FieldNotAllowAdd()
101 | formList.AddField("Ip", "ip", db.Varchar, form.Text)
102 | formList.AddField("Name", "name", db.Varchar, form.Text)
103 | formList.AddField("Gender", "gender", db.Tinyint, form.Radio).
104 | FieldOptions(types.FieldOptions{
105 | {Text: "men", Value: "0"},
106 | {Text: "women", Value: "1"},
107 | }).FieldDefault("0")
108 | formList.AddField("Phone", "phone", db.Varchar, form.Text)
109 | formList.AddField("Country", "country", db.Tinyint, form.SelectSingle).
110 | FieldOptions(types.FieldOptions{
111 | {Text: "China", Value: "0"},
112 | {Text: "America", Value: "1"},
113 | {Text: "England", Value: "2"},
114 | {Text: "Canada", Value: "3"},
115 | }).FieldDefault("0").FieldOnChooseAjax("city", "/choose/country",
116 | func(ctx *context.Context) (bool, string, interface{}) {
117 | country := ctx.FormValue("value")
118 | var data = make(selection.Options, 0)
119 | switch country {
120 | case "0":
121 | data = selection.Options{
122 | {Text: "Beijing", ID: "beijing"},
123 | {Text: "ShangHai", ID: "shangHai"},
124 | {Text: "GuangZhou", ID: "guangZhou"},
125 | {Text: "ShenZhen", ID: "shenZhen"},
126 | }
127 | case "1":
128 | data = selection.Options{
129 | {Text: "Los Angeles", ID: "los angeles"},
130 | {Text: "Washington, dc", ID: "washington, dc"},
131 | {Text: "New York", ID: "new york"},
132 | {Text: "Las Vegas", ID: "las vegas"},
133 | }
134 | case "2":
135 | data = selection.Options{
136 | {Text: "London", ID: "london"},
137 | {Text: "Cambridge", ID: "cambridge"},
138 | {Text: "Manchester", ID: "manchester"},
139 | {Text: "Liverpool", ID: "liverpool"},
140 | }
141 | case "3":
142 | data = selection.Options{
143 | {Text: "Vancouver", ID: "vancouver"},
144 | {Text: "Toronto", ID: "toronto"},
145 | }
146 | default:
147 | data = selection.Options{
148 | {Text: "Beijing", ID: "beijing"},
149 | {Text: "ShangHai", ID: "shangHai"},
150 | {Text: "GuangZhou", ID: "guangZhou"},
151 | {Text: "ShenZhen", ID: "shenZhen"},
152 | }
153 | }
154 | return true, "ok", data
155 | })
156 | formList.AddField("City", "city", db.Varchar, form.SelectSingle).
157 | FieldOptionInitFn(func(val types.FieldModel) types.FieldOptions {
158 | return types.FieldOptions{
159 | {Value: val.Value, Text: val.Value, Selected: true},
160 | }
161 | })
162 | formList.AddField("Custom Field", "role", db.Varchar, form.Text).
163 | FieldPostFilterFn(func(value types.PostFieldModel) interface{} {
164 | fmt.Println("user custom field", value)
165 | return ""
166 | })
167 |
168 | formList.AddField("UpdatedAt", "updated_at", db.Timestamp, form.Default).FieldNotAllowAdd()
169 | formList.AddField("CreatedAt", "created_at", db.Timestamp, form.Default).FieldNotAllowAdd()
170 |
171 | userTable.GetForm().SetTabGroups(types.
172 | NewTabGroups("id", "ip", "name", "gender", "country", "city").
173 | AddGroup("phone", "role", "created_at", "updated_at")).
174 | SetTabHeaders("profile1", "profile2")
175 |
176 | formList.SetTable("users").SetTitle("Users").SetDescription("Users")
177 |
178 | formList.SetPostHook(func(values form2.Values) error {
179 | fmt.Println("userTable.GetForm().PostHook", values)
180 | return nil
181 | })
182 |
183 | return
184 | }
185 |
--------------------------------------------------------------------------------
/uploads/a.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoAdminGroup/example/956d61425a561b823fa00bc7c9a5098882411f42/uploads/a.txt
--------------------------------------------------------------------------------