diff --git a/Makefile b/Makefile index 506c463..b0fd7d6 100644 --- a/Makefile +++ b/Makefile @@ -2,3 +2,7 @@ dockerimage: @echo "building Jump Jump docker image..." docker build -t studiomj/jump-jump:latest -f build/package/Dockerfile . + +.PHONY: docs +docs: + swag init -g ./internal/app/routers/router.go \ No newline at end of file diff --git a/README.md b/README.md index dab758e..9560806 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ * [设置短链接域名](#设置短链接域名) * [获取完整短链接](#获取完整短链接) * [部署到服务器](#部署到服务器) +* [接口文档](#接口文档) * [感谢](#感谢) --- @@ -100,6 +101,11 @@ docker-compose -f deployments/docker-compose.yaml -p jumpjump exec apiserver ./c 这里提供了使用 docker-compose 的部署方案,[点击查看](http://t.majiawei.com/fk1ta3)。 +## 接口文档 + +使用 Swagger UI 提供了一个可调试文档,具体使用方法查看这个 [PR](https://github.com/jwma/jump-jump/pull/40),希望这份文档能够帮助 +到大家! + ## 感谢 在这里感谢所有为 Jump Jump 提供建议和反馈 bug 的朋友们,有你们 Jump Jump 会变得更好! diff --git a/api/config/v1/basics.http b/api/config/v1/basics.http deleted file mode 100644 index 81180ad..0000000 --- a/api/config/v1/basics.http +++ /dev/null @@ -1,85 +0,0 @@ -# 获取配置 -GET http://{{host}}/v1/config - -> {% - client.test('Get config successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### - -# 用户登入 -POST http://{{host}}/v1/user/login -Content-Type: application/json - -{ - "username": "{{adminUsername}}", - "password": "{{adminPassword}}" -} - -> {% - client.test('Login successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); - client.global.set('token', 'Bearer ' + response.body.data.token); -%} - -### - -# 更新 landingHosts 配置 -PATCH http://{{host}}/v1/config/landing-hosts -Content-Type: application/json -Authorization: {{token}} - -{ - "hosts": [ - "http://127.0.0.1:8081/" - ] -} - -> {% - client.test('Update landing successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### - -# 更新随机 ID 长度设置 -PATCH http://{{host}}/v1/config/id-length -Content-Type: application/json -Authorization: {{token}} - -{ - "idMinimumLength": 6, - "idLength": 8, - "idMaximumLength": 10 -} - -> {% - client.test('Update landing successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### - -# 更新短链接 404 处理配置 -PATCH http://{{host}}/v1/config/short-link-404-handling -Content-Type: application/json -Authorization: {{token}} - -{ - "mode": "redirect", - "value": "https://www.google.com" -} - -> {% - client.test('Update landing successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - client.assert(0 === response.body.code, 'Want 0, but got ' + response.body.code); - }); -%} - -### \ No newline at end of file diff --git a/api/http-client.env.json b/api/http-client.env.json deleted file mode 100644 index 47097dc..0000000 --- a/api/http-client.env.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "dev": { - "host": "127.0.0.1:8080", - "username": "", - "password": "", - "adminUsername": "", - "adminPassword": "" - } -} \ No newline at end of file diff --git a/api/shortlink/v1/base-cases.http b/api/shortlink/v1/base-cases.http deleted file mode 100644 index 6f25940..0000000 --- a/api/shortlink/v1/base-cases.http +++ /dev/null @@ -1,120 +0,0 @@ -# 短链接管理接口基础测试 - -# 1. 用户登入 -POST http://{{host}}/v1/user/login -Content-Type: application/json - -{ - "username": "{{username}}", - "password": "{{password}}" -} - -> {% - client.test('Login successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); - client.global.set('token', 'Bearer ' + response.body.data.token); -%} - -### - -# 2. 创建短链接 -POST http://{{host}}/v1/short-link/ -Content-Type: application/json -Authorization: {{token}} - -{ - "url": "http://anmuji.com/?t={{$timestamp}}", - "description": "{{$uuid}}", - "is_enable": true -} - -> {% - client.test('Create short link successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); - client.global.set("short_link_id", response.body.data.shortLink.id); -%} - -### - -# 3. 获取短链接 -GET http://{{host}}/v1/short-link/{{short_link_id}} -Content-Type: application/json -Authorization: {{token}} - -> {% - client.test('Get short link successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### - -# 4. 获取短链接最近的访问历史 -GET http://{{host}}/v1/short-link/{{short_link_id}}/latest-request-history -Content-Type: application/json -Authorization: {{token}} - -> {% - client.test('Get short link history successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### - -# 5. 更新短链接 -PATCH http://{{host}}/v1/short-link/{{short_link_id}} -Content-Type: application/json -Authorization: {{token}} - -{ - "url": "http://anmuji.com", - "description": "{{$uuid}}", - "isEnable": true -} - -> {% - client.test('Update short link successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### - -# 6. 删除短链接 -DELETE http://{{host}}/v1/short-link/{{short_link_id}} -Authorization: {{token}} - -> {% - client.test('Delete short link successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### - -# 7. 重复删除短链接 -DELETE http://{{host}}/v1/short-link/{{short_link_id}} -Authorization: {{token}} - -> {% - client.test('Delete short link failed', function() { - client.assert(4999 === response.body.code, 'Want 4999, but got ' + response.body.code); - }); -%} - -### - -# 8. 获取短链接列表 -GET http://{{host}}/v1/short-link/ -Authorization: {{token}} - -> {% - client.test('List short links successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### \ No newline at end of file diff --git a/api/shortlink/v1/test-role.http b/api/shortlink/v1/test-role.http deleted file mode 100644 index 8374223..0000000 --- a/api/shortlink/v1/test-role.http +++ /dev/null @@ -1,164 +0,0 @@ -# 1. 使用 RoleUser 角色的用户登入 -POST http://{{host}}/v1/user/login -Content-Type: application/json - -{ - "username": "{{username}}", - "password": "{{password}}" -} - -> {% - client.test('Login successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); - client.global.set('token', 'Bearer ' + response.body.data.token); -%} - -### - -# 2. 使用 RoleAdmin 角色的用户登入 -POST http://{{host}}/v1/user/login -Content-Type: application/json - -{ - "username": "{{adminUsername}}", - "password": "{{adminPassword}}" -} - -> {% - client.test('Login successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); - client.global.set('admin_token', 'Bearer ' + response.body.data.token); -%} - -### - -# 3. 使用 token 请求创建短链接接口 -POST http://{{host}}/v1/short-link/ -Content-Type: application/json -Authorization: {{token}} - -{ - "url": "http://anmuji.com/?t={{$timestamp}}", - "description": "{{$uuid}}", - "is_enable": true -} - -> {% - client.test('Create short link successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); - client.global.set('user_shortlink_id', response.body.data.shortLink.id); -%} - -### - -# 4. 使用 admin_token 请求创建短链接接口 -POST http://{{host}}/v1/short-link/ -Content-Type: application/json -Authorization: {{admin_token}} - -{ - "url": "http://anmuji.com/?t={{$timestamp}}", - "description": "{{$uuid}}", - "is_enable": true -} - -> {% - client.test('Create short link successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); - client.global.set('admin_shortlink_id', response.body.data.shortLink.id); -%} - -### - -# 5. 使用 token 获取使用 token 创建的短链接 -GET http://{{host}}/v1/short-link/{{user_shortlink_id}}/ -Content-Type: application/json -Authorization: {{token}} - -> {% - client.test('Get short link successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### - -# 6. 使用 token 获取使用 admin_token 所创建的短链接 -GET http://{{host}}/v1/short-link/{{admin_shortlink_id}}/ -Content-Type: application/json -Authorization: {{token}} - -> {% - client.test('Get admin short link failed', function() { - client.assert(4999 === response.body.code, 'Want 4999, but got ' + response.body.code); - }); -%} - -### - -# 7. 使用 token 更新使用 token 创建的短链接 -PATCH http://{{host}}/v1/short-link/{{user_shortlink_id}} -Content-Type: application/json -Authorization: {{token}} - -{ - "url": "http://anmuji.com", - "description": "{{$uuid}}", - "isEnable": true -} - -> {% - client.test('Update user short link successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### - -# 8. 使用 token 更新使用 admin_token 创建的短链接 -# 期望返回 403 -PATCH http://{{host}}/v1/short-link/{{admin_shortlink_id}} -Content-Type: application/json -Authorization: {{token}} - -{ - "url": "http://anmuji.com", - "description": "{{$uuid}}", - "isEnable": true -} - -> {% - client.test('Update admin short link failed', function() { - client.assert(4999 === response.body.code, 'Want 4999, but got ' + response.body.code); - }); -%} - -### - -# 9. 使用 token 删除使用 token 创建的短链接 -DELETE http://{{host}}/v1/short-link/{{user_shortlink_id}} -Authorization: {{token}} - -> {% - client.test('Delete short link successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### - -# 10. 使用 token 删除使用 admin_token 创建的短链接 -DELETE http://{{host}}/v1/short-link/{{admin_shortlink_id}} -Authorization: {{token}} - -> {% - client.test('Delete short link failed', function() { - client.assert(4999 === response.body.code, 'Want 4999, but got ' + response.body.code); - }); -%} - -### \ No newline at end of file diff --git a/api/user/v1/test-change-password.http b/api/user/v1/test-change-password.http deleted file mode 100644 index a3a5834..0000000 --- a/api/user/v1/test-change-password.http +++ /dev/null @@ -1,88 +0,0 @@ -# 1. 登入 -POST http://{{host}}/v1/user/login -Content-Type: application/json - -{ - "username": "{{username}}", - "password": "{{password}}" -} - -> {% - client.test('Login successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); - client.global.set('token', 'Bearer ' + response.body.data.token); -%} - -### - -# 2. 修改密码 -PATCH http://{{host}}/v1/user/change-password -Content-Type: application/json -Authorization: {{token}} - -{ - "password": "{{password}}", - "newPassword": "123456" -} - -> {% - client.test('Change password successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### - -# 3. 使用旧密码登入失败 -POST http://{{host}}/v1/user/login -Content-Type: application/json - -{ - "username": "{{username}}", - "password": "{{password}}" -} - -> {% - client.test('Login with old password failed', function() { - client.assert(4999 === response.body.code, 'Want 4999, but got ' + response.body.code); - }); -%} - -### - -# 4. 使用新密码登入成功 -POST http://{{host}}/v1/user/login -Content-Type: application/json - -{ - "username": "{{username}}", - "password": "123456" -} - -> {% - client.test('Login with new password successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); - client.global.set('token', 'Bearer ' + response.body.data.token); -%} - -### - -# 5. 改回旧密码 -PATCH http://{{host}}/v1/user/change-password -Content-Type: application/json -Authorization: {{token}} - -{ - "password": "123456", - "newPassword": "{{password}}" -} - -> {% - client.test('Reset password to old password successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### diff --git a/api/user/v1/user.http b/api/user/v1/user.http deleted file mode 100644 index 36fd2f6..0000000 --- a/api/user/v1/user.http +++ /dev/null @@ -1,16 +0,0 @@ -# 登入 -POST http://{{host}}/v1/user/login -Content-Type: application/json - -{ - "username": "{{adminUsername}}", - "password": "{{adminPassword}}" -} - -> {% - client.test('Login successfully', function() { - client.assert(200 === response.status, 'Want 200, but got ' + response.status); - }); -%} - -### \ No newline at end of file diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..76222dc --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,1129 @@ +// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// This file was generated by swaggo/swag + +package docs + +import ( + "bytes" + "encoding/json" + "strings" + + "github.com/alecthomas/template" + "github.com/swaggo/swag" +) + +var doc = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{.Description}}", + "title": "{{.Title}}", + "contact": { + "name": "MJ Ma", + "url": "https://www.linkedin.com/in/mj-profile/", + "email": "m.mjw.ma@gmail.com" + }, + "license": { + "name": "MIT", + "url": "https://github.com/jwma/jump-jump/blob/master/LICENSE" + }, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/config": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取系统配置信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统配置" + ], + "summary": "获取系统配置信息", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetConfigAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/config/id-length": { + "patch": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新短链接 ID 设置", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统配置" + ], + "summary": "更新短链接 ID 设置", + "parameters": [ + { + "description": "更新短链接 ID 设置请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/IdConfig" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetConfigAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/config/landing-hosts": { + "patch": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新落地页 Hosts", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统配置" + ], + "summary": "更新落地页 Hosts", + "parameters": [ + { + "description": "更新落地页 Hosts 请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateLandingHostsAPIRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetConfigAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/config/short-link-404-handling": { + "patch": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新短链接 404 设置", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统配置" + ], + "summary": "更新短链接 404 设置", + "parameters": [ + { + "description": "更新短链接 404 设置请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ShortLinkNotFoundConfig" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetConfigAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/short-link/": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "短链接列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "短链接列表", + "parameters": [ + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页条数", + "name": "pageSize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/ListShortLinksAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + }, + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "创建短链接", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "创建短链接", + "parameters": [ + { + "description": "创建短链接请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateShortLinkAPIRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/CreateShortLinkAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/short-link/{id}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取系统配置信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "获取指定 ID 短链接", + "parameters": [ + { + "type": "string", + "description": "短链接 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetShortLinkAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "删除短链接", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "删除短链接", + "parameters": [ + { + "type": "string", + "description": "短链接 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/Response" + } + }, + "401": { + "description": "" + } + } + }, + "patch": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新短链接", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "更新短链接", + "parameters": [ + { + "type": "string", + "description": "短链接 ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新短链接请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateShortLinkAPIRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/UpdateShortLinkAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/short-link/{id}/data": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "可查询短链接某个日期范围内的访问数据", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "短链接访问数据", + "parameters": [ + { + "type": "string", + "description": "短链接 ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "开始日期 YYYY-mm-dd", + "name": "startDate", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "结束日期 YYYY-mm-dd", + "name": "endDate", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/ShortLinkDataAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/user/change-password": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "修改账号密码", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "账号" + ], + "summary": "修改账号密码", + "parameters": [ + { + "description": "修改密码请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ChangePasswordAPIRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/Response" + } + }, + "401": { + "description": "" + } + } + } + }, + "/user/info": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取账号信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "账号" + ], + "summary": "获取账号信息", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetUserInfoAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/user/login": { + "post": { + "description": "账号密码登入", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "账号" + ], + "summary": "账号登入", + "parameters": [ + { + "description": "登入请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/LoginAPIRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/LoginAPIResponseData" + } + } + } + ] + } + } + } + } + }, + "/user/logout": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "登出", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "账号" + ], + "summary": "登出", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/Response" + } + }, + "401": { + "description": "" + } + } + } + } + }, + "definitions": { + "ChangePasswordAPIRequest": { + "type": "object", + "properties": { + "newPassword": { + "description": "新密码", + "type": "string" + }, + "password": { + "description": "原密码", + "type": "string" + } + } + }, + "CreateShortLinkAPIRequest": { + "type": "object", + "properties": { + "description": { + "description": "描述", + "type": "string", + "example": "Jump Jump project" + }, + "id": { + "description": "只有管理员可以在创建的时候指定 ID", + "type": "string", + "format": "string", + "example": "RANDOM_ID" + }, + "idLength": { + "description": "短链接 ID 长度", + "type": "integer", + "format": "int", + "example": 4 + }, + "isEnable": { + "description": "是否启用", + "type": "boolean", + "format": "boolean", + "example": true + }, + "url": { + "description": "目标链接", + "type": "string", + "example": "https://github.com/jwma/jump-jump" + } + } + }, + "CreateShortLinkAPIResponseData": { + "type": "object", + "properties": { + "shortLink": { + "$ref": "#/definitions/ShortLinkData" + } + } + }, + "GetConfigAPIResponseData": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/SystemConfig" + } + } + }, + "GetShortLinkAPIResponseData": { + "type": "object", + "properties": { + "shortLink": { + "$ref": "#/definitions/ShortLinkData" + } + } + }, + "GetUserInfoAPIResponseData": { + "type": "object", + "properties": { + "role": { + "description": "角色,1 普通用户 | 2 管理员", + "type": "integer", + "enum": [ + 1, + 2 + ], + "example": 1 + }, + "username": { + "description": "用户名", + "type": "string", + "example": "admin" + } + } + }, + "IdConfig": { + "type": "object", + "properties": { + "idLength": { + "description": "ID 长度", + "type": "integer", + "format": "int", + "example": 6 + }, + "idMaximumLength": { + "description": "最大 ID 长度", + "type": "integer", + "format": "int", + "example": 10 + }, + "idMinimumLength": { + "description": "最小 ID 长度", + "type": "integer", + "format": "int", + "example": 2 + } + } + }, + "ListShortLinksAPIResponseData": { + "type": "object", + "properties": { + "shortLinks": { + "type": "array", + "items": { + "$ref": "#/definitions/ShortLinkData" + } + }, + "total": { + "type": "integer", + "format": "10", + "example": 10 + } + } + }, + "LoginAPIRequest": { + "type": "object", + "required": [ + "password", + "username" + ], + "properties": { + "password": { + "description": "密码", + "type": "string", + "example": "your_password" + }, + "username": { + "description": "用户名", + "type": "string", + "example": "your_username" + } + } + }, + "LoginAPIResponseData": { + "type": "object", + "properties": { + "token": { + "description": "json web token", + "type": "string", + "example": "xxx.xxx.xxx" + } + } + }, + "RequestHistory": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "time": { + "type": "string" + }, + "ua": { + "type": "string" + }, + "url": { + "description": "由于短链接的目标连接可能会被修改,可以在访问历史记录中记录一下当前的目标连接", + "type": "string" + } + } + }, + "Response": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int", + "default": 0, + "example": 0 + }, + "data": { + "type": "object" + }, + "msg": { + "type": "string", + "default": "ok", + "example": "ok" + } + } + }, + "ShortLinkData": { + "type": "object", + "properties": { + "createTime": { + "description": "创建时间", + "type": "string" + }, + "createdBy": { + "description": "创建者", + "type": "string", + "format": "string", + "example": "admin" + }, + "description": { + "description": "描述", + "type": "string", + "format": "string", + "example": "Jump Jump project" + }, + "id": { + "type": "string", + "format": "string", + "example": "RANDOM_ID" + }, + "isEnable": { + "description": "是否启用", + "type": "boolean", + "format": "boolean", + "example": true + }, + "updateTime": { + "description": "最后更新时间", + "type": "string" + }, + "url": { + "description": "目标链接", + "type": "string", + "format": "string", + "example": "https://github.com/jwma/jump-jump" + } + } + }, + "ShortLinkDataAPIResponseData": { + "type": "object", + "properties": { + "histories": { + "type": "array", + "items": { + "$ref": "#/definitions/RequestHistory" + } + } + } + }, + "ShortLinkNotFoundConfig": { + "type": "object", + "required": [ + "mode", + "value" + ], + "properties": { + "mode": { + "description": "模式", + "type": "string", + "enum": [ + "content", + "redirect" + ], + "example": "content" + }, + "value": { + "description": "值", + "type": "string", + "example": "page not found" + } + } + }, + "SystemConfig": { + "type": "object", + "properties": { + "idConfig": { + "description": "ID 配置", + "$ref": "#/definitions/IdConfig" + }, + "landingHosts": { + "description": "落地页 Host 列表", + "type": "array", + "format": "array", + "items": { + "type": "string" + }, + "example": [ + "https://a.com/", + "https://b.com/" + ] + }, + "shortLinkNotFoundConfig": { + "description": "短链接 404 配置", + "$ref": "#/definitions/ShortLinkNotFoundConfig" + } + } + }, + "UpdateLandingHostsAPIRequest": { + "type": "object", + "properties": { + "hosts": { + "type": "array", + "format": "array", + "items": { + "type": "string" + }, + "example": [ + "https://a.com/", + "https://b.com/" + ] + } + } + }, + "UpdateShortLinkAPIRequest": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "description": { + "description": "描述", + "type": "string", + "example": "Jump Jump project" + }, + "isEnable": { + "description": "是否启用", + "type": "boolean", + "format": "boolean", + "example": true + }, + "url": { + "description": "目标链接", + "type": "string", + "example": "https://github.com/jwma/jump-jump" + } + } + }, + "UpdateShortLinkAPIResponseData": { + "type": "object", + "properties": { + "shortLink": { + "$ref": "#/definitions/ShortLinkData" + } + } + } + }, + "securityDefinitions": { + "ApiKeyAuth": { + "type": "apiKey", + "name": "Authorization", + "in": "header" + } + } +}` + +type swaggerInfo struct { + Version string + Host string + BasePath string + Schemes []string + Title string + Description string +} + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = swaggerInfo{ + Version: "", + Host: "", + BasePath: "", + Schemes: []string{}, + Title: "", + Description: "", +} + +type s struct{} + +func (s *s) ReadDoc() string { + sInfo := SwaggerInfo + sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1) + + t, err := template.New("swagger_info").Funcs(template.FuncMap{ + "marshal": func(v interface{}) string { + a, _ := json.Marshal(v) + return string(a) + }, + }).Parse(doc) + if err != nil { + return doc + } + + var tpl bytes.Buffer + if err := t.Execute(&tpl, sInfo); err != nil { + return doc + } + + return tpl.String() +} + +func init() { + swag.Register(swag.Name, &s{}) +} diff --git a/docs/swagger.json b/docs/swagger.json new file mode 100644 index 0000000..395d7fe --- /dev/null +++ b/docs/swagger.json @@ -0,0 +1,1062 @@ +{ + "swagger": "2.0", + "info": { + "contact": { + "name": "MJ Ma", + "url": "https://www.linkedin.com/in/mj-profile/", + "email": "m.mjw.ma@gmail.com" + }, + "license": { + "name": "MIT", + "url": "https://github.com/jwma/jump-jump/blob/master/LICENSE" + } + }, + "paths": { + "/config": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取系统配置信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统配置" + ], + "summary": "获取系统配置信息", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetConfigAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/config/id-length": { + "patch": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新短链接 ID 设置", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统配置" + ], + "summary": "更新短链接 ID 设置", + "parameters": [ + { + "description": "更新短链接 ID 设置请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/IdConfig" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetConfigAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/config/landing-hosts": { + "patch": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新落地页 Hosts", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统配置" + ], + "summary": "更新落地页 Hosts", + "parameters": [ + { + "description": "更新落地页 Hosts 请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateLandingHostsAPIRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetConfigAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/config/short-link-404-handling": { + "patch": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新短链接 404 设置", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统配置" + ], + "summary": "更新短链接 404 设置", + "parameters": [ + { + "description": "更新短链接 404 设置请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ShortLinkNotFoundConfig" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetConfigAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/short-link/": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "短链接列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "短链接列表", + "parameters": [ + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页条数", + "name": "pageSize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/ListShortLinksAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + }, + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "创建短链接", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "创建短链接", + "parameters": [ + { + "description": "创建短链接请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateShortLinkAPIRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/CreateShortLinkAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/short-link/{id}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取系统配置信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "获取指定 ID 短链接", + "parameters": [ + { + "type": "string", + "description": "短链接 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetShortLinkAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "删除短链接", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "删除短链接", + "parameters": [ + { + "type": "string", + "description": "短链接 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/Response" + } + }, + "401": { + "description": "" + } + } + }, + "patch": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新短链接", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "更新短链接", + "parameters": [ + { + "type": "string", + "description": "短链接 ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新短链接请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateShortLinkAPIRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/UpdateShortLinkAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/short-link/{id}/data": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "可查询短链接某个日期范围内的访问数据", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "短链接" + ], + "summary": "短链接访问数据", + "parameters": [ + { + "type": "string", + "description": "短链接 ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "开始日期 YYYY-mm-dd", + "name": "startDate", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "结束日期 YYYY-mm-dd", + "name": "endDate", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/ShortLinkDataAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/user/change-password": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "修改账号密码", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "账号" + ], + "summary": "修改账号密码", + "parameters": [ + { + "description": "修改密码请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ChangePasswordAPIRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/Response" + } + }, + "401": { + "description": "" + } + } + } + }, + "/user/info": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取账号信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "账号" + ], + "summary": "获取账号信息", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/GetUserInfoAPIResponseData" + } + } + } + ] + } + }, + "401": { + "description": "" + } + } + } + }, + "/user/login": { + "post": { + "description": "账号密码登入", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "账号" + ], + "summary": "账号登入", + "parameters": [ + { + "description": "登入请求", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/LoginAPIRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/LoginAPIResponseData" + } + } + } + ] + } + } + } + } + }, + "/user/logout": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "登出", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "账号" + ], + "summary": "登出", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/Response" + } + }, + "401": { + "description": "" + } + } + } + } + }, + "definitions": { + "ChangePasswordAPIRequest": { + "type": "object", + "properties": { + "newPassword": { + "description": "新密码", + "type": "string" + }, + "password": { + "description": "原密码", + "type": "string" + } + } + }, + "CreateShortLinkAPIRequest": { + "type": "object", + "properties": { + "description": { + "description": "描述", + "type": "string", + "example": "Jump Jump project" + }, + "id": { + "description": "只有管理员可以在创建的时候指定 ID", + "type": "string", + "format": "string", + "example": "RANDOM_ID" + }, + "idLength": { + "description": "短链接 ID 长度", + "type": "integer", + "format": "int", + "example": 4 + }, + "isEnable": { + "description": "是否启用", + "type": "boolean", + "format": "boolean", + "example": true + }, + "url": { + "description": "目标链接", + "type": "string", + "example": "https://github.com/jwma/jump-jump" + } + } + }, + "CreateShortLinkAPIResponseData": { + "type": "object", + "properties": { + "shortLink": { + "$ref": "#/definitions/ShortLinkData" + } + } + }, + "GetConfigAPIResponseData": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/SystemConfig" + } + } + }, + "GetShortLinkAPIResponseData": { + "type": "object", + "properties": { + "shortLink": { + "$ref": "#/definitions/ShortLinkData" + } + } + }, + "GetUserInfoAPIResponseData": { + "type": "object", + "properties": { + "role": { + "description": "角色,1 普通用户 | 2 管理员", + "type": "integer", + "enum": [ + 1, + 2 + ], + "example": 1 + }, + "username": { + "description": "用户名", + "type": "string", + "example": "admin" + } + } + }, + "IdConfig": { + "type": "object", + "properties": { + "idLength": { + "description": "ID 长度", + "type": "integer", + "format": "int", + "example": 6 + }, + "idMaximumLength": { + "description": "最大 ID 长度", + "type": "integer", + "format": "int", + "example": 10 + }, + "idMinimumLength": { + "description": "最小 ID 长度", + "type": "integer", + "format": "int", + "example": 2 + } + } + }, + "ListShortLinksAPIResponseData": { + "type": "object", + "properties": { + "shortLinks": { + "type": "array", + "items": { + "$ref": "#/definitions/ShortLinkData" + } + }, + "total": { + "type": "integer", + "format": "10", + "example": 10 + } + } + }, + "LoginAPIRequest": { + "type": "object", + "required": [ + "password", + "username" + ], + "properties": { + "password": { + "description": "密码", + "type": "string", + "example": "your_password" + }, + "username": { + "description": "用户名", + "type": "string", + "example": "your_username" + } + } + }, + "LoginAPIResponseData": { + "type": "object", + "properties": { + "token": { + "description": "json web token", + "type": "string", + "example": "xxx.xxx.xxx" + } + } + }, + "RequestHistory": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "time": { + "type": "string" + }, + "ua": { + "type": "string" + }, + "url": { + "description": "由于短链接的目标连接可能会被修改,可以在访问历史记录中记录一下当前的目标连接", + "type": "string" + } + } + }, + "Response": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int", + "default": 0, + "example": 0 + }, + "data": { + "type": "object" + }, + "msg": { + "type": "string", + "default": "ok", + "example": "ok" + } + } + }, + "ShortLinkData": { + "type": "object", + "properties": { + "createTime": { + "description": "创建时间", + "type": "string" + }, + "createdBy": { + "description": "创建者", + "type": "string", + "format": "string", + "example": "admin" + }, + "description": { + "description": "描述", + "type": "string", + "format": "string", + "example": "Jump Jump project" + }, + "id": { + "type": "string", + "format": "string", + "example": "RANDOM_ID" + }, + "isEnable": { + "description": "是否启用", + "type": "boolean", + "format": "boolean", + "example": true + }, + "updateTime": { + "description": "最后更新时间", + "type": "string" + }, + "url": { + "description": "目标链接", + "type": "string", + "format": "string", + "example": "https://github.com/jwma/jump-jump" + } + } + }, + "ShortLinkDataAPIResponseData": { + "type": "object", + "properties": { + "histories": { + "type": "array", + "items": { + "$ref": "#/definitions/RequestHistory" + } + } + } + }, + "ShortLinkNotFoundConfig": { + "type": "object", + "required": [ + "mode", + "value" + ], + "properties": { + "mode": { + "description": "模式", + "type": "string", + "enum": [ + "content", + "redirect" + ], + "example": "content" + }, + "value": { + "description": "值", + "type": "string", + "example": "page not found" + } + } + }, + "SystemConfig": { + "type": "object", + "properties": { + "idConfig": { + "description": "ID 配置", + "$ref": "#/definitions/IdConfig" + }, + "landingHosts": { + "description": "落地页 Host 列表", + "type": "array", + "format": "array", + "items": { + "type": "string" + }, + "example": [ + "https://a.com/", + "https://b.com/" + ] + }, + "shortLinkNotFoundConfig": { + "description": "短链接 404 配置", + "$ref": "#/definitions/ShortLinkNotFoundConfig" + } + } + }, + "UpdateLandingHostsAPIRequest": { + "type": "object", + "properties": { + "hosts": { + "type": "array", + "format": "array", + "items": { + "type": "string" + }, + "example": [ + "https://a.com/", + "https://b.com/" + ] + } + } + }, + "UpdateShortLinkAPIRequest": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "description": { + "description": "描述", + "type": "string", + "example": "Jump Jump project" + }, + "isEnable": { + "description": "是否启用", + "type": "boolean", + "format": "boolean", + "example": true + }, + "url": { + "description": "目标链接", + "type": "string", + "example": "https://github.com/jwma/jump-jump" + } + } + }, + "UpdateShortLinkAPIResponseData": { + "type": "object", + "properties": { + "shortLink": { + "$ref": "#/definitions/ShortLinkData" + } + } + } + }, + "securityDefinitions": { + "ApiKeyAuth": { + "type": "apiKey", + "name": "Authorization", + "in": "header" + } + } +} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml new file mode 100644 index 0000000..882bbfa --- /dev/null +++ b/docs/swagger.yaml @@ -0,0 +1,672 @@ +definitions: + ChangePasswordAPIRequest: + properties: + newPassword: + description: 新密码 + type: string + password: + description: 原密码 + type: string + type: object + CreateShortLinkAPIRequest: + properties: + description: + description: 描述 + example: Jump Jump project + type: string + id: + description: 只有管理员可以在创建的时候指定 ID + example: RANDOM_ID + format: string + type: string + idLength: + description: 短链接 ID 长度 + example: 4 + format: int + type: integer + isEnable: + description: 是否启用 + example: true + format: boolean + type: boolean + url: + description: 目标链接 + example: https://github.com/jwma/jump-jump + type: string + type: object + CreateShortLinkAPIResponseData: + properties: + shortLink: + $ref: '#/definitions/ShortLinkData' + type: object + GetConfigAPIResponseData: + properties: + config: + $ref: '#/definitions/SystemConfig' + type: object + GetShortLinkAPIResponseData: + properties: + shortLink: + $ref: '#/definitions/ShortLinkData' + type: object + GetUserInfoAPIResponseData: + properties: + role: + description: 角色,1 普通用户 | 2 管理员 + enum: + - 1 + - 2 + example: 1 + type: integer + username: + description: 用户名 + example: admin + type: string + type: object + IdConfig: + properties: + idLength: + description: ID 长度 + example: 6 + format: int + type: integer + idMaximumLength: + description: 最大 ID 长度 + example: 10 + format: int + type: integer + idMinimumLength: + description: 最小 ID 长度 + example: 2 + format: int + type: integer + type: object + ListShortLinksAPIResponseData: + properties: + shortLinks: + items: + $ref: '#/definitions/ShortLinkData' + type: array + total: + example: 10 + format: "10" + type: integer + type: object + LoginAPIRequest: + properties: + password: + description: 密码 + example: your_password + type: string + username: + description: 用户名 + example: your_username + type: string + required: + - password + - username + type: object + LoginAPIResponseData: + properties: + token: + description: json web token + example: xxx.xxx.xxx + type: string + type: object + RequestHistory: + properties: + id: + type: string + ip: + type: string + time: + type: string + ua: + type: string + url: + description: 由于短链接的目标连接可能会被修改,可以在访问历史记录中记录一下当前的目标连接 + type: string + type: object + Response: + properties: + code: + default: 0 + example: 0 + format: int + type: integer + data: + type: object + msg: + default: ok + example: ok + type: string + type: object + ShortLinkData: + properties: + createTime: + description: 创建时间 + type: string + createdBy: + description: 创建者 + example: admin + format: string + type: string + description: + description: 描述 + example: Jump Jump project + format: string + type: string + id: + example: RANDOM_ID + format: string + type: string + isEnable: + description: 是否启用 + example: true + format: boolean + type: boolean + updateTime: + description: 最后更新时间 + type: string + url: + description: 目标链接 + example: https://github.com/jwma/jump-jump + format: string + type: string + type: object + ShortLinkDataAPIResponseData: + properties: + histories: + items: + $ref: '#/definitions/RequestHistory' + type: array + type: object + ShortLinkNotFoundConfig: + properties: + mode: + description: 模式 + enum: + - content + - redirect + example: content + type: string + value: + description: 值 + example: page not found + type: string + required: + - mode + - value + type: object + SystemConfig: + properties: + idConfig: + $ref: '#/definitions/IdConfig' + description: ID 配置 + landingHosts: + description: 落地页 Host 列表 + example: + - https://a.com/ + - https://b.com/ + format: array + items: + type: string + type: array + shortLinkNotFoundConfig: + $ref: '#/definitions/ShortLinkNotFoundConfig' + description: 短链接 404 配置 + type: object + UpdateLandingHostsAPIRequest: + properties: + hosts: + example: + - https://a.com/ + - https://b.com/ + format: array + items: + type: string + type: array + type: object + UpdateShortLinkAPIRequest: + properties: + description: + description: 描述 + example: Jump Jump project + type: string + isEnable: + description: 是否启用 + example: true + format: boolean + type: boolean + url: + description: 目标链接 + example: https://github.com/jwma/jump-jump + type: string + required: + - url + type: object + UpdateShortLinkAPIResponseData: + properties: + shortLink: + $ref: '#/definitions/ShortLinkData' + type: object +info: + contact: + email: m.mjw.ma@gmail.com + name: MJ Ma + url: https://www.linkedin.com/in/mj-profile/ + license: + name: MIT + url: https://github.com/jwma/jump-jump/blob/master/LICENSE +paths: + /config: + get: + consumes: + - application/json + description: 获取系统配置信息 + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/Response' + - properties: + data: + $ref: '#/definitions/GetConfigAPIResponseData' + type: object + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 获取系统配置信息 + tags: + - 系统配置 + /config/id-length: + patch: + consumes: + - application/json + description: 更新短链接 ID 设置 + parameters: + - description: 更新短链接 ID 设置请求 + in: body + name: body + required: true + schema: + $ref: '#/definitions/IdConfig' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/Response' + - properties: + data: + $ref: '#/definitions/GetConfigAPIResponseData' + type: object + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 更新短链接 ID 设置 + tags: + - 系统配置 + /config/landing-hosts: + patch: + consumes: + - application/json + description: 更新落地页 Hosts + parameters: + - description: 更新落地页 Hosts 请求 + in: body + name: body + required: true + schema: + $ref: '#/definitions/UpdateLandingHostsAPIRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/Response' + - properties: + data: + $ref: '#/definitions/GetConfigAPIResponseData' + type: object + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 更新落地页 Hosts + tags: + - 系统配置 + /config/short-link-404-handling: + patch: + consumes: + - application/json + description: 更新短链接 404 设置 + parameters: + - description: 更新短链接 404 设置请求 + in: body + name: body + required: true + schema: + $ref: '#/definitions/ShortLinkNotFoundConfig' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/Response' + - properties: + data: + $ref: '#/definitions/GetConfigAPIResponseData' + type: object + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 更新短链接 404 设置 + tags: + - 系统配置 + /short-link/: + get: + consumes: + - application/json + description: 短链接列表 + parameters: + - description: 页码 + in: query + name: page + type: integer + - description: 每页条数 + in: query + name: pageSize + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/Response' + - properties: + data: + $ref: '#/definitions/ListShortLinksAPIResponseData' + type: object + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 短链接列表 + tags: + - 短链接 + post: + consumes: + - application/json + description: 创建短链接 + parameters: + - description: 创建短链接请求 + in: body + name: body + required: true + schema: + $ref: '#/definitions/CreateShortLinkAPIRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/Response' + - properties: + data: + $ref: '#/definitions/CreateShortLinkAPIResponseData' + type: object + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 创建短链接 + tags: + - 短链接 + /short-link/{id}: + delete: + consumes: + - application/json + description: 删除短链接 + parameters: + - description: 短链接 ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/Response' + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 删除短链接 + tags: + - 短链接 + get: + consumes: + - application/json + description: 获取系统配置信息 + parameters: + - description: 短链接 ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/Response' + - properties: + data: + $ref: '#/definitions/GetShortLinkAPIResponseData' + type: object + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 获取指定 ID 短链接 + tags: + - 短链接 + patch: + consumes: + - application/json + description: 更新短链接 + parameters: + - description: 短链接 ID + in: path + name: id + required: true + type: string + - description: 更新短链接请求 + in: body + name: body + required: true + schema: + $ref: '#/definitions/UpdateShortLinkAPIRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/Response' + - properties: + data: + $ref: '#/definitions/UpdateShortLinkAPIResponseData' + type: object + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 更新短链接 + tags: + - 短链接 + /short-link/{id}/data: + get: + consumes: + - application/json + description: 可查询短链接某个日期范围内的访问数据 + parameters: + - description: 短链接 ID + in: path + name: id + required: true + type: string + - description: 开始日期 YYYY-mm-dd + in: query + name: startDate + required: true + type: string + - description: 结束日期 YYYY-mm-dd + in: query + name: endDate + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/Response' + - properties: + data: + $ref: '#/definitions/ShortLinkDataAPIResponseData' + type: object + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 短链接访问数据 + tags: + - 短链接 + /user/change-password: + post: + consumes: + - application/json + description: 修改账号密码 + parameters: + - description: 修改密码请求 + in: body + name: body + required: true + schema: + $ref: '#/definitions/ChangePasswordAPIRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/Response' + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 修改账号密码 + tags: + - 账号 + /user/info: + get: + consumes: + - application/json + description: 获取账号信息 + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/Response' + - properties: + data: + $ref: '#/definitions/GetUserInfoAPIResponseData' + type: object + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 获取账号信息 + tags: + - 账号 + /user/login: + post: + consumes: + - application/json + description: 账号密码登入 + parameters: + - description: 登入请求 + in: body + name: body + required: true + schema: + $ref: '#/definitions/LoginAPIRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/Response' + - properties: + data: + $ref: '#/definitions/LoginAPIResponseData' + type: object + summary: 账号登入 + tags: + - 账号 + /user/logout: + post: + consumes: + - application/json + description: 登出 + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/Response' + "401": + description: "" + security: + - ApiKeyAuth: [] + summary: 登出 + tags: + - 账号 +securityDefinitions: + ApiKeyAuth: + in: header + name: Authorization + type: apiKey +swagger: "2.0" diff --git a/go.mod b/go.mod index a1fb12b..d79438e 100644 --- a/go.mod +++ b/go.mod @@ -3,26 +3,29 @@ module github.com/jwma/jump-jump go 1.13 require ( + github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/gin-contrib/cors v1.3.1 - github.com/gin-gonic/gin v1.5.0 - github.com/go-playground/universal-translator v0.17.0 // indirect + github.com/gin-gonic/gin v1.6.3 + github.com/go-openapi/spec v0.20.3 // indirect + github.com/go-playground/validator/v10 v10.4.1 // indirect github.com/go-redis/redis v6.15.7+incompatible - github.com/golang/protobuf v1.3.3 // indirect - github.com/json-iterator/go v1.1.9 // indirect + github.com/golang/protobuf v1.4.3 // indirect + github.com/json-iterator/go v1.1.10 // indirect github.com/jwma/reborn v0.0.0-20200326132007-2fa07c258aec - github.com/leodido/go-urn v1.2.0 // indirect - github.com/mattn/go-isatty v0.0.12 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mssola/user_agent v0.5.2 github.com/onsi/ginkgo v1.12.0 // indirect github.com/onsi/gomega v1.9.0 // indirect + github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 + github.com/swaggo/gin-swagger v1.3.0 + github.com/swaggo/swag v1.7.0 github.com/thoas/go-funk v0.6.0 - golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d - golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect - golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c // indirect - golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect - gopkg.in/go-playground/validator.v9 v9.31.0 // indirect - gopkg.in/yaml.v2 v2.2.8 // indirect + github.com/ugorji/go v1.2.4 // indirect + golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b + golang.org/x/net v0.0.0-20210315170653-34ac3e1c2000 // indirect + golang.org/x/sys v0.0.0-20210316092937-0b90fd5c4c48 // indirect + golang.org/x/tools v0.1.0 // indirect + google.golang.org/protobuf v1.25.0 // indirect ) diff --git a/go.sum b/go.sum index 661d39e..e16bba1 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,68 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA= github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk= +github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc= +github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w= +github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/gin-gonic/gin v1.5.0 h1:fi+bqFAx/oLK54somfCtEZs9HeH1LHVoEPUgARpTqyc= github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.4 h1:3Vw+rh13uq2JFNxgnMTGE1rnoieU9FmyE1gvnyylsYg= +github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.14 h1:r4fbYFo6N4ZelmSX8G6p+cv/hZRXzcuqQIADGT1iNKM= +github.com/go-openapi/spec v0.19.14/go.mod h1:gwrgJS15eCUgjLpMjBJmbZezCsw88LmgeEip0M63doA= +github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ= +github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.11 h1:RFTu/dlFySpyVvJDfp/7674JY4SDglYWKztbiIGFpmc= +github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY= +github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc= github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= @@ -19,20 +71,47 @@ github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rm github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-redis/redis v6.15.7+incompatible h1:3skhDh95XQMpnqeqNftPkQD9jL9e5e36z/1SUm6dy1U= github.com/go-redis/redis v6.15.7+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jwma/reborn v0.0.0-20200326132007-2fa07c258aec h1:bfzlqMldSDAEG6ZDo7Y3iOu1H216vUIAcZjz2eH+kOY= github.com/jwma/reborn v0.0.0-20200326132007-2fa07c258aec/go.mod h1:tshy8uF9ZnJaltJqDX9F/hSe6AeCf8CKbt6OO/rwxHE= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -40,10 +119,24 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= @@ -58,64 +151,183 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mssola/user_agent v0.5.2 h1:CZkTUahjL1+OcZ5zv3kZr8QiJ8jy2H08vZIEkBeRbxo= github.com/mssola/user_agent v0.5.2/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM= +github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= +github.com/swaggo/gin-swagger v1.3.0 h1:eOmp7r57oUgZPw2dJOjcGNMse9cvXcI4tTqBcnZtPsI= +github.com/swaggo/gin-swagger v1.3.0/go.mod h1:oy1BRA6WvgtCp848lhxce7BnWH4C8Bxa0m5SkWx+cS0= +github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y= +github.com/swaggo/swag v1.7.0 h1:5bCA/MTLQoIqDXXyHfOpMeDvL9j68OY/udlK4pQoo4E= +github.com/swaggo/swag v1.7.0/go.mod h1:BdPIL73gvS9NBsdi7M1JOxLvlbfvNRaBP8m6WT6Aajo= github.com/thoas/go-funk v0.6.0 h1:ryxN0pa9FnI7YHgODdLIZ4T6paCZJt8od6N9oRztMxM= github.com/thoas/go-funk v0.6.0/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= +github.com/ugorji/go v1.2.4 h1:cTciPbZ/VSOzCLKclmssnfQ/jyoVyOcJ3aoJyUV1Urc= +github.com/ugorji/go v1.2.4/go.mod h1:EuaSCk8iZMdIspsu6HXH7X2UGKw1ezO4wCfGszGmmo4= +github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= +github.com/ugorji/go/codec v1.2.4 h1:C5VurWRRCKjuENsbM6GYVw8W++WVW9rSxoACKIvxzz8= +github.com/ugorji/go/codec v1.2.4/go.mod h1:bWBu1+kIRWcF8uMklKaJrR6fTWQOwAlrIzX22pHwryA= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b h1:wSOdpTq0/eI46Ez/LkDwIsAKA71YP2SRKBODiRWM0as= +golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210315170653-34ac3e1c2000 h1:6mqyFav9MzRNys8OnKlbKYSJxsoVvhb773Si3bu5fYE= +golang.org/x/net v0.0.0-20210315170653-34ac3e1c2000/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c h1:jceGD5YNJGgGMkJz79agzOln1K9TaZUjv5ird16qniQ= -golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316092937-0b90fd5c4c48 h1:70qalHWW1n9yoI8B8zEQxFJO/D6NUWIX8SNmJO+rvNw= +golang.org/x/sys v0.0.0-20210316092937-0b90fd5c4c48/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e h1:t96dS3DO8DGjawSLJL/HIdz8CycAd2v07XxqB3UPTi0= +golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc= gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= -gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= -gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/app/config/config.go b/internal/app/config/config.go index ce1df39..fda32f8 100644 --- a/internal/app/config/config.go +++ b/internal/app/config/config.go @@ -13,6 +13,51 @@ const ( ShortLinkNotFoundRedirectMode = "redirect" ) +type IdConfig struct { + // ID 长度 + IdLength int `json:"idLength" format:"int" example:"6"` + + // 最小 ID 长度 + IdMinimumLength int `json:"idMinimumLength" format:"int" example:"2"` + + // 最大 ID 长度 + IdMaximumLength int `json:"idMaximumLength" format:"int" example:"10"` +} // @name IdConfig + +type ShortLinkNotFoundConfig struct { + // 模式 + Mode string `json:"mode" binding:"required" example:"content" enums:"content,redirect"` + + // 值 + Value string `json:"value" binding:"required" example:"page not found"` +} // @name ShortLinkNotFoundConfig + +func (s *ShortLinkNotFoundConfig) ToMap() map[string]string { + return map[string]string{ + "mode": s.Mode, + "value": s.Value, + } +} + +type SystemConfig struct { + // 落地页 Host 列表 + LandingHosts []string `json:"landingHosts" format:"array" example:"https://a.com/,https://b.com/"` + + // ID 配置 + IdConfig *IdConfig `json:"idConfig"` + + // 短链接 404 配置 + ShortLinkNotFoundConfig *ShortLinkNotFoundConfig `json:"shortLinkNotFoundConfig"` +} // @name SystemConfig + +func GetIdConfig() *IdConfig { + return &IdConfig{ + IdLength: config.GetIntValue("idLength", 6), + IdMinimumLength: config.GetIntValue("idMinimumLength", 2), + IdMaximumLength: config.GetIntValue("idMaximumLength", 10), + } +} + func GetDefaultShortLinkNotFoundConfig() map[string]string { return map[string]string{ "mode": ShortLinkNotFoundContentMode, @@ -20,13 +65,40 @@ func GetDefaultShortLinkNotFoundConfig() map[string]string { } } -func NewShortLinkNotFoundConfig(mode string, value string) map[string]string { - return map[string]string{ - "mode": mode, - "value": value, +func GetShortLinkNotFoundConfig() *ShortLinkNotFoundConfig { + c := config.GetStringStringMapValue("shortLinkNotFoundConfig", GetDefaultShortLinkNotFoundConfig()) + + return &ShortLinkNotFoundConfig{ + Mode: c["mode"], + Value: c["value"], + } +} + +func GetSystemConfig() *SystemConfig { + return &SystemConfig{ + LandingHosts: config.GetStringSliceValue("landingHosts", make([]string, 0)), + IdConfig: GetIdConfig(), + ShortLinkNotFoundConfig: GetShortLinkNotFoundConfig(), } } +func UpdateLandingHosts(hosts []string) { + config.SetValue("landingHosts", hosts) + config.Persist() +} + +func UpdateIdConfig(c *IdConfig) { + config.SetValue("idMinimumLength", c.IdMinimumLength) + config.SetValue("idLength", c.IdLength) + config.SetValue("idMaximumLength", c.IdMaximumLength) + config.Persist() +} + +func UpdateShortLinkNotFoundConfig(s *ShortLinkNotFoundConfig) { + config.SetValue("shortLinkNotFoundConfig", s.ToMap()) + config.Persist() +} + func getDefaultConfig() *reborn.Config { d := reborn.NewConfig() d.SetValue("landingHosts", []string{"http://127.0.0.1:8081/"}) diff --git a/internal/app/handlers/config.go b/internal/app/handlers/config.go index b131928..a399b8e 100644 --- a/internal/app/handlers/config.go +++ b/internal/app/handlers/config.go @@ -8,181 +8,115 @@ import ( "net/http" ) -func GetConfig(c *gin.Context) { - cfg := config.GetConfig() - landingHosts := cfg.GetStringSliceValue("landingHosts", make([]string, 0)) - idMinimumLength := cfg.GetIntValue("idMinimumLength", 2) - idLength := cfg.GetIntValue("idLength", 6) - idMaximumLength := cfg.GetIntValue("idMaximumLength", 10) - shortLinkNotFoundConfig := cfg.GetStringStringMapValue("shortLinkNotFoundConfig", - config.GetDefaultShortLinkNotFoundConfig()) - - c.JSON(http.StatusOK, gin.H{ - "msg": "ok", - "code": 0, - "data": gin.H{ - "config": gin.H{ - "landingHosts": landingHosts, - "idConfig": gin.H{ - "idMinimumLength": idMinimumLength, - "idLength": idLength, - "idMaximumLength": idMaximumLength, - }, - "shortLinkNotFoundConfig": shortLinkNotFoundConfig, - }, - }, - }) -} - -type LandingHostsParameter struct { - Hosts []string `json:"hosts"` +// GetConfigAPI godoc +// @Security ApiKeyAuth +// @Summary 获取系统配置信息 +// @Description 获取系统配置信息 +// @Tags 系统配置 +// @Accept json +// @Produce json +// @Success 200 {object} models.Response{data=models.GetConfigAPIResponseData} +// @Failure 401 +// @Router /config [get] +func GetConfigAPI(c *gin.Context) { + c.JSON(http.StatusOK, models.NewSuccessResponse(models.GetConfigAPIResponseData{Config: config.GetSystemConfig()})) } +// UpdateLandingHostsAPI godoc +// @Security ApiKeyAuth +// @Summary 更新落地页 Hosts +// @Description 更新落地页 Hosts +// @Tags 系统配置 +// @Accept json +// @Produce json +// @Param body body models.UpdateLandingHostsAPIRequest true "更新落地页 Hosts 请求" +// @Success 200 {object} models.Response{data=models.GetConfigAPIResponseData} +// @Failure 401 +// @Router /config/landing-hosts [patch] func UpdateLandingHostsAPI() gin.HandlerFunc { return Authenticator(func(c *gin.Context, user *models.User) { if user.Role != models.RoleAdmin { - c.JSON(http.StatusOK, gin.H{ - "msg": "你无权修改短链接域名", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("你无权修改短链接域名")) return } - p := &LandingHostsParameter{} + p := &models.UpdateLandingHostsAPIRequest{} if err := c.ShouldBindJSON(p); err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) return } - cfg := config.GetConfig() - cfg.SetValue("landingHosts", p.Hosts) - cfg.Persist() - - c.JSON(http.StatusOK, gin.H{ - "msg": "", - "code": 0, - "data": gin.H{ - "config": gin.H{"landingHosts": cfg.GetStringSliceValue("landingHosts", make([]string, 0))}, - }, - }) + config.UpdateLandingHosts(p.Hosts) // 更新 + c.JSON(http.StatusOK, models.NewSuccessResponse(models.GetConfigAPIResponseData{Config: config.GetSystemConfig()})) }) } -type idLengthParameter struct { - IdMinimumLength int `json:"idMinimumLength"` - IdLength int `json:"idLength"` - IdMaximumLength int `json:"idMaximumLength"` -} - +// UpdateIdLengthConfigAPI godoc +// @Security ApiKeyAuth +// @Summary 更新短链接 ID 设置 +// @Description 更新短链接 ID 设置 +// @Tags 系统配置 +// @Accept json +// @Produce json +// @Param body body config.IdConfig true "更新短链接 ID 设置请求" +// @Success 200 {object} models.Response{data=models.GetConfigAPIResponseData} +// @Failure 401 +// @Router /config/id-length [patch] func UpdateIdLengthConfigAPI() gin.HandlerFunc { return Authenticator(func(c *gin.Context, user *models.User) { if user.Role != models.RoleAdmin { - c.JSON(http.StatusOK, gin.H{ - "msg": "你无权修改随机 ID 长度设置", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("你无权修改随机 ID 长度设置")) return } - p := &idLengthParameter{} - + p := &config.IdConfig{} if err := c.ShouldBindJSON(p); err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) return } if p.IdMinimumLength <= p.IdLength && p.IdLength <= p.IdMaximumLength && p.IdMinimumLength > 0 && p.IdLength > 0 && p.IdMaximumLength > 0 { - cfg := config.GetConfig() - cfg.SetValue("idMinimumLength", p.IdMinimumLength) - cfg.SetValue("idLength", p.IdLength) - cfg.SetValue("idMaximumLength", p.IdMaximumLength) - cfg.Persist() - - c.JSON(http.StatusOK, gin.H{ - "msg": "", - "code": 0, - "data": gin.H{ - "config": gin.H{ - "idConfig": gin.H{ - "idMinimumLength": p.IdMinimumLength, - "idLength": p.IdLength, - "idMaximumLength": p.IdMaximumLength, - }, - }, - }, - }) + config.UpdateIdConfig(p) + c.JSON(http.StatusOK, models.NewSuccessResponse(models.GetConfigAPIResponseData{Config: config.GetSystemConfig()})) return } - c.JSON(http.StatusOK, gin.H{ - "msg": "最小长度 <= 默认长度 <= 最大长度,三个值均大于 0", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("最小长度 <= 默认长度 <= 最大长度,三个值均大于 0")) }) } -type shortLinkNotFoundConfigParameter struct { - Mode string `json:"mode" binding:"required"` - Value string `json:"value" binding:"required"` -} - +// UpdateShortLinkNotFoundConfigAPI godoc +// @Security ApiKeyAuth +// @Summary 更新短链接 404 设置 +// @Description 更新短链接 404 设置 +// @Tags 系统配置 +// @Accept json +// @Produce json +// @Param body body config.ShortLinkNotFoundConfig true "更新短链接 404 设置请求" +// @Success 200 {object} models.Response{data=models.GetConfigAPIResponseData} +// @Failure 401 +// @Router /config/short-link-404-handling [patch] func UpdateShortLinkNotFoundConfigAPI() gin.HandlerFunc { return Authenticator(func(c *gin.Context, user *models.User) { if user.Role != models.RoleAdmin { - c.JSON(http.StatusOK, gin.H{ - "msg": "你无权修改短链接 404 处理配置", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("你无权修改短链接 404 处理配置")) return } - p := &shortLinkNotFoundConfigParameter{} - + p := &config.ShortLinkNotFoundConfig{} if err := c.ShouldBindJSON(p); err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) return } if !funk.ContainsString([]string{config.ShortLinkNotFoundContentMode, config.ShortLinkNotFoundRedirectMode}, p.Mode) { - c.JSON(http.StatusOK, gin.H{ - "msg": "处理模式参数不正确", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("处理模式参数不正确")) return } - cc := config.NewShortLinkNotFoundConfig(p.Mode, p.Value) - cfg := config.GetConfig() - cfg.SetValue("shortLinkNotFoundConfig", cc) - cfg.Persist() - - c.JSON(http.StatusOK, gin.H{ - "msg": "", - "code": 0, - "data": gin.H{ - "config": gin.H{ - "shortLinkNotFoundConfig": cc, - }, - }, - }) + config.UpdateShortLinkNotFoundConfig(p) + c.JSON(http.StatusOK, models.NewSuccessResponse(models.GetConfigAPIResponseData{Config: config.GetSystemConfig()})) }) } diff --git a/internal/app/handlers/shortlink.go b/internal/app/handlers/shortlink.go index 66ca443..ea43b5f 100644 --- a/internal/app/handlers/shortlink.go +++ b/internal/app/handlers/shortlink.go @@ -13,57 +13,62 @@ import ( "time" ) +// GetShortLinkAPI godoc +// @Security ApiKeyAuth +// @Summary 获取指定 ID 短链接 +// @Description 获取系统配置信息 +// @Tags 短链接 +// @Accept json +// @Produce json +// @Param id path string true "短链接 ID" +// @Success 200 {object} models.Response{data=models.GetShortLinkAPIResponseData} +// @Failure 401 +// @Router /short-link/{id} [get] func GetShortLinkAPI() gin.HandlerFunc { return Authenticator(func(c *gin.Context, user *models.User) { slRepo := repository.GetShortLinkRepo(db.GetRedisClient()) s, err := slRepo.Get(c.Param("id")) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) return } if !user.IsAdmin() && user.Username != s.CreatedBy { - c.JSON(http.StatusOK, gin.H{ - "msg": "你无权查看", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("你无权查看")) return } - c.JSON(http.StatusOK, gin.H{ - "msg": "ok", - "code": 0, - "data": gin.H{ - "shortLink": s, - }, - }) + c.JSON(http.StatusOK, models.NewSuccessResponse(&models.GetShortLinkAPIResponseData{ + ShortLinkData: models.ToShortLinkData(s), + })) }) } +// CreateShortLinkAPI godoc +// @Security ApiKeyAuth +// @Summary 创建短链接 +// @Description 创建短链接 +// @Tags 短链接 +// @Accept json +// @Produce json +// @Param body body models.CreateShortLinkAPIRequest true "创建短链接请求" +// @Success 200 {object} models.Response{data=models.CreateShortLinkAPIResponseData} +// @Failure 401 +// @Router /short-link/ [post] func CreateShortLinkAPI() gin.HandlerFunc { return Authenticator(func(c *gin.Context, user *models.User) { var err error - s := &models.ShortLink{CreatedBy: user.Username} - params := &models.CreateShortLinkParameter{} - params.ShortLink = s + params := &models.CreateShortLinkAPIRequest{} if err := c.ShouldBindJSON(¶ms); err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": "参数错误", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("参数错误")) return } + s := models.NewShortLink(user.Username, params) repo := repository.GetShortLinkRepo(db.GetRedisClient()) - cfg := config.GetConfig() - idLen := config.GetConfig().GetIntValue("idLength", 6) + idCfg := config.GetIdConfig() + idLen := idCfg.IdLength if user.Role == models.RoleUser { s.Id = "" // 如果是普通用户,创建时不可以指定 ID @@ -74,19 +79,12 @@ func CreateShortLinkAPI() gin.HandlerFunc { checkShortLink, _ := repo.Get(s.Id) if checkShortLink.Id != "" { - c.JSON(http.StatusOK, gin.H{ - "msg": fmt.Sprintf("%s 已被占用,请使用其他 ID。", s.Id), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(fmt.Sprintf("%s 已被占用,请使用其他 ID。", s.Id))) return } } else { // 如果管理员没有指定 ID,则计算随机 ID 的长度 - idMinimumLength := cfg.GetIntValue("idMinimumLength", 2) - idMaximumLength := cfg.GetIntValue("idMaximumLength", 10) - - if idMinimumLength <= params.IdLength && params.IdLength <= idMaximumLength { // 检查是否在合法的范围内 + if idCfg.IdMinimumLength <= params.IdLength && params.IdLength <= idCfg.IdMaximumLength { // 检查是否在合法的范围内 idLen = params.IdLength } @@ -94,11 +92,7 @@ func CreateShortLinkAPI() gin.HandlerFunc { if err != nil { log.Printf("generate id failed, error: %v\n", err) - c.JSON(http.StatusOK, gin.H{ - "msg": "服务器繁忙,请稍后再试", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("服务器繁忙,请稍后再试")) return } @@ -107,113 +101,150 @@ func CreateShortLinkAPI() gin.HandlerFunc { if s.Id == "" { log.Println("短链接 ID 为空") - c.JSON(http.StatusOK, gin.H{ - "msg": "ID 错误", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("ID 错误")) } err = repo.Save(s) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) return } - c.JSON(http.StatusOK, gin.H{ - "msg": "ok", - "code": 0, - "data": gin.H{"shortLink": s}, - }) + c.JSON(http.StatusOK, models.NewSuccessResponse(models.CreateShortLinkAPIResponseData{ + ShortLinkData: models.ToShortLinkData(s), + })) }) } +// UpdateShortLinkAPI godoc +// @Security ApiKeyAuth +// @Summary 更新短链接 +// @Description 更新短链接 +// @Tags 短链接 +// @Accept json +// @Produce json +// @Param id path string true "短链接 ID" +// @Param body body models.UpdateShortLinkAPIRequest true "更新短链接请求" +// @Success 200 {object} models.Response{data=models.UpdateShortLinkAPIResponseData} +// @Failure 401 +// @Router /short-link/{id} [patch] func UpdateShortLinkAPI() gin.HandlerFunc { return Authenticator(func(c *gin.Context, user *models.User) { slRepo := repository.GetShortLinkRepo(db.GetRedisClient()) s, err := slRepo.Get(c.Param("id")) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) return } if !user.IsAdmin() && user.Username != s.CreatedBy { - c.JSON(http.StatusOK, gin.H{ - "msg": "你无权修改", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("你无权修改此短链接")) return } - updateShortLink := &models.UpdateShortLinkParameter{} + updateShortLink := &models.UpdateShortLinkAPIRequest{} if err := c.ShouldBindJSON(updateShortLink); err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) return } repo := repository.GetShortLinkRepo(db.GetRedisClient()) err = repo.Update(s, updateShortLink) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) + return } - c.JSON(http.StatusOK, gin.H{ - "msg": "ok", - "code": 0, - "data": gin.H{"shortLink": s}, - }) + c.JSON(http.StatusOK, models.NewSuccessResponse(models.UpdateShortLinkAPIResponseData{ + ShortLinkData: models.ToShortLinkData(s), + })) }) } +// DeleteShortLinkAPI godoc +// @Security ApiKeyAuth +// @Summary 删除短链接 +// @Description 删除短链接 +// @Tags 短链接 +// @Accept json +// @Produce json +// @Param id path string true "短链接 ID" +// @Success 200 {object} models.Response +// @Failure 401 +// @Router /short-link/{id} [delete] func DeleteShortLinkAPI() gin.HandlerFunc { return Authenticator(func(c *gin.Context, user *models.User) { slRepo := repository.GetShortLinkRepo(db.GetRedisClient()) s, err := slRepo.Get(c.Param("id")) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) return } if !user.IsAdmin() && user.Username != s.CreatedBy { - c.JSON(http.StatusOK, gin.H{ - "msg": "你无权修改", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("你无权删除此短链接")) return } repo := repository.GetShortLinkRepo(db.GetRedisClient()) repo.Delete(s) - c.JSON(http.StatusOK, gin.H{ - "msg": "ok", - "code": 0, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewSuccessResponse(nil)) }) } +// ListShortLinksAPI godoc +// @Security ApiKeyAuth +// @Summary 短链接列表 +// @Description 短链接列表 +// @Tags 短链接 +// @Accept json +// @Produce json +// @Param page query int false "页码" +// @Param pageSize query int false "每页条数" +// @Success 200 {object} models.Response{data=models.ListShortLinksAPIResponseData} +// @Failure 401 +// @Router /short-link/ [get] +func ListShortLinksAPI() gin.HandlerFunc { + return Authenticator(func(c *gin.Context, user *models.User) { + var page = utils.GetIntQueryValue(c, "page", 1) + var pageSize = utils.GetIntQueryValue(c, "pageSize", 20) + start := int64((page - 1) * pageSize) + stop := start - 1 + int64(pageSize) + + var key string + if user.IsAdmin() { + key = utils.GetShortLinksKey() + } else { + key = utils.GetUserShortLinksKey(user.Username) + } + + slRepo := repository.GetShortLinkRepo(db.GetRedisClient()) + result, err := slRepo.List(key, start, stop) + if err != nil { + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) + return + } + + c.JSON(http.StatusOK, models.NewSuccessResponse(&models.ListShortLinksAPIResponseData{ + ShortLinks: models.ToShortLinkDataSlice(result.ShortLinks), + Total: result.Total, + })) + }) +} + +// ShortLinkDataAPI godoc +// @Security ApiKeyAuth +// @Summary 短链接访问数据 +// @Description 可查询短链接某个日期范围内的访问数据 +// @Tags 短链接 +// @Accept json +// @Produce json +// @Param id path string true "短链接 ID" +// @Param startDate query string true "开始日期 YYYY-mm-dd" +// @Param endDate query string true "结束日期 YYYY-mm-dd" +// @Success 200 {object} models.Response{data=models.ShortLinkDataAPIResponseData} +// @Failure 401 +// @Router /short-link/{id}/data [get] func ShortLinkActionAPI() gin.HandlerFunc { return Authenticator(func(c *gin.Context, user *models.User) { @@ -222,20 +253,12 @@ func ShortLinkActionAPI() gin.HandlerFunc { s, err := slRepo.Get(c.Param("id")) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) return } if !user.IsAdmin() && user.Username != s.CreatedBy { - c.JSON(http.StatusOK, gin.H{ - "msg": "你无权查看", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("你无权查看")) return } @@ -243,11 +266,7 @@ func ShortLinkActionAPI() gin.HandlerFunc { endDate := c.Query("endDate") if startDate == "" || endDate == "" { - c.JSON(http.StatusOK, gin.H{ - "msg": "参数错误", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("参数错误")) return } @@ -255,11 +274,7 @@ func ShortLinkActionAPI() gin.HandlerFunc { endTime, err := time.ParseInLocation("2006-01-02", endDate, time.Local) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": "日期参数错误", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("日期参数错误")) return } @@ -267,98 +282,13 @@ func ShortLinkActionAPI() gin.HandlerFunc { rhRepo := repository.GetRequestHistoryRepo(db.GetRedisClient()) rhs := rhRepo.FindByDateRange(s.Id, startTime, endTime) - c.JSON(http.StatusOK, gin.H{ - "msg": "ok", - "code": 0, - "data": gin.H{ - "histories": rhs, - }, - }) - return - } else if c.Param("action") == "/latest-request-history" { - slRepo := repository.GetShortLinkRepo(db.GetRedisClient()) - s, err := slRepo.Get(c.Param("id")) - - if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) - return - } - - if !user.IsAdmin() && user.Username != s.CreatedBy { - c.JSON(http.StatusOK, gin.H{ - "msg": "你无权查看", - "code": 4999, - "data": nil, - }) - return - } - - repo := repository.GetRequestHistoryRepo(db.GetRedisClient()) - size := utils.GetIntQueryValue(c, "size", 20) - - r, err := repo.FindLatest(s.Id, int64(size)) - - if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) - return - } - - c.JSON(http.StatusOK, gin.H{ - "msg": "ok", - "code": 0, - "data": r, - }) + c.JSON(http.StatusOK, models.NewSuccessResponse(&models.ShortLinkDataAPIResponseData{Histories: rhs})) return } else if c.Param("action") == "/" { GetShortLinkAPI()(c) return } - c.JSON(http.StatusOK, gin.H{ - "msg": "请求资源不存在", - "code": 4999, - "data": nil, - }) - }) -} - -func ListShortLinksAPI() gin.HandlerFunc { - return Authenticator(func(c *gin.Context, user *models.User) { - var page = utils.GetIntQueryValue(c, "page", 1) - var pageSize = utils.GetIntQueryValue(c, "pageSize", 20) - start := int64((page - 1) * pageSize) - stop := start - 1 + int64(pageSize) - - var key string - if user.IsAdmin() { - key = utils.GetShortLinksKey() - } else { - key = utils.GetUserShortLinksKey(user.Username) - } - - slRepo := repository.GetShortLinkRepo(db.GetRedisClient()) - result, err := slRepo.List(key, start, stop) - if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) - return - } - - c.JSON(http.StatusOK, gin.H{ - "msg": "", - "code": 0, - "data": result, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("请求资源不存在")) }) } diff --git a/internal/app/handlers/user.go b/internal/app/handlers/user.go index 649b826..0254a51 100644 --- a/internal/app/handlers/user.go +++ b/internal/app/handlers/user.go @@ -10,95 +10,98 @@ import ( "strings" ) -type loginForm struct { - Username string `json:"username" binding:"required"` - Password string `json:"password" binding:"required"` -} - -func Login(c *gin.Context) { - f := &loginForm{} +// LoginAPI godoc +// @Summary 账号登入 +// @Description 账号密码登入 +// @Tags 账号 +// @Accept json +// @Produce json +// @Param body body models.LoginAPIRequest true "登入请求" +// @Success 200 {object} models.Response{data=models.LoginAPIResponseData} +// @Router /user/login [post] +func LoginAPI(c *gin.Context) { + f := &models.LoginAPIRequest{} err := c.BindJSON(f) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": "用户名或密码错误", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("用户名或密码错误")) return } repo := repository.GetUserRepo(db.GetRedisClient()) u, err := repo.FindOneByUsername(strings.TrimSpace(f.Username)) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": "用户名或密码错误", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("用户名或密码错误")) return } dk, _ := utils.EncodePassword([]byte(f.Password), u.Salt) if string(u.Password) != string(dk) { - c.JSON(http.StatusOK, gin.H{ - "msg": "用户名或密码错误", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("用户名或密码错误")) return } - c.JSON(http.StatusOK, gin.H{ - "msg": "ok", - "code": 0, - "data": gin.H{ - "token": utils.GenerateJWT(u.Username), - }, - }) + c.JSON(http.StatusOK, models.NewSuccessResponse(models.LoginAPIResponseData{ + Token: utils.GenerateJWT(u.Username), + })) } +// GetUserInfoAPI godoc +// @Security ApiKeyAuth +// @Summary 获取账号信息 +// @Description 获取账号信息 +// @Tags 账号 +// @Accept json +// @Produce json +// @Success 200 {object} models.Response{data=models.GetUserInfoAPIResponseData} +// @Failure 401 +// @Router /user/info [get] func GetUserInfoAPI() gin.HandlerFunc { return Authenticator(func(c *gin.Context, user *models.User) { - c.JSON(http.StatusOK, gin.H{ - "msg": "", - "code": 0, - "data": gin.H{ - "username": user.Username, - "role": user.Role, - }, - }) + c.JSON(http.StatusOK, models.NewSuccessResponse(models.GetUserInfoAPIResponseData{ + Username: user.Username, + Role: user.Role, + })) }) } +// LogoutAPI godoc +// @Security ApiKeyAuth +// @Summary 登出 +// @Description 登出 +// @Tags 账号 +// @Accept json +// @Produce json +// @Success 200 {object} models.Response +// @Failure 401 +// @Router /user/logout [post] func LogoutAPI() gin.HandlerFunc { return Authenticator(func(c *gin.Context, user *models.User) { - c.JSON(http.StatusOK, gin.H{ - "msg": "", - "code": 0, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewSuccessResponse(nil)) }) } +// ChangePasswordAPI godoc +// @Security ApiKeyAuth +// @Summary 修改账号密码 +// @Description 修改账号密码 +// @Tags 账号 +// @Accept json +// @Produce json +// @Param body body models.ChangePasswordAPIRequest true "修改密码请求" +// @Success 200 {object} models.Response +// @Failure 401 +// @Router /user/change-password [post] func ChangePasswordAPI() gin.HandlerFunc { return Authenticator(func(c *gin.Context, user *models.User) { - p := &models.ChangePasswordParameter{} + p := &models.ChangePasswordAPIRequest{} if err := c.ShouldBindJSON(p); err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": "请填写原密码和新密码", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("请填写原密码和新密码")) return } dk, _ := utils.EncodePassword([]byte(p.Password), user.Salt) if string(user.Password) != string(dk) { - c.JSON(http.StatusOK, gin.H{ - "msg": "原密码错误", - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse("原密码错误")) return } @@ -107,18 +110,10 @@ func ChangePasswordAPI() gin.HandlerFunc { repo := repository.GetUserRepo(db.GetRedisClient()) err := repo.UpdatePassword(user) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "msg": err.Error(), - "code": 4999, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewErrorResponse(err.Error())) return } - c.JSON(http.StatusOK, gin.H{ - "msg": "ok", - "code": 0, - "data": nil, - }) + c.JSON(http.StatusOK, models.NewSuccessResponse(nil)) }) } diff --git a/internal/app/models/models.go b/internal/app/models/models.go index dab7f9f..c3aad0c 100644 --- a/internal/app/models/models.go +++ b/internal/app/models/models.go @@ -2,6 +2,7 @@ package models import ( "encoding/json" + "github.com/jwma/jump-jump/internal/app/config" "time" ) @@ -13,11 +14,65 @@ var Roles = map[int]string{ RoleAdmin: "admin", } -type ChangePasswordParameter struct { - Password string `json:"password"` - NewPassword string `json:"newPassword"` +type Response struct { + Msg string `json:"msg" example:"ok" default:"ok"` + Code int `json:"code" example:"0" format:"int" default:"0"` + Data interface{} `json:"data"` +} // @name Response + +func NewSuccessResponse(data interface{}) *Response { + return &Response{ + Msg: "ok", + Code: 0, + Data: data, + } +} + +func NewErrorResponse(msg string) *Response { + return &Response{ + Msg: msg, + Code: 4999, + Data: nil, + } } +type LoginAPIRequest struct { + // 用户名 + Username string `json:"username" binding:"required" example:"your_username"` + + // 密码 + Password string `json:"password" binding:"required" example:"your_password"` +} // @name LoginAPIRequest + +type LoginAPIResponseData struct { + // json web token + Token string `json:"token,omitempty" example:"xxx.xxx.xxx"` +} // @name LoginAPIResponseData + +type GetUserInfoAPIResponseData struct { + // 用户名 + Username string `json:"username" example:"admin"` + + // 角色,1 普通用户 | 2 管理员 + Role int `json:"role" example:"1" enums:"1,2"` +} // @name GetUserInfoAPIResponseData + +type ChangePasswordAPIRequest struct { + // 原密码 + Password string `json:"password"` + + // 新密码 + NewPassword string `json:"newPassword"` +} // @name ChangePasswordAPIRequest + +type GetConfigAPIResponseData struct { + Config *config.SystemConfig `json:"config"` +} // @name GetConfigAPIResponseData + +type UpdateLandingHostsAPIRequest struct { + Hosts []string `json:"hosts" format:"array" example:"https://a.com/,https://b.com/"` +} // @name UpdateLandingHostsAPIRequest + type User struct { Username string `json:"username"` Role int `json:"role"` @@ -32,7 +87,7 @@ func (u *User) IsAdmin() bool { } type ShortLink struct { - Id string `json:"id"` + Id string `json:"id" ` Url string `json:"url"` Description string `json:"description"` IsEnable bool `json:"is_enable"` @@ -41,17 +96,102 @@ type ShortLink struct { UpdateTime time.Time `json:"update_time"` } -type CreateShortLinkParameter struct { - *ShortLink - IdLength int `json:"id_length"` +func NewShortLink(createdBy string, r *CreateShortLinkAPIRequest) *ShortLink { + return &ShortLink{ + Id: r.Id, + Url: r.Url, + Description: r.Description, + IsEnable: r.IsEnable, + CreatedBy: createdBy, + } +} + +type ShortLinkData struct { + Id string `json:"id" example:"RANDOM_ID" format:"string"` + // 目标链接 + Url string `json:"url" example:"https://github.com/jwma/jump-jump" format:"string"` + + // 描述 + Description string `json:"description" example:"Jump Jump project" format:"string"` + + // 是否启用 + IsEnable bool `json:"isEnable" example:"true" format:"boolean"` + + // 创建者 + CreatedBy string `json:"createdBy" example:"admin" format:"string"` + + // 创建时间 + CreateTime time.Time `json:"createTime"` + + // 最后更新时间 + UpdateTime time.Time `json:"updateTime"` +} // @name ShortLinkData + +func ToShortLinkData(s *ShortLink) *ShortLinkData { + return &ShortLinkData{ + Id: s.Id, + Url: s.Url, + Description: s.Description, + IsEnable: s.IsEnable, + CreatedBy: s.CreatedBy, + CreateTime: s.CreateTime, + UpdateTime: s.UpdateTime, + } } -type UpdateShortLinkParameter struct { - Url string `json:"url" binding:"required"` - Description string `json:"description"` - IsEnable bool `json:"is_enable"` +func ToShortLinkDataSlice(s []*ShortLink) []*ShortLinkData { + r := make([]*ShortLinkData, 0) + for _, ss := range s { + r = append(r, ToShortLinkData(ss)) + } + return r } +type CreateShortLinkAPIRequest struct { + // 只有管理员可以在创建的时候指定 ID + Id string `json:"id" format:"string" example:"RANDOM_ID"` + + // 目标链接 + Url string `json:"url" example:"https://github.com/jwma/jump-jump"` + + // 描述 + Description string `json:"description" example:"Jump Jump project"` + + // 是否启用 + IsEnable bool `json:"isEnable" example:"true" format:"boolean"` + + // 短链接 ID 长度 + IdLength int `json:"idLength" example:"4" format:"int"` +} // @name CreateShortLinkAPIRequest + +type GetShortLinkAPIResponseData struct { + ShortLinkData *ShortLinkData `json:"shortLink"` +} // @name GetShortLinkAPIResponseData + +type CreateShortLinkAPIResponseData struct { + ShortLinkData *ShortLinkData `json:"shortLink"` +} // @name CreateShortLinkAPIResponseData + +type UpdateShortLinkAPIResponseData struct { + ShortLinkData *ShortLinkData `json:"shortLink"` +} // @name UpdateShortLinkAPIResponseData + +type UpdateShortLinkAPIRequest struct { + // 目标链接 + Url string `json:"url" binding:"required" example:"https://github.com/jwma/jump-jump"` + + // 描述 + Description string `json:"description" example:"Jump Jump project"` + + // 是否启用 + IsEnable bool `json:"isEnable" example:"true" format:"boolean"` +} // @name UpdateShortLinkAPIRequest + +type ListShortLinksAPIResponseData struct { + ShortLinks []*ShortLinkData `json:"shortLinks"` + Total int64 `json:"total" example:"10" format:"10"` +} // @name ListShortLinksAPIResponseData + type RequestHistory struct { Id string `json:"id"` Link *ShortLink `json:"-"` @@ -59,7 +199,7 @@ type RequestHistory struct { IP string `json:"ip"` UA string `json:"ua"` Time time.Time `json:"time"` -} +} // @name RequestHistory func (r *RequestHistory) MarshalBinary() (data []byte, err error) { return json.Marshal(r) @@ -69,6 +209,10 @@ func NewRequestHistory(link *ShortLink, IP string, UA string) *RequestHistory { return &RequestHistory{Link: link, IP: IP, UA: UA, Url: link.Url} } +type ShortLinkDataAPIResponseData struct { + Histories []*RequestHistory `json:"histories"` +} // @name ShortLinkDataAPIResponseData + type ActiveLink struct { Id string Time time.Time diff --git a/internal/app/repository/repository.go b/internal/app/repository/repository.go index 6009eee..3432980 100644 --- a/internal/app/repository/repository.go +++ b/internal/app/repository/repository.go @@ -251,7 +251,7 @@ func (r *shortLinkRepository) Save(s *models.ShortLink) error { return r.save(s, false) } -func (r *shortLinkRepository) Update(s *models.ShortLink, params *models.UpdateShortLinkParameter) error { +func (r *shortLinkRepository) Update(s *models.ShortLink, params *models.UpdateShortLinkAPIRequest) error { s.Url = params.Url s.Description = params.Description s.IsEnable = params.IsEnable diff --git a/internal/app/repository/repository_test.go b/internal/app/repository/repository_test.go index 038f096..40ca5fc 100644 --- a/internal/app/repository/repository_test.go +++ b/internal/app/repository/repository_test.go @@ -56,7 +56,7 @@ func TestShortLinkRepository_Update(t *testing.T) { t.Error(err) } - params := &models.UpdateShortLinkParameter{ + params := &models.UpdateShortLinkAPIRequest{ Url: "http://github.com/jwma", Description: "安木鸡的 Github", IsEnable: true, diff --git a/internal/app/routers/router.go b/internal/app/routers/router.go index fbfc3c2..f92c021 100644 --- a/internal/app/routers/router.go +++ b/internal/app/routers/router.go @@ -3,13 +3,71 @@ package routers import ( "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" + docs "github.com/jwma/jump-jump/docs" "github.com/jwma/jump-jump/internal/app/handlers" + swaggerFiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" "net/http" + "os" + "strings" ) +// @securityDefinitions.apikey ApiKeyAuth +// @in header +// @name Authorization + +// @contact.name MJ Ma +// @contact.url https://www.linkedin.com/in/mj-profile/ +// @contact.email m.mjw.ma@gmail.com + +// @license.name MIT +// @license.url https://github.com/jwma/jump-jump/blob/master/LICENSE + +func getAPIDocBasicAccounts() gin.Accounts { + defaultUsername := "apidoc" + defaultPassword := "showmethedoc" + + u := os.Getenv("API_DOC_USERNAME") + p := os.Getenv("API_DOC_PASSWORD") + + if u == "" || p == "" { + return gin.Accounts{defaultUsername: defaultPassword} + } + + return gin.Accounts{u: p} +} + +func detectAPIDocHost() { + // 如果通过该环境变量指明了 API 文档使用的 Host,则直接使用 + h := os.Getenv("API_DOC_HOST") + if h != "" { + docs.SwaggerInfo.Host = h + return + } + + if gin.Mode() == gin.DebugMode { + docs.SwaggerInfo.Host = os.Getenv("J2_API_ADDR") + } else { + docs.SwaggerInfo.Host = strings.Split(os.Getenv("ALLOWED_HOSTS"), ",")[0] + } +} + func SetupRouter() *gin.Engine { r := gin.Default() + // Swagger + docs.SwaggerInfo.Title = "Jump Jump API Documentation" + docs.SwaggerInfo.Description = "🚀🚀🚀" + docs.SwaggerInfo.Version = "v1" + docs.SwaggerInfo.BasePath = "/v1" + docs.SwaggerInfo.Schemes = []string{"http", "https"} + url := ginSwagger.URL("/swagger/doc.json") + detectAPIDocHost() + docsR := r.Group("/swagger", gin.BasicAuth(getAPIDocBasicAccounts())) + { + docsR.GET("/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, url)) + } + if gin.Mode() == gin.DebugMode { // 开发环境下,开启 CORS corsCfg := cors.DefaultConfig() corsCfg.AllowAllOrigins = true @@ -19,33 +77,38 @@ func SetupRouter() *gin.Engine { r.Use(handlers.AllowedHostsMiddleware()) + // serve dashboard static resources r.LoadHTMLFiles("./web/admin/index.html") r.StaticFS("/static", http.Dir("./web/admin/static")) r.GET("/", func(c *gin.Context) { c.HTML(http.StatusOK, "index.html", gin.H{}) }) - r.POST("/v1/user/login", handlers.Login) - r.GET("/v1/user/info", handlers.JWTAuthenticatorMiddleware(), handlers.GetUserInfoAPI()) - r.POST("/v1/user/logout", handlers.JWTAuthenticatorMiddleware(), handlers.LogoutAPI()) - r.PATCH("/v1/user/change-password", handlers.JWTAuthenticatorMiddleware(), handlers.ChangePasswordAPI()) - - r.GET("/v1/config", handlers.GetConfig) - r.PATCH("/v1/config/landing-hosts", handlers.JWTAuthenticatorMiddleware(), - handlers.UpdateLandingHostsAPI()) - r.PATCH("/v1/config/id-length", handlers.JWTAuthenticatorMiddleware(), - handlers.UpdateIdLengthConfigAPI()) - r.PATCH("/v1/config/short-link-404-handling", handlers.JWTAuthenticatorMiddleware(), - handlers.UpdateShortLinkNotFoundConfigAPI()) - - shortLinkAPI := r.Group("/v1/short-link") - shortLinkAPI.Use(handlers.JWTAuthenticatorMiddleware()) - shortLinkAPI.GET("/", handlers.ListShortLinksAPI()) - shortLinkAPI.GET("/:id", handlers.GetShortLinkAPI()) - shortLinkAPI.POST("/", handlers.CreateShortLinkAPI()) - shortLinkAPI.PATCH("/:id", handlers.UpdateShortLinkAPI()) - shortLinkAPI.DELETE("/:id", handlers.DeleteShortLinkAPI()) - shortLinkAPI.GET("/:id/*action", handlers.ShortLinkActionAPI()) + // v1 API's + v1 := r.Group("/v1") + { + // account stuff + v1.POST("/user/login", handlers.LoginAPI) + v1.GET("/user/info", handlers.JWTAuthenticatorMiddleware(), handlers.GetUserInfoAPI()) + v1.POST("/user/logout", handlers.JWTAuthenticatorMiddleware(), handlers.LogoutAPI()) + v1.POST("/user/change-password", handlers.JWTAuthenticatorMiddleware(), handlers.ChangePasswordAPI()) + + // system configuration stuff + v1.GET("/config", handlers.JWTAuthenticatorMiddleware(), handlers.GetConfigAPI) + v1.PATCH("/config/landing-hosts", handlers.JWTAuthenticatorMiddleware(), handlers.UpdateLandingHostsAPI()) + v1.PATCH("/config/id-length", handlers.JWTAuthenticatorMiddleware(), handlers.UpdateIdLengthConfigAPI()) + v1.PATCH("/config/short-link-404-handling", handlers.JWTAuthenticatorMiddleware(), handlers.UpdateShortLinkNotFoundConfigAPI()) + + // short link stuff + shortLinkAPI := v1.Group("/short-link") + shortLinkAPI.Use(handlers.JWTAuthenticatorMiddleware()) + shortLinkAPI.GET("/", handlers.ListShortLinksAPI()) + shortLinkAPI.GET("/:id", handlers.GetShortLinkAPI()) + shortLinkAPI.POST("/", handlers.CreateShortLinkAPI()) + shortLinkAPI.PATCH("/:id", handlers.UpdateShortLinkAPI()) + shortLinkAPI.DELETE("/:id", handlers.DeleteShortLinkAPI()) + shortLinkAPI.GET("/:id/*action", handlers.ShortLinkActionAPI()) + } return r } diff --git a/web/admin/index.html b/web/admin/index.html index ba5813d..957b8ef 100644 --- a/web/admin/index.html +++ b/web/admin/index.html @@ -1 +1 @@ -Jump Jump Admin
\ No newline at end of file +Jump Jump Admin
\ No newline at end of file diff --git a/web/admin/static/css/chunk-13714370.2672e5fe.css b/web/admin/static/css/chunk-13714370.2672e5fe.css new file mode 100644 index 0000000..2a38215 --- /dev/null +++ b/web/admin/static/css/chunk-13714370.2672e5fe.css @@ -0,0 +1 @@ +.paginator-container[data-v-901f7d5c]{margin-top:10px} \ No newline at end of file diff --git a/web/admin/static/css/chunk-60a4aa86.68815401.css b/web/admin/static/css/chunk-60a4aa86.68815401.css deleted file mode 100644 index aac31f5..0000000 --- a/web/admin/static/css/chunk-60a4aa86.68815401.css +++ /dev/null @@ -1 +0,0 @@ -.paginator-container[data-v-23d33577]{margin-top:10px} \ No newline at end of file diff --git a/web/admin/static/js/app.2389be4d.js b/web/admin/static/js/app.841517a2.js similarity index 68% rename from web/admin/static/js/app.2389be4d.js rename to web/admin/static/js/app.841517a2.js index 82f3424..eb93766 100644 --- a/web/admin/static/js/app.2389be4d.js +++ b/web/admin/static/js/app.841517a2.js @@ -1 +1 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["app"],{0:function(e,t,n){e.exports=n("56d7")},"028b":function(e,t,n){"use strict";var a=n("f12c"),s=n.n(a);s.a},"031b":function(e,t,n){},"186a":function(e,t,n){"use strict";var a=n("dc52"),s=n.n(a);s.a},"18f0":function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-link",use:"icon-link-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(o);t["default"]=o},2995:function(e,t,n){},"2a3d":function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-password",use:"icon-password-usage",viewBox:"0 0 128 128",content:''});r.a.add(o);t["default"]=o},3289:function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-list",use:"icon-list-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(o);t["default"]=o},"34c8":function(e,t,n){"use strict";var a=n("88a1"),s=n.n(a);s.a},4360:function(e,t,n){"use strict";var a=n("2b0e"),s=n("2f62"),i=(n("b54a"),n("7f7f"),{sidebar:function(e){return e.app.sidebar},device:function(e){return e.app.device},token:function(e){return e.user.token},name:function(e){return e.user.name},role:function(e){return e.user.role},pinned:function(e){return e.link.pinned}}),r=i,o=n("a78e"),c=n.n(o),u={sidebar:{opened:!c.a.get("sidebarStatus")||!!+c.a.get("sidebarStatus"),withoutAnimation:!1},device:"desktop"},d={TOGGLE_SIDEBAR:function(e){e.sidebar.opened=!e.sidebar.opened,e.sidebar.withoutAnimation=!1,e.sidebar.opened?c.a.set("sidebarStatus",1):c.a.set("sidebarStatus",0)},CLOSE_SIDEBAR:function(e,t){c.a.set("sidebarStatus",0),e.sidebar.opened=!1,e.sidebar.withoutAnimation=t},TOGGLE_DEVICE:function(e,t){e.device=t}},l={toggleSideBar:function(e){var t=e.commit;t("TOGGLE_SIDEBAR")},closeSideBar:function(e,t){var n=e.commit,a=t.withoutAnimation;n("CLOSE_SIDEBAR",a)},toggleDevice:function(e,t){var n=e.commit;n("TOGGLE_DEVICE",t)}},f={namespaced:!0,state:u,mutations:d,actions:l},h=n("83d6"),m=n.n(h),b=m.a.showSettings,p=m.a.fixedHeader,v=m.a.sidebarLogo,g={showSettings:b,fixedHeader:p,sidebarLogo:v},j={CHANGE_SETTING:function(e,t){var n=t.key,a=t.value;e.hasOwnProperty(n)&&(e[n]=a)}},w={changeSetting:function(e,t){var n=e.commit;n("CHANGE_SETTING",t)}},k={namespaced:!0,state:g,mutations:j,actions:w},y=n("c24f"),x=n("5f87"),_=n("a18c"),C=function(){return{token:Object(x["a"])(),name:"",role:1}},O=C(),z={RESET_STATE:function(e){Object.assign(e,C())},SET_TOKEN:function(e,t){e.token=t},SET_NAME:function(e,t){e.name=t},SET_ROLE:function(e,t){e.role=t}},S={login:function(e,t){var n=e.commit,a=t.username,s=t.password;return new Promise((function(e,t){Object(y["c"])({username:a.trim(),password:s}).then((function(t){var a=t.data;n("SET_TOKEN",a.token),Object(x["c"])(a.token),e()})).catch((function(e){t(e)}))}))},getInfo:function(e){var t=e.commit;e.state;return new Promise((function(e,n){Object(y["b"])().then((function(a){var s=a.data;s||n("登入信息验证失败,请重新登入");var i=s.username,r=s.role;t("SET_NAME",i),t("SET_ROLE",r),e(s)})).catch((function(e){n(e)}))}))},logout:function(e){var t=e.commit,n=e.state;return new Promise((function(e,a){Object(y["d"])(n.token).then((function(){Object(x["b"])(),Object(_["b"])(),t("RESET_STATE"),e()})).catch((function(e){a(e)}))}))},resetToken:function(e){var t=e.commit;return new Promise((function(e){Object(x["b"])(),t("RESET_STATE"),e()}))}},E={namespaced:!0,state:O,mutations:z,actions:S},M="pinned",B={pinned:JSON.parse(localStorage.getItem(M)||"[]")},T={PIN:function(e,t){e.pinned.push(t)},UNPIN:function(e,t){e.pinned.indexOf(t)>=0&&e.pinned.splice(e.pinned.indexOf(t),1)}},L={pin:function(e,t){var n=e.commit,a=e.state;n("PIN",t),localStorage.setItem(M,JSON.stringify(a.pinned))},unpin:function(e,t){var n=e.commit,a=e.state;n("UNPIN",t),localStorage.setItem(M,JSON.stringify(a.pinned))}},$={namespaced:!0,state:B,mutations:T,actions:L};a["default"].use(s["a"]);var A=new s["a"].Store({modules:{app:f,settings:k,user:E,link:$},getters:r});t["a"]=A},4678:function(e,t,n){var a={"./af":"2bfb","./af.js":"2bfb","./ar":"8e73","./ar-dz":"a356","./ar-dz.js":"a356","./ar-kw":"423e","./ar-kw.js":"423e","./ar-ly":"1cfd","./ar-ly.js":"1cfd","./ar-ma":"0a84","./ar-ma.js":"0a84","./ar-sa":"8230","./ar-sa.js":"8230","./ar-tn":"6d83","./ar-tn.js":"6d83","./ar.js":"8e73","./az":"485c","./az.js":"485c","./be":"1fc1","./be.js":"1fc1","./bg":"84aa","./bg.js":"84aa","./bm":"a7fa","./bm.js":"a7fa","./bn":"9043","./bn.js":"9043","./bo":"d26a","./bo.js":"d26a","./br":"6887","./br.js":"6887","./bs":"2554","./bs.js":"2554","./ca":"d716","./ca.js":"d716","./cs":"3c0d","./cs.js":"3c0d","./cv":"03ec","./cv.js":"03ec","./cy":"9797","./cy.js":"9797","./da":"0f14","./da.js":"0f14","./de":"b469","./de-at":"b3eb","./de-at.js":"b3eb","./de-ch":"bb71","./de-ch.js":"bb71","./de.js":"b469","./dv":"598a","./dv.js":"598a","./el":"8d47","./el.js":"8d47","./en-SG":"cdab","./en-SG.js":"cdab","./en-au":"0e6b","./en-au.js":"0e6b","./en-ca":"3886","./en-ca.js":"3886","./en-gb":"39a6","./en-gb.js":"39a6","./en-ie":"e1d3","./en-ie.js":"e1d3","./en-il":"7333","./en-il.js":"7333","./en-nz":"6f50","./en-nz.js":"6f50","./eo":"65db","./eo.js":"65db","./es":"898b","./es-do":"0a3c","./es-do.js":"0a3c","./es-us":"55c9","./es-us.js":"55c9","./es.js":"898b","./et":"ec18","./et.js":"ec18","./eu":"0ff2","./eu.js":"0ff2","./fa":"8df4","./fa.js":"8df4","./fi":"81e9","./fi.js":"81e9","./fo":"0721","./fo.js":"0721","./fr":"9f26","./fr-ca":"d9f8","./fr-ca.js":"d9f8","./fr-ch":"0e49","./fr-ch.js":"0e49","./fr.js":"9f26","./fy":"7118","./fy.js":"7118","./ga":"5120","./ga.js":"5120","./gd":"f6b4","./gd.js":"f6b4","./gl":"8840","./gl.js":"8840","./gom-latn":"0caa","./gom-latn.js":"0caa","./gu":"e0c5","./gu.js":"e0c5","./he":"c7aa","./he.js":"c7aa","./hi":"dc4d","./hi.js":"dc4d","./hr":"4ba9","./hr.js":"4ba9","./hu":"5b14","./hu.js":"5b14","./hy-am":"d6b6","./hy-am.js":"d6b6","./id":"5038","./id.js":"5038","./is":"0558","./is.js":"0558","./it":"6e98","./it-ch":"6f12","./it-ch.js":"6f12","./it.js":"6e98","./ja":"079e","./ja.js":"079e","./jv":"b540","./jv.js":"b540","./ka":"201b","./ka.js":"201b","./kk":"6d79","./kk.js":"6d79","./km":"e81d","./km.js":"e81d","./kn":"3e92","./kn.js":"3e92","./ko":"22f8","./ko.js":"22f8","./ku":"2421","./ku.js":"2421","./ky":"9609","./ky.js":"9609","./lb":"440c","./lb.js":"440c","./lo":"b29d","./lo.js":"b29d","./lt":"26f9","./lt.js":"26f9","./lv":"b97c","./lv.js":"b97c","./me":"293c","./me.js":"293c","./mi":"688b","./mi.js":"688b","./mk":"6909","./mk.js":"6909","./ml":"02fb","./ml.js":"02fb","./mn":"958b","./mn.js":"958b","./mr":"39bd","./mr.js":"39bd","./ms":"ebe4","./ms-my":"6403","./ms-my.js":"6403","./ms.js":"ebe4","./mt":"1b45","./mt.js":"1b45","./my":"8689","./my.js":"8689","./nb":"6ce3","./nb.js":"6ce3","./ne":"3a39","./ne.js":"3a39","./nl":"facd","./nl-be":"db29","./nl-be.js":"db29","./nl.js":"facd","./nn":"b84c","./nn.js":"b84c","./pa-in":"f3ff","./pa-in.js":"f3ff","./pl":"8d57","./pl.js":"8d57","./pt":"f260","./pt-br":"d2d4","./pt-br.js":"d2d4","./pt.js":"f260","./ro":"972c","./ro.js":"972c","./ru":"957c","./ru.js":"957c","./sd":"6784","./sd.js":"6784","./se":"ffff","./se.js":"ffff","./si":"eda5","./si.js":"eda5","./sk":"7be6","./sk.js":"7be6","./sl":"8155","./sl.js":"8155","./sq":"c8f3","./sq.js":"c8f3","./sr":"cf1e","./sr-cyrl":"13e9","./sr-cyrl.js":"13e9","./sr.js":"cf1e","./ss":"52bd","./ss.js":"52bd","./sv":"5fbd","./sv.js":"5fbd","./sw":"74dc","./sw.js":"74dc","./ta":"3de5","./ta.js":"3de5","./te":"5cbb","./te.js":"5cbb","./tet":"576c","./tet.js":"576c","./tg":"3b1b","./tg.js":"3b1b","./th":"10e8","./th.js":"10e8","./tl-ph":"0f38","./tl-ph.js":"0f38","./tlh":"cf75","./tlh.js":"cf75","./tr":"0e81","./tr.js":"0e81","./tzl":"cf51","./tzl.js":"cf51","./tzm":"c109","./tzm-latn":"b53d","./tzm-latn.js":"b53d","./tzm.js":"c109","./ug-cn":"6117","./ug-cn.js":"6117","./uk":"ada2","./uk.js":"ada2","./ur":"5294","./ur.js":"5294","./uz":"2e8c","./uz-latn":"010e","./uz-latn.js":"010e","./uz.js":"2e8c","./vi":"2921","./vi.js":"2921","./x-pseudo":"fd7e","./x-pseudo.js":"fd7e","./yo":"7f33","./yo.js":"7f33","./zh-cn":"5c3a","./zh-cn.js":"5c3a","./zh-hk":"49ab","./zh-hk.js":"49ab","./zh-tw":"90ea","./zh-tw.js":"90ea"};function s(e){var t=i(e);return n(t)}function i(e){var t=a[e];if(!(t+1)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return t}s.keys=function(){return Object.keys(a)},s.resolve=i,e.exports=s,s.id="4678"},"4cdc":function(e,t,n){},"4df5":function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-eye",use:"icon-eye-usage",viewBox:"0 0 128 64",content:''});r.a.add(o);t["default"]=o},"51ff":function(e,t,n){var a={"./add.svg":"c2a3","./dashboard.svg":"f782","./eye-open.svg":"d7ec","./eye.svg":"4df5","./form.svg":"eb1b","./github.svg":"558d","./link.svg":"18f0","./list.svg":"3289","./password.svg":"2a3d","./user.svg":"b3b5"};function s(e){var t=i(e);return n(t)}function i(e){var t=a[e];if(!(t+1)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return t}s.keys=function(){return Object.keys(a)},s.resolve=i,e.exports=s,s.id="51ff"},"558d":function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-github",use:"icon-github-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(o);t["default"]=o},"56d7":function(e,t,n){"use strict";n.r(t);n("cadf"),n("551c"),n("f751"),n("097d");var a=n("2b0e"),s=n("c1df"),i=n.n(s),r=(n("f5df"),n("5c96")),o=n.n(r),c=(n("0fae"),n("b20f"),function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{attrs:{id:"app"}},[n("router-view")],1)}),u=[],d={name:"App"},l=d,f=n("2877"),h=Object(f["a"])(l,c,u,!1,null,null,null),m=h.exports,b=n("4360"),p=n("a18c"),v=(n("ac6a"),function(){var e=this,t=e.$createElement,n=e._self._c||t;return e.isExternal?n("div",e._g({staticClass:"svg-external-icon svg-icon",style:e.styleExternalIcon},e.$listeners)):n("svg",e._g({class:e.svgClass,attrs:{"aria-hidden":"true"}},e.$listeners),[n("use",{attrs:{href:e.iconName}})])}),g=[],j=n("61f7"),w={name:"SvgIcon",props:{iconClass:{type:String,required:!0},className:{type:String,default:""}},computed:{isExternal:function(){return Object(j["a"])(this.iconClass)},iconName:function(){return"#icon-".concat(this.iconClass)},svgClass:function(){return this.className?"svg-icon "+this.className:"svg-icon"},styleExternalIcon:function(){return{mask:"url(".concat(this.iconClass,") no-repeat 50% 50%"),"-webkit-mask":"url(".concat(this.iconClass,") no-repeat 50% 50%")}}}},k=w,y=(n("d1a7"),Object(f["a"])(k,v,g,!1,null,"4342976c",null)),x=y.exports;a["default"].component("svg-icon",x);var _=n("51ff"),C=function(e){return e.keys().map(e)};C(_);n("7f7f"),n("96cf");var O=n("3b8d"),z=n("323e"),S=n.n(z),E=(n("a5d8"),n("5f87")),M=n("83d6"),B=n.n(M),T=B.a.title||"Vue Admin Template";function L(e){return e?"".concat(e," - ").concat(T):"".concat(T)}S.a.configure({showSpinner:!1});var $=["/login"];p["a"].beforeEach(function(){var e=Object(O["a"])(regeneratorRuntime.mark((function e(t,n,a){var s,i;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:if(S.a.start(),document.title=L(t.meta.title),s=Object(E["a"])(),!s){e.next=29;break}if("/login"!==t.path){e.next=9;break}a({path:"/"}),S.a.done(),e.next=27;break;case 9:if(i=b["a"].getters.name,!i){e.next=14;break}a(),e.next=27;break;case 14:return e.prev=14,e.next=17,b["a"].dispatch("user/getInfo");case 17:a(),e.next=27;break;case 20:return e.prev=20,e.t0=e["catch"](14),e.next=24,b["a"].dispatch("user/resetToken");case 24:r["Message"].error(e.t0||"Has Error"),a("/login?redirect=".concat(t.path)),S.a.done();case 27:e.next=30;break;case 29:-1!==$.indexOf(t.path)?a():(a("/login?redirect=".concat(t.path)),S.a.done());case 30:case"end":return e.stop()}}),e,null,[[14,20]])})));return function(t,n,a){return e.apply(this,arguments)}}()),p["a"].afterEach((function(){S.a.done()})),a["default"].filter("dateformat",(function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"YYYY-MM-DD HH:mm:ss";return e?i()(e).format(t):"-"})),a["default"].use(o.a),a["default"].config.productionTip=!1,new a["default"]({el:"#app",router:p["a"],store:b["a"],render:function(e){return e(m)}})},"5f87":function(e,t,n){"use strict";n.d(t,"a",(function(){return r})),n.d(t,"c",(function(){return o})),n.d(t,"b",(function(){return c}));var a=n("a78e"),s=n.n(a),i="j2_token";function r(){return s.a.get(i)}function o(e){return s.a.set(i,e)}function c(){return s.a.remove(i)}},"61f7":function(e,t,n){"use strict";n.d(t,"a",(function(){return a})),n.d(t,"c",(function(){return s})),n.d(t,"b",(function(){return r}));n("3b2b");function a(e){return/^(https?:|mailto:|tel:)/.test(e)}function s(e){return e.length>=2}var i=new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|localhost|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\#[-a-z\\d_\\/]*)?(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$","i");function r(e){return!!i.test(e)}},"6b31":function(e,t,n){"use strict";var a=n("4cdc"),s=n.n(a);s.a},"83d6":function(e,t){e.exports={title:"Jump Jump Admin",fixedHeader:!1,sidebarLogo:!1}},"88a1":function(e,t,n){},8902:function(e,t,n){},"9f2b":function(e,t,n){"use strict";var a=n("bf90"),s=n.n(a);s.a},"9f43":function(e,t,n){"use strict";var a=n("2995"),s=n.n(a);s.a},a18c:function(e,t,n){"use strict";var a,s,i=n("2b0e"),r=n("8c4f"),o=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"app-wrapper",class:e.classObj},["mobile"===e.device&&e.sidebar.opened?n("div",{staticClass:"drawer-bg",on:{click:e.handleClickOutside}}):e._e(),e._v(" "),n("sidebar",{staticClass:"sidebar-container"}),e._v(" "),n("div",{staticClass:"main-container"},[n("div",{class:{"fixed-header":e.fixedHeader}},[n("navbar")],1),e._v(" "),n("app-main")],1)],1)},c=[],u=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"navbar"},[n("hamburger",{staticClass:"hamburger-container",attrs:{"is-active":e.sidebar.opened},on:{toggleClick:e.toggleSideBar}}),e._v(" "),n("breadcrumb",{staticClass:"breadcrumb-container"}),e._v(" "),n("div",{staticClass:"right-menu"},[n("el-dropdown",{staticClass:"username-container",attrs:{trigger:"click"}},[n("div",{staticClass:"username-wrapper"},[n("span",{staticStyle:{cursor:"pointer"}},[e._v(e._s(e.name))])]),e._v(" "),n("el-dropdown-menu",{staticClass:"user-dropdown",attrs:{slot:"dropdown"},slot:"dropdown"},[n("router-link",{attrs:{to:"/"}},[n("el-dropdown-item",[e._v("首页")])],1),e._v(" "),n("router-link",{attrs:{to:"/security/change-password"}},[n("el-dropdown-item",[e._v("修改密码")])],1),e._v(" "),n("a",{attrs:{target:"_blank",href:"https://github.com/jwma/jump-jump"}},[n("el-dropdown-item",[e._v("Github")])],1),e._v(" "),n("el-dropdown-item",{attrs:{divided:""},nativeOn:{click:function(t){return e.logout(t)}}},[n("span",{staticStyle:{display:"block"}},[e._v("登出")])])],1)],1)],1)],1)},d=[],l=(n("96cf"),n("3b8d")),f=n("db72"),h=n("2f62"),m=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-breadcrumb",{staticClass:"app-breadcrumb",attrs:{separator:"/"}},[n("transition-group",{attrs:{name:"breadcrumb"}},e._l(e.levelList,(function(t,a){return n("el-breadcrumb-item",{key:t.path},["noRedirect"===t.redirect||a==e.levelList.length-1?n("span",{staticClass:"no-redirect"},[e._v(e._s(t.meta.title))]):n("a",{on:{click:function(n){return n.preventDefault(),e.handleLink(t)}}},[e._v(e._s(t.meta.title))])])})),1)],1)},b=[],p=(n("7f7f"),n("bd11")),v=n.n(p),g={data:function(){return{levelList:null}},watch:{$route:function(){this.getBreadcrumb()}},created:function(){this.getBreadcrumb()},methods:{getBreadcrumb:function(){var e=this.$route.matched.filter((function(e){return e.meta&&e.meta.title})),t=e[0];this.isDashboard(t)||(e=[{path:"/dashboard",meta:{title:"Dashboard"}}].concat(e)),this.levelList=e.filter((function(e){return e.meta&&e.meta.title&&!1!==e.meta.breadcrumb}))},isDashboard:function(e){var t=e&&e.name;return!!t&&t.trim().toLocaleLowerCase()==="Dashboard".toLocaleLowerCase()},pathCompile:function(e){var t=this.$route.params,n=v.a.compile(e);return n(t)},handleLink:function(e){var t=e.redirect,n=e.path;t?this.$router.push(t):this.$router.push(this.pathCompile(n))}}},j=g,w=(n("34c8"),n("2877")),k=Object(w["a"])(j,m,b,!1,null,"62cc9144",null),y=k.exports,x=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticStyle:{padding:"0 15px"},on:{click:e.toggleClick}},[n("svg",{staticClass:"hamburger",class:{"is-active":e.isActive},attrs:{viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg",width:"64",height:"64"}},[n("path",{attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"}})])])},_=[],C={name:"Hamburger",props:{isActive:{type:Boolean,default:!1}},methods:{toggleClick:function(){this.$emit("toggleClick")}}},O=C,z=(n("186a"),Object(w["a"])(O,x,_,!1,null,"49e15297",null)),S=z.exports,E={components:{Breadcrumb:y,Hamburger:S},computed:Object(f["a"])({},Object(h["b"])(["sidebar","name"])),methods:{toggleSideBar:function(){this.$store.dispatch("app/toggleSideBar")},logout:function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return e.next=2,this.$store.dispatch("user/logout");case 2:this.$router.push("/login?redirect=".concat(this.$route.fullPath));case 3:case"end":return e.stop()}}),e,this)})));function t(){return e.apply(this,arguments)}return t}()}},M=E,B=(n("9f43"),Object(w["a"])(M,u,d,!1,null,"26745010",null)),T=B.exports,L=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:{"has-logo":e.showLogo}},[e.showLogo?n("logo",{attrs:{collapse:e.isCollapse}}):e._e(),e._v(" "),n("el-scrollbar",{attrs:{"wrap-class":"scrollbar-wrapper"}},[n("el-menu",{attrs:{"default-active":e.activeMenu,collapse:e.isCollapse,"background-color":e.variables.menuBg,"text-color":e.variables.menuText,"unique-opened":!1,"active-text-color":e.variables.menuActiveText,"collapse-transition":!1,mode:"vertical"}},e._l(e.routes,(function(e){return n("sidebar-item",{key:e.path,attrs:{item:e,"base-path":e.path}})})),1)],1)],1)},$=[],A=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"sidebar-logo-container",class:{collapse:e.collapse}},[n("transition",{attrs:{name:"sidebarLogoFade"}},[e.collapse?n("router-link",{key:"collapse",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])]):n("router-link",{key:"expand",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):e._e(),e._v(" "),n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])])],1)],1)},H=[],N={name:"SidebarLogo",props:{collapse:{type:Boolean,required:!0}},data:function(){return{title:"Vue Admin Template",logo:"https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png"}}},I=N,P=(n("6b31"),Object(w["a"])(I,A,H,!1,null,"5bb1c0e2",null)),D=P.exports,q=function(){var e=this,t=e.$createElement,n=e._self._c||t;return e.item.hidden?e._e():n("div",[!e.hasOneShowingChild(e.item.children,e.item)||e.onlyOneChild.children&&!e.onlyOneChild.noShowingChildren||e.item.alwaysShow?n("el-submenu",{ref:"subMenu",attrs:{index:e.resolvePath(e.item.path),"popper-append-to-body":""}},[n("template",{slot:"title"},[e.item.meta?n("item",{attrs:{icon:e.item.meta&&e.item.meta.icon,title:e.item.meta.title}}):e._e()],1),e._v(" "),e._l(e.item.children,(function(t){return n("sidebar-item",{key:t.path,staticClass:"nest-menu",attrs:{"is-nest":!0,item:t,"base-path":e.resolvePath(t.path)}})}))],2):[e.onlyOneChild.meta?n("app-link",{attrs:{to:e.resolvePath(e.onlyOneChild.path)}},[n("el-menu-item",{class:{"submenu-title-noDropdown":!e.isNest},attrs:{index:e.resolvePath(e.onlyOneChild.path)}},[n("item",{attrs:{icon:e.onlyOneChild.meta.icon||e.item.meta&&e.item.meta.icon,title:e.onlyOneChild.meta.title}})],1)],1):e._e()]],2)},R=[],G=n("df7c"),U=n.n(G),V=n("61f7"),F={name:"MenuItem",functional:!0,props:{icon:{type:String,default:""},title:{type:String,default:""}},render:function(e,t){var n=t.props,a=n.icon,s=n.title,i=[];return a&&i.push(e("svg-icon",{attrs:{"icon-class":a}})),s&&i.push(e("span",{slot:"title"},[s])),i}},J=F,Y=Object(w["a"])(J,a,s,!1,null,null,null),K=Y.exports,W=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("component",e._b({},"component",e.linkProps(e.to),!1),[e._t("default")],2)},Q=[],X={props:{to:{type:String,required:!0}},methods:{linkProps:function(e){return Object(V["a"])(e)?{is:"a",href:e,target:"_blank",rel:"noopener"}:{is:"router-link",to:e}}}},Z=X,ee=Object(w["a"])(Z,W,Q,!1,null,null,null),te=ee.exports,ne={computed:{device:function(){return this.$store.state.app.device}},mounted:function(){this.fixBugIniOS()},methods:{fixBugIniOS:function(){var e=this,t=this.$refs.subMenu;if(t){var n=t.handleMouseleave;t.handleMouseleave=function(t){"mobile"!==e.device&&n(t)}}}}},ae={name:"SidebarItem",components:{Item:K,AppLink:te},mixins:[ne],props:{item:{type:Object,required:!0},isNest:{type:Boolean,default:!1},basePath:{type:String,default:""}},data:function(){return this.onlyOneChild=null,{}},methods:{hasOneShowingChild:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],n=arguments.length>1?arguments[1]:void 0,a=t.filter((function(t){return!t.hidden&&(e.onlyOneChild=t,!0)}));return 1===a.length||0===a.length&&(this.onlyOneChild=Object(f["a"])({},n,{path:"",noShowingChildren:!0}),!0)},resolvePath:function(e){return Object(V["a"])(e)?e:Object(V["a"])(this.basePath)?this.basePath:U.a.resolve(this.basePath,e)}}},se=ae,ie=Object(w["a"])(se,q,R,!1,null,null,null),re=ie.exports,oe=n("cf1e2"),ce=n.n(oe),ue={components:{SidebarItem:re,Logo:D},computed:Object(f["a"])({},Object(h["b"])(["sidebar"]),{routes:function(){return this.$router.options.routes},activeMenu:function(){var e=this.$route,t=e.meta,n=e.path;return t.activeMenu?t.activeMenu:n},showLogo:function(){return this.$store.state.settings.sidebarLogo},variables:function(){return ce.a},isCollapse:function(){return!this.sidebar.opened}})},de=ue,le=Object(w["a"])(de,L,$,!1,null,null,null),fe=le.exports,he=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("section",{staticClass:"app-main"},[n("transition",{attrs:{name:"fade-transform",mode:"out-in"}},[n("router-view",{key:e.key})],1)],1)},me=[],be={name:"AppMain",computed:{key:function(){return this.$route.path}}},pe=be,ve=(n("e4de"),n("028b"),Object(w["a"])(pe,he,me,!1,null,"64cf4d83",null)),ge=ve.exports,je=n("4360"),we=document,ke=we.body,ye=992,xe={watch:{$route:function(e){"mobile"===this.device&&this.sidebar.opened&&je["a"].dispatch("app/closeSideBar",{withoutAnimation:!1})}},beforeMount:function(){window.addEventListener("resize",this.$_resizeHandler)},beforeDestroy:function(){window.removeEventListener("resize",this.$_resizeHandler)},mounted:function(){var e=this.$_isMobile();e&&(je["a"].dispatch("app/toggleDevice","mobile"),je["a"].dispatch("app/closeSideBar",{withoutAnimation:!0}))},methods:{$_isMobile:function(){var e=ke.getBoundingClientRect();return e.width-1'});r.a.add(o);t["default"]=o},b775:function(e,t,n){"use strict";var a=n("bc3a"),s=n.n(a),i=n("5c96"),r=n("4360"),o=n("5f87"),c=s.a.create({baseURL:"",timeout:5e3});c.interceptors.request.use((function(e){return r["a"].getters.token&&(e.headers["Authorization"]="Bearer "+Object(o["a"])()),e}),(function(e){return console.log(e),Promise.reject(e)})),c.interceptors.response.use((function(e){var t=e.data;return 4999===t.code?(Object(i["Message"])({message:t.msg||"Error",type:"error",duration:5e3}),Promise.reject(new Error(t.message||"Error"))):t}),(function(e){var t=e.response;return 401===t.status?i["MessageBox"].confirm("你的登入已过期,请重新登入","登入过期",{confirmButtonText:"重新登入",cancelButtonText:"取消",type:"warning"}).then((function(){r["a"].dispatch("user/resetToken").then((function(){location.reload()}))})):500===t.status&&Object(i["Message"])({message:"服务器繁忙,请稍后再试...",type:"error",duration:5e3}),Promise.reject(e)})),t["a"]=c},bf90:function(e,t,n){},c24f:function(e,t,n){"use strict";n.d(t,"c",(function(){return s})),n.d(t,"b",(function(){return i})),n.d(t,"d",(function(){return r})),n.d(t,"a",(function(){return o}));var a=n("b775");function s(e){return Object(a["a"])({url:"/v1/user/login",method:"post",data:e})}function i(){return Object(a["a"])({url:"/v1/user/info",method:"get"})}function r(){return Object(a["a"])({url:"/v1/user/logout",method:"post"})}function o(e){return Object(a["a"])({url:"/v1/user/change-password",method:"patch",data:e})}},c2a3:function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-add",use:"icon-add-usage",viewBox:"0 0 1026 1024",content:''});r.a.add(o);t["default"]=o},cf1e2:function(e,t,n){e.exports={menuText:"#bfcbd9",menuActiveText:"#409EFF",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},d1a7:function(e,t,n){"use strict";var a=n("031b"),s=n.n(a);s.a},d7ec:function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-eye-open",use:"icon-eye-open-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(o);t["default"]=o},dc52:function(e,t,n){},e4de:function(e,t,n){"use strict";var a=n("8902"),s=n.n(a);s.a},eb1b:function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-form",use:"icon-form-usage",viewBox:"0 0 128 128",content:''});r.a.add(o);t["default"]=o},f12c:function(e,t,n){},f782:function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-dashboard",use:"icon-dashboard-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(o);t["default"]=o}},[[0,"runtime","chunk-elementUI","chunk-libs"]]]); \ No newline at end of file +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["app"],{0:function(e,t,n){e.exports=n("56d7")},"028b":function(e,t,n){"use strict";var a=n("f12c"),s=n.n(a);s.a},"031b":function(e,t,n){},"186a":function(e,t,n){"use strict";var a=n("dc52"),s=n.n(a);s.a},"18f0":function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-link",use:"icon-link-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(o);t["default"]=o},2995:function(e,t,n){},"2a3d":function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-password",use:"icon-password-usage",viewBox:"0 0 128 128",content:''});r.a.add(o);t["default"]=o},3289:function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-list",use:"icon-list-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(o);t["default"]=o},"34c8":function(e,t,n){"use strict";var a=n("88a1"),s=n.n(a);s.a},4360:function(e,t,n){"use strict";var a=n("2b0e"),s=n("2f62"),i=(n("b54a"),n("7f7f"),{sidebar:function(e){return e.app.sidebar},device:function(e){return e.app.device},token:function(e){return e.user.token},name:function(e){return e.user.name},role:function(e){return e.user.role},pinned:function(e){return e.link.pinned}}),r=i,o=n("a78e"),c=n.n(o),u={sidebar:{opened:!c.a.get("sidebarStatus")||!!+c.a.get("sidebarStatus"),withoutAnimation:!1},device:"desktop"},d={TOGGLE_SIDEBAR:function(e){e.sidebar.opened=!e.sidebar.opened,e.sidebar.withoutAnimation=!1,e.sidebar.opened?c.a.set("sidebarStatus",1):c.a.set("sidebarStatus",0)},CLOSE_SIDEBAR:function(e,t){c.a.set("sidebarStatus",0),e.sidebar.opened=!1,e.sidebar.withoutAnimation=t},TOGGLE_DEVICE:function(e,t){e.device=t}},l={toggleSideBar:function(e){var t=e.commit;t("TOGGLE_SIDEBAR")},closeSideBar:function(e,t){var n=e.commit,a=t.withoutAnimation;n("CLOSE_SIDEBAR",a)},toggleDevice:function(e,t){var n=e.commit;n("TOGGLE_DEVICE",t)}},f={namespaced:!0,state:u,mutations:d,actions:l},m=n("83d6"),h=n.n(m),b=h.a.showSettings,p=h.a.fixedHeader,v=h.a.sidebarLogo,g={showSettings:b,fixedHeader:p,sidebarLogo:v},j={CHANGE_SETTING:function(e,t){var n=t.key,a=t.value;e.hasOwnProperty(n)&&(e[n]=a)}},w={changeSetting:function(e,t){var n=e.commit;n("CHANGE_SETTING",t)}},k={namespaced:!0,state:g,mutations:j,actions:w},y=n("c24f"),x=n("5f87"),_=n("a18c"),C=function(){return{token:Object(x["a"])(),name:"",role:1}},O=C(),z={RESET_STATE:function(e){Object.assign(e,C())},SET_TOKEN:function(e,t){e.token=t},SET_NAME:function(e,t){e.name=t},SET_ROLE:function(e,t){e.role=t}},S={login:function(e,t){var n=e.commit,a=t.username,s=t.password;return new Promise((function(e,t){Object(y["c"])({username:a.trim(),password:s}).then((function(t){var a=t.data;n("SET_TOKEN",a.token),Object(x["c"])(a.token),e()})).catch((function(e){t(e)}))}))},getInfo:function(e){var t=e.commit;e.state;return new Promise((function(e,n){Object(y["b"])().then((function(a){var s=a.data;s||n("登入信息验证失败,请重新登入");var i=s.username,r=s.role;t("SET_NAME",i),t("SET_ROLE",r),e(s)})).catch((function(e){n(e)}))}))},logout:function(e){var t=e.commit,n=e.state;return new Promise((function(e,a){Object(y["d"])(n.token).then((function(){Object(x["b"])(),Object(_["b"])(),t("RESET_STATE"),e()})).catch((function(e){a(e)}))}))},resetToken:function(e){var t=e.commit;return new Promise((function(e){Object(x["b"])(),t("RESET_STATE"),e()}))}},E={namespaced:!0,state:O,mutations:z,actions:S},M="pinned",B={pinned:JSON.parse(localStorage.getItem(M)||"[]")},T={PIN:function(e,t){e.pinned.push(t)},UNPIN:function(e,t){e.pinned.indexOf(t)>=0&&e.pinned.splice(e.pinned.indexOf(t),1)}},L={pin:function(e,t){var n=e.commit,a=e.state;n("PIN",t),localStorage.setItem(M,JSON.stringify(a.pinned))},unpin:function(e,t){var n=e.commit,a=e.state;n("UNPIN",t),localStorage.setItem(M,JSON.stringify(a.pinned))}},$={namespaced:!0,state:B,mutations:T,actions:L};a["default"].use(s["a"]);var A=new s["a"].Store({modules:{app:f,settings:k,user:E,link:$},getters:r});t["a"]=A},4678:function(e,t,n){var a={"./af":"2bfb","./af.js":"2bfb","./ar":"8e73","./ar-dz":"a356","./ar-dz.js":"a356","./ar-kw":"423e","./ar-kw.js":"423e","./ar-ly":"1cfd","./ar-ly.js":"1cfd","./ar-ma":"0a84","./ar-ma.js":"0a84","./ar-sa":"8230","./ar-sa.js":"8230","./ar-tn":"6d83","./ar-tn.js":"6d83","./ar.js":"8e73","./az":"485c","./az.js":"485c","./be":"1fc1","./be.js":"1fc1","./bg":"84aa","./bg.js":"84aa","./bm":"a7fa","./bm.js":"a7fa","./bn":"9043","./bn.js":"9043","./bo":"d26a","./bo.js":"d26a","./br":"6887","./br.js":"6887","./bs":"2554","./bs.js":"2554","./ca":"d716","./ca.js":"d716","./cs":"3c0d","./cs.js":"3c0d","./cv":"03ec","./cv.js":"03ec","./cy":"9797","./cy.js":"9797","./da":"0f14","./da.js":"0f14","./de":"b469","./de-at":"b3eb","./de-at.js":"b3eb","./de-ch":"bb71","./de-ch.js":"bb71","./de.js":"b469","./dv":"598a","./dv.js":"598a","./el":"8d47","./el.js":"8d47","./en-SG":"cdab","./en-SG.js":"cdab","./en-au":"0e6b","./en-au.js":"0e6b","./en-ca":"3886","./en-ca.js":"3886","./en-gb":"39a6","./en-gb.js":"39a6","./en-ie":"e1d3","./en-ie.js":"e1d3","./en-il":"7333","./en-il.js":"7333","./en-nz":"6f50","./en-nz.js":"6f50","./eo":"65db","./eo.js":"65db","./es":"898b","./es-do":"0a3c","./es-do.js":"0a3c","./es-us":"55c9","./es-us.js":"55c9","./es.js":"898b","./et":"ec18","./et.js":"ec18","./eu":"0ff2","./eu.js":"0ff2","./fa":"8df4","./fa.js":"8df4","./fi":"81e9","./fi.js":"81e9","./fo":"0721","./fo.js":"0721","./fr":"9f26","./fr-ca":"d9f8","./fr-ca.js":"d9f8","./fr-ch":"0e49","./fr-ch.js":"0e49","./fr.js":"9f26","./fy":"7118","./fy.js":"7118","./ga":"5120","./ga.js":"5120","./gd":"f6b4","./gd.js":"f6b4","./gl":"8840","./gl.js":"8840","./gom-latn":"0caa","./gom-latn.js":"0caa","./gu":"e0c5","./gu.js":"e0c5","./he":"c7aa","./he.js":"c7aa","./hi":"dc4d","./hi.js":"dc4d","./hr":"4ba9","./hr.js":"4ba9","./hu":"5b14","./hu.js":"5b14","./hy-am":"d6b6","./hy-am.js":"d6b6","./id":"5038","./id.js":"5038","./is":"0558","./is.js":"0558","./it":"6e98","./it-ch":"6f12","./it-ch.js":"6f12","./it.js":"6e98","./ja":"079e","./ja.js":"079e","./jv":"b540","./jv.js":"b540","./ka":"201b","./ka.js":"201b","./kk":"6d79","./kk.js":"6d79","./km":"e81d","./km.js":"e81d","./kn":"3e92","./kn.js":"3e92","./ko":"22f8","./ko.js":"22f8","./ku":"2421","./ku.js":"2421","./ky":"9609","./ky.js":"9609","./lb":"440c","./lb.js":"440c","./lo":"b29d","./lo.js":"b29d","./lt":"26f9","./lt.js":"26f9","./lv":"b97c","./lv.js":"b97c","./me":"293c","./me.js":"293c","./mi":"688b","./mi.js":"688b","./mk":"6909","./mk.js":"6909","./ml":"02fb","./ml.js":"02fb","./mn":"958b","./mn.js":"958b","./mr":"39bd","./mr.js":"39bd","./ms":"ebe4","./ms-my":"6403","./ms-my.js":"6403","./ms.js":"ebe4","./mt":"1b45","./mt.js":"1b45","./my":"8689","./my.js":"8689","./nb":"6ce3","./nb.js":"6ce3","./ne":"3a39","./ne.js":"3a39","./nl":"facd","./nl-be":"db29","./nl-be.js":"db29","./nl.js":"facd","./nn":"b84c","./nn.js":"b84c","./pa-in":"f3ff","./pa-in.js":"f3ff","./pl":"8d57","./pl.js":"8d57","./pt":"f260","./pt-br":"d2d4","./pt-br.js":"d2d4","./pt.js":"f260","./ro":"972c","./ro.js":"972c","./ru":"957c","./ru.js":"957c","./sd":"6784","./sd.js":"6784","./se":"ffff","./se.js":"ffff","./si":"eda5","./si.js":"eda5","./sk":"7be6","./sk.js":"7be6","./sl":"8155","./sl.js":"8155","./sq":"c8f3","./sq.js":"c8f3","./sr":"cf1e","./sr-cyrl":"13e9","./sr-cyrl.js":"13e9","./sr.js":"cf1e","./ss":"52bd","./ss.js":"52bd","./sv":"5fbd","./sv.js":"5fbd","./sw":"74dc","./sw.js":"74dc","./ta":"3de5","./ta.js":"3de5","./te":"5cbb","./te.js":"5cbb","./tet":"576c","./tet.js":"576c","./tg":"3b1b","./tg.js":"3b1b","./th":"10e8","./th.js":"10e8","./tl-ph":"0f38","./tl-ph.js":"0f38","./tlh":"cf75","./tlh.js":"cf75","./tr":"0e81","./tr.js":"0e81","./tzl":"cf51","./tzl.js":"cf51","./tzm":"c109","./tzm-latn":"b53d","./tzm-latn.js":"b53d","./tzm.js":"c109","./ug-cn":"6117","./ug-cn.js":"6117","./uk":"ada2","./uk.js":"ada2","./ur":"5294","./ur.js":"5294","./uz":"2e8c","./uz-latn":"010e","./uz-latn.js":"010e","./uz.js":"2e8c","./vi":"2921","./vi.js":"2921","./x-pseudo":"fd7e","./x-pseudo.js":"fd7e","./yo":"7f33","./yo.js":"7f33","./zh-cn":"5c3a","./zh-cn.js":"5c3a","./zh-hk":"49ab","./zh-hk.js":"49ab","./zh-tw":"90ea","./zh-tw.js":"90ea"};function s(e){var t=i(e);return n(t)}function i(e){var t=a[e];if(!(t+1)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return t}s.keys=function(){return Object.keys(a)},s.resolve=i,e.exports=s,s.id="4678"},"4cdc":function(e,t,n){},"4df5":function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-eye",use:"icon-eye-usage",viewBox:"0 0 128 64",content:''});r.a.add(o);t["default"]=o},"51ff":function(e,t,n){var a={"./add.svg":"c2a3","./dashboard.svg":"f782","./eye-open.svg":"d7ec","./eye.svg":"4df5","./form.svg":"eb1b","./github.svg":"558d","./link.svg":"18f0","./list.svg":"3289","./password.svg":"2a3d","./user.svg":"b3b5"};function s(e){var t=i(e);return n(t)}function i(e){var t=a[e];if(!(t+1)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return t}s.keys=function(){return Object.keys(a)},s.resolve=i,e.exports=s,s.id="51ff"},"558d":function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-github",use:"icon-github-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(o);t["default"]=o},"56d7":function(e,t,n){"use strict";n.r(t);n("cadf"),n("551c"),n("f751"),n("097d");var a=n("2b0e"),s=n("c1df"),i=n.n(s),r=(n("f5df"),n("5c96")),o=n.n(r),c=(n("0fae"),n("b20f"),function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{attrs:{id:"app"}},[n("router-view")],1)}),u=[],d={name:"App"},l=d,f=n("2877"),m=Object(f["a"])(l,c,u,!1,null,null,null),h=m.exports,b=n("4360"),p=n("a18c"),v=(n("ac6a"),function(){var e=this,t=e.$createElement,n=e._self._c||t;return e.isExternal?n("div",e._g({staticClass:"svg-external-icon svg-icon",style:e.styleExternalIcon},e.$listeners)):n("svg",e._g({class:e.svgClass,attrs:{"aria-hidden":"true"}},e.$listeners),[n("use",{attrs:{href:e.iconName}})])}),g=[],j=n("61f7"),w={name:"SvgIcon",props:{iconClass:{type:String,required:!0},className:{type:String,default:""}},computed:{isExternal:function(){return Object(j["a"])(this.iconClass)},iconName:function(){return"#icon-".concat(this.iconClass)},svgClass:function(){return this.className?"svg-icon "+this.className:"svg-icon"},styleExternalIcon:function(){return{mask:"url(".concat(this.iconClass,") no-repeat 50% 50%"),"-webkit-mask":"url(".concat(this.iconClass,") no-repeat 50% 50%")}}}},k=w,y=(n("d1a7"),Object(f["a"])(k,v,g,!1,null,"4342976c",null)),x=y.exports;a["default"].component("svg-icon",x);var _=n("51ff"),C=function(e){return e.keys().map(e)};C(_);n("7f7f"),n("96cf");var O=n("3b8d"),z=n("323e"),S=n.n(z),E=(n("a5d8"),n("5f87")),M=n("83d6"),B=n.n(M),T=B.a.title||"Vue Admin Template";function L(e){return e?"".concat(e," - ").concat(T):"".concat(T)}S.a.configure({showSpinner:!1});var $=["/login"];p["a"].beforeEach(function(){var e=Object(O["a"])(regeneratorRuntime.mark((function e(t,n,a){var s,i;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:if(S.a.start(),document.title=L(t.meta.title),s=Object(E["a"])(),!s){e.next=29;break}if("/login"!==t.path){e.next=9;break}a({path:"/"}),S.a.done(),e.next=27;break;case 9:if(i=b["a"].getters.name,!i){e.next=14;break}a(),e.next=27;break;case 14:return e.prev=14,e.next=17,b["a"].dispatch("user/getInfo");case 17:a(),e.next=27;break;case 20:return e.prev=20,e.t0=e["catch"](14),e.next=24,b["a"].dispatch("user/resetToken");case 24:r["Message"].error(e.t0||"Has Error"),a("/login?redirect=".concat(t.path)),S.a.done();case 27:e.next=30;break;case 29:-1!==$.indexOf(t.path)?a():(a("/login?redirect=".concat(t.path)),S.a.done());case 30:case"end":return e.stop()}}),e,null,[[14,20]])})));return function(t,n,a){return e.apply(this,arguments)}}()),p["a"].afterEach((function(){S.a.done()})),a["default"].filter("dateformat",(function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"YYYY-MM-DD HH:mm:ss";return e?i()(e).format(t):"-"})),a["default"].use(o.a),a["default"].config.productionTip=!1,new a["default"]({el:"#app",router:p["a"],store:b["a"],render:function(e){return e(h)}})},"5f87":function(e,t,n){"use strict";n.d(t,"a",(function(){return r})),n.d(t,"c",(function(){return o})),n.d(t,"b",(function(){return c}));var a=n("a78e"),s=n.n(a),i="j2_token";function r(){return s.a.get(i)}function o(e){return s.a.set(i,e)}function c(){return s.a.remove(i)}},"61f7":function(e,t,n){"use strict";n.d(t,"a",(function(){return a})),n.d(t,"c",(function(){return s})),n.d(t,"b",(function(){return r}));n("3b2b");function a(e){return/^(https?:|mailto:|tel:)/.test(e)}function s(e){return e.length>=2}var i=new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|localhost|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\#[-a-z\\d_\\/]*)?(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$","i");function r(e){return!!i.test(e)}},"6b31":function(e,t,n){"use strict";var a=n("4cdc"),s=n.n(a);s.a},"83d6":function(e,t){e.exports={title:"Jump Jump Admin",fixedHeader:!1,sidebarLogo:!1}},"88a1":function(e,t,n){},8902:function(e,t,n){},"9f2b":function(e,t,n){"use strict";var a=n("bf90"),s=n.n(a);s.a},"9f43":function(e,t,n){"use strict";var a=n("2995"),s=n.n(a);s.a},a18c:function(e,t,n){"use strict";var a,s,i=n("2b0e"),r=n("8c4f"),o=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"app-wrapper",class:e.classObj},["mobile"===e.device&&e.sidebar.opened?n("div",{staticClass:"drawer-bg",on:{click:e.handleClickOutside}}):e._e(),e._v(" "),n("sidebar",{staticClass:"sidebar-container"}),e._v(" "),n("div",{staticClass:"main-container"},[n("div",{class:{"fixed-header":e.fixedHeader}},[n("navbar")],1),e._v(" "),n("app-main")],1)],1)},c=[],u=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"navbar"},[n("hamburger",{staticClass:"hamburger-container",attrs:{"is-active":e.sidebar.opened},on:{toggleClick:e.toggleSideBar}}),e._v(" "),n("breadcrumb",{staticClass:"breadcrumb-container"}),e._v(" "),n("div",{staticClass:"right-menu"},[n("el-dropdown",{staticClass:"username-container",attrs:{trigger:"click"}},[n("div",{staticClass:"username-wrapper"},[n("span",{staticStyle:{cursor:"pointer"}},[e._v(e._s(e.name))])]),e._v(" "),n("el-dropdown-menu",{staticClass:"user-dropdown",attrs:{slot:"dropdown"},slot:"dropdown"},[n("router-link",{attrs:{to:"/"}},[n("el-dropdown-item",[e._v("首页")])],1),e._v(" "),n("router-link",{attrs:{to:"/security/change-password"}},[n("el-dropdown-item",[e._v("修改密码")])],1),e._v(" "),n("a",{attrs:{target:"_blank",href:"https://github.com/jwma/jump-jump"}},[n("el-dropdown-item",[e._v("Github")])],1),e._v(" "),n("el-dropdown-item",{attrs:{divided:""},nativeOn:{click:function(t){return e.logout(t)}}},[n("span",{staticStyle:{display:"block"}},[e._v("登出")])])],1)],1)],1)],1)},d=[],l=(n("96cf"),n("3b8d")),f=n("db72"),m=n("2f62"),h=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-breadcrumb",{staticClass:"app-breadcrumb",attrs:{separator:"/"}},[n("transition-group",{attrs:{name:"breadcrumb"}},e._l(e.levelList,(function(t,a){return n("el-breadcrumb-item",{key:t.path},["noRedirect"===t.redirect||a==e.levelList.length-1?n("span",{staticClass:"no-redirect"},[e._v(e._s(t.meta.title))]):n("a",{on:{click:function(n){return n.preventDefault(),e.handleLink(t)}}},[e._v(e._s(t.meta.title))])])})),1)],1)},b=[],p=(n("7f7f"),n("bd11")),v=n.n(p),g={data:function(){return{levelList:null}},watch:{$route:function(){this.getBreadcrumb()}},created:function(){this.getBreadcrumb()},methods:{getBreadcrumb:function(){var e=this.$route.matched.filter((function(e){return e.meta&&e.meta.title})),t=e[0];this.isDashboard(t)||(e=[{path:"/dashboard",meta:{title:"Dashboard"}}].concat(e)),this.levelList=e.filter((function(e){return e.meta&&e.meta.title&&!1!==e.meta.breadcrumb}))},isDashboard:function(e){var t=e&&e.name;return!!t&&t.trim().toLocaleLowerCase()==="Dashboard".toLocaleLowerCase()},pathCompile:function(e){var t=this.$route.params,n=v.a.compile(e);return n(t)},handleLink:function(e){var t=e.redirect,n=e.path;t?this.$router.push(t):this.$router.push(this.pathCompile(n))}}},j=g,w=(n("34c8"),n("2877")),k=Object(w["a"])(j,h,b,!1,null,"62cc9144",null),y=k.exports,x=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticStyle:{padding:"0 15px"},on:{click:e.toggleClick}},[n("svg",{staticClass:"hamburger",class:{"is-active":e.isActive},attrs:{viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg",width:"64",height:"64"}},[n("path",{attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"}})])])},_=[],C={name:"Hamburger",props:{isActive:{type:Boolean,default:!1}},methods:{toggleClick:function(){this.$emit("toggleClick")}}},O=C,z=(n("186a"),Object(w["a"])(O,x,_,!1,null,"49e15297",null)),S=z.exports,E={components:{Breadcrumb:y,Hamburger:S},computed:Object(f["a"])({},Object(m["b"])(["sidebar","name"])),methods:{toggleSideBar:function(){this.$store.dispatch("app/toggleSideBar")},logout:function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return e.next=2,this.$store.dispatch("user/logout");case 2:this.$router.push("/login?redirect=".concat(this.$route.fullPath));case 3:case"end":return e.stop()}}),e,this)})));function t(){return e.apply(this,arguments)}return t}()}},M=E,B=(n("9f43"),Object(w["a"])(M,u,d,!1,null,"26745010",null)),T=B.exports,L=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:{"has-logo":e.showLogo}},[e.showLogo?n("logo",{attrs:{collapse:e.isCollapse}}):e._e(),e._v(" "),n("el-scrollbar",{attrs:{"wrap-class":"scrollbar-wrapper"}},[n("el-menu",{attrs:{"default-active":e.activeMenu,collapse:e.isCollapse,"background-color":e.variables.menuBg,"text-color":e.variables.menuText,"unique-opened":!1,"active-text-color":e.variables.menuActiveText,"collapse-transition":!1,mode:"vertical"}},e._l(e.routes,(function(e){return n("sidebar-item",{key:e.path,attrs:{item:e,"base-path":e.path}})})),1)],1)],1)},$=[],A=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"sidebar-logo-container",class:{collapse:e.collapse}},[n("transition",{attrs:{name:"sidebarLogoFade"}},[e.collapse?n("router-link",{key:"collapse",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])]):n("router-link",{key:"expand",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):e._e(),e._v(" "),n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])])],1)],1)},H=[],N={name:"SidebarLogo",props:{collapse:{type:Boolean,required:!0}},data:function(){return{title:"Vue Admin Template",logo:"https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png"}}},I=N,P=(n("6b31"),Object(w["a"])(I,A,H,!1,null,"5bb1c0e2",null)),D=P.exports,q=function(){var e=this,t=e.$createElement,n=e._self._c||t;return e.item.hidden?e._e():n("div",[!e.hasOneShowingChild(e.item.children,e.item)||e.onlyOneChild.children&&!e.onlyOneChild.noShowingChildren||e.item.alwaysShow?n("el-submenu",{ref:"subMenu",attrs:{index:e.resolvePath(e.item.path),"popper-append-to-body":""}},[n("template",{slot:"title"},[e.item.meta?n("item",{attrs:{icon:e.item.meta&&e.item.meta.icon,title:e.item.meta.title}}):e._e()],1),e._v(" "),e._l(e.item.children,(function(t){return n("sidebar-item",{key:t.path,staticClass:"nest-menu",attrs:{"is-nest":!0,item:t,"base-path":e.resolvePath(t.path)}})}))],2):[e.onlyOneChild.meta?n("app-link",{attrs:{to:e.resolvePath(e.onlyOneChild.path)}},[n("el-menu-item",{class:{"submenu-title-noDropdown":!e.isNest},attrs:{index:e.resolvePath(e.onlyOneChild.path)}},[n("item",{attrs:{icon:e.onlyOneChild.meta.icon||e.item.meta&&e.item.meta.icon,title:e.onlyOneChild.meta.title}})],1)],1):e._e()]],2)},R=[],G=n("df7c"),U=n.n(G),V=n("61f7"),F={name:"MenuItem",functional:!0,props:{icon:{type:String,default:""},title:{type:String,default:""}},render:function(e,t){var n=t.props,a=n.icon,s=n.title,i=[];return a&&i.push(e("svg-icon",{attrs:{"icon-class":a}})),s&&i.push(e("span",{slot:"title"},[s])),i}},J=F,Y=Object(w["a"])(J,a,s,!1,null,null,null),K=Y.exports,W=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("component",e._b({},"component",e.linkProps(e.to),!1),[e._t("default")],2)},Q=[],X={props:{to:{type:String,required:!0}},methods:{linkProps:function(e){return Object(V["a"])(e)?{is:"a",href:e,target:"_blank",rel:"noopener"}:{is:"router-link",to:e}}}},Z=X,ee=Object(w["a"])(Z,W,Q,!1,null,null,null),te=ee.exports,ne={computed:{device:function(){return this.$store.state.app.device}},mounted:function(){this.fixBugIniOS()},methods:{fixBugIniOS:function(){var e=this,t=this.$refs.subMenu;if(t){var n=t.handleMouseleave;t.handleMouseleave=function(t){"mobile"!==e.device&&n(t)}}}}},ae={name:"SidebarItem",components:{Item:K,AppLink:te},mixins:[ne],props:{item:{type:Object,required:!0},isNest:{type:Boolean,default:!1},basePath:{type:String,default:""}},data:function(){return this.onlyOneChild=null,{}},methods:{hasOneShowingChild:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],n=arguments.length>1?arguments[1]:void 0,a=t.filter((function(t){return!t.hidden&&(e.onlyOneChild=t,!0)}));return 1===a.length||0===a.length&&(this.onlyOneChild=Object(f["a"])({},n,{path:"",noShowingChildren:!0}),!0)},resolvePath:function(e){return Object(V["a"])(e)?e:Object(V["a"])(this.basePath)?this.basePath:U.a.resolve(this.basePath,e)}}},se=ae,ie=Object(w["a"])(se,q,R,!1,null,null,null),re=ie.exports,oe=n("cf1e2"),ce=n.n(oe),ue={components:{SidebarItem:re,Logo:D},computed:Object(f["a"])({},Object(m["b"])(["sidebar"]),{routes:function(){return this.$router.options.routes},activeMenu:function(){var e=this.$route,t=e.meta,n=e.path;return t.activeMenu?t.activeMenu:n},showLogo:function(){return this.$store.state.settings.sidebarLogo},variables:function(){return ce.a},isCollapse:function(){return!this.sidebar.opened}})},de=ue,le=Object(w["a"])(de,L,$,!1,null,null,null),fe=le.exports,me=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("section",{staticClass:"app-main"},[n("transition",{attrs:{name:"fade-transform",mode:"out-in"}},[n("router-view",{key:e.key})],1)],1)},he=[],be={name:"AppMain",computed:{key:function(){return this.$route.path}}},pe=be,ve=(n("e4de"),n("028b"),Object(w["a"])(pe,me,he,!1,null,"64cf4d83",null)),ge=ve.exports,je=n("4360"),we=document,ke=we.body,ye=992,xe={watch:{$route:function(e){"mobile"===this.device&&this.sidebar.opened&&je["a"].dispatch("app/closeSideBar",{withoutAnimation:!1})}},beforeMount:function(){window.addEventListener("resize",this.$_resizeHandler)},beforeDestroy:function(){window.removeEventListener("resize",this.$_resizeHandler)},mounted:function(){var e=this.$_isMobile();e&&(je["a"].dispatch("app/toggleDevice","mobile"),je["a"].dispatch("app/closeSideBar",{withoutAnimation:!0}))},methods:{$_isMobile:function(){var e=ke.getBoundingClientRect();return e.width-1'});r.a.add(o);t["default"]=o},b775:function(e,t,n){"use strict";var a=n("bc3a"),s=n.n(a),i=n("5c96"),r=n("4360"),o=n("5f87"),c=s.a.create({baseURL:"",timeout:5e3});c.interceptors.request.use((function(e){return r["a"].getters.token&&(e.headers["Authorization"]="Bearer "+Object(o["a"])()),e}),(function(e){return console.log(e),Promise.reject(e)})),c.interceptors.response.use((function(e){var t=e.data;return 4999===t.code?(Object(i["Message"])({message:t.msg||"Error",type:"error",duration:5e3}),Promise.reject(new Error(t.message||"Error"))):t}),(function(e){var t=e.response;return 401===t.status?i["MessageBox"].confirm("你的登入已过期,请重新登入","登入过期",{confirmButtonText:"重新登入",cancelButtonText:"取消",type:"warning"}).then((function(){r["a"].dispatch("user/resetToken").then((function(){location.reload()}))})):500===t.status&&Object(i["Message"])({message:"服务器繁忙,请稍后再试...",type:"error",duration:5e3}),Promise.reject(e)})),t["a"]=c},bf90:function(e,t,n){},c24f:function(e,t,n){"use strict";n.d(t,"c",(function(){return s})),n.d(t,"b",(function(){return i})),n.d(t,"d",(function(){return r})),n.d(t,"a",(function(){return o}));var a=n("b775");function s(e){return Object(a["a"])({url:"/v1/user/login",method:"post",data:e})}function i(){return Object(a["a"])({url:"/v1/user/info",method:"get"})}function r(){return Object(a["a"])({url:"/v1/user/logout",method:"post"})}function o(e){return Object(a["a"])({url:"/v1/user/change-password",method:"post",data:e})}},c2a3:function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-add",use:"icon-add-usage",viewBox:"0 0 1026 1024",content:''});r.a.add(o);t["default"]=o},cf1e2:function(e,t,n){e.exports={menuText:"#bfcbd9",menuActiveText:"#409EFF",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},d1a7:function(e,t,n){"use strict";var a=n("031b"),s=n.n(a);s.a},d7ec:function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-eye-open",use:"icon-eye-open-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(o);t["default"]=o},dc52:function(e,t,n){},e4de:function(e,t,n){"use strict";var a=n("8902"),s=n.n(a);s.a},eb1b:function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-form",use:"icon-form-usage",viewBox:"0 0 128 128",content:''});r.a.add(o);t["default"]=o},f12c:function(e,t,n){},f782:function(e,t,n){"use strict";n.r(t);var a=n("e017"),s=n.n(a),i=n("21a1"),r=n.n(i),o=new s.a({id:"icon-dashboard",use:"icon-dashboard-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(o);t["default"]=o}},[[0,"runtime","chunk-elementUI","chunk-libs"]]]); \ No newline at end of file diff --git a/web/admin/static/js/chunk-13714370.65803237.js b/web/admin/static/js/chunk-13714370.65803237.js new file mode 100644 index 0000000..ebbd013 --- /dev/null +++ b/web/admin/static/js/chunk-13714370.65803237.js @@ -0,0 +1,8 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-13714370"],{"80f1":function(e,t,r){},9472:function(e,t,r){"use strict";r.r(t);var n=function(){var e=this,t=e.$createElement,r=e._self._c||t;return r("el-main",[r("el-drawer",{ref:"createFormDrawer",attrs:{visible:e.createFormDrawer,direction:"rtl","before-close":e.handleCreateFormDrawerClose},on:{"update:visible":function(t){e.createFormDrawer=t}}},[r("div",{staticStyle:{width:"90%","margin-left":"15px"}},[r("h2",{staticStyle:{"margin-top":"0",color:"#606266"}},[e._v("添加短链接")]),e._v(" "),r("el-form",{ref:"createForm",attrs:{model:e.createForm,rules:e.createFormRules}},[r("el-form-item",{directives:[{name:"show",rawName:"v-show",value:2===e.role,expression:"role === 2"}],attrs:{label:"指定 ID",prop:"id"}},[r("el-switch",{on:{change:function(t){return e.specifyIdChange(t)}},model:{value:e.createForm.specifyId,callback:function(t){e.$set(e.createForm,"specifyId",t)},expression:"createForm.specifyId"}}),e._v(" "),r("el-popover",{attrs:{placement:"bottom",width:"320",trigger:"hover"}},[r("p",[e._v("设置你期望的ID,设置后随机ID将不起作用。")]),e._v(" "),r("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})]),e._v(" "),r("el-input",{directives:[{name:"show",rawName:"v-show",value:e.createForm.specifyId,expression:"createForm.specifyId"}],attrs:{disabled:e.createForm.setIdLength,placeholder:"示例:home"},model:{value:e.createForm.id,callback:function(t){e.$set(e.createForm,"id",t)},expression:"createForm.id"}})],1),e._v(" "),r("el-form-item",{directives:[{name:"show",rawName:"v-show",value:2===e.role,expression:"role === 2"}],attrs:{label:"指定随机 ID 长度",prop:"idLength"}},[r("el-switch",{on:{change:function(t){return e.setIdLengthChange(t)}},model:{value:e.createForm.setIdLength,callback:function(t){e.$set(e.createForm,"setIdLength",t)},expression:"createForm.setIdLength"}}),e._v(" "),r("el-popover",{attrs:{placement:"bottom",width:"320",trigger:"hover"}},[r("p",[e._v("在允许的范围内指定随机ID的长度,不指定时会使用系统默认设置。")]),e._v(" "),r("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})]),e._v(" "),r("el-slider",{directives:[{name:"show",rawName:"v-show",value:e.createForm.setIdLength,expression:"createForm.setIdLength"}],attrs:{"show-input":"",disabled:e.createForm.specifyId,min:e.idConfig.idMinimumLength,max:e.idConfig.idMaximumLength},model:{value:e.createForm.idLength,callback:function(t){e.$set(e.createForm,"idLength",t)},expression:"createForm.idLength"}})],1),e._v(" "),r("el-form-item",{attrs:{label:"目标链接",prop:"url"}},[r("el-input",{attrs:{placeholder:"示例:https://github.com/jwma/jump-jump"},model:{value:e.createForm.url,callback:function(t){e.$set(e.createForm,"url",t)},expression:"createForm.url"}})],1),e._v(" "),r("el-form-item",{attrs:{label:"描述",prop:"description"}},[r("el-input",{attrs:{type:"textarea",placeholder:"示例:某某帖子使用"},model:{value:e.createForm.description,callback:function(t){e.$set(e.createForm,"description",t)},expression:"createForm.description"}})],1),e._v(" "),r("el-form-item",{attrs:{label:"启用?",prop:"isEnable"}},[r("el-switch",{model:{value:e.createForm.isEnable,callback:function(t){e.$set(e.createForm,"isEnable",t)},expression:"createForm.isEnable"}}),e._v(" "),r("el-popover",{attrs:{placement:"bottom",width:"320",trigger:"hover"}},[r("p",[e._v("开启后短链接可以正常被访问,关闭后短链接被访问时会告知用户访问的页面不存在。"),r("br"),e._v(" "),r("strong",[e._v("注意:关闭后不会统计短链接访问的数据。")])]),e._v(" "),r("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})])],1),e._v(" "),r("el-form-item",[r("el-button",{attrs:{size:"mini",type:"primary"},on:{click:e.onCreateFormSubmit}},[e._v("添加")]),e._v(" "),r("el-button",{attrs:{size:"mini"},on:{click:e.onCreateFormCancel}},[e._v("取消")])],1)],1)],1)]),e._v(" "),r("el-drawer",{ref:"editFormDrawer",attrs:{visible:e.editFormDrawer,direction:"rtl","before-close":e.handleEditFormDrawerClose},on:{"update:visible":function(t){e.editFormDrawer=t}}},[r("div",{staticStyle:{width:"90%","margin-left":"15px"}},[r("h2",{staticStyle:{"margin-top":"0",color:"#606266"}},[e._v("更新:"+e._s(e.editForm.id))]),e._v(" "),r("el-form",{ref:"editForm",attrs:{model:e.editForm,rules:e.editFormRules}},[r("el-form-item",{attrs:{label:"目标链接",prop:"url"}},[r("el-input",{attrs:{placeholder:"示例:https://github.com/jwma/jump-jump"},model:{value:e.editForm.url,callback:function(t){e.$set(e.editForm,"url",t)},expression:"editForm.url"}})],1),e._v(" "),r("el-form-item",{attrs:{label:"描述",prop:"description"}},[r("el-input",{attrs:{type:"textarea",placeholder:"示例:某某帖子使用"},model:{value:e.editForm.description,callback:function(t){e.$set(e.editForm,"description",t)},expression:"editForm.description"}})],1),e._v(" "),r("el-form-item",{attrs:{label:"启用?",prop:"isEnable"}},[r("el-switch",{model:{value:e.editForm.isEnable,callback:function(t){e.$set(e.editForm,"isEnable",t)},expression:"editForm.isEnable"}}),e._v(" "),r("el-popover",{attrs:{placement:"bottom",width:"320",trigger:"hover"}},[r("p",[e._v("开启后短链接可以正常被访问,关闭后短链接被访问时会告知用户访问的页面不存在。"),r("br"),e._v(" "),r("strong",[e._v("注意:关闭后不会统计短链接访问的数据。")])]),e._v(" "),r("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})])],1),e._v(" "),r("el-form-item",{attrs:{label:"创建人"}},[r("span",{staticStyle:{color:"#909399"}},[e._v(e._s(e.editForm.createdBy))])]),e._v(" "),r("el-form-item",{attrs:{label:"添加时间"}},[r("span",{staticStyle:{color:"#909399"}},[e._v(e._s(e._f("dateformat")(e.editForm.createTime)))])]),e._v(" "),r("el-form-item",{attrs:{label:"更新时间"}},[r("span",{staticStyle:{color:"#909399"}},[e._v(e._s(e._f("dateformat")(e.editForm.updateTime)))])]),e._v(" "),r("el-form-item",[r("el-button",{attrs:{size:"mini",type:"primary"},on:{click:e.onEditFormSubmit}},[e._v("更新")]),e._v(" "),r("el-button",{attrs:{size:"mini"},on:{click:e.onEditFormCancel}},[e._v("取消")])],1)],1)],1)]),e._v(" "),r("el-button",{attrs:{icon:"el-icon-refresh",size:"mini"},on:{click:function(t){return e.getList(e.currentPage)}}},[e._v("刷新")]),e._v(" "),r("el-button",{attrs:{icon:"el-icon-plus",size:"mini",type:"primary"},on:{click:function(t){return e.toCreate()}}},[e._v("添加\n ")]),e._v(" "),r("el-table",{staticStyle:{width:"100%"},attrs:{data:e.list,"max-height":"800",fit:""}},[r("el-table-column",{attrs:{label:"短链接",width:"250"},scopedSlots:e._u([{key:"default",fn:function(t){return[r("i",{class:{"el-icon-star-off":-1==e.pinned.indexOf(t.row.id),"el-icon-star-on":-1!=e.pinned.indexOf(t.row.id)},staticStyle:{cursor:"pointer"},on:{click:function(r){return e.pin(t.row.id)}}}),e._v(" "),r("el-dropdown",{attrs:{size:"small"}},[r("span",{staticClass:"el-dropdown-link",staticStyle:{cursor:"pointer"}},[e._v("\n "+e._s(t.row.id)),r("i",{staticClass:"el-icon-arrow-down el-icon--right"})]),e._v(" "),r("el-dropdown-menu",{attrs:{slot:"dropdown"},slot:"dropdown"},e._l(e.landingHosts,(function(n){return r("el-dropdown-item",[r("span",{on:{click:function(r){return e.copyShortLink(n+t.row.id,r)}}},[e._v(e._s(n+t.row.id))])])})),1)],1)]}}])}),e._v(" "),r("el-table-column",{attrs:{prop:"url",label:"目标链接",width:"250"},scopedSlots:e._u([{key:"default",fn:function(t){return[r("el-dropdown",{attrs:{size:"small"}},[r("span",{staticClass:"el-dropdown-link",staticStyle:{cursor:"pointer"}},[r("span",{staticStyle:{width:"200px",overflow:"hidden","text-overflow":"ellipsis","white-space":"nowrap",display:"inline-block"}},[e._v(e._s(t.row.url))])]),e._v(" "),r("el-dropdown-menu",{attrs:{slot:"dropdown"},slot:"dropdown"},[r("el-dropdown-item",{staticStyle:{"line-height":"18px"}},[r("span",{on:{click:function(r){return e.copyShortLink(t.row.url,r)}}},[e._v(e._s(t.row.url))])])],1)],1)]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"描述",width:"300"},scopedSlots:e._u([{key:"default",fn:function(t){return[e._v("\n "+e._s(t.row.description?t.row.description:"-")+"\n ")]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"启用?",width:"70",align:"center"},scopedSlots:e._u([{key:"default",fn:function(e){return[r("i",{class:{"el-icon-check":e.row.isEnable,"el-icon-close":!e.row.isEnable}})]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"创建人",width:"150",align:"center"},scopedSlots:e._u([{key:"default",fn:function(t){return[e._v("\n "+e._s(t.row.createdBy)+"\n ")]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"添加时间",width:"100"},scopedSlots:e._u([{key:"default",fn:function(t){return[e._v("\n "+e._s(e._f("dateformat")(t.row.createTime,"DD/MM/YY"))+"\n ")]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"更新时间",width:"100"},scopedSlots:e._u([{key:"default",fn:function(t){return[e._v("\n "+e._s(e._f("dateformat")(t.row.updateTime,"DD/MM/YY"))+"\n ")]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"操作"},scopedSlots:e._u([{key:"default",fn:function(t){return[r("el-button",{attrs:{size:"mini",circle:"",icon:"el-icon-s-data"},on:{click:function(r){return e.goto({name:"ShortLinkData",params:{id:t.row.id}})}}}),e._v(" "),r("el-button",{attrs:{size:"mini",circle:"",icon:"el-icon-edit-outline"},on:{click:function(r){return e.toEdit(t.row.id)}}}),e._v(" "),r("el-button",{attrs:{type:"danger",size:"mini",icon:"el-icon-delete-solid",circle:""},on:{click:function(r){return e.deleteShortLink(t.row.id)}}})]}}])})],1),e._v(" "),r("div",{staticClass:"paginator-container"},[r("el-pagination",{attrs:{"current-page":e.currentPage,"page-sizes":[10,20,30],"page-size":e.pageSize,layout:"total, sizes, prev, pager, next, jumper",total:e.total},on:{"size-change":e.handlePageSizeChange,"current-change":e.handleCurrentPageChange}})],1)],1)},i=[],o=r("db72"),a=r("bfad"),c=r("da71"),s=r("61f7"),l=r("2b0e"),u=r("b311"),d=r.n(u);function f(){l["default"].prototype.$message({message:"复制成功",type:"success",duration:1500})}function m(){l["default"].prototype.$message({message:"复制失败",type:"error"})}function h(e,t){var r=new d.a(t.target,{text:function(){return e}});r.on("success",(function(){f(),r.off("error"),r.off("success"),r.destroy()})),r.on("error",(function(){m(),r.off("error"),r.off("success"),r.destroy()})),r.onClick(t)}var p=r("2f62"),g={name:"ShortLinkList",data:function(){var e=function(e,t,r){""!==t?r():r(new Error("请输入目标链接"))};return{landingHosts:[],list:[],total:0,currentPage:1,pageSize:20,createFormDrawer:!1,idConfig:{idMinimumLength:0,idLength:0,idMaximumLength:0},createForm:{specifyId:!1,setIdLength:!1,id:"",url:"",description:"",isEnable:!1,idLength:0},createFormRules:{url:[{required:!0,validator:e,trigger:"blur"}]},editFormDrawer:!1,editForm:{id:"",url:"",description:"",isEnable:!1,createdBy:"",createTime:"",updateTime:""},editFormRules:{url:[{validator:e,trigger:"blur"}]}}},beforeRouteUpdate:function(e,t,r){this.currentPage=e.query.page||this.currentPage,this.pageSize=e.query.pageSize||this.pageSize,this.getList(this.currentPage),r()},created:function(){var e=this;this.currentPage=parseInt(this.$route.query.page)||this.currentPage,this.pageSize=parseInt(this.$route.query.pageSize)||this.pageSize,Object(c["a"])().then((function(t){e.landingHosts=t.data.config.landingHosts,e.idConfig=t.data.config.idConfig,e.createForm.idLength=e.idConfig.idLength,e.getList(e.currentPage)}))},computed:Object(o["a"])({},Object(p["b"])(["role","pinned"])),methods:{goto:function(e){this.$router.push(e)},copyShortLink:function(e,t){h(e,t)},getList:function(e){var t=this;Object(a["b"])(e,this.pageSize).then((function(r){t.currentPage=e,t.total=r.data.total,t.list=r.data.shortLinks,1!==t.currentPage&&0===t.list.length&&t.total>0&&(t.currentPage=1,t.getList(1))}))},resetCreateForm:function(){this.createForm.specifyId=!1,this.createForm.setIdLength=!1,this.createForm.id="",this.createForm.url="",this.createForm.description="",this.createForm.isEnable=!1},resetEditForm:function(){this.editForm.url="",this.editForm.description="",this.editForm.isEnable=!1,this.editForm.createdBy="",this.editForm.createTime="",this.editForm.updateTime=""},getInvalidUrlTipsText:function(e){return'
目标链接不是常规的URL,确定继续?")},handlePageSizeChange:function(e){this.pageSize=e,this.currentPage=1,this.$router.push({name:"ShortLinkList",query:{page:1,pageSize:e}})},handleCurrentPageChange:function(e){this.currentPage=e,this.$router.push({name:"ShortLinkList",query:{page:e,pageSize:this.pageSize}})},toCreate:function(){var e=this;Object(c["a"])().then((function(t){e.idConfig=t.data.config.idConfig,e.createForm.idLength=e.idConfig.idLength,e.createFormDrawer=!0}))},handleCreateFormDrawerClose:function(e){this.resetCreateForm(),e()},submitCreateForm:function(){var e=this;Object(a["a"])(this.createForm).then((function(t){e.$refs.createFormDrawer.closeDrawer(),e.$notify({title:"添加短链接成功",message:"ID:"+t.data.shortLink.id,type:"success"}),e.getList(e.currentPage)}))},onCreateFormSubmit:function(){var e=this;this.$refs.createForm.validate((function(t){if(!t)return!1;Object(s["b"])(e.createForm.url)?e.submitCreateForm():e.$confirm(e.getInvalidUrlTipsText(e.createForm.url),"提示",{confirmButtonText:"确定",cancelButtonText:"再改改",type:"warning",dangerouslyUseHTMLString:!0}).then((function(){e.submitCreateForm()}))}))},onCreateFormCancel:function(){this.resetCreateForm(),this.createFormDrawer=!1},toEdit:function(e){var t=this;Object(a["c"])(e).then((function(e){t.editFormDrawer=!0,t.editForm=e.data.shortLink}))},handleEditFormDrawerClose:function(e){this.resetEditForm(),e()},submitEditForm:function(){var e=this;Object(a["f"])(this.editForm.id,this.editForm).then((function(t){e.$refs.editFormDrawer.closeDrawer(),e.$notify({title:"更新成功",message:"ID:"+t.data.shortLink.id,type:"success"}),e.getList(e.currentPage)}))},onEditFormSubmit:function(){var e=this;this.$refs.editForm.validate((function(t){if(!t)return!1;Object(s["b"])(e.editForm.url)?e.submitEditForm():e.$confirm(e.getInvalidUrlTipsText(e.editForm.url),"提示",{confirmButtonText:"确定",cancelButtonText:"再改改",type:"warning",dangerouslyUseHTMLString:!0}).then((function(){e.submitEditForm()}))}))},onEditFormCancel:function(){this.resetEditForm(),this.editFormDrawer=!1},deleteShortLink:function(e){var t=this;this.$confirm("此操作会永久删除短链接,是否继续?","删除确认",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then((function(){Object(a["e"])(e).then((function(r){t.$notify({title:"成功删除短链接",message:"ID:".concat(e),type:"success"}),t.getList(t.currentPage),t.$store.dispatch("link/unpin",e)}))}))},specifyIdChange:function(e){e?(this.createForm.setIdLength=!1,this.setIdLengthChange(!1)):this.createForm.id=""},setIdLengthChange:function(e){e?(this.createForm.specifyId=!1,this.specifyIdChange(!1)):this.createForm.idLength=this.idConfig.idLength},pin:function(e){-1==this.pinned.indexOf(e)?(this.$store.dispatch("link/pin",e),this.$message({showClose:!0,type:"success",message:"Pin ".concat(e)})):(this.$store.dispatch("link/unpin",e),this.$message({showClose:!0,type:"success",message:"Unpin ".concat(e)}))}}},v=g,b=(r("e160"),r("2877")),y=Object(b["a"])(v,n,i,!1,null,"901f7d5c",null);t["default"]=y.exports},b311:function(e,t,r){ +/*! + * clipboard.js v2.0.6 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +(function(t,r){e.exports=r()})(0,(function(){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=6)}([function(e,t){function r(e){var t;if("SELECT"===e.nodeName)e.focus(),t=e.value;else if("INPUT"===e.nodeName||"TEXTAREA"===e.nodeName){var r=e.hasAttribute("readonly");r||e.setAttribute("readonly",""),e.select(),e.setSelectionRange(0,e.value.length),r||e.removeAttribute("readonly"),t=e.value}else{e.hasAttribute("contenteditable")&&e.focus();var n=window.getSelection(),i=document.createRange();i.selectNodeContents(e),n.removeAllRanges(),n.addRange(i),t=n.toString()}return t}e.exports=r},function(e,t){function r(){}r.prototype={on:function(e,t,r){var n=this.e||(this.e={});return(n[e]||(n[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var n=this;function i(){n.off(e,i),t.apply(r,arguments)}return i._=t,this.on(e,i,r)},emit:function(e){var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),n=0,i=r.length;for(n;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=e.action,this.container=e.container,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var e=this,t="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[t?"right":"left"]="-9999px";var r=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=r+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=i()(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=i()(this.target),this.copyText()}},{key:"copyText",value:function(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),document.activeElement.blur(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(e){if(void 0!==e){if(!e||"object"!==("undefined"===typeof e?"undefined":o(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function(){return this._target}}]),e}(),l=s,u=r(1),d=r.n(u),f=r(2),m=r.n(f),h="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},p=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"===typeof e.action?e.action:this.defaultAction,this.target="function"===typeof e.target?e.target:this.defaultTarget,this.text="function"===typeof e.text?e.text:this.defaultText,this.container="object"===h(e.container)?e.container:document.body}},{key:"listenClick",value:function(e){var t=this;this.listener=m()(e,"click",(function(e){return t.onClick(e)}))}},{key:"onClick",value:function(e){var t=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new l({action:this.action(t),target:this.target(t),text:this.text(t),container:this.container,trigger:t,emitter:this})}},{key:"defaultAction",value:function(e){return w("action",e)}},{key:"defaultTarget",value:function(e){var t=w("target",e);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(e){return w("text",e)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"===typeof e?[e]:e,r=!!document.queryCommandSupported;return t.forEach((function(e){r=r&&!!document.queryCommandSupported(e)})),r}}]),t}(d.a);function w(e,t){var r="data-clipboard-"+e;if(t.hasAttribute(r))return t.getAttribute(r)}t["default"]=y}])["default"]}))},bfad:function(e,t,r){"use strict";r.d(t,"c",(function(){return i})),r.d(t,"b",(function(){return o})),r.d(t,"a",(function(){return a})),r.d(t,"e",(function(){return c})),r.d(t,"f",(function(){return s})),r.d(t,"d",(function(){return l}));var n=r("b775");function i(e){return Object(n["a"])({url:"/v1/short-link/".concat(e),method:"get"})}function o(e,t){return Object(n["a"])({url:"/v1/short-link/?page=".concat(e,"&pageSize=").concat(t),method:"get"})}function a(e){return Object(n["a"])({url:"/v1/short-link/",method:"post",data:e})}function c(e){return Object(n["a"])({url:"/v1/short-link/".concat(e),method:"delete"})}function s(e,t){return Object(n["a"])({url:"/v1/short-link/".concat(e),method:"patch",data:t})}function l(e,t,r){return Object(n["a"])({url:"/v1/short-link/".concat(e,"/data?startDate=").concat(t,"&endDate=").concat(r),method:"get"})}},da71:function(e,t,r){"use strict";r.d(t,"a",(function(){return i})),r.d(t,"c",(function(){return o})),r.d(t,"b",(function(){return a})),r.d(t,"d",(function(){return c}));var n=r("b775");function i(){return Object(n["a"])({url:"/v1/config",method:"get"})}function o(e){return Object(n["a"])({url:"/v1/config/landing-hosts",method:"patch",data:e})}function a(e){return Object(n["a"])({url:"/v1/config/id-length",method:"patch",data:e})}function c(e){return Object(n["a"])({url:"/v1/config/short-link-404-handling",method:"patch",data:e})}},e160:function(e,t,r){"use strict";var n=r("80f1"),i=r.n(n);i.a}}]); \ No newline at end of file diff --git a/web/admin/static/js/chunk-5011652c.8ca5679a.js b/web/admin/static/js/chunk-5011652c.8ca5679a.js new file mode 100644 index 0000000..9732cfc --- /dev/null +++ b/web/admin/static/js/chunk-5011652c.8ca5679a.js @@ -0,0 +1 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-5011652c"],{"14c9":function(t,a,e){"use strict";var n=function(){var t=this,a=t.$createElement,e=t._self._c||a;return e("div",{class:t.className,style:{height:t.height,width:t.width}})},i=[],r=e("313e"),o=e.n(r);e("817d");var c={props:{className:{type:String,default:"chart"},width:{type:String,default:"100%"},height:{type:String,default:"350px"},autoResize:{type:Boolean,default:!0},chartData:{type:Object,required:!0},title:{type:Object,default:{}}},data:function(){return{chart:null}},watch:{chartData:{deep:!0,handler:function(t){this.setOptions(t)}}},mounted:function(){var t=this;this.$nextTick((function(){t.initChart()}))},beforeDestroy:function(){this.chart&&(this.chart.dispose(),this.chart=null)},methods:{initChart:function(){this.chart=o.a.init(this.$el,"macarons"),this.setOptions(this.chartData)},setOptions:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},a=t.pv,e=t.uv,n=t.dates;this.chart&&this.chart.setOption({title:this.title,xAxis:{data:n,boundaryGap:!1,axisTick:{show:!1}},grid:{left:50,right:50,bottom:20,top:30,containLabel:!0},tooltip:{trigger:"axis",axisPointer:{type:"cross"},padding:[5,10]},yAxis:{axisTick:{show:!1}},legend:{data:["PV","UV"]},series:[{name:"PV",itemStyle:{normal:{color:"#FF005A",lineStyle:{color:"#FF005A",width:2}}},smooth:!0,type:"line",data:a,animationDuration:2800,animationEasing:"cubicInOut"},{name:"UV",smooth:!0,type:"line",itemStyle:{normal:{color:"#3888fa",lineStyle:{color:"#3888fa",width:2},areaStyle:{color:"#f3f8ff"}}},data:e,animationDuration:2800,animationEasing:"quadraticOut"}]})}}},s=c,l=e("2877"),u=Object(l["a"])(s,n,i,!1,null,null,null);a["a"]=u.exports},bfad:function(t,a,e){"use strict";e.d(a,"c",(function(){return i})),e.d(a,"b",(function(){return r})),e.d(a,"a",(function(){return o})),e.d(a,"e",(function(){return c})),e.d(a,"f",(function(){return s})),e.d(a,"d",(function(){return l}));var n=e("b775");function i(t){return Object(n["a"])({url:"/v1/short-link/".concat(t),method:"get"})}function r(t,a){return Object(n["a"])({url:"/v1/short-link/?page=".concat(t,"&pageSize=").concat(a),method:"get"})}function o(t){return Object(n["a"])({url:"/v1/short-link/",method:"post",data:t})}function c(t){return Object(n["a"])({url:"/v1/short-link/".concat(t),method:"delete"})}function s(t,a){return Object(n["a"])({url:"/v1/short-link/".concat(t),method:"patch",data:a})}function l(t,a,e){return Object(n["a"])({url:"/v1/short-link/".concat(t,"/data?startDate=").concat(a,"&endDate=").concat(e),method:"get"})}},c3cc:function(t,a,e){"use strict";e.d(a,"b",(function(){return r})),e.d(a,"a",(function(){return o}));e("ac6a");var n=e("c1df"),i=e.n(n);function r(t){var a=i()(),e=a.clone().add(-(t-1),"d"),n=a.clone(),r=e.clone(),o=[];while(r.isSameOrBefore(n))o.push(r.format("YYYY-MM-DD")),r.add(1,"d");return{startDate:e,endDate:n,dates:o}}function o(t,a){var e={};t.forEach((function(t){e[t]={pv:0,ips:[]}})),a.forEach((function(t,a){var n=i()(t.time).format("YYYY-MM-DD");e[n].pv+=1,-1===e[n].ips.indexOf(t.ip)&&e[n].ips.push(t.ip)}));var n=[],r=[];return t.forEach((function(t){n.push(e[t].pv),r.push(e[t].ips.length)})),{pv:n,uv:r}}},df03:function(t,a,e){"use strict";e.r(a);var n=function(){var t=this,a=t.$createElement,e=t._self._c||a;return e("el-main",{staticStyle:{"margin-top":"5px","background-color":"rgb(240, 242, 245)",position:"relative"}},[e("el-page-header",{attrs:{content:t.title},on:{back:t.back}}),t._v(" "),e("el-divider"),t._v(" "),e("h3",{staticStyle:{color:"#555"}},[t._v("点击量/点击人数")]),t._v(" "),e("div",{staticStyle:{width:"100%","background-color":"#fff","padding-top":"15px"}},[e("line-chart",{attrs:{"chart-data":t.chartData.PvUv,height:"300px",title:{}}})],1),t._v(" "),e("el-divider"),t._v(" "),e("h3",{staticStyle:{color:"#555"}},[t._v("访问记录")]),t._v(" "),e("el-table",{attrs:{data:t.list,size:"mini"}},[e("el-table-column",{attrs:{prop:"url",label:"目标链接",width:"300"},scopedSlots:t._u([{key:"default",fn:function(a){return[e("el-link",{attrs:{type:"info",href:a.row.url,target:"_blank"}},[t._v(t._s(a.row.url))])]}}])}),t._v(" "),e("el-table-column",{attrs:{prop:"ip",label:"IP",width:"200"}}),t._v(" "),e("el-table-column",{attrs:{prop:"ua",label:"User Agent"}}),t._v(" "),e("el-table-column",{attrs:{label:"访问时间"},scopedSlots:t._u([{key:"default",fn:function(a){return[t._v("\n "+t._s(t._f("dateformat")(a.row.time))+"\n ")]}}])})],1)],1)},i=[],r=e("bfad"),o=e("14c9"),c=e("c3cc"),s={name:"ShortLinkData",components:{LineChart:o["a"]},data:function(){return{title:"",list:[],chartData:{PvUv:{pv:[],uv:[],dates:[]}},startDate:null,endDate:null}},created:function(){var t=Object(c["b"])(7);this.chartData.PvUv.dates=t.dates,this.getRequestHistoriesByDateRange(this.$route.params.id,t.startDate.format("YYYY-MM-DD"),t.endDate.format("YYYY-MM-DD"))},methods:{getRequestHistoriesByDateRange:function(t,a,e){var n=this;Object(r["d"])(t,a,e).then((function(t){n.list=t.data.histories;var a=Object(c["a"])(n.chartData.PvUv.dates,t.data.histories);n.chartData.PvUv.pv=a.pv,n.chartData.PvUv.uv=a.uv}))},back:function(){this.$router.go(-1)}}},l=s,u=e("2877"),d=Object(u["a"])(l,n,i,!1,null,"f0932b08",null);a["default"]=d.exports}}]); \ No newline at end of file diff --git a/web/admin/static/js/chunk-5011652c.b44c15c9.js b/web/admin/static/js/chunk-5011652c.b44c15c9.js deleted file mode 100644 index 24a2807..0000000 --- a/web/admin/static/js/chunk-5011652c.b44c15c9.js +++ /dev/null @@ -1 +0,0 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-5011652c"],{"14c9":function(t,e,a){"use strict";var n=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{class:t.className,style:{height:t.height,width:t.width}})},i=[],r=a("313e"),o=a.n(r);a("817d");var c={props:{className:{type:String,default:"chart"},width:{type:String,default:"100%"},height:{type:String,default:"350px"},autoResize:{type:Boolean,default:!0},chartData:{type:Object,required:!0},title:{type:Object,default:{}}},data:function(){return{chart:null}},watch:{chartData:{deep:!0,handler:function(t){this.setOptions(t)}}},mounted:function(){var t=this;this.$nextTick((function(){t.initChart()}))},beforeDestroy:function(){this.chart&&(this.chart.dispose(),this.chart=null)},methods:{initChart:function(){this.chart=o.a.init(this.$el,"macarons"),this.setOptions(this.chartData)},setOptions:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.pv,a=t.uv,n=t.dates;this.chart&&this.chart.setOption({title:this.title,xAxis:{data:n,boundaryGap:!1,axisTick:{show:!1}},grid:{left:50,right:50,bottom:20,top:30,containLabel:!0},tooltip:{trigger:"axis",axisPointer:{type:"cross"},padding:[5,10]},yAxis:{axisTick:{show:!1}},legend:{data:["PV","UV"]},series:[{name:"PV",itemStyle:{normal:{color:"#FF005A",lineStyle:{color:"#FF005A",width:2}}},smooth:!0,type:"line",data:e,animationDuration:2800,animationEasing:"cubicInOut"},{name:"UV",smooth:!0,type:"line",itemStyle:{normal:{color:"#3888fa",lineStyle:{color:"#3888fa",width:2},areaStyle:{color:"#f3f8ff"}}},data:a,animationDuration:2800,animationEasing:"quadraticOut"}]})}}},s=c,l=a("2877"),u=Object(l["a"])(s,n,i,!1,null,null,null);e["a"]=u.exports},bfad:function(t,e,a){"use strict";a.d(e,"d",(function(){return i})),a.d(e,"c",(function(){return r})),a.d(e,"a",(function(){return o})),a.d(e,"f",(function(){return c})),a.d(e,"g",(function(){return s})),a.d(e,"b",(function(){return l})),a.d(e,"e",(function(){return u}));var n=a("b775");function i(t){return Object(n["a"])({url:"/v1/short-link/".concat(t),method:"get"})}function r(t,e){return Object(n["a"])({url:"/v1/short-link/?page=".concat(t,"&pageSize=").concat(e),method:"get"})}function o(t){return Object(n["a"])({url:"/v1/short-link/",method:"post",data:t})}function c(t){return Object(n["a"])({url:"/v1/short-link/".concat(t),method:"delete"})}function s(t,e){return Object(n["a"])({url:"/v1/short-link/".concat(t),method:"patch",data:e})}function l(t,e){return Object(n["a"])({url:"/v1/short-link/".concat(t,"/latest-request-history?size=").concat(e),method:"get"})}function u(t,e,a){return Object(n["a"])({url:"/v1/short-link/".concat(t,"/data?startDate=").concat(e,"&endDate=").concat(a),method:"get"})}},c3cc:function(t,e,a){"use strict";a.d(e,"b",(function(){return r})),a.d(e,"a",(function(){return o}));a("ac6a");var n=a("c1df"),i=a.n(n);function r(t){var e=i()(),a=e.clone().add(-(t-1),"d"),n=e.clone(),r=a.clone(),o=[];while(r.isSameOrBefore(n))o.push(r.format("YYYY-MM-DD")),r.add(1,"d");return{startDate:a,endDate:n,dates:o}}function o(t,e){var a={};t.forEach((function(t){a[t]={pv:0,ips:[]}})),e.forEach((function(t,e){var n=i()(t.time).format("YYYY-MM-DD");a[n].pv+=1,-1===a[n].ips.indexOf(t.ip)&&a[n].ips.push(t.ip)}));var n=[],r=[];return t.forEach((function(t){n.push(a[t].pv),r.push(a[t].ips.length)})),{pv:n,uv:r}}},df03:function(t,e,a){"use strict";a.r(e);var n=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("el-main",{staticStyle:{"margin-top":"5px","background-color":"rgb(240, 242, 245)",position:"relative"}},[a("el-page-header",{attrs:{content:t.title},on:{back:t.back}}),t._v(" "),a("el-divider"),t._v(" "),a("h3",{staticStyle:{color:"#555"}},[t._v("点击量/点击人数")]),t._v(" "),a("div",{staticStyle:{width:"100%","background-color":"#fff","padding-top":"15px"}},[a("line-chart",{attrs:{"chart-data":t.chartData.PvUv,height:"300px"}})],1),t._v(" "),a("el-divider"),t._v(" "),a("h3",{staticStyle:{color:"#555"}},[t._v("访问记录")]),t._v(" "),a("el-table",{attrs:{data:t.list,size:"mini"}},[a("el-table-column",{attrs:{prop:"url",label:"目标链接",width:"300"},scopedSlots:t._u([{key:"default",fn:function(e){return[a("el-link",{attrs:{type:"info",href:e.row.url,target:"_blank"}},[t._v(t._s(e.row.url))])]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"ip",label:"IP",width:"200"}}),t._v(" "),a("el-table-column",{attrs:{prop:"ua",label:"User Agent"}}),t._v(" "),a("el-table-column",{attrs:{label:"访问时间"},scopedSlots:t._u([{key:"default",fn:function(e){return[t._v("\n "+t._s(t._f("dateformat")(e.row.time))+"\n ")]}}])})],1)],1)},i=[],r=(a("c1df"),a("bfad")),o=a("14c9"),c=a("c3cc"),s={name:"ShortLinkData",components:{LineChart:o["a"]},data:function(){return{title:"",list:[],chartData:{PvUv:{pv:[],uv:[],dates:[]}},startDate:null,endDate:null}},created:function(){this.title='"'.concat(this.$route.params.id,'" 近7日的数据');var t=Object(c["b"])(7);this.chartData.PvUv.dates=t.dates,this.getRequestHistoriesByDateRange(this.$route.params.id,t.startDate.format("YYYY-MM-DD"),t.endDate.format("YYYY-MM-DD"))},methods:{getRequestHistoriesByDateRange:function(t,e,a){var n=this;Object(r["e"])(t,e,a).then((function(t){n.list=t.data.histories;var e=Object(c["a"])(n.chartData.PvUv.dates,t.data.histories);n.chartData.PvUv.pv=e.pv,n.chartData.PvUv.uv=e.uv}))},back:function(){this.$router.go(-1)}}},l=s,u=a("2877"),h=Object(u["a"])(l,n,i,!1,null,"5f58dab4",null);e["default"]=h.exports}}]); \ No newline at end of file diff --git a/web/admin/static/js/chunk-60a4aa86.399c75e0.js b/web/admin/static/js/chunk-60a4aa86.399c75e0.js deleted file mode 100644 index b7b640a..0000000 --- a/web/admin/static/js/chunk-60a4aa86.399c75e0.js +++ /dev/null @@ -1,8 +0,0 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-60a4aa86"],{9472:function(e,t,r){"use strict";r.r(t);var n=function(){var e=this,t=e.$createElement,r=e._self._c||t;return r("el-main",[r("el-drawer",{ref:"createFormDrawer",attrs:{visible:e.createFormDrawer,direction:"rtl","before-close":e.handleCreateFormDrawerClose},on:{"update:visible":function(t){e.createFormDrawer=t}}},[r("div",{staticStyle:{width:"90%","margin-left":"15px"}},[r("h2",{staticStyle:{"margin-top":"0",color:"#606266"}},[e._v("添加短链接")]),e._v(" "),r("el-form",{ref:"createForm",attrs:{model:e.createForm,rules:e.createFormRules}},[r("el-form-item",{directives:[{name:"show",rawName:"v-show",value:2===e.role,expression:"role === 2"}],attrs:{label:"指定 ID",prop:"id"}},[r("el-switch",{on:{change:function(t){return e.specifyIdChange(t)}},model:{value:e.createForm.specifyId,callback:function(t){e.$set(e.createForm,"specifyId",t)},expression:"createForm.specifyId"}}),e._v(" "),r("el-popover",{attrs:{placement:"bottom",width:"320",trigger:"hover"}},[r("p",[e._v("设置你期望的ID,设置后随机ID将不起作用。")]),e._v(" "),r("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})]),e._v(" "),r("el-input",{directives:[{name:"show",rawName:"v-show",value:e.createForm.specifyId,expression:"createForm.specifyId"}],attrs:{disabled:e.createForm.setIdLength,placeholder:"示例:home"},model:{value:e.createForm.id,callback:function(t){e.$set(e.createForm,"id",t)},expression:"createForm.id"}})],1),e._v(" "),r("el-form-item",{directives:[{name:"show",rawName:"v-show",value:2===e.role,expression:"role === 2"}],attrs:{label:"指定随机 ID 长度",prop:"id_length"}},[r("el-switch",{on:{change:function(t){return e.setIdLengthChange(t)}},model:{value:e.createForm.setIdLength,callback:function(t){e.$set(e.createForm,"setIdLength",t)},expression:"createForm.setIdLength"}}),e._v(" "),r("el-popover",{attrs:{placement:"bottom",width:"320",trigger:"hover"}},[r("p",[e._v("在允许的范围内指定随机ID的长度,不指定时会使用系统默认设置。")]),e._v(" "),r("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})]),e._v(" "),r("el-slider",{directives:[{name:"show",rawName:"v-show",value:e.createForm.setIdLength,expression:"createForm.setIdLength"}],attrs:{"show-input":"",disabled:e.createForm.specifyId,min:e.idConfig.idMinimumLength,max:e.idConfig.idMaximumLength},model:{value:e.createForm.id_length,callback:function(t){e.$set(e.createForm,"id_length",t)},expression:"createForm.id_length"}})],1),e._v(" "),r("el-form-item",{attrs:{label:"目标链接",prop:"url"}},[r("el-input",{attrs:{placeholder:"示例:https://github.com/jwma/jump-jump"},model:{value:e.createForm.url,callback:function(t){e.$set(e.createForm,"url",t)},expression:"createForm.url"}})],1),e._v(" "),r("el-form-item",{attrs:{label:"描述",prop:"description"}},[r("el-input",{attrs:{type:"textarea",placeholder:"示例:某某帖子使用"},model:{value:e.createForm.description,callback:function(t){e.$set(e.createForm,"description",t)},expression:"createForm.description"}})],1),e._v(" "),r("el-form-item",{attrs:{label:"启用?",prop:"is_enable"}},[r("el-switch",{model:{value:e.createForm.is_enable,callback:function(t){e.$set(e.createForm,"is_enable",t)},expression:"createForm.is_enable"}}),e._v(" "),r("el-popover",{attrs:{placement:"bottom",width:"320",trigger:"hover"}},[r("p",[e._v("开启后短链接可以正常被访问,关闭后短链接被访问时会告知用户访问的页面不存在。"),r("br"),e._v(" "),r("strong",[e._v("注意:关闭后不会统计短链接访问的数据。")])]),e._v(" "),r("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})])],1),e._v(" "),r("el-form-item",[r("el-button",{attrs:{size:"mini",type:"primary"},on:{click:e.onCreateFormSubmit}},[e._v("添加")]),e._v(" "),r("el-button",{attrs:{size:"mini"},on:{click:e.onCreateFormCancel}},[e._v("取消")])],1)],1)],1)]),e._v(" "),r("el-drawer",{ref:"editFormDrawer",attrs:{visible:e.editFormDrawer,direction:"rtl","before-close":e.handleEditFormDrawerClose},on:{"update:visible":function(t){e.editFormDrawer=t}}},[r("div",{staticStyle:{width:"90%","margin-left":"15px"}},[r("h2",{staticStyle:{"margin-top":"0",color:"#606266"}},[e._v("更新:"+e._s(e.editForm.id))]),e._v(" "),r("el-form",{ref:"editForm",attrs:{model:e.editForm,rules:e.editFormRules}},[r("el-form-item",{attrs:{label:"目标链接",prop:"url"}},[r("el-input",{attrs:{placeholder:"示例:https://github.com/jwma/jump-jump"},model:{value:e.editForm.url,callback:function(t){e.$set(e.editForm,"url",t)},expression:"editForm.url"}})],1),e._v(" "),r("el-form-item",{attrs:{label:"描述",prop:"description"}},[r("el-input",{attrs:{type:"textarea",placeholder:"示例:某某帖子使用"},model:{value:e.editForm.description,callback:function(t){e.$set(e.editForm,"description",t)},expression:"editForm.description"}})],1),e._v(" "),r("el-form-item",{attrs:{label:"启用?",prop:"is_enable"}},[r("el-switch",{model:{value:e.editForm.is_enable,callback:function(t){e.$set(e.editForm,"is_enable",t)},expression:"editForm.is_enable"}}),e._v(" "),r("el-popover",{attrs:{placement:"bottom",width:"320",trigger:"hover"}},[r("p",[e._v("开启后短链接可以正常被访问,关闭后短链接被访问时会告知用户访问的页面不存在。"),r("br"),e._v(" "),r("strong",[e._v("注意:关闭后不会统计短链接访问的数据。")])]),e._v(" "),r("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})])],1),e._v(" "),r("el-form-item",{attrs:{label:"创建人"}},[r("span",{staticStyle:{color:"#909399"}},[e._v(e._s(e.editForm.created_by))])]),e._v(" "),r("el-form-item",{attrs:{label:"添加时间"}},[r("span",{staticStyle:{color:"#909399"}},[e._v(e._s(e._f("dateformat")(e.editForm.create_time)))])]),e._v(" "),r("el-form-item",{attrs:{label:"更新时间"}},[r("span",{staticStyle:{color:"#909399"}},[e._v(e._s(e._f("dateformat")(e.editForm.update_time)))])]),e._v(" "),r("el-form-item",[r("el-button",{attrs:{size:"mini",type:"primary"},on:{click:e.onEditFormSubmit}},[e._v("更新")]),e._v(" "),r("el-button",{attrs:{size:"mini"},on:{click:e.onEditFormCancel}},[e._v("取消")])],1)],1)],1)]),e._v(" "),r("el-button",{attrs:{icon:"el-icon-refresh",size:"mini"},on:{click:function(t){return e.getList(e.currentPage)}}},[e._v("刷新")]),e._v(" "),r("el-button",{attrs:{icon:"el-icon-plus",size:"mini",type:"primary"},on:{click:function(t){return e.toCreate()}}},[e._v("添加\n ")]),e._v(" "),r("el-table",{staticStyle:{width:"100%"},attrs:{data:e.list,"max-height":"800",fit:""}},[r("el-table-column",{attrs:{label:"短链接",width:"250"},scopedSlots:e._u([{key:"default",fn:function(t){return[r("i",{class:{"el-icon-star-off":-1==e.pinned.indexOf(t.row.id),"el-icon-star-on":-1!=e.pinned.indexOf(t.row.id)},staticStyle:{cursor:"pointer"},on:{click:function(r){return e.pin(t.row.id)}}}),e._v(" "),r("el-dropdown",{attrs:{size:"small"}},[r("span",{staticClass:"el-dropdown-link",staticStyle:{cursor:"pointer"}},[e._v("\n "+e._s(t.row.id)),r("i",{staticClass:"el-icon-arrow-down el-icon--right"})]),e._v(" "),r("el-dropdown-menu",{attrs:{slot:"dropdown"},slot:"dropdown"},e._l(e.landingHosts,(function(n){return r("el-dropdown-item",[r("span",{on:{click:function(r){return e.copyShortLink(n+t.row.id,r)}}},[e._v(e._s(n+t.row.id))])])})),1)],1)]}}])}),e._v(" "),r("el-table-column",{attrs:{prop:"url",label:"目标链接",width:"250"},scopedSlots:e._u([{key:"default",fn:function(t){return[r("el-dropdown",{attrs:{size:"small"}},[r("span",{staticClass:"el-dropdown-link",staticStyle:{cursor:"pointer"}},[r("span",{staticStyle:{width:"200px",overflow:"hidden","text-overflow":"ellipsis","white-space":"nowrap",display:"inline-block"}},[e._v(e._s(t.row.url))])]),e._v(" "),r("el-dropdown-menu",{attrs:{slot:"dropdown"},slot:"dropdown"},[r("el-dropdown-item",{staticStyle:{"line-height":"18px"}},[r("span",{on:{click:function(r){return e.copyShortLink(t.row.url,r)}}},[e._v(e._s(t.row.url))])])],1)],1)]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"描述",width:"300"},scopedSlots:e._u([{key:"default",fn:function(t){return[e._v("\n "+e._s(t.row.description?t.row.description:"-")+"\n ")]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"启用?",width:"70",align:"center"},scopedSlots:e._u([{key:"default",fn:function(e){return[r("i",{class:{"el-icon-check":e.row.is_enable,"el-icon-close":!e.row.is_enable}})]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"创建人",width:"150",align:"center"},scopedSlots:e._u([{key:"default",fn:function(t){return[e._v("\n "+e._s(t.row.created_by)+"\n ")]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"添加时间",width:"100"},scopedSlots:e._u([{key:"default",fn:function(t){return[e._v("\n "+e._s(e._f("dateformat")(t.row.create_time,"DD/MM/YY"))+"\n ")]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"更新时间",width:"100"},scopedSlots:e._u([{key:"default",fn:function(t){return[e._v("\n "+e._s(e._f("dateformat")(t.row.update_time,"DD/MM/YY"))+"\n ")]}}])}),e._v(" "),r("el-table-column",{attrs:{label:"操作"},scopedSlots:e._u([{key:"default",fn:function(t){return[r("el-button",{attrs:{size:"mini",circle:"",icon:"el-icon-s-data"},on:{click:function(r){return e.goto({name:"ShortLinkData",params:{id:t.row.id}})}}}),e._v(" "),r("el-button",{attrs:{size:"mini",circle:"",icon:"el-icon-edit-outline"},on:{click:function(r){return e.toEdit(t.row.id)}}}),e._v(" "),r("el-button",{attrs:{type:"danger",size:"mini",icon:"el-icon-delete-solid",circle:""},on:{click:function(r){return e.deleteShortLink(t.row.id)}}})]}}])})],1),e._v(" "),r("div",{staticClass:"paginator-container"},[r("el-pagination",{attrs:{"current-page":e.currentPage,"page-sizes":[10,20,30],"page-size":e.pageSize,layout:"total, sizes, prev, pager, next, jumper",total:e.total},on:{"size-change":e.handlePageSizeChange,"current-change":e.handleCurrentPageChange}})],1)],1)},i=[],o=r("db72"),a=r("bfad"),c=r("da71"),s=r("61f7"),l=r("2b0e"),u=r("b311"),d=r.n(u);function f(){l["default"].prototype.$message({message:"复制成功",type:"success",duration:1500})}function h(){l["default"].prototype.$message({message:"复制失败",type:"error"})}function m(e,t){var r=new d.a(t.target,{text:function(){return e}});r.on("success",(function(){f(),r.off("error"),r.off("success"),r.destroy()})),r.on("error",(function(){h(),r.off("error"),r.off("success"),r.destroy()})),r.onClick(t)}var p=r("2f62"),g={name:"ShortLinkList",data:function(){var e=function(e,t,r){""!==t?r():r(new Error("请输入目标链接"))};return{landingHosts:[],list:[],total:0,currentPage:1,pageSize:20,createFormDrawer:!1,idConfig:{idMinimumLength:0,idLength:0,idMaximumLength:0},createForm:{specifyId:!1,setIdLength:!1,id:"",url:"",description:"",is_enable:!1,id_length:0},createFormRules:{url:[{required:!0,validator:e,trigger:"blur"}]},editFormDrawer:!1,editForm:{id:"",url:"",description:"",is_enable:!1,created_by:"",create_time:"",update_time:""},editFormRules:{url:[{validator:e,trigger:"blur"}]}}},beforeRouteUpdate:function(e,t,r){this.currentPage=e.query.page||this.currentPage,this.pageSize=e.query.pageSize||this.pageSize,this.getList(this.currentPage),r()},created:function(){var e=this;this.currentPage=parseInt(this.$route.query.page)||this.currentPage,this.pageSize=parseInt(this.$route.query.pageSize)||this.pageSize,Object(c["a"])().then((function(t){e.landingHosts=t.data.config.landingHosts,e.idConfig=t.data.config.idConfig,e.createForm.id_length=e.idConfig.idLength,e.getList(e.currentPage)}))},computed:Object(o["a"])({},Object(p["b"])(["role","pinned"])),methods:{goto:function(e){this.$router.push(e)},copyShortLink:function(e,t){m(e,t)},getList:function(e){var t=this;Object(a["c"])(e,this.pageSize).then((function(r){t.currentPage=e,t.total=r.data.total,t.list=r.data.shortLinks,1!==t.currentPage&&0===t.list.length&&t.total>0&&(t.currentPage=1,t.getList(1))}))},resetCreateForm:function(){this.createForm.specifyId=!1,this.createForm.setIdLength=!1,this.createForm.id="",this.createForm.url="",this.createForm.description="",this.createForm.is_enable=!1},resetEditForm:function(){this.editForm.url="",this.editForm.description="",this.editForm.is_enable=!1,this.editForm.created_by="",this.editForm.create_time="",this.editForm.update_time=""},getInvalidUrlTipsText:function(e){return'
目标链接不是常规的URL,确定继续?")},handlePageSizeChange:function(e){this.pageSize=e,this.currentPage=1,this.$router.push({name:"ShortLinkList",query:{page:1,pageSize:e}})},handleCurrentPageChange:function(e){this.currentPage=e,this.$router.push({name:"ShortLinkList",query:{page:e,pageSize:this.pageSize}})},toCreate:function(){var e=this;Object(c["a"])().then((function(t){e.idConfig=t.data.config.idConfig,e.createForm.id_length=e.idConfig.idLength,e.createFormDrawer=!0}))},handleCreateFormDrawerClose:function(e){this.resetCreateForm(),e()},submitCreateForm:function(){var e=this;Object(a["a"])(this.createForm).then((function(t){e.$refs.createFormDrawer.closeDrawer(),e.$notify({title:"添加短链接成功",message:"ID:"+t.data.shortLink.id,type:"success"}),e.getList(e.currentPage)}))},onCreateFormSubmit:function(){var e=this;this.$refs.createForm.validate((function(t){if(!t)return!1;Object(s["b"])(e.createForm.url)?e.submitCreateForm():e.$confirm(e.getInvalidUrlTipsText(e.createForm.url),"提示",{confirmButtonText:"确定",cancelButtonText:"再改改",type:"warning",dangerouslyUseHTMLString:!0}).then((function(){e.submitCreateForm()}))}))},onCreateFormCancel:function(){this.resetCreateForm(),this.createFormDrawer=!1},toEdit:function(e){var t=this;Object(a["d"])(e).then((function(e){t.editFormDrawer=!0,t.editForm=e.data.shortLink}))},handleEditFormDrawerClose:function(e){this.resetEditForm(),e()},submitEditForm:function(){var e=this;Object(a["g"])(this.editForm.id,this.editForm).then((function(t){e.$refs.editFormDrawer.closeDrawer(),e.$notify({title:"更新成功",message:"ID:"+t.data.shortLink.id,type:"success"}),e.getList(e.currentPage)}))},onEditFormSubmit:function(){var e=this;this.$refs.editForm.validate((function(t){if(!t)return!1;Object(s["b"])(e.editForm.url)?e.submitEditForm():e.$confirm(e.getInvalidUrlTipsText(e.editForm.url),"提示",{confirmButtonText:"确定",cancelButtonText:"再改改",type:"warning",dangerouslyUseHTMLString:!0}).then((function(){e.submitEditForm()}))}))},onEditFormCancel:function(){this.resetEditForm(),this.editFormDrawer=!1},deleteShortLink:function(e){var t=this;this.$confirm("此操作会永久删除短链接,是否继续?","删除确认",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then((function(){Object(a["f"])(e).then((function(r){t.$notify({title:"成功删除短链接",message:"ID:".concat(e),type:"success"}),t.getList(t.currentPage),t.$store.dispatch("link/unpin",e)}))}))},specifyIdChange:function(e){e?(this.createForm.setIdLength=!1,this.setIdLengthChange(!1)):this.createForm.id=""},setIdLengthChange:function(e){e?(this.createForm.specifyId=!1,this.specifyIdChange(!1)):this.createForm.id_length=this.idConfig.idLength},pin:function(e){-1==this.pinned.indexOf(e)?(this.$store.dispatch("link/pin",e),this.$message({showClose:!0,type:"success",message:"Pin ".concat(e)})):(this.$store.dispatch("link/unpin",e),this.$message({showClose:!0,type:"success",message:"Unpin ".concat(e)}))}}},v=g,b=(r("c559"),r("2877")),y=Object(b["a"])(v,n,i,!1,null,"23d33577",null);t["default"]=y.exports},b311:function(e,t,r){ -/*! - * clipboard.js v2.0.6 - * https://clipboardjs.com/ - * - * Licensed MIT © Zeno Rocha - */ -(function(t,r){e.exports=r()})(0,(function(){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=6)}([function(e,t){function r(e){var t;if("SELECT"===e.nodeName)e.focus(),t=e.value;else if("INPUT"===e.nodeName||"TEXTAREA"===e.nodeName){var r=e.hasAttribute("readonly");r||e.setAttribute("readonly",""),e.select(),e.setSelectionRange(0,e.value.length),r||e.removeAttribute("readonly"),t=e.value}else{e.hasAttribute("contenteditable")&&e.focus();var n=window.getSelection(),i=document.createRange();i.selectNodeContents(e),n.removeAllRanges(),n.addRange(i),t=n.toString()}return t}e.exports=r},function(e,t){function r(){}r.prototype={on:function(e,t,r){var n=this.e||(this.e={});return(n[e]||(n[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var n=this;function i(){n.off(e,i),t.apply(r,arguments)}return i._=t,this.on(e,i,r)},emit:function(e){var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),n=0,i=r.length;for(n;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=e.action,this.container=e.container,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var e=this,t="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[t?"right":"left"]="-9999px";var r=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=r+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=i()(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=i()(this.target),this.copyText()}},{key:"copyText",value:function(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),document.activeElement.blur(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(e){if(void 0!==e){if(!e||"object"!==("undefined"===typeof e?"undefined":o(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function(){return this._target}}]),e}(),l=s,u=r(1),d=r.n(u),f=r(2),h=r.n(f),m="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},p=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"===typeof e.action?e.action:this.defaultAction,this.target="function"===typeof e.target?e.target:this.defaultTarget,this.text="function"===typeof e.text?e.text:this.defaultText,this.container="object"===m(e.container)?e.container:document.body}},{key:"listenClick",value:function(e){var t=this;this.listener=h()(e,"click",(function(e){return t.onClick(e)}))}},{key:"onClick",value:function(e){var t=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new l({action:this.action(t),target:this.target(t),text:this.text(t),container:this.container,trigger:t,emitter:this})}},{key:"defaultAction",value:function(e){return _("action",e)}},{key:"defaultTarget",value:function(e){var t=_("target",e);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(e){return _("text",e)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"===typeof e?[e]:e,r=!!document.queryCommandSupported;return t.forEach((function(e){r=r&&!!document.queryCommandSupported(e)})),r}}]),t}(d.a);function _(e,t){var r="data-clipboard-"+e;if(t.hasAttribute(r))return t.getAttribute(r)}t["default"]=y}])["default"]}))},bfad:function(e,t,r){"use strict";r.d(t,"d",(function(){return i})),r.d(t,"c",(function(){return o})),r.d(t,"a",(function(){return a})),r.d(t,"f",(function(){return c})),r.d(t,"g",(function(){return s})),r.d(t,"b",(function(){return l})),r.d(t,"e",(function(){return u}));var n=r("b775");function i(e){return Object(n["a"])({url:"/v1/short-link/".concat(e),method:"get"})}function o(e,t){return Object(n["a"])({url:"/v1/short-link/?page=".concat(e,"&pageSize=").concat(t),method:"get"})}function a(e){return Object(n["a"])({url:"/v1/short-link/",method:"post",data:e})}function c(e){return Object(n["a"])({url:"/v1/short-link/".concat(e),method:"delete"})}function s(e,t){return Object(n["a"])({url:"/v1/short-link/".concat(e),method:"patch",data:t})}function l(e,t){return Object(n["a"])({url:"/v1/short-link/".concat(e,"/latest-request-history?size=").concat(t),method:"get"})}function u(e,t,r){return Object(n["a"])({url:"/v1/short-link/".concat(e,"/data?startDate=").concat(t,"&endDate=").concat(r),method:"get"})}},c559:function(e,t,r){"use strict";var n=r("ce06"),i=r.n(n);i.a},ce06:function(e,t,r){},da71:function(e,t,r){"use strict";r.d(t,"a",(function(){return i})),r.d(t,"c",(function(){return o})),r.d(t,"b",(function(){return a})),r.d(t,"d",(function(){return c}));var n=r("b775");function i(){return Object(n["a"])({url:"/v1/config",method:"get"})}function o(e){return Object(n["a"])({url:"/v1/config/landing-hosts",method:"patch",data:e})}function a(e){return Object(n["a"])({url:"/v1/config/id-length",method:"patch",data:e})}function c(e){return Object(n["a"])({url:"/v1/config/short-link-404-handling",method:"patch",data:e})}}}]); \ No newline at end of file diff --git a/web/admin/static/js/chunk-672304de.4615defb.js b/web/admin/static/js/chunk-672304de.4615defb.js deleted file mode 100644 index bb02ac1..0000000 --- a/web/admin/static/js/chunk-672304de.4615defb.js +++ /dev/null @@ -1 +0,0 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-672304de"],{"02f4":function(t,e,r){var n=r("4588"),a=r("be13");t.exports=function(t){return function(e,r){var c,o,i=String(a(e)),u=n(r),l=i.length;return u<0||u>=l?t?"":void 0:(c=i.charCodeAt(u),c<55296||c>56319||u+1===l||(o=i.charCodeAt(u+1))<56320||o>57343?t?i.charAt(u):c:t?i.slice(u,u+2):o-56320+(c-55296<<10)+65536)}}},"0390":function(t,e,r){"use strict";var n=r("02f4")(!0);t.exports=function(t,e,r){return e+(r?n(t,e).length:1)}},"07e5":function(t,e,r){"use strict";r.r(e);var n=function(){var t=this,e=t.$createElement,r=t._self._c||e;return r("el-main",[r("el-page-header",{attrs:{content:t.title},on:{back:t.back}}),t._v(" "),r("el-divider"),t._v(" "),r("el-table",{attrs:{data:t.list,size:"mini"}},[r("el-table-column",{attrs:{prop:"url",label:"目标链接",width:"300"},scopedSlots:t._u([{key:"default",fn:function(e){return[r("el-link",{attrs:{type:"info",href:e.row.url,target:"_blank"}},[t._v(t._s(e.row.url))])]}}])}),t._v(" "),r("el-table-column",{attrs:{prop:"ip",label:"IP",width:"200"}}),t._v(" "),r("el-table-column",{attrs:{prop:"ua",label:"User Agent"}}),t._v(" "),r("el-table-column",{attrs:{label:"访问时间"},scopedSlots:t._u([{key:"default",fn:function(e){return[t._v("\n "+t._s(t._f("dateformat")(e.row.time))+"\n ")]}}])})],1)],1)},a=[],c=(r("a481"),r("bfad")),o={name:"LatestRequestHistory",data:function(){return{title:"",list:[]}},created:function(){var t=this.$route.params.id;this.title="".concat(t," 的最近访问记录"),this.getLatestRequestHistory(t)},methods:{getLatestRequestHistory:function(t){var e=this;Object(c["b"])(t,this.$route.query.size||20).then((function(t){e.list=t.data.histories}))},back:function(){this.$router.replace("/short-link")}}},i=o,u=r("2877"),l=Object(u["a"])(i,n,a,!1,null,"7fefcfa9",null);e["default"]=l.exports},"214f":function(t,e,r){"use strict";r("b0c5");var n=r("2aba"),a=r("32e9"),c=r("79e5"),o=r("be13"),i=r("2b4c"),u=r("520a"),l=i("species"),s=!c((function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$")})),f=function(){var t=/(?:)/,e=t.exec;t.exec=function(){return e.apply(this,arguments)};var r="ab".split(t);return 2===r.length&&"a"===r[0]&&"b"===r[1]}();t.exports=function(t,e,r){var d=i(t),v=!c((function(){var e={};return e[d]=function(){return 7},7!=""[t](e)})),h=v?!c((function(){var e=!1,r=/a/;return r.exec=function(){return e=!0,null},"split"===t&&(r.constructor={},r.constructor[l]=function(){return r}),r[d](""),!e})):void 0;if(!v||!h||"replace"===t&&!s||"split"===t&&!f){var p=/./[d],b=r(o,d,""[t],(function(t,e,r,n,a){return e.exec===u?v&&!a?{done:!0,value:p.call(e,r,n)}:{done:!0,value:t.call(r,e,n)}:{done:!1}})),g=b[0],x=b[1];n(String.prototype,t,g),a(RegExp.prototype,d,2==e?function(t,e){return x.call(t,this,e)}:function(t){return x.call(t,this)})}}},"520a":function(t,e,r){"use strict";var n=r("0bfb"),a=RegExp.prototype.exec,c=String.prototype.replace,o=a,i="lastIndex",u=function(){var t=/a/,e=/b*/g;return a.call(t,"a"),a.call(e,"a"),0!==t[i]||0!==e[i]}(),l=void 0!==/()??/.exec("")[1],s=u||l;s&&(o=function(t){var e,r,o,s,f=this;return l&&(r=new RegExp("^"+f.source+"$(?!\\s)",n.call(f))),u&&(e=f[i]),o=a.call(f,t),u&&o&&(f[i]=f.global?o.index+o[0].length:e),l&&o&&o.length>1&&c.call(o[0],r,(function(){for(s=1;s]*>)/g,v=/\$([$&`']|\d\d?)/g,h=function(t){return void 0===t?t:String(t)};r("214f")("replace",2,(function(t,e,r,p){return[function(n,a){var c=t(this),o=void 0==n?void 0:n[e];return void 0!==o?o.call(n,c,a):r.call(String(c),n,a)},function(t,e){var a=p(r,t,this,e);if(a.done)return a.value;var f=n(t),d=String(this),v="function"===typeof e;v||(e=String(e));var g=f.global;if(g){var x=f.unicode;f.lastIndex=0}var m=[];while(1){var k=u(f,d);if(null===k)break;if(m.push(k),!g)break;var y=String(k[0]);""===y&&(f.lastIndex=i(d,c(f.lastIndex),x))}for(var w="",_=0,S=0;S=_&&(w+=d.slice(_,j)+q,_=j+$.length)}return w+d.slice(_)}];function b(t,e,n,c,o,i){var u=n+t.length,l=c.length,s=v;return void 0!==o&&(o=a(o),s=d),r.call(i,s,(function(r,a){var i;switch(a.charAt(0)){case"$":return"$";case"&":return t;case"`":return e.slice(0,n);case"'":return e.slice(u);case"<":i=o[a.slice(1,-1)];break;default:var s=+a;if(0===s)return r;if(s>l){var d=f(s/10);return 0===d?r:d<=l?void 0===c[d-1]?a.charAt(1):c[d-1]+a.charAt(1):r}i=c[s-1]}return void 0===i?"":i}))}}))},b0c5:function(t,e,r){"use strict";var n=r("520a");r("5ca1")({target:"RegExp",proto:!0,forced:n!==/./.exec},{exec:n})},bfad:function(t,e,r){"use strict";r.d(e,"d",(function(){return a})),r.d(e,"c",(function(){return c})),r.d(e,"a",(function(){return o})),r.d(e,"f",(function(){return i})),r.d(e,"g",(function(){return u})),r.d(e,"b",(function(){return l})),r.d(e,"e",(function(){return s}));var n=r("b775");function a(t){return Object(n["a"])({url:"/v1/short-link/".concat(t),method:"get"})}function c(t,e){return Object(n["a"])({url:"/v1/short-link/?page=".concat(t,"&pageSize=").concat(e),method:"get"})}function o(t){return Object(n["a"])({url:"/v1/short-link/",method:"post",data:t})}function i(t){return Object(n["a"])({url:"/v1/short-link/".concat(t),method:"delete"})}function u(t,e){return Object(n["a"])({url:"/v1/short-link/".concat(t),method:"patch",data:e})}function l(t,e){return Object(n["a"])({url:"/v1/short-link/".concat(t,"/latest-request-history?size=").concat(e),method:"get"})}function s(t,e,r){return Object(n["a"])({url:"/v1/short-link/".concat(t,"/data?startDate=").concat(e,"&endDate=").concat(r),method:"get"})}}}]); \ No newline at end of file diff --git a/web/admin/static/js/chunk-7f8ff64d.e42f1527.js b/web/admin/static/js/chunk-7f8ff64d.0553663a.js similarity index 84% rename from web/admin/static/js/chunk-7f8ff64d.e42f1527.js rename to web/admin/static/js/chunk-7f8ff64d.0553663a.js index f22d0ba..dbec205 100644 --- a/web/admin/static/js/chunk-7f8ff64d.e42f1527.js +++ b/web/admin/static/js/chunk-7f8ff64d.0553663a.js @@ -1 +1 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-7f8ff64d"],{"14c9":function(t,n,e){"use strict";var o=function(){var t=this,n=t.$createElement,e=t._self._c||n;return e("div",{class:t.className,style:{height:t.height,width:t.width}})},i=[],r=e("313e"),a=e.n(r);e("817d");var s={props:{className:{type:String,default:"chart"},width:{type:String,default:"100%"},height:{type:String,default:"350px"},autoResize:{type:Boolean,default:!0},chartData:{type:Object,required:!0},title:{type:Object,default:{}}},data:function(){return{chart:null}},watch:{chartData:{deep:!0,handler:function(t){this.setOptions(t)}}},mounted:function(){var t=this;this.$nextTick((function(){t.initChart()}))},beforeDestroy:function(){this.chart&&(this.chart.dispose(),this.chart=null)},methods:{initChart:function(){this.chart=a.a.init(this.$el,"macarons"),this.setOptions(this.chartData)},setOptions:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.pv,e=t.uv,o=t.dates;this.chart&&this.chart.setOption({title:this.title,xAxis:{data:o,boundaryGap:!1,axisTick:{show:!1}},grid:{left:50,right:50,bottom:20,top:30,containLabel:!0},tooltip:{trigger:"axis",axisPointer:{type:"cross"},padding:[5,10]},yAxis:{axisTick:{show:!1}},legend:{data:["PV","UV"]},series:[{name:"PV",itemStyle:{normal:{color:"#FF005A",lineStyle:{color:"#FF005A",width:2}}},smooth:!0,type:"line",data:n,animationDuration:2800,animationEasing:"cubicInOut"},{name:"UV",smooth:!0,type:"line",itemStyle:{normal:{color:"#3888fa",lineStyle:{color:"#3888fa",width:2},areaStyle:{color:"#f3f8ff"}}},data:e,animationDuration:2800,animationEasing:"quadraticOut"}]})}}},l=s,c=e("2877"),u=Object(c["a"])(l,o,i,!1,null,null,null);n["a"]=u.exports},"1af6":function(t,n,e){var o=e("63b6");o(o.S,"Array",{isArray:e("9003")})},"549b":function(t,n,e){"use strict";var o=e("d864"),i=e("63b6"),r=e("241e"),a=e("b0dc"),s=e("3702"),l=e("b447"),c=e("20fd"),u=e("7cd6");i(i.S+i.F*!e("4ee1")((function(t){Array.from(t)})),"Array",{from:function(t){var n,e,i,d,f=r(t),h="function"==typeof this?this:Array,m=arguments.length,v=m>1?arguments[1]:void 0,g=void 0!==v,p=0,b=u(f);if(g&&(v=o(v,m>2?arguments[2]:void 0,2)),void 0==b||h==Array&&s(b))for(n=l(f.length),e=new h(n);n>p;p++)c(e,p,g?v(f[p],p):f[p]);else for(d=b.call(f),e=new h;!(i=d.next()).done;p++)c(e,p,g?a(d,v,[i.value,p],!0):i.value);return e.length=p,e}})},"54a1":function(t,n,e){e("6c1c"),e("1654"),t.exports=e("95d5")},"774e":function(t,n,e){t.exports=e("d2d5")},9406:function(t,n,e){"use strict";e.r(n);var o=function(){var t=this,n=t.$createElement,e=t._self._c||n;return e("el-main",[e("el-row",{directives:[{name:"show",rawName:"v-show",value:t.pinned.length>0,expression:"pinned.length > 0"}],attrs:{gutter:5}},[e("h3",{staticStyle:{color:"#555"}},[t._v("Pin")]),t._v(" "),t._l(t.pinned,(function(n,o){return e("el-col",{attrs:{span:8}},[e("line-chart",{attrs:{title:{text:n,align:"right"},"chart-data":{pv:t.pinnedLinksData.perDayPvUv[n].pv,uv:t.pinnedLinksData.perDayPvUv[n].uv,dates:t.pinnedLinksData.dates},height:"200px"}})],1)}))],2),t._v(" "),t.pinned.length>0?e("el-divider"):t._e(),t._v(" "),e("el-row",{attrs:{gutter:20}},[e("h3",{staticStyle:{color:"#555"}},[t._v("系统设置")]),t._v(" "),e("el-col",{attrs:{span:7}},[e("el-card",[e("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[e("span",[t._v("短链接域名\n "),e("el-popover",{attrs:{placement:"bottom",width:"300",trigger:"hover"}},[e("p",[t._v("\n 配置短链接域名后,可以在短链接列表快速拷贝完整的短链接。"),e("br"),t._v("\n 示例:http://t.anmuji.com/"),e("br"),t._v(" "),e("strong",[t._v('注意:以 "/" 结尾。')])]),t._v(" "),e("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})])],1),t._v(" "),e("div",{directives:[{name:"show",rawName:"v-show",value:2===t.role,expression:"role === 2"}],staticStyle:{float:"right"}},[e("el-button",{attrs:{icon:"el-icon-refresh",size:"mini",circle:""},on:{click:function(n){return t.getConfig("landingHostsForm")}}}),t._v(" "),e("el-button",{attrs:{icon:"el-icon-plus",size:"mini",circle:""},on:{click:function(n){return t.addLandingHost()}}}),t._v(" "),e("el-button",{attrs:{icon:"el-icon-check",size:"mini",circle:""},on:{click:function(n){return t.updateLadingHosts()}}})],1)]),t._v(" "),e("el-form",{ref:"landingHostsForm",attrs:{model:t.landingHostsForm,"label-position":"left","label-width":"0px",size:"mini"}},t._l(t.landingHostsForm.hosts,(function(n,o){return e("el-form-item",{key:n.key,attrs:{prop:"hosts."+o+".value",rules:t.landingHostRules}},[e("el-input",{staticStyle:{width:"90%"},attrs:{readonly:2!==t.role,placeholder:"示例:http://anmuji.com/t/ 以 / 结尾"},model:{value:n.value,callback:function(e){t.$set(n,"value",e)},expression:"host.value"}}),t._v(" "),e("el-button",{directives:[{name:"show",rawName:"v-show",value:t.landingHostsForm.hosts.length>1&&2===t.role,expression:"landingHostsForm.hosts.length > 1 && role === 2"}],staticStyle:{padding:"1px"},attrs:{icon:"el-icon-minus",size:"mini",type:"danger",circle:""},on:{click:function(n){return t.removeLandingHost(o)}}})],1)})),1)],1)],1),t._v(" "),e("el-col",{attrs:{span:10}},[e("el-card",[e("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[e("span",[t._v("随机 ID 长度设置\n "),e("el-popover",{attrs:{placement:"bottom",width:"300",trigger:"hover"}},[e("p",[t._v("默认长度即随机生成 ID 的长度,"),e("br"),t._v("最小长度 <= 默认长度 <= 最大长度")]),t._v(" "),e("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})])],1),t._v(" "),e("div",{directives:[{name:"show",rawName:"v-show",value:2===t.role,expression:"role === 2"}],staticStyle:{float:"right"}},[e("el-button",{attrs:{icon:"el-icon-refresh",size:"mini",circle:""},on:{click:function(n){return t.getConfig("idConfigForm")}}}),t._v(" "),e("el-button",{attrs:{icon:"el-icon-check",size:"mini",circle:""},on:{click:function(n){return t.updateIdLengthConfig()}}})],1)]),t._v(" "),e("el-form",{ref:"idConfigForm",attrs:{model:t.idConfigForm,size:"mini","label-position":"top",inline:!0}},[e("el-form-item",{attrs:{prop:"idMinimumLength",label:"最小长度"}},[e("el-input-number",{attrs:{size:"mini",disabled:2!==t.role},model:{value:t.idConfigForm.idMinimumLength,callback:function(n){t.$set(t.idConfigForm,"idMinimumLength",n)},expression:"idConfigForm.idMinimumLength"}})],1),t._v(" "),e("el-form-item",{attrs:{prop:"idLength",label:"默认长度"}},[e("el-input-number",{attrs:{size:"mini",disabled:2!==t.role},model:{value:t.idConfigForm.idLength,callback:function(n){t.$set(t.idConfigForm,"idLength",n)},expression:"idConfigForm.idLength"}})],1),t._v(" "),e("el-form-item",{attrs:{prop:"idMaximumLength",label:"最大长度"}},[e("el-input-number",{attrs:{size:"mini",disabled:2!==t.role},model:{value:t.idConfigForm.idMaximumLength,callback:function(n){t.$set(t.idConfigForm,"idMaximumLength",n)},expression:"idConfigForm.idMaximumLength"}})],1)],1)],1)],1),t._v(" "),e("el-col",{attrs:{span:7}},[e("el-card",[e("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[e("span",[t._v("短链接 404 处理\n "),e("el-popover",{attrs:{placement:"bottom",width:"320",trigger:"hover"}},[e("p",[t._v("展示文案:当访问的短链接找不到时,展示设定的文案")]),t._v(" "),e("p",[t._v("URL跳转:当访问的短链接找不到时,跳转到设定的URL")]),t._v(" "),e("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})])],1),t._v(" "),e("div",{directives:[{name:"show",rawName:"v-show",value:2===t.role,expression:"role === 2"}],staticStyle:{float:"right"}},[e("el-button",{attrs:{icon:"el-icon-refresh",size:"mini",circle:""},on:{click:function(n){return t.getConfig("shortLinkNotFoundConfigForm")}}}),t._v(" "),e("el-button",{attrs:{icon:"el-icon-check",size:"mini",circle:""},on:{click:function(n){return t.updateShortLinkNotFoundConfig()}}})],1)]),t._v(" "),e("el-form",{ref:"shortLinkNotFoundConfigForm",attrs:{model:t.shortLinkNotFoundConfigForm,size:"mini","label-position":"top"}},[e("el-form-item",{attrs:{prop:"mode",label:"模式"}},[e("el-select",{attrs:{placeholder:"请选择",disabled:2!==t.role},model:{value:t.shortLinkNotFoundConfigForm.mode,callback:function(n){t.$set(t.shortLinkNotFoundConfigForm,"mode",n)},expression:"shortLinkNotFoundConfigForm.mode"}},t._l(t.shortLinkNotFoundModeOptions,(function(t){return e("el-option",{key:t.value,attrs:{label:t.label,value:t.value}})})),1)],1),t._v(" "),e("el-form-item",{directives:[{name:"show",rawName:"v-show",value:"content"===t.shortLinkNotFoundConfigForm.mode,expression:"shortLinkNotFoundConfigForm.mode === 'content'"}],attrs:{prop:"value",label:"文案",rules:t.shortLinkNotFoundConfigRules}},[e("el-input",{attrs:{type:"textarea",placeholder:"你访问的页面不存在哦",readonly:2!==t.role},model:{value:t.shortLinkNotFoundConfigForm.value,callback:function(n){t.$set(t.shortLinkNotFoundConfigForm,"value",n)},expression:"shortLinkNotFoundConfigForm.value"}})],1),t._v(" "),e("el-form-item",{directives:[{name:"show",rawName:"v-show",value:"redirect"===t.shortLinkNotFoundConfigForm.mode,expression:"shortLinkNotFoundConfigForm.mode === 'redirect'"}],attrs:{prop:"value",label:"URL",rules:t.shortLinkNotFoundConfigRules}},[e("el-input",{attrs:{placeholder:"示例:https://github.com/jwma/jump-jump"},model:{value:t.shortLinkNotFoundConfigForm.value,callback:function(n){t.$set(t.shortLinkNotFoundConfigForm,"value",n)},expression:"shortLinkNotFoundConfigForm.value"}})],1)],1)],1)],1)],1)],1)},i=[],r=e("a745"),a=e.n(r);function s(t){if(a()(t)){for(var n=0,e=new Array(t.length);n0){var n=Object(L["b"])(7);this.pinnedLinksData.dates=n.dates,this.pinned.forEach((function(e,o){t.$set(t.pinnedLinksData.perDayPvUv,e,{pv:[],uv:[]}),t.getRequestHistoriesByDateRange(e,n.startDate.format("YYYY-MM-DD"),n.endDate.format("YYYY-MM-DD"))}))}},methods:{getConfig:function(t){var n=this;Object(g["a"])().then((function(e){"landingHostsForm"!==t&&"all"!==t||(n.landingHostsForm.hosts=[],e.data.config.landingHosts.forEach((function(t,e){n.landingHostsForm.hosts.push({value:t,key:Date.now()+e})})),0===e.data.config.landingHosts.length&&n.addLandingHost()),"idConfigForm"!==t&&"all"!==t||(n.idConfigForm.idMinimumLength=e.data.config.idConfig.idMinimumLength,n.idConfigForm.idLength=e.data.config.idConfig.idLength,n.idConfigForm.idMaximumLength=e.data.config.idConfig.idMaximumLength),"shortLinkNotFoundConfigForm"!==t&&"all"!==t||(n.shortLinkNotFoundConfigForm.mode=e.data.config.shortLinkNotFoundConfig.mode,n.shortLinkNotFoundConfigForm.value=e.data.config.shortLinkNotFoundConfig.value)}))},addLandingHost:function(){this.landingHostsForm.hosts.push({value:"",key:Date.now()})},removeLandingHost:function(t){this.landingHostsForm.hosts.splice(t,1)},updateLadingHosts:function(){var t=this;this.$refs["landingHostsForm"].validate((function(n){if(!n)return!1;var e=[];t.landingHostsForm.hosts.forEach((function(t){e.push(t.value)})),Object(g["c"])({hosts:e}).then((function(n){t.$notify({title:"更新成功",message:"成功更新短链接域名",type:"success"})}))}))},updateIdLengthConfig:function(){var t=this;Object(g["b"])(this.idConfigForm).then((function(n){t.$notify({title:"更新成功",message:"成功更新随机 ID 长度",type:"success"})}))},updateShortLinkNotFoundConfig:function(){var t=this;this.$refs["shortLinkNotFoundConfigForm"].validate((function(n){if(!n)return!1;Object(g["d"])(t.shortLinkNotFoundConfigForm).then((function(n){t.$notify({title:"更新成功",message:"短链接 404 处理配置",type:"success"})}))}))},getRequestHistoriesByDateRange:function(t,n,e){var o=this;Object(k["e"])(t,n,e).then((function(n){var e,i;o.list=n.data.histories;var r=Object(L["a"])(o.pinnedLinksData.dates,n.data.histories);(e=o.pinnedLinksData.perDayPvUv[t].pv).push.apply(e,m(r.pv)),(i=o.pinnedLinksData.perDayPvUv[t].uv).push.apply(i,m(r.uv))}))}}},y=C,w=(e("f8a7"),e("2877")),x=Object(w["a"])(y,o,i,!1,null,null,null);n["default"]=x.exports},"95d5":function(t,n,e){var o=e("40c3"),i=e("5168")("iterator"),r=e("481b");t.exports=e("584a").isIterable=function(t){var n=Object(t);return void 0!==n[i]||"@@iterator"in n||r.hasOwnProperty(o(n))}},a745:function(t,n,e){t.exports=e("f410")},acf4:function(t,n,e){},bfad:function(t,n,e){"use strict";e.d(n,"d",(function(){return i})),e.d(n,"c",(function(){return r})),e.d(n,"a",(function(){return a})),e.d(n,"f",(function(){return s})),e.d(n,"g",(function(){return l})),e.d(n,"b",(function(){return c})),e.d(n,"e",(function(){return u}));var o=e("b775");function i(t){return Object(o["a"])({url:"/v1/short-link/".concat(t),method:"get"})}function r(t,n){return Object(o["a"])({url:"/v1/short-link/?page=".concat(t,"&pageSize=").concat(n),method:"get"})}function a(t){return Object(o["a"])({url:"/v1/short-link/",method:"post",data:t})}function s(t){return Object(o["a"])({url:"/v1/short-link/".concat(t),method:"delete"})}function l(t,n){return Object(o["a"])({url:"/v1/short-link/".concat(t),method:"patch",data:n})}function c(t,n){return Object(o["a"])({url:"/v1/short-link/".concat(t,"/latest-request-history?size=").concat(n),method:"get"})}function u(t,n,e){return Object(o["a"])({url:"/v1/short-link/".concat(t,"/data?startDate=").concat(n,"&endDate=").concat(e),method:"get"})}},c3cc:function(t,n,e){"use strict";e.d(n,"b",(function(){return r})),e.d(n,"a",(function(){return a}));e("ac6a");var o=e("c1df"),i=e.n(o);function r(t){var n=i()(),e=n.clone().add(-(t-1),"d"),o=n.clone(),r=e.clone(),a=[];while(r.isSameOrBefore(o))a.push(r.format("YYYY-MM-DD")),r.add(1,"d");return{startDate:e,endDate:o,dates:a}}function a(t,n){var e={};t.forEach((function(t){e[t]={pv:0,ips:[]}})),n.forEach((function(t,n){var o=i()(t.time).format("YYYY-MM-DD");e[o].pv+=1,-1===e[o].ips.indexOf(t.ip)&&e[o].ips.push(t.ip)}));var o=[],r=[];return t.forEach((function(t){o.push(e[t].pv),r.push(e[t].ips.length)})),{pv:o,uv:r}}},c8bb:function(t,n,e){t.exports=e("54a1")},d2d5:function(t,n,e){e("1654"),e("549b"),t.exports=e("584a").Array.from},da71:function(t,n,e){"use strict";e.d(n,"a",(function(){return i})),e.d(n,"c",(function(){return r})),e.d(n,"b",(function(){return a})),e.d(n,"d",(function(){return s}));var o=e("b775");function i(){return Object(o["a"])({url:"/v1/config",method:"get"})}function r(t){return Object(o["a"])({url:"/v1/config/landing-hosts",method:"patch",data:t})}function a(t){return Object(o["a"])({url:"/v1/config/id-length",method:"patch",data:t})}function s(t){return Object(o["a"])({url:"/v1/config/short-link-404-handling",method:"patch",data:t})}},f410:function(t,n,e){e("1af6"),t.exports=e("584a").Array.isArray},f8a7:function(t,n,e){"use strict";var o=e("acf4"),i=e.n(o);i.a}}]); \ No newline at end of file +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-7f8ff64d"],{"14c9":function(t,n,e){"use strict";var o=function(){var t=this,n=t.$createElement,e=t._self._c||n;return e("div",{class:t.className,style:{height:t.height,width:t.width}})},i=[],r=e("313e"),a=e.n(r);e("817d");var s={props:{className:{type:String,default:"chart"},width:{type:String,default:"100%"},height:{type:String,default:"350px"},autoResize:{type:Boolean,default:!0},chartData:{type:Object,required:!0},title:{type:Object,default:{}}},data:function(){return{chart:null}},watch:{chartData:{deep:!0,handler:function(t){this.setOptions(t)}}},mounted:function(){var t=this;this.$nextTick((function(){t.initChart()}))},beforeDestroy:function(){this.chart&&(this.chart.dispose(),this.chart=null)},methods:{initChart:function(){this.chart=a.a.init(this.$el,"macarons"),this.setOptions(this.chartData)},setOptions:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.pv,e=t.uv,o=t.dates;this.chart&&this.chart.setOption({title:this.title,xAxis:{data:o,boundaryGap:!1,axisTick:{show:!1}},grid:{left:50,right:50,bottom:20,top:30,containLabel:!0},tooltip:{trigger:"axis",axisPointer:{type:"cross"},padding:[5,10]},yAxis:{axisTick:{show:!1}},legend:{data:["PV","UV"]},series:[{name:"PV",itemStyle:{normal:{color:"#FF005A",lineStyle:{color:"#FF005A",width:2}}},smooth:!0,type:"line",data:n,animationDuration:2800,animationEasing:"cubicInOut"},{name:"UV",smooth:!0,type:"line",itemStyle:{normal:{color:"#3888fa",lineStyle:{color:"#3888fa",width:2},areaStyle:{color:"#f3f8ff"}}},data:e,animationDuration:2800,animationEasing:"quadraticOut"}]})}}},l=s,c=e("2877"),u=Object(c["a"])(l,o,i,!1,null,null,null);n["a"]=u.exports},"1af6":function(t,n,e){var o=e("63b6");o(o.S,"Array",{isArray:e("9003")})},"549b":function(t,n,e){"use strict";var o=e("d864"),i=e("63b6"),r=e("241e"),a=e("b0dc"),s=e("3702"),l=e("b447"),c=e("20fd"),u=e("7cd6");i(i.S+i.F*!e("4ee1")((function(t){Array.from(t)})),"Array",{from:function(t){var n,e,i,d,f=r(t),h="function"==typeof this?this:Array,m=arguments.length,v=m>1?arguments[1]:void 0,g=void 0!==v,p=0,b=u(f);if(g&&(v=o(v,m>2?arguments[2]:void 0,2)),void 0==b||h==Array&&s(b))for(n=l(f.length),e=new h(n);n>p;p++)c(e,p,g?v(f[p],p):f[p]);else for(d=b.call(f),e=new h;!(i=d.next()).done;p++)c(e,p,g?a(d,v,[i.value,p],!0):i.value);return e.length=p,e}})},"54a1":function(t,n,e){e("6c1c"),e("1654"),t.exports=e("95d5")},"774e":function(t,n,e){t.exports=e("d2d5")},9406:function(t,n,e){"use strict";e.r(n);var o=function(){var t=this,n=t.$createElement,e=t._self._c||n;return e("el-main",[e("el-row",{directives:[{name:"show",rawName:"v-show",value:t.pinned.length>0,expression:"pinned.length > 0"}],attrs:{gutter:5}},[e("h3",{staticStyle:{color:"#555"}},[t._v("Pin")]),t._v(" "),t._l(t.pinned,(function(n,o){return e("el-col",{attrs:{span:8}},[e("line-chart",{attrs:{title:{text:n,align:"right"},"chart-data":{pv:t.pinnedLinksData.perDayPvUv[n].pv,uv:t.pinnedLinksData.perDayPvUv[n].uv,dates:t.pinnedLinksData.dates},height:"200px"}})],1)}))],2),t._v(" "),t.pinned.length>0?e("el-divider"):t._e(),t._v(" "),e("el-row",{attrs:{gutter:20}},[e("h3",{staticStyle:{color:"#555"}},[t._v("系统设置")]),t._v(" "),e("el-col",{attrs:{span:7}},[e("el-card",[e("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[e("span",[t._v("短链接域名\n "),e("el-popover",{attrs:{placement:"bottom",width:"300",trigger:"hover"}},[e("p",[t._v("\n 配置短链接域名后,可以在短链接列表快速拷贝完整的短链接。"),e("br"),t._v("\n 示例:http://t.anmuji.com/"),e("br"),t._v(" "),e("strong",[t._v('注意:以 "/" 结尾。')])]),t._v(" "),e("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})])],1),t._v(" "),e("div",{directives:[{name:"show",rawName:"v-show",value:2===t.role,expression:"role === 2"}],staticStyle:{float:"right"}},[e("el-button",{attrs:{icon:"el-icon-refresh",size:"mini",circle:""},on:{click:function(n){return t.getConfig("landingHostsForm")}}}),t._v(" "),e("el-button",{attrs:{icon:"el-icon-plus",size:"mini",circle:""},on:{click:function(n){return t.addLandingHost()}}}),t._v(" "),e("el-button",{attrs:{icon:"el-icon-check",size:"mini",circle:""},on:{click:function(n){return t.updateLadingHosts()}}})],1)]),t._v(" "),e("el-form",{ref:"landingHostsForm",attrs:{model:t.landingHostsForm,"label-position":"left","label-width":"0px",size:"mini"}},t._l(t.landingHostsForm.hosts,(function(n,o){return e("el-form-item",{key:n.key,attrs:{prop:"hosts."+o+".value",rules:t.landingHostRules}},[e("el-input",{staticStyle:{width:"90%"},attrs:{readonly:2!==t.role,placeholder:"示例:http://anmuji.com/t/ 以 / 结尾"},model:{value:n.value,callback:function(e){t.$set(n,"value",e)},expression:"host.value"}}),t._v(" "),e("el-button",{directives:[{name:"show",rawName:"v-show",value:t.landingHostsForm.hosts.length>1&&2===t.role,expression:"landingHostsForm.hosts.length > 1 && role === 2"}],staticStyle:{padding:"1px"},attrs:{icon:"el-icon-minus",size:"mini",type:"danger",circle:""},on:{click:function(n){return t.removeLandingHost(o)}}})],1)})),1)],1)],1),t._v(" "),e("el-col",{attrs:{span:10}},[e("el-card",[e("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[e("span",[t._v("随机 ID 长度设置\n "),e("el-popover",{attrs:{placement:"bottom",width:"300",trigger:"hover"}},[e("p",[t._v("默认长度即随机生成 ID 的长度,"),e("br"),t._v("最小长度 <= 默认长度 <= 最大长度")]),t._v(" "),e("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})])],1),t._v(" "),e("div",{directives:[{name:"show",rawName:"v-show",value:2===t.role,expression:"role === 2"}],staticStyle:{float:"right"}},[e("el-button",{attrs:{icon:"el-icon-refresh",size:"mini",circle:""},on:{click:function(n){return t.getConfig("idConfigForm")}}}),t._v(" "),e("el-button",{attrs:{icon:"el-icon-check",size:"mini",circle:""},on:{click:function(n){return t.updateIdLengthConfig()}}})],1)]),t._v(" "),e("el-form",{ref:"idConfigForm",attrs:{model:t.idConfigForm,size:"mini","label-position":"top",inline:!0}},[e("el-form-item",{attrs:{prop:"idMinimumLength",label:"最小长度"}},[e("el-input-number",{attrs:{size:"mini",disabled:2!==t.role},model:{value:t.idConfigForm.idMinimumLength,callback:function(n){t.$set(t.idConfigForm,"idMinimumLength",n)},expression:"idConfigForm.idMinimumLength"}})],1),t._v(" "),e("el-form-item",{attrs:{prop:"idLength",label:"默认长度"}},[e("el-input-number",{attrs:{size:"mini",disabled:2!==t.role},model:{value:t.idConfigForm.idLength,callback:function(n){t.$set(t.idConfigForm,"idLength",n)},expression:"idConfigForm.idLength"}})],1),t._v(" "),e("el-form-item",{attrs:{prop:"idMaximumLength",label:"最大长度"}},[e("el-input-number",{attrs:{size:"mini",disabled:2!==t.role},model:{value:t.idConfigForm.idMaximumLength,callback:function(n){t.$set(t.idConfigForm,"idMaximumLength",n)},expression:"idConfigForm.idMaximumLength"}})],1)],1)],1)],1),t._v(" "),e("el-col",{attrs:{span:7}},[e("el-card",[e("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[e("span",[t._v("短链接 404 处理\n "),e("el-popover",{attrs:{placement:"bottom",width:"320",trigger:"hover"}},[e("p",[t._v("展示文案:当访问的短链接找不到时,展示设定的文案")]),t._v(" "),e("p",[t._v("URL跳转:当访问的短链接找不到时,跳转到设定的URL")]),t._v(" "),e("i",{staticClass:"el-icon-question",attrs:{slot:"reference"},slot:"reference"})])],1),t._v(" "),e("div",{directives:[{name:"show",rawName:"v-show",value:2===t.role,expression:"role === 2"}],staticStyle:{float:"right"}},[e("el-button",{attrs:{icon:"el-icon-refresh",size:"mini",circle:""},on:{click:function(n){return t.getConfig("shortLinkNotFoundConfigForm")}}}),t._v(" "),e("el-button",{attrs:{icon:"el-icon-check",size:"mini",circle:""},on:{click:function(n){return t.updateShortLinkNotFoundConfig()}}})],1)]),t._v(" "),e("el-form",{ref:"shortLinkNotFoundConfigForm",attrs:{model:t.shortLinkNotFoundConfigForm,size:"mini","label-position":"top"}},[e("el-form-item",{attrs:{prop:"mode",label:"模式"}},[e("el-select",{attrs:{placeholder:"请选择",disabled:2!==t.role},model:{value:t.shortLinkNotFoundConfigForm.mode,callback:function(n){t.$set(t.shortLinkNotFoundConfigForm,"mode",n)},expression:"shortLinkNotFoundConfigForm.mode"}},t._l(t.shortLinkNotFoundModeOptions,(function(t){return e("el-option",{key:t.value,attrs:{label:t.label,value:t.value}})})),1)],1),t._v(" "),e("el-form-item",{directives:[{name:"show",rawName:"v-show",value:"content"===t.shortLinkNotFoundConfigForm.mode,expression:"shortLinkNotFoundConfigForm.mode === 'content'"}],attrs:{prop:"value",label:"文案",rules:t.shortLinkNotFoundConfigRules}},[e("el-input",{attrs:{type:"textarea",placeholder:"你访问的页面不存在哦",readonly:2!==t.role},model:{value:t.shortLinkNotFoundConfigForm.value,callback:function(n){t.$set(t.shortLinkNotFoundConfigForm,"value",n)},expression:"shortLinkNotFoundConfigForm.value"}})],1),t._v(" "),e("el-form-item",{directives:[{name:"show",rawName:"v-show",value:"redirect"===t.shortLinkNotFoundConfigForm.mode,expression:"shortLinkNotFoundConfigForm.mode === 'redirect'"}],attrs:{prop:"value",label:"URL",rules:t.shortLinkNotFoundConfigRules}},[e("el-input",{attrs:{placeholder:"示例:https://github.com/jwma/jump-jump"},model:{value:t.shortLinkNotFoundConfigForm.value,callback:function(n){t.$set(t.shortLinkNotFoundConfigForm,"value",n)},expression:"shortLinkNotFoundConfigForm.value"}})],1)],1)],1)],1)],1)],1)},i=[],r=e("a745"),a=e.n(r);function s(t){if(a()(t)){for(var n=0,e=new Array(t.length);n0){var n=Object(L["b"])(7);this.pinnedLinksData.dates=n.dates,this.pinned.forEach((function(e,o){t.$set(t.pinnedLinksData.perDayPvUv,e,{pv:[],uv:[]}),t.getRequestHistoriesByDateRange(e,n.startDate.format("YYYY-MM-DD"),n.endDate.format("YYYY-MM-DD"))}))}},methods:{getConfig:function(t){var n=this;Object(g["a"])().then((function(e){"landingHostsForm"!==t&&"all"!==t||(n.landingHostsForm.hosts=[],e.data.config.landingHosts.forEach((function(t,e){n.landingHostsForm.hosts.push({value:t,key:Date.now()+e})})),0===e.data.config.landingHosts.length&&n.addLandingHost()),"idConfigForm"!==t&&"all"!==t||(n.idConfigForm.idMinimumLength=e.data.config.idConfig.idMinimumLength,n.idConfigForm.idLength=e.data.config.idConfig.idLength,n.idConfigForm.idMaximumLength=e.data.config.idConfig.idMaximumLength),"shortLinkNotFoundConfigForm"!==t&&"all"!==t||(n.shortLinkNotFoundConfigForm.mode=e.data.config.shortLinkNotFoundConfig.mode,n.shortLinkNotFoundConfigForm.value=e.data.config.shortLinkNotFoundConfig.value)}))},addLandingHost:function(){this.landingHostsForm.hosts.push({value:"",key:Date.now()})},removeLandingHost:function(t){this.landingHostsForm.hosts.splice(t,1)},updateLadingHosts:function(){var t=this;this.$refs["landingHostsForm"].validate((function(n){if(!n)return!1;var e=[];t.landingHostsForm.hosts.forEach((function(t){e.push(t.value)})),Object(g["c"])({hosts:e}).then((function(n){t.$notify({title:"更新成功",message:"成功更新短链接域名",type:"success"})}))}))},updateIdLengthConfig:function(){var t=this;Object(g["b"])(this.idConfigForm).then((function(n){t.$notify({title:"更新成功",message:"成功更新随机 ID 长度",type:"success"})}))},updateShortLinkNotFoundConfig:function(){var t=this;this.$refs["shortLinkNotFoundConfigForm"].validate((function(n){if(!n)return!1;Object(g["d"])(t.shortLinkNotFoundConfigForm).then((function(n){t.$notify({title:"更新成功",message:"短链接 404 处理配置",type:"success"})}))}))},getRequestHistoriesByDateRange:function(t,n,e){var o=this;Object(k["d"])(t,n,e).then((function(n){var e,i;o.list=n.data.histories;var r=Object(L["a"])(o.pinnedLinksData.dates,n.data.histories);(e=o.pinnedLinksData.perDayPvUv[t].pv).push.apply(e,m(r.pv)),(i=o.pinnedLinksData.perDayPvUv[t].uv).push.apply(i,m(r.uv))}))}}},y=C,w=(e("f8a7"),e("2877")),x=Object(w["a"])(y,o,i,!1,null,null,null);n["default"]=x.exports},"95d5":function(t,n,e){var o=e("40c3"),i=e("5168")("iterator"),r=e("481b");t.exports=e("584a").isIterable=function(t){var n=Object(t);return void 0!==n[i]||"@@iterator"in n||r.hasOwnProperty(o(n))}},a745:function(t,n,e){t.exports=e("f410")},acf4:function(t,n,e){},bfad:function(t,n,e){"use strict";e.d(n,"c",(function(){return i})),e.d(n,"b",(function(){return r})),e.d(n,"a",(function(){return a})),e.d(n,"e",(function(){return s})),e.d(n,"f",(function(){return l})),e.d(n,"d",(function(){return c}));var o=e("b775");function i(t){return Object(o["a"])({url:"/v1/short-link/".concat(t),method:"get"})}function r(t,n){return Object(o["a"])({url:"/v1/short-link/?page=".concat(t,"&pageSize=").concat(n),method:"get"})}function a(t){return Object(o["a"])({url:"/v1/short-link/",method:"post",data:t})}function s(t){return Object(o["a"])({url:"/v1/short-link/".concat(t),method:"delete"})}function l(t,n){return Object(o["a"])({url:"/v1/short-link/".concat(t),method:"patch",data:n})}function c(t,n,e){return Object(o["a"])({url:"/v1/short-link/".concat(t,"/data?startDate=").concat(n,"&endDate=").concat(e),method:"get"})}},c3cc:function(t,n,e){"use strict";e.d(n,"b",(function(){return r})),e.d(n,"a",(function(){return a}));e("ac6a");var o=e("c1df"),i=e.n(o);function r(t){var n=i()(),e=n.clone().add(-(t-1),"d"),o=n.clone(),r=e.clone(),a=[];while(r.isSameOrBefore(o))a.push(r.format("YYYY-MM-DD")),r.add(1,"d");return{startDate:e,endDate:o,dates:a}}function a(t,n){var e={};t.forEach((function(t){e[t]={pv:0,ips:[]}})),n.forEach((function(t,n){var o=i()(t.time).format("YYYY-MM-DD");e[o].pv+=1,-1===e[o].ips.indexOf(t.ip)&&e[o].ips.push(t.ip)}));var o=[],r=[];return t.forEach((function(t){o.push(e[t].pv),r.push(e[t].ips.length)})),{pv:o,uv:r}}},c8bb:function(t,n,e){t.exports=e("54a1")},d2d5:function(t,n,e){e("1654"),e("549b"),t.exports=e("584a").Array.from},da71:function(t,n,e){"use strict";e.d(n,"a",(function(){return i})),e.d(n,"c",(function(){return r})),e.d(n,"b",(function(){return a})),e.d(n,"d",(function(){return s}));var o=e("b775");function i(){return Object(o["a"])({url:"/v1/config",method:"get"})}function r(t){return Object(o["a"])({url:"/v1/config/landing-hosts",method:"patch",data:t})}function a(t){return Object(o["a"])({url:"/v1/config/id-length",method:"patch",data:t})}function s(t){return Object(o["a"])({url:"/v1/config/short-link-404-handling",method:"patch",data:t})}},f410:function(t,n,e){e("1af6"),t.exports=e("584a").Array.isArray},f8a7:function(t,n,e){"use strict";var o=e("acf4"),i=e.n(o);i.a}}]); \ No newline at end of file