├── .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

  1. 23234
  2. 2342342342
  3. 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 := `
375 |
376 | 377 | 378 |
379 |
380 | 381 | 382 |
383 |
` 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 --------------------------------------------------------------------------------