前端代码
|
|
@ -38,3 +38,6 @@ bin/
|
|||
.cache/
|
||||
.idea/
|
||||
*.swp
|
||||
|
||||
web/dist/
|
||||
web/node_modules/
|
||||
|
|
|
|||
21
LICENSE
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 go-kratos
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
# Kra 管理后台
|
||||
|
||||
## 范围
|
||||
|
||||
Kra 管理后台由 Kratos 应用承载生命周期,Gin 提供兼容管理端的 HTTP 路由。后端按 `service -> biz -> data` 分层,前端位于 `web/`。
|
||||
|
||||
保留的业务模块:
|
||||
|
||||
- 初始化、认证、用户和个人中心
|
||||
- 角色、菜单、API、Casbin 和按钮权限
|
||||
- 部门、岗位和数据范围
|
||||
- 字典、字典项和系统参数
|
||||
- 安全策略、系统配置和 API Token
|
||||
- Excel 导入导出与版本管理
|
||||
- 操作日志、登录日志、数据访问日志、错误日志和文件日志
|
||||
- 定时任务、SSE、媒体上传和附件分类
|
||||
- 公告管理与邮件发送
|
||||
|
||||
不包含代码生成、智能辅助、模块安装发布、客户示例和测试页面。
|
||||
|
||||
## 目录
|
||||
|
||||
| 目录 | 职责 |
|
||||
|---|---|
|
||||
| `internal/server` | Gin 路由、中间件和 Kratos transport 生命周期 |
|
||||
| `internal/service` | HTTP DTO 与领域对象转换、用例编排 |
|
||||
| `internal/biz` | 领域对象、业务规则和仓储接口 |
|
||||
| `internal/data` | GORM、MySQL、Redis 和本地文件存储实现 |
|
||||
| `web` | Vue 3 管理端 |
|
||||
|
||||
## 兼容约定
|
||||
|
||||
- HTTP 响应为 `{code, data, msg}`,成功码为 `0`。
|
||||
- JWT 接受 `x-token` Header 和同名 Cookie。
|
||||
- 初始化创建后台数据表、管理员、菜单,并从 Gin 路由同步 API 权限数据。
|
||||
- 超级管理员角色 `888` 保留全权限旁路,其他角色由 Casbin 控制。
|
||||
- SMTP 配置位于 `admin.email`;未配置时错误邮件告警保持关闭。
|
||||
- 媒体文件默认使用本地 `uploads/file` 存储。
|
||||
|
||||
## 验证
|
||||
|
||||
```bash
|
||||
go generate ./cmd/kratos-admin
|
||||
go test ./...
|
||||
go vet ./...
|
||||
go build ./...
|
||||
|
||||
cd web
|
||||
pnpm install
|
||||
pnpm run lint
|
||||
pnpm run build
|
||||
```
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
# GVA 管理后端迁移清单
|
||||
|
||||
## 基线与范围
|
||||
|
||||
- 参考基线:工作区 `gva/server`,Git `02f37833`。
|
||||
- 目标:保留 GVA Vue 管理端使用的 HTTP 路径、方法、请求字段、统一响应结构和核心业务语义,同时按 Kratos 的 `service -> biz -> data` 分层落地。
|
||||
- 明确排除:代码生成、代码生成历史、插件打包/安装、AI/LLM、MCP、Skills,以及测试文件。
|
||||
- 公告与邮件位于 `gva/server/plugin`;两者均已按 Kratos 分层迁移,不保留 GVA 的插件式全局变量结构。
|
||||
- 推荐范围包含 177 个 GVA HTTP 路由,目标端全部覆盖;另增加 `GET /health`,目标实际注册路由总数为 178。
|
||||
|
||||
## 模块契约矩阵
|
||||
|
||||
| 模块 | 路由数 | 迁移内容 |
|
||||
|---|---:|---|
|
||||
| 初始化、登录、用户、个人中心 | 17 | 初始化、验证码、登录、JWT、用户 CRUD、多角色、个人资料、密码、菜单、注销 |
|
||||
| 角色 | 9 | 角色树、创建、复制、更新、删除、用户关联、数据范围 |
|
||||
| 菜单 | 10 | 菜单树、CRUD、角色菜单、菜单角色、菜单按钮 |
|
||||
| API 与 Casbin | 19 | API CRUD/同步/忽略、角色 API、Casbin 策略、按钮权限 |
|
||||
| 组织 | 16 | 部门树、岗位、用户关联、自定义数据范围 |
|
||||
| 字典与参数 | 24 | 字典/字典项 CRUD、树、路径、导入导出、系统参数 |
|
||||
| 安全、系统配置、API Token | 9 | 安全策略热更新、限流、锁定、密码策略、配置、服务器信息、Token 签发/作废 |
|
||||
| Excel 导入导出 | 12 | 模板 CRUD、SQL 预览、一次性下载令牌、Excel 导入导出 |
|
||||
| 版本管理 | 7 | 菜单/API/字典版本打包、记录、下载和导入 |
|
||||
| 审计与日志 | 20 | 操作、登录、数据访问、错误日志以及安全的文件日志查看 |
|
||||
| 定时任务与 SSE | 9 | Cron CRUD/启停/触发、HTTP/本地执行器、执行日志、失败告警 SSE |
|
||||
| 媒体 | 15 | 文件库、附件分类、本地存储枚举、普通上传、秒传与分片续传 |
|
||||
| 公告 | 8 | 公告 CRUD、批量删除、分页、发布者数据源和公开接口 |
|
||||
| 邮件 | 2 | SMTP 测试、主动发送,以及失败请求邮件告警中间件 |
|
||||
|
||||
## 分层映射
|
||||
|
||||
| Kratos 层 | 职责 |
|
||||
|---|---|
|
||||
| `internal/server` | Gin 路由、鉴权/审计中间件、HTTP 请求绑定与响应写出、Kratos transport 生命周期 |
|
||||
| `internal/service` | HTTP DTO 与领域数据的适配、用例编排 |
|
||||
| `internal/biz` | 用户、权限、设置、审计、任务、媒体等领域对象、仓储接口与业务规则 |
|
||||
| `internal/data` | GORM PO、MySQL 仓储、Redis/内存缓存、本地文件存储 |
|
||||
| `cmd/kratos-admin` | Wire 依赖注入与 Kratos 应用组装 |
|
||||
|
||||
## 兼容性说明
|
||||
|
||||
- HTTP 响应保持 `{code, data, msg}`,成功码为 `0`。
|
||||
- JWT 继续接受 `x-token` Header 和同名 Cookie;角色切换返回 `new-token`、`new-expires-at`。
|
||||
- 初始化会自动迁移表、写入管理员与菜单,并从 Gin 实际路由同步 API 表。
|
||||
- 超级管理员角色 `888` 保留全权限旁路;其他角色由 Casbin 策略控制。
|
||||
- 代码中的 `*-gva` 字符串仅是原 Vue 图标库的图标标识,为页面显示兼容而保留;Go 文件、类型、变量和方法均使用实际职责命名。
|
||||
- 当前首先实现 MySQL、Redis(不可用时退化为进程缓存)和本地文件存储;云 OSS 驱动没有混入领域层。
|
||||
- SMTP 参数位于 `admin.email`;未配置服务器、发件人或密钥时错误告警保持关闭,邮件接口会返回明确的配置错误。
|
||||
|
||||
## 验证命令
|
||||
|
||||
```bash
|
||||
go generate ./cmd/kratos-admin
|
||||
go test ./...
|
||||
go vet ./...
|
||||
go build ./...
|
||||
git diff --check
|
||||
```
|
||||
1
gva
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 02f37833255e0e339c3d69199cb5a468f17de9fc
|
||||
|
|
@ -22,7 +22,7 @@ type announcementPO struct {
|
|||
Attachments []byte `gorm:"type:json"`
|
||||
}
|
||||
|
||||
func (announcementPO) TableName() string { return "gva_announcements_info" }
|
||||
func (announcementPO) TableName() string { return "kra_announcements_info" }
|
||||
|
||||
type announcementRepo struct{ data *Data }
|
||||
|
||||
|
|
|
|||
|
|
@ -419,13 +419,13 @@ func defaultMenus() []menuPO {
|
|||
}
|
||||
return []menuPO{
|
||||
{Path: "dashboard", Name: "dashboard", Component: "view/dashboard/index.vue", Title: "仪表盘", Icon: "odometer", Sort: 1},
|
||||
root("permission", "permission", "权限管理", "perm-gva", 2), root("org", "org", "组织管理", "share", 3), root("systemConfig", "systemConfig", "系统设置", "config-gva", 4), root("monitor", "monitor", "运维监控", "monitor-gva", 5), root("media", "media", "媒体管理", "folder-opened", 6), root("plugin", "plugin", "插件系统", "cherry", 10),
|
||||
root("permission", "permission", "权限管理", "perm-kra", 2), root("org", "org", "组织管理", "share", 3), root("systemConfig", "systemConfig", "系统设置", "config-kra", 4), root("monitor", "monitor", "运维监控", "monitor-kra", 5), root("media", "media", "媒体管理", "folder-opened", 6), root("extensions", "extensions", "扩展功能", "cherry", 10),
|
||||
{Path: "person", Name: "person", Component: "view/person/person.vue", Title: "个人信息", Icon: "postcard", Hidden: true, Sort: 13},
|
||||
child("permission", "authority", "authority", "view/superAdmin/authority/authority.vue", "角色管理", "role-gva", 1), child("permission", "menu", "menu", "view/superAdmin/menu/menu.vue", "菜单管理", "tickets", 2), child("permission", "api", "api", "view/superAdmin/api/api.vue", "api管理", "api-gva", 3), child("permission", "apiToken", "apiToken", "view/systemTools/apiToken/index.vue", "API Token", "key", 4),
|
||||
child("permission", "authority", "authority", "view/superAdmin/authority/authority.vue", "角色管理", "role-kra", 1), child("permission", "menu", "menu", "view/superAdmin/menu/menu.vue", "菜单管理", "tickets", 2), child("permission", "api", "api", "view/superAdmin/api/api.vue", "api管理", "api-kra", 3), child("permission", "apiToken", "apiToken", "view/systemTools/apiToken/index.vue", "API Token", "key", 4),
|
||||
child("org", "user", "user", "view/superAdmin/user/user.vue", "用户管理", "user", 1), child("org", "department", "department", "view/superAdmin/department/department.vue", "部门管理", "office-building", 2), child("org", "position", "position", "view/superAdmin/position/position.vue", "岗位管理", "postcard", 3),
|
||||
child("systemConfig", "system", "system", "view/systemTools/system/system.vue", "配置文件", "config-file-gva", 1), child("systemConfig", "dictionary", "dictionary", "view/superAdmin/dictionary/sysDictionary.vue", "字典管理", "notebook", 2), child("systemConfig", "sysParams", "sysParams", "view/superAdmin/params/sysParams.vue", "参数管理", "set-up", 3), child("systemConfig", "security", "security", "view/system/security/index.vue", "安全配置", "security-gva", 4),
|
||||
child("monitor", "operation", "operation", "view/superAdmin/operation/sysOperationRecord.vue", "操作历史", "document", 1), child("monitor", "loginLog", "loginLog", "view/systemTools/loginLog/index.vue", "登录日志", "clock", 2), child("monitor", "sysError", "sysError", "view/systemTools/sysError/sysError.vue", "错误日志", "error-gva", 3), child("monitor", "sysVersion", "sysVersion", "view/systemTools/version/version.vue", "版本管理", "version-gva", 4), child("monitor", "state", "state", "view/system/state.vue", "服务器状态", "server", 5), child("monitor", "dataAccessLog", "dataAccessLog", "view/superAdmin/dataAccessLog/dataAccessLog.vue", "数据权限审计", "warning", 6), child("monitor", "timedTask", "timedTask", "view/systemTools/timedTask/index.vue", "定时任务", "timer", 7), child("monitor", "logViewer", "logViewer", "view/systemTools/logViewer/index.vue", "文件日志", "document", 8),
|
||||
child("systemConfig", "system", "system", "view/systemTools/system/system.vue", "配置文件", "config-file-kra", 1), child("systemConfig", "dictionary", "dictionary", "view/superAdmin/dictionary/sysDictionary.vue", "字典管理", "notebook", 2), child("systemConfig", "sysParams", "sysParams", "view/superAdmin/params/sysParams.vue", "参数管理", "set-up", 3), child("systemConfig", "security", "security", "view/system/security/index.vue", "安全配置", "security-kra", 4),
|
||||
child("monitor", "operation", "operation", "view/superAdmin/operation/sysOperationRecord.vue", "操作历史", "document", 1), child("monitor", "loginLog", "loginLog", "view/systemTools/loginLog/index.vue", "登录日志", "clock", 2), child("monitor", "sysError", "sysError", "view/systemTools/sysError/sysError.vue", "错误日志", "error-kra", 3), child("monitor", "sysVersion", "sysVersion", "view/systemTools/version/version.vue", "版本管理", "version-kra", 4), child("monitor", "state", "state", "view/system/state.vue", "服务器状态", "server", 5), child("monitor", "dataAccessLog", "dataAccessLog", "view/superAdmin/dataAccessLog/dataAccessLog.vue", "数据权限审计", "warning", 6), child("monitor", "timedTask", "timedTask", "view/systemTools/timedTask/index.vue", "定时任务", "timer", 7), child("monitor", "logViewer", "logViewer", "view/systemTools/logViewer/index.vue", "文件日志", "document", 8),
|
||||
child("media", "upload", "upload", "view/media/upload.vue", "媒体库(上传下载)", "upload", 1), child("media", "chunkUpload", "chunkUpload", "view/media/chunkUpload.vue", "大文件上传", "folder-add", 2),
|
||||
child("plugin", "plugin-email", "plugin-email", "plugin/email/view/index.vue", "邮件插件", "message", 4), child("plugin", "anInfo", "anInfo", "plugin/announcement/view/info.vue", "公告管理[示例]", "bell", 5),
|
||||
child("extensions", "email", "email", "modules/email/view/index.vue", "邮件发送", "message", 4), child("extensions", "anInfo", "anInfo", "modules/announcement/view/info.vue", "公告管理", "bell", 5),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,15 +216,6 @@ func registerAuditRoutes(group, public *gin.RouterGroup, svc *service.AuditServi
|
|||
}
|
||||
writeResult(c, codeSuccess, pageResult{List: items, Total: total, Page: page, PageSize: size}, "获取成功")
|
||||
})
|
||||
errorsRoute.GET("/getSysErrorSolution", func(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
item, err := svc.Error(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
fail(c, "查询失败")
|
||||
return
|
||||
}
|
||||
writeResult(c, codeSuccess, gin.H{"solution": item["solution"]}, "获取成功")
|
||||
})
|
||||
public.Group("/sysError").POST("/createSysError", func(c *gin.Context) {
|
||||
var req struct {
|
||||
Form string `json:"form"`
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
module.exports = { extends: ['@commitlint/config-conventional'] };
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
server {
|
||||
listen 8080;
|
||||
server_name localhost;
|
||||
|
||||
#charset koi8-r;
|
||||
#access_log logs/host.access.log main;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
rewrite ^/api/(.*)$ /$1 break; #重写
|
||||
proxy_pass http://177.7.0.12:8888; # 设置代理服务器的协议和地址
|
||||
}
|
||||
|
||||
location /api/swagger/index.html {
|
||||
proxy_pass http://127.0.0.1:8888/swagger/index.html;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
#charset koi8-r;
|
||||
#access_log logs/host.access.log main;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html/dist;
|
||||
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
rewrite ^/api/(.*)$ /$1 break; #重写
|
||||
proxy_pass http://127.0.0.1:8888; # 设置代理服务器的协议和地址
|
||||
}
|
||||
location /form-generator {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_pass http://127.0.0.1:8888;
|
||||
}
|
||||
location /api/swagger/index.html {
|
||||
proxy_pass http://127.0.0.1:8888/swagger/index.html;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
node_modules/
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
ENV = 'development'
|
||||
VITE_CLI_PORT = 8080
|
||||
VITE_SERVER_PORT = 8000
|
||||
VITE_BASE_API = /api
|
||||
VITE_FILE_API = /api
|
||||
VITE_BASE_PATH = http://127.0.0.1
|
||||
VITE_POSITION = open
|
||||
VITE_EDITOR = code
|
||||
// VITE_EDITOR = webstorm 如果使用webstorm开发且要使用dom定位到代码行功能 请先自定添加 webstorm到环境变量 再将VITE_EDITOR值修改为webstorm
|
||||
// 如果使用docker-compose开发模式,设置为下面的地址或本机主机IP
|
||||
//VITE_BASE_PATH = http://177.7.0.12
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
ENV = 'production'
|
||||
|
||||
#下方为上线需要用到的程序代理前缀,一般用于nginx代理转发
|
||||
VITE_BASE_API = /api
|
||||
VITE_FILE_API = /api
|
||||
|
|
@ -1,41 +1,6 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
**/node_modules
|
||||
# roadhog-api-doc ignore
|
||||
/src/utils/request-temp.js
|
||||
_roadhog-api-doc
|
||||
|
||||
# production
|
||||
/dist
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
npm-debug.log*
|
||||
yarn-error.log
|
||||
|
||||
/coverage
|
||||
.idea
|
||||
yarn.lock
|
||||
/node_modules/
|
||||
/dist/
|
||||
package-lock.json
|
||||
*bak
|
||||
.vscode
|
||||
|
||||
|
||||
# visual studio code
|
||||
.history
|
||||
*.log
|
||||
functions/*
|
||||
.temp/**
|
||||
|
||||
# umi
|
||||
.umi
|
||||
.umi-production
|
||||
.umi-test
|
||||
.turbopack
|
||||
|
||||
# screenshot
|
||||
screenshot
|
||||
.firebase
|
||||
|
||||
build
|
||||
yarn.lock
|
||||
bun.lockb
|
||||
config.yaml
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
npx --no -- commitlint --edit $1
|
||||
|
|
@ -1 +0,0 @@
|
|||
lint-staged
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"**/*.{js,jsx,tsx,ts,md,css,less,json}": [
|
||||
"npx @biomejs/biome check --write"
|
||||
]
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
legacy-peer-deps=true
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "always",
|
||||
"vueIndentScriptAndStyle": true,
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# 如果需要用 cicd ,请设置环境变量:
|
||||
# variables:
|
||||
# DOCKER_BUILDKIT: 1
|
||||
|
||||
FROM node:20-slim AS base
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
COPY . /app
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
FROM base AS prod-deps
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod
|
||||
|
||||
FROM base AS build
|
||||
COPY --from=prod-deps /app/node_modules /app/node_modules
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install && pnpm run build
|
||||
|
||||
|
||||
FROM nginx:alpine
|
||||
COPY --from=base /app/.docker-compose/nginx/conf.d/my.conf /etc/nginx/conf.d/my.conf
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
RUN ls -al /usr/share/nginx/html
|
||||
21
web/LICENSE
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019-present Alipay.inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# Kra 管理后台
|
||||
|
||||
Kra 的 Vue 3 管理端,与仓库中的 Kratos + Gin 后端配套使用。
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
生产构建:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
开发环境默认把 `/api` 代理到 `http://127.0.0.1:8000`。
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// Babel 配置
|
||||
//
|
||||
// 用 .cjs 而非 .js:本项目 package.json 为 "type": "module",.js 会被当作 ESM,
|
||||
// 而 @babel/eslint-parser 需要「同步」读取 babel 配置(ESLint 是同步解析的),
|
||||
// ESM 配置无法同步加载。.cjs 强制 CommonJS,保证 eslint 能正常读取本文件。
|
||||
//
|
||||
// 目前主要供 @babel/eslint-parser 解析 .js / .vue<script> 使用;
|
||||
// 如日后需要 babel 做实际转译,可直接复用这份 preset。
|
||||
module.exports = {
|
||||
presets: [
|
||||
['@babel/preset-env', { targets: 'defaults' }]
|
||||
]
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
{
|
||||
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
|
||||
"files": {
|
||||
"ignoreUnknown": true,
|
||||
"includes": [
|
||||
"**/*",
|
||||
"!**/.umi",
|
||||
"!**/.umi-production",
|
||||
"!**/.umi-test",
|
||||
"!**/.umi-test-production",
|
||||
"!**/src/services",
|
||||
"!**/mock",
|
||||
"!**/dist",
|
||||
"!**/server",
|
||||
"!**/public",
|
||||
"!**/coverage",
|
||||
"!**/node_modules",
|
||||
"!biome.json"
|
||||
]
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "space"
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true,
|
||||
"suspicious": {
|
||||
"noExplicitAny": "off"
|
||||
},
|
||||
"correctness": {
|
||||
"useUniqueElementIds": "off",
|
||||
"useExhaustiveDependencies": "off"
|
||||
},
|
||||
"a11y": {
|
||||
"noStaticElementInteractions": "off",
|
||||
"useValidAnchor": "off",
|
||||
"useKeyWithClickEvents": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"javascript": {
|
||||
"jsxRuntime": "reactClassic",
|
||||
"formatter": {
|
||||
"quoteStyle": "single"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
// https://umijs.org/config/
|
||||
|
||||
import { defineConfig } from "@umijs/max";
|
||||
import { join } from "node:path";
|
||||
import defaultSettings from "./defaultSettings";
|
||||
import proxy from "./proxy";
|
||||
|
||||
import routes from "./routes";
|
||||
|
||||
const { UMI_ENV = "dev" } = process.env;
|
||||
|
||||
/**
|
||||
* @name 使用公共路径
|
||||
* @description 部署时的路径,如果部署在非根目录下,需要配置这个变量
|
||||
* @doc https://umijs.org/docs/api/config#publicpath
|
||||
*/
|
||||
const PUBLIC_PATH: string = "/";
|
||||
|
||||
export default defineConfig({
|
||||
/**
|
||||
* @name 开启 hash 模式
|
||||
* @description 让 build 之后的产物包含 hash 后缀。通常用于增量发布和避免浏览器加载缓存。
|
||||
* @doc https://umijs.org/docs/api/config#hash
|
||||
*/
|
||||
hash: true,
|
||||
|
||||
publicPath: PUBLIC_PATH,
|
||||
|
||||
/**
|
||||
* @name 兼容性设置
|
||||
* @description 设置 ie11 不一定完美兼容,需要检查自己使用的所有依赖
|
||||
* @doc https://umijs.org/docs/api/config#targets
|
||||
*/
|
||||
// targets: {
|
||||
// ie: 11,
|
||||
// },
|
||||
/**
|
||||
* @name 路由的配置,不在路由中引入的文件不会编译
|
||||
* @description 只支持 path,component,routes,redirect,wrappers,title 的配置
|
||||
* @doc https://umijs.org/docs/guides/routes
|
||||
*/
|
||||
// umi routes: https://umijs.org/docs/routing
|
||||
routes,
|
||||
/**
|
||||
* @name 主题的配置
|
||||
* @description 虽然叫主题,但是其实只是 less 的变量设置
|
||||
* @doc antd的主题设置 https://ant.design/docs/react/customize-theme-cn
|
||||
* @doc umi 的 theme 配置 https://umijs.org/docs/api/config#theme
|
||||
*/
|
||||
// theme: { '@primary-color': '#1DA57A' }
|
||||
/**
|
||||
* @name moment 的国际化配置
|
||||
* @description 如果对国际化没有要求,打开之后能减少js的包大小
|
||||
* @doc https://umijs.org/docs/api/config#ignoremomentlocale
|
||||
*/
|
||||
ignoreMomentLocale: true,
|
||||
/**
|
||||
* @name 代理配置
|
||||
* @description 可以让你的本地服务器代理到你的服务器上,这样你就可以访问服务器的数据了
|
||||
* @see 要注意以下 代理只能在本地开发时使用,build 之后就无法使用了。
|
||||
* @doc 代理介绍 https://umijs.org/docs/guides/proxy
|
||||
* @doc 代理配置 https://umijs.org/docs/api/config#proxy
|
||||
*/
|
||||
proxy: proxy[UMI_ENV as keyof typeof proxy],
|
||||
/**
|
||||
* @name 快速热更新配置
|
||||
* @description 一个不错的热更新组件,更新时可以保留 state
|
||||
*/
|
||||
fastRefresh: true,
|
||||
//============== 以下都是max的插件配置 ===============
|
||||
/**
|
||||
* @name 数据流插件
|
||||
* @@doc https://umijs.org/docs/max/data-flow
|
||||
*/
|
||||
model: {},
|
||||
/**
|
||||
* 一个全局的初始数据流,可以用它在插件之间共享数据
|
||||
* @description 可以用来存放一些全局的数据,比如用户信息,或者一些全局的状态,全局初始状态在整个 Umi 项目的最开始创建。
|
||||
* @doc https://umijs.org/docs/max/data-flow#%E5%85%A8%E5%B1%80%E5%88%9D%E5%A7%8B%E7%8A%B6%E6%80%81
|
||||
*/
|
||||
initialState: {},
|
||||
/**
|
||||
* @name layout 插件
|
||||
* @doc https://umijs.org/docs/max/layout-menu
|
||||
*/
|
||||
title: "Ant Design Pro",
|
||||
layout: {
|
||||
locale: true,
|
||||
...defaultSettings,
|
||||
},
|
||||
/**
|
||||
* @name moment2dayjs 插件
|
||||
* @description 将项目中的 moment 替换为 dayjs
|
||||
* @doc https://umijs.org/docs/max/moment2dayjs
|
||||
*/
|
||||
moment2dayjs: {
|
||||
preset: "antd",
|
||||
plugins: ["duration"],
|
||||
},
|
||||
/**
|
||||
* @name 国际化插件
|
||||
* @doc https://umijs.org/docs/max/i18n
|
||||
*/
|
||||
locale: {
|
||||
// default zh-CN
|
||||
default: "zh-CN",
|
||||
antd: true,
|
||||
// default true, when it is true, will use `navigator.language` overwrite default
|
||||
baseNavigator: true,
|
||||
},
|
||||
/**
|
||||
* @name antd 插件
|
||||
* @description 内置了 babel import 插件
|
||||
* @doc https://umijs.org/docs/max/antd#antd
|
||||
*/
|
||||
antd: {
|
||||
appConfig: {},
|
||||
configProvider: {
|
||||
theme: {
|
||||
token: {
|
||||
fontFamily: "AlibabaSans, sans-serif",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
/**
|
||||
* @name 网络请求配置
|
||||
* @description 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
|
||||
* @doc https://umijs.org/docs/max/request
|
||||
*/
|
||||
request: {},
|
||||
/**
|
||||
* @name 权限插件
|
||||
* @description 基于 initialState 的权限插件,必须先打开 initialState
|
||||
* @doc https://umijs.org/docs/max/access
|
||||
*/
|
||||
access: {},
|
||||
/**
|
||||
* @name <head> 中额外的 script
|
||||
* @description 配置 <head> 中额外的 script
|
||||
*/
|
||||
headScripts: [
|
||||
// 解决首次加载时白屏的问题
|
||||
{ src: join(PUBLIC_PATH, "scripts/loading.js"), async: true },
|
||||
],
|
||||
//================ pro 插件配置 =================
|
||||
presets: ["umi-presets-pro"],
|
||||
mock: {
|
||||
include: ["mock/**/*", "src/pages/**/_mock.ts"],
|
||||
},
|
||||
utoopack: {},
|
||||
requestRecord: {},
|
||||
exportStatic: {},
|
||||
define: {
|
||||
"process.env.CI": process.env.CI,
|
||||
},
|
||||
});
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
import type { ProLayoutProps } from '@ant-design/pro-components';
|
||||
|
||||
/**
|
||||
* @name
|
||||
*/
|
||||
const Settings: ProLayoutProps & {
|
||||
pwa?: boolean;
|
||||
logo?: string;
|
||||
} = {
|
||||
navTheme: 'light',
|
||||
// 拂晓蓝
|
||||
colorPrimary: '#1890ff',
|
||||
layout: 'mix',
|
||||
contentWidth: 'Fluid',
|
||||
fixedHeader: false,
|
||||
fixSiderbar: true,
|
||||
colorWeak: false,
|
||||
title: 'Ant Design Pro',
|
||||
pwa: true,
|
||||
logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
|
||||
iconfontUrl: '',
|
||||
token: {
|
||||
// 参见ts声明,demo 见文档,通过token 修改样式
|
||||
//https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F
|
||||
},
|
||||
};
|
||||
|
||||
export default Settings;
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/**
|
||||
* @name 代理的配置
|
||||
* @see 在生产环境 代理是无法生效的,所以这里没有生产环境的配置
|
||||
* -------------------------------
|
||||
* The agent cannot take effect in the production environment
|
||||
* so there is no configuration of the production environment
|
||||
* For details, please see
|
||||
* https://pro.ant.design/docs/deploy
|
||||
*
|
||||
* @doc https://umijs.org/docs/guides/proxy
|
||||
*/
|
||||
export default {
|
||||
/**
|
||||
* @name 详细的代理配置
|
||||
* @doc https://github.com/chimurai/http-proxy-middleware
|
||||
*/
|
||||
dev: {
|
||||
"/v1/": {
|
||||
target: "http://localhost:8000",
|
||||
changeOrigin: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/**
|
||||
* @name umi 的路由配置
|
||||
* @description 只支持 path,component,routes,redirect,wrappers,name,icon 的配置
|
||||
* @param path path 只支持两种占位符配置,第一种是动态参数 :id 的形式,第二种是 * 通配符,通配符只能出现路由字符串的最后。
|
||||
* @param component 配置 location 和 path 匹配后用于渲染的 React 组件路径。可以是绝对路径,也可以是相对路径,如果是相对路径,会从 src/pages 开始找起。
|
||||
* @param routes 配置子路由,通常在需要为多个路径增加 layout 组件时使用。
|
||||
* @param redirect 配置路由跳转
|
||||
* @param wrappers 配置路由组件的包装组件,通过包装组件可以为当前的路由组件组合进更多的功能。 比如,可以用于路由级别的权限校验
|
||||
* @param name 配置路由的标题,默认读取国际化文件 menu.ts 中 menu.xxxx 的值,如配置 name 为 login,则读取 menu.ts 中 menu.login 的取值作为标题
|
||||
* @param icon 配置路由的图标,取值参考 https://ant.design/components/icon-cn, 注意去除风格后缀和大小写,如想要配置图标为 <StepBackwardOutlined /> 则取值应为 stepBackward 或 StepBackward,如想要配置图标为 <UserOutlined /> 则取值应为 user 或者 User
|
||||
* @doc https://umijs.org/docs/guides/routes
|
||||
*/
|
||||
export default [
|
||||
{
|
||||
path: "/user",
|
||||
layout: false,
|
||||
routes: [
|
||||
{
|
||||
name: "login",
|
||||
path: "/user/login",
|
||||
component: "./user/login",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/welcome",
|
||||
name: "welcome",
|
||||
icon: "smile",
|
||||
component: "./Welcome",
|
||||
},
|
||||
{
|
||||
name: "admin",
|
||||
icon: "crown",
|
||||
path: "/admins",
|
||||
access: "canAdmin",
|
||||
component: "./admins",
|
||||
},
|
||||
{
|
||||
path: "/",
|
||||
redirect: "/welcome",
|
||||
},
|
||||
{
|
||||
component: "404",
|
||||
layout: false,
|
||||
path: "./*",
|
||||
},
|
||||
];
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* ESLint 扁平配置(flat config)
|
||||
*
|
||||
* 解析链:.js/.jsx 交给 @babel/eslint-parser(读 babel.config.cjs);.vue 顶层由
|
||||
* vue-eslint-parser 解析 <template>,其 <script> 再委托给 babel。统一走 babel 而非默认
|
||||
* espree,是为了和项目 babel 工具链保持一致,日后引入 espree 尚不支持的语法也无需换解析器。
|
||||
*/
|
||||
import js from '@eslint/js'
|
||||
import pluginVue from 'eslint-plugin-vue'
|
||||
import globals from 'globals'
|
||||
import babelParser from '@babel/eslint-parser'
|
||||
import vueParser from 'vue-eslint-parser'
|
||||
|
||||
// .js 与 .vue<script> 复用的一份 babel 解析选项,改一处即两处生效,避免漂移
|
||||
const BABEL_PARSER_OPTIONS = {
|
||||
requireConfigFile: true, // 必须读到 babel.config.cjs(缺失即报错,杜绝悄悄回退到无配置)
|
||||
ecmaFeatures: { jsx: true } // 放开 JSX,渲染函数 / 个别组件偶有用到
|
||||
}
|
||||
|
||||
// 不参与检查的构建产物与静态资源
|
||||
const IGNORE_GLOBS = ['**/dist/**', '**/build/*.js', '**/src/assets/**', '**/public/**']
|
||||
|
||||
export default [
|
||||
// 基线规则集:ESLint 官方推荐 + Vue3 基础必备,后面的块只在此之上做增量覆盖
|
||||
js.configs.recommended,
|
||||
...pluginVue.configs['flat/essential'],
|
||||
|
||||
// 纯脚本文件:整段交给 babel 解析
|
||||
{
|
||||
name: 'app/js-babel',
|
||||
files: ['**/*.{js,mjs,jsx}'],
|
||||
languageOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
parser: babelParser,
|
||||
parserOptions: BABEL_PARSER_OPTIONS,
|
||||
globals: globals.node
|
||||
}
|
||||
},
|
||||
|
||||
// 单文件组件:顶层用 vue 解析器吃 <template>,<script> 再转交 babel
|
||||
{
|
||||
name: 'app/vue-babel',
|
||||
files: ['**/*.vue'],
|
||||
languageOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
parser: vueParser,
|
||||
parserOptions: { parser: babelParser, ...BABEL_PARSER_OPTIONS },
|
||||
globals: globals.node
|
||||
}
|
||||
},
|
||||
|
||||
// CommonJS 配置文件(如 babel.config.cjs):走 Node 环境,别把 module/require 判成未定义
|
||||
{
|
||||
name: 'app/commonjs',
|
||||
files: ['**/*.cjs'],
|
||||
languageOptions: {
|
||||
sourceType: 'commonjs',
|
||||
globals: globals.node
|
||||
}
|
||||
},
|
||||
|
||||
// 规则微调:只列与本项目习惯相冲、需显式放宽/收紧的项,其余沿用基线
|
||||
{
|
||||
name: 'app/rules',
|
||||
files: ['**/*.{js,mjs,jsx,vue}'],
|
||||
rules: {
|
||||
'vue/max-attributes-per-line': 0, // 每行属性数不限,排版交给人工
|
||||
'vue/no-v-model-argument': 0, // 允许 v-model:arg(EP 等组件写法)
|
||||
'vue/multi-word-component-names': 'off', // 允许单词组件名(大量既有页面如此)
|
||||
'no-lone-blocks': 'off', // 允许独立块级作用域
|
||||
'no-extend-native': 'off', // 允许扩展原生原型(个别工具函数依赖)
|
||||
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }] // 未用变量报错;下划线前缀参数放行
|
||||
}
|
||||
},
|
||||
|
||||
// 忽略目录
|
||||
{
|
||||
name: 'app/files-to-ignore',
|
||||
ignores: IGNORE_GLOBS
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
<!doctype html>
|
||||
<html lang="zh-cn" class="transition-colors">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||
<meta
|
||||
content="Kra,管理后台,Vue,Kratos,Gin"
|
||||
name="keywords"
|
||||
/>
|
||||
<link rel="icon" href="/logo.svg" />
|
||||
<title>Kra</title>
|
||||
<script>
|
||||
;(() => {
|
||||
try {
|
||||
// 必须与 THEME_SETTINGS_VERSION 保持一致:首屏防闪脚本无法 import 常量,
|
||||
// 缓存形态为版本信封 { version, settings },版本不匹配时与 store 一样回落默认。
|
||||
const VERSION = 1
|
||||
const raw = localStorage.getItem('kra-theme-settings')
|
||||
const parsed = raw ? JSON.parse(raw) : null
|
||||
const settings =
|
||||
parsed && parsed.version === VERSION && parsed.settings ? parsed.settings : null
|
||||
const scheme = settings && settings.themeScheme ? settings.themeScheme : 'auto'
|
||||
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
const isDark = scheme === 'dark' || (scheme === 'auto' && prefersDark)
|
||||
const root = document.documentElement
|
||||
root.classList.toggle('dark', isDark)
|
||||
root.classList.toggle('light', !isDark)
|
||||
if (settings && settings.themeColor) root.style.setProperty('--64f90c3645474bd5', settings.themeColor)
|
||||
} catch {}
|
||||
})()
|
||||
</script>
|
||||
<style>
|
||||
:root {
|
||||
--64f90c3645474bd5: #2264f2;
|
||||
/* 首屏 loading 背景/文字:默认浅色,与 App 的 bg-gray-50 对齐 */
|
||||
--kra-loading-bg: #f9fafb;
|
||||
--kra-loading-text: #6b7280;
|
||||
}
|
||||
/* 暗黑下与 App 的 dark:bg-slate-800 对齐,避免首屏 loading 白屏闪烁
|
||||
(class 由 head 内联 bootstrap 脚本在首次绘制前写入) */
|
||||
html.dark {
|
||||
--kra-loading-bg: #1e293b;
|
||||
--kra-loading-text: #94a3b8;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
background-color: var(--kra-loading-bg);
|
||||
}
|
||||
.transition-colors {
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
#kra-loading-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
background-color: var(--kra-loading-bg);
|
||||
}
|
||||
#loading-text {
|
||||
position: absolute;
|
||||
bottom: calc(50% - 100px);
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
color: var(--kra-loading-text);
|
||||
font-size: 14px;
|
||||
}
|
||||
#loading {
|
||||
position: absolute;
|
||||
top: calc(50% - 20px);
|
||||
left: calc(50% - 20px);
|
||||
}
|
||||
@keyframes loader {
|
||||
0% {
|
||||
left: -100px;
|
||||
}
|
||||
100% {
|
||||
left: 110%;
|
||||
}
|
||||
}
|
||||
#box {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: var(--64f90c3645474bd5);
|
||||
animation: animate 0.5s linear infinite;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: 3px;
|
||||
}
|
||||
@keyframes animate {
|
||||
17% {
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
25% {
|
||||
transform: translateY(9px) rotate(22.5deg);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(18px) scale(1, 0.9) rotate(45deg);
|
||||
border-bottom-right-radius: 40px;
|
||||
}
|
||||
75% {
|
||||
transform: translateY(9px) rotate(67.5deg);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0) rotate(90deg);
|
||||
}
|
||||
}
|
||||
#shadow {
|
||||
width: 50px;
|
||||
height: 5px;
|
||||
background: #000;
|
||||
opacity: 0.1;
|
||||
position: absolute;
|
||||
top: 59px;
|
||||
left: 0;
|
||||
border-radius: 50%;
|
||||
animation: shadow 0.5s linear infinite;
|
||||
}
|
||||
.dark #shadow {
|
||||
background: #fff;
|
||||
}
|
||||
@keyframes shadow {
|
||||
50% {
|
||||
transform: scale(1.2, 1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="kra-loading-box">
|
||||
<div id="loading">
|
||||
<div id="shadow"></div>
|
||||
<div id="box"></div>
|
||||
</div>
|
||||
<div id="loading-text">系统正在加载中,请稍候...</div>
|
||||
</div>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="./src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import { configUmiAlias, createConfig } from '@umijs/max/test';
|
||||
|
||||
export default async (): Promise<any> => {
|
||||
const config = await configUmiAlias({
|
||||
...createConfig({
|
||||
target: 'browser',
|
||||
}),
|
||||
});
|
||||
return {
|
||||
...config,
|
||||
testEnvironmentOptions: {
|
||||
...(config?.testEnvironmentOptions || {}),
|
||||
url: 'http://localhost:8000',
|
||||
},
|
||||
setupFiles: [...(config.setupFiles || []), './tests/setupTests.jsx'],
|
||||
globals: {
|
||||
...config.globals,
|
||||
localStorage: null,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"],
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
152
web/package.json
|
|
@ -1,96 +1,74 @@
|
|||
{
|
||||
"name": "ant-design-pro",
|
||||
"version": "6.0.0",
|
||||
"name": "kra",
|
||||
"version": "3.0.0",
|
||||
"private": true,
|
||||
"description": "An out-of-box UI solution for enterprise applications",
|
||||
"repository": "git@github.com:ant-design/ant-design-pro.git",
|
||||
"scripts": {
|
||||
"analyze": "cross-env ANALYZE=1 max build",
|
||||
"build": "max build",
|
||||
"deploy": "npm run build && npm run gh-pages",
|
||||
"dev": "npm run start:dev",
|
||||
"gh-pages": "gh-pages -d dist",
|
||||
"i18n-remove": "pro i18n-remove --locale=zh-CN --write",
|
||||
"postinstall": "max setup",
|
||||
"jest": "jest",
|
||||
"lint": "npm run biome:lint && npm run tsc",
|
||||
"lint-staged": "lint-staged",
|
||||
"biome:lint": "npx @biomejs/biome lint",
|
||||
"prepare": "husky",
|
||||
"preview": "npm run build && max preview --port 8000",
|
||||
"record": "cross-env NODE_ENV=development UMI_ENV=test max record --scene=login",
|
||||
"serve": "umi-serve",
|
||||
"start": "cross-env UMI_ENV=dev max dev",
|
||||
"start:dev": "cross-env UMI_ENV=dev PORT=3000 MOCK=none max dev",
|
||||
"start:no-mock": "cross-env MOCK=none max dev",
|
||||
"start:pre": "cross-env UMI_ENV=pre MOCK=none max dev",
|
||||
"start:test": "cross-env UMI_ENV=test MOCK=none max dev",
|
||||
"test": "jest",
|
||||
"test:coverage": "npm run jest -- --coverage",
|
||||
"test:update": "npm run jest -- -u",
|
||||
"tsc": "tsc --noEmit"
|
||||
"dev": "vite --host --mode development",
|
||||
"serve": "vite --host --mode development",
|
||||
"build": "vite build --mode production",
|
||||
"preview": "vite preview --host 0.0.0.0 --mode development",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
"browserslist": ["defaults"],
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^6.2.5",
|
||||
"@ant-design/pro-components": "^3.1.12-0",
|
||||
"antd": "^6.4.4",
|
||||
"antd-style": "^4.1.0",
|
||||
"classnames": "^2.5.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0"
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@iconify/vue": "^5.0.0",
|
||||
"@simple-prism/core": "^0.1.4",
|
||||
"@unocss/transformer-directives": "^66.4.2",
|
||||
"@vue-office/docx": "^1.6.2",
|
||||
"@vue-office/excel": "^1.7.11",
|
||||
"@vue-office/pdf": "^2.0.2",
|
||||
"@vueuse/core": "^12.8.2",
|
||||
"@vueuse/integrations": "^12.8.2",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"arcdash": "^0.0.60",
|
||||
"axios": "1.8.2",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"echarts": "5.5.1",
|
||||
"element-plus": "^2.13.6",
|
||||
"highlight.js": "^11.10.0",
|
||||
"mitt": "^3.0.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.2.2",
|
||||
"qs": "^6.13.0",
|
||||
"reka-ui": "^2.10.0",
|
||||
"screenfull": "^6.0.2",
|
||||
"sortablejs": "^1.15.3",
|
||||
"spark-md5": "^3.0.2",
|
||||
"tailwind-merge": "^3.6.0",
|
||||
"universal-cookie": "^7",
|
||||
"vite-auto-import-svg": "^2.9.8",
|
||||
"vue": "^3.5.31",
|
||||
"vue-cropper": "^1.1.4",
|
||||
"vue-echarts": "^7.0.3",
|
||||
"vue-qr": "^4.0.9",
|
||||
"vue-router": "^4.4.3",
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ant-design/pro-cli": "^3.3.0",
|
||||
"@commitlint/cli": "^20.1.0",
|
||||
"@commitlint/config-conventional": "^20.0.0",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@types/express": "^5.0.3",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@types/react-helmet": "^6.1.11",
|
||||
"@umijs/lint": "^4.6.1",
|
||||
"@umijs/max": "^4.6.2",
|
||||
"cross-env": "^10.0.0",
|
||||
"express": "^5.2.0",
|
||||
"gh-pages": "^6.1.1",
|
||||
"husky": "^9.1.7",
|
||||
"jest": "^30.0.4",
|
||||
"jest-environment-jsdom": "^30.0.5",
|
||||
"lint-staged": "^16.1.2",
|
||||
"mockjs": "^1.1.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.6.3",
|
||||
"umi-presets-pro": "^2.0.3",
|
||||
"umi-serve": "^1.9.11",
|
||||
"@biomejs/biome": "^2.1.1",
|
||||
"@types/node": "^24.0.13"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
},
|
||||
"create-umi": {
|
||||
"ignoreScript": ["docker*", "functions*", "site", "generateMock"],
|
||||
"ignoreDependencies": ["netlify*", "serverless"],
|
||||
"ignore": [
|
||||
".dockerignore",
|
||||
".git",
|
||||
".github",
|
||||
".gitpod.yml",
|
||||
"CODE_OF_CONDUCT.md",
|
||||
"Dockerfile",
|
||||
"Dockerfile.*",
|
||||
"lambda",
|
||||
"LICENSE",
|
||||
"netlify.toml",
|
||||
"README.*.md",
|
||||
"azure-pipelines.yml",
|
||||
"docker",
|
||||
"CNAME",
|
||||
"create-umi"
|
||||
]
|
||||
"@babel/core": "^7.25.0",
|
||||
"@babel/eslint-parser": "^7.25.1",
|
||||
"@babel/preset-env": "^7.25.0",
|
||||
"@eslint/js": "^8.56.0",
|
||||
"@unocss/extractor-svelte": "^66.4.2",
|
||||
"@unocss/preset-wind3": "^66.4.2",
|
||||
"@unocss/vite": "^66.5.0",
|
||||
"@vitejs/plugin-vue": "^6.0.6",
|
||||
"@vue/compiler-sfc": "^3.5.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"chalk": "^5.3.0",
|
||||
"chokidar": "^4.0.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-vue": "^9.19.2",
|
||||
"globals": "^16.3.0",
|
||||
"sass": "^1.78.0",
|
||||
"vite": "^8.0.10",
|
||||
"vite-check-multiple-dom": "0.2.1",
|
||||
"vite-plugin-vue-devtools": "^8.1.1",
|
||||
"vue-eslint-parser": "^9.4.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
allowBuilds:
|
||||
'@parcel/watcher': set this to true or false
|
||||
'@vue-office/docx': set this to true or false
|
||||
'@vue-office/excel': set this to true or false
|
||||
'@vue-office/pdf': set this to true or false
|
||||
es5-ext: set this to true or false
|
||||
vue-demi: set this to true or false
|
||||
|
|
@ -1 +0,0 @@
|
|||
preview.pro.ant.design
|
||||
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
|
|
@ -1 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" version="1.1" viewBox="0 0 200 200"><title>Group 28 Copy 5</title><desc>Created with Sketch.</desc><defs><linearGradient id="linearGradient-1" x1="62.102%" x2="108.197%" y1="0%" y2="37.864%"><stop offset="0%" stop-color="#4285EB"/><stop offset="100%" stop-color="#2EC7FF"/></linearGradient><linearGradient id="linearGradient-2" x1="69.644%" x2="54.043%" y1="0%" y2="108.457%"><stop offset="0%" stop-color="#29CDFF"/><stop offset="37.86%" stop-color="#148EFF"/><stop offset="100%" stop-color="#0A60FF"/></linearGradient><linearGradient id="linearGradient-3" x1="69.691%" x2="16.723%" y1="-12.974%" y2="117.391%"><stop offset="0%" stop-color="#FA816E"/><stop offset="41.473%" stop-color="#F74A5C"/><stop offset="100%" stop-color="#F51D2C"/></linearGradient><linearGradient id="linearGradient-4" x1="68.128%" x2="30.44%" y1="-35.691%" y2="114.943%"><stop offset="0%" stop-color="#FA8E7D"/><stop offset="51.264%" stop-color="#F74A5C"/><stop offset="100%" stop-color="#F51D2C"/></linearGradient></defs><g id="Page-1" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="logo" transform="translate(-20.000000, -20.000000)"><g id="Group-28-Copy-5" transform="translate(20.000000, 20.000000)"><g id="Group-27-Copy-3"><g id="Group-25" fill-rule="nonzero"><g id="2"><path id="Shape" fill="url(#linearGradient-1)" d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C99.2571609,26.9692191 101.032305,26.9692191 102.20193,28.1378823 L129.985225,55.8983314 C134.193707,60.1033528 141.017005,60.1033528 145.225487,55.8983314 C149.433969,51.69331 149.433969,44.8756232 145.225487,40.6706018 L108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z"/><path id="Shape" fill="url(#linearGradient-2)" d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C100.999864,25.6271836 105.751642,20.541824 112.729652,19.3524487 C117.915585,18.4685261 123.585219,20.4140239 129.738554,25.1889424 C125.624663,21.0784292 118.571995,14.0340304 108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z"/></g><path id="Shape" fill="url(#linearGradient-3)" d="M153.685633,135.854579 C157.894115,140.0596 164.717412,140.0596 168.925894,135.854579 L195.959977,108.842726 C200.659183,104.147384 200.659183,96.5636133 195.960527,91.8688194 L168.690777,64.7181159 C164.472332,60.5180858 157.646868,60.5241425 153.435895,64.7316526 C149.227413,68.936674 149.227413,75.7543607 153.435895,79.9593821 L171.854035,98.3623765 C173.02366,99.5310396 173.02366,101.304724 171.854035,102.473387 L153.685633,120.626849 C149.47715,124.83187 149.47715,131.649557 153.685633,135.854579 Z"/></g><ellipse id="Combined-Shape" cx="100.519" cy="100.437" fill="url(#linearGradient-4)" rx="23.6" ry="23.581"/></g></g></g></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="Kra">
|
||||
<rect width="128" height="128" rx="28" fill="#2264f2"/>
|
||||
<path d="M34 26v76h16V72l33 30h22L65 64l38-38H82L50 59V26H34z" fill="#fff"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 235 B |
|
|
@ -1,5 +0,0 @@
|
|||
<svg width="42" height="42" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<path fill="#070707" d="m6.717392,13.773912l5.6,0c2.8,0 4.7,1.9 4.7,4.7c0,2.8 -2,4.7 -4.9,4.7l-2.5,0l0,4.3l-2.9,0l0,-13.7zm2.9,2.2l0,4.9l1.9,0c1.6,0 2.6,-0.9 2.6,-2.4c0,-1.6 -0.9,-2.4 -2.6,-2.4l-1.9,0l0,-0.1zm8.9,11.5l2.7,0l0,-5.7c0,-1.4 0.8,-2.3 2.2,-2.3c0.4,0 0.8,0.1 1,0.2l0,-2.4c-0.2,-0.1 -0.5,-0.1 -0.8,-0.1c-1.2,0 -2.1,0.7 -2.4,2l-0.1,0l0,-1.9l-2.7,0l0,10.2l0.1,0zm11.7,0.1c-3.1,0 -5,-2 -5,-5.3c0,-3.3 2,-5.3 5,-5.3s5,2 5,5.3c0,3.4 -1.9,5.3 -5,5.3zm0,-2.1c1.4,0 2.2,-1.1 2.2,-3.2c0,-2 -0.8,-3.2 -2.2,-3.2c-1.4,0 -2.2,1.2 -2.2,3.2c0,2.1 0.8,3.2 2.2,3.2z" class="st0" id="Ant-Design-Pro"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 677 B |
|
|
@ -1,202 +0,0 @@
|
|||
/**
|
||||
* loading 占位
|
||||
* 解决首次加载时白屏的问题
|
||||
*/
|
||||
(function () {
|
||||
const _root = document.querySelector('#root');
|
||||
if (_root && _root.innerHTML === '') {
|
||||
_root.innerHTML = `
|
||||
<style>
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#root {
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% auto;
|
||||
}
|
||||
|
||||
.loading-title {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.loading-sub-title {
|
||||
margin-top: 20px;
|
||||
font-size: 1rem;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.page-loading-warp {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 26px;
|
||||
}
|
||||
.ant-spin {
|
||||
position: absolute;
|
||||
display: none;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
color: #1890ff;
|
||||
font-size: 14px;
|
||||
font-variant: tabular-nums;
|
||||
line-height: 1.5;
|
||||
text-align: center;
|
||||
list-style: none;
|
||||
opacity: 0;
|
||||
-webkit-transition: -webkit-transform 0.3s
|
||||
cubic-bezier(0.78, 0.14, 0.15, 0.86);
|
||||
transition: -webkit-transform 0.3s
|
||||
cubic-bezier(0.78, 0.14, 0.15, 0.86);
|
||||
transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
|
||||
transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86),
|
||||
-webkit-transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
|
||||
-webkit-font-feature-settings: "tnum";
|
||||
font-feature-settings: "tnum";
|
||||
}
|
||||
|
||||
.ant-spin-spinning {
|
||||
position: static;
|
||||
display: inline-block;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.ant-spin-dot {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.ant-spin-dot-item {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
background-color: #1890ff;
|
||||
border-radius: 100%;
|
||||
-webkit-transform: scale(0.75);
|
||||
-ms-transform: scale(0.75);
|
||||
transform: scale(0.75);
|
||||
-webkit-transform-origin: 50% 50%;
|
||||
-ms-transform-origin: 50% 50%;
|
||||
transform-origin: 50% 50%;
|
||||
opacity: 0.3;
|
||||
-webkit-animation: antspinmove 1s infinite linear alternate;
|
||||
animation: antSpinMove 1s infinite linear alternate;
|
||||
}
|
||||
|
||||
.ant-spin-dot-item:nth-child(1) {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.ant-spin-dot-item:nth-child(2) {
|
||||
top: 0;
|
||||
right: 0;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
.ant-spin-dot-item:nth-child(3) {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
-webkit-animation-delay: 0.8s;
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
|
||||
.ant-spin-dot-item:nth-child(4) {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
-webkit-animation-delay: 1.2s;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
|
||||
.ant-spin-dot-spin {
|
||||
-webkit-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
-webkit-animation: antrotate 1.2s infinite linear;
|
||||
animation: antRotate 1.2s infinite linear;
|
||||
}
|
||||
|
||||
.ant-spin-lg .ant-spin-dot {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.ant-spin-lg .ant-spin-dot i {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
|
||||
.ant-spin-blur {
|
||||
background: #fff;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes antSpinMove {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes antSpinMove {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes antRotate {
|
||||
to {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes antRotate {
|
||||
to {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div style="
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
min-height: 362px;
|
||||
">
|
||||
<div class="page-loading-warp">
|
||||
<div class="ant-spin ant-spin-lg ant-spin-spinning">
|
||||
<span class="ant-spin-dot ant-spin-dot-spin">
|
||||
<i class="ant-spin-dot-item"></i>
|
||||
<i class="ant-spin-dot-item"></i>
|
||||
<i class="ant-spin-dot-item"></i>
|
||||
<i class="ant-spin-dot-item"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="loading-title">
|
||||
正在加载资源
|
||||
</div>
|
||||
<div class="loading-sub-title">
|
||||
初次加载资源可能需要较多时间 请耐心等待
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<div
|
||||
id="app"
|
||||
class="bg-gray-50 text-slate-700 text-sm !dark:text-slate-500 dark:bg-slate-800"
|
||||
>
|
||||
<el-config-provider :locale="zhCn" v-bind="themeStore.elConfig">
|
||||
<router-view />
|
||||
<Application />
|
||||
</el-config-provider>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||
import Application from '@/components/application/index.vue'
|
||||
import { useThemeStore } from '@/pinia'
|
||||
|
||||
const themeStore = useThemeStore()
|
||||
defineOptions({
|
||||
name: 'App'
|
||||
})
|
||||
</script>
|
||||
<style lang="scss">
|
||||
// 引入初始化样式
|
||||
#app {
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
.el-button {
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
.kra-body-h {
|
||||
min-height: calc(100% - 3rem);
|
||||
}
|
||||
|
||||
.kra-container {
|
||||
height: calc(100% - 2.5rem);
|
||||
}
|
||||
|
||||
.kra-container2 {
|
||||
height: calc(100% - 2.5rem);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
import type { Admin } from "@/services";
|
||||
|
||||
/**
|
||||
* @see https://umijs.org/docs/max/access#access
|
||||
* */
|
||||
export default function access(
|
||||
initialState: { currentUser?: Admin } | undefined,
|
||||
) {
|
||||
const { currentUser } = initialState ?? {};
|
||||
return {
|
||||
canAdmin: currentUser && currentUser.access === "admin",
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
// @Tags api
|
||||
// @Summary 分页获取角色列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body modelInterface.PageInfo true "分页获取用户列表"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /api/getApiList [post]
|
||||
// {
|
||||
// page int
|
||||
// pageSize int
|
||||
// }
|
||||
export const getApiList = (data) => {
|
||||
return service({
|
||||
url: '/api/getApiList',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Api
|
||||
// @Summary 创建基础api
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body api.CreateApiParams true "创建api"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /api/createApi [post]
|
||||
export const createApi = (data) => {
|
||||
return service({
|
||||
url: '/api/createApi',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags menu
|
||||
// @Summary 根据id获取菜单
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body api.GetById true "根据id获取菜单"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /menu/getApiById [post]
|
||||
export const getApiById = (data) => {
|
||||
return service({
|
||||
url: '/api/getApiById',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Api
|
||||
// @Summary 更新api
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body api.CreateApiParams true "更新api"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
|
||||
// @Router /api/updateApi [post]
|
||||
export const updateApi = (data) => {
|
||||
return service({
|
||||
url: '/api/updateApi',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Api
|
||||
// @Summary 更新api
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body api.CreateApiParams true "更新api"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
|
||||
// @Router /api/setAuthApi [post]
|
||||
export const setAuthApi = (data) => {
|
||||
return service({
|
||||
url: '/api/setAuthApi',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Api
|
||||
// @Summary 获取所有的Api 不分页
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /api/getAllApis [post]
|
||||
export const getAllApis = (data) => {
|
||||
return service({
|
||||
url: '/api/getAllApis',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Api
|
||||
// @Summary 删除指定api
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body dbModel.Api true "删除api"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /api/deleteApi [post]
|
||||
export const deleteApi = (data) => {
|
||||
return service({
|
||||
url: '/api/deleteApi',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysApi
|
||||
// @Summary 删除选中Api
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.IdsReq true "ID"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /api/deleteApisByIds [delete]
|
||||
export const deleteApisByIds = (data) => {
|
||||
return service({
|
||||
url: '/api/deleteApisByIds',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// FreshCasbin
|
||||
// @Tags SysApi
|
||||
// @Summary 刷新casbin缓存
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{msg=string} "刷新成功"
|
||||
// @Router /api/freshCasbin [get]
|
||||
export const freshCasbin = () => {
|
||||
return service({
|
||||
url: '/api/freshCasbin',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export const syncApi = () => {
|
||||
return service({
|
||||
url: '/api/syncApi',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export const getApiGroups = () => {
|
||||
return service({
|
||||
url: '/api/getApiGroups',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export const ignoreApi = (data) => {
|
||||
return service({
|
||||
url: '/api/ignoreApi',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const enterSyncApi = (data) => {
|
||||
return service({
|
||||
url: '/api/enterSyncApi',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拥有指定API权限的角色ID列表
|
||||
* @param {string} path API路径
|
||||
* @param {string} method 请求方法
|
||||
* @returns {Promise<number[]>} 角色ID数组
|
||||
*/
|
||||
export const getApiRoles = (path, method) => {
|
||||
return service({
|
||||
url: '/api/getApiRoles',
|
||||
method: 'get',
|
||||
params: { path, method }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 全量覆盖某API关联的角色列表
|
||||
* @param {Object} data
|
||||
* @param {string} data.path API路径
|
||||
* @param {string} data.method 请求方法
|
||||
* @param {number[]} data.authorityIds 角色ID列表
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export const setApiRoles = (data) => {
|
||||
return service({
|
||||
url: '/api/setApiRoles',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import service from '@/utils/request'
|
||||
// 分类列表
|
||||
export const getCategoryList = () => {
|
||||
return service({
|
||||
url: '/attachmentCategory/getCategoryList',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
// 添加/编辑分类
|
||||
export const addCategory = (data) => {
|
||||
return service({
|
||||
url: '/attachmentCategory/addCategory',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除分类
|
||||
export const deleteCategory = (data) => {
|
||||
return service({
|
||||
url: '/attachmentCategory/deleteCategory',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
import service from '@/utils/request'
|
||||
// @Router /authority/getAuthorityList [post]
|
||||
export const getAuthorityList = (data) => {
|
||||
return service({
|
||||
url: '/authority/getAuthorityList',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 删除角色
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body {authorityId uint} true "删除角色"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /authority/deleteAuthority [post]
|
||||
export const deleteAuthority = (data) => {
|
||||
return service({
|
||||
url: '/authority/deleteAuthority',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 创建角色
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body api.CreateAuthorityPatams true "创建角色"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /authority/createAuthority [post]
|
||||
export const createAuthority = (data) => {
|
||||
return service({
|
||||
url: '/authority/createAuthority',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags authority
|
||||
// @Summary 拷贝角色
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body api.CreateAuthorityPatams true "拷贝角色"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"拷贝成功"}"
|
||||
// @Router /authority/copyAuthority [post]
|
||||
export const copyAuthority = (data) => {
|
||||
return service({
|
||||
url: '/authority/copyAuthority',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 设置角色数据范围(数据权限)
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body {authorityId:uint,dataScope:int} true "设置角色数据范围"
|
||||
// @Router /authority/setDataScope [post]
|
||||
export const setDataScope = (data) => {
|
||||
return service({
|
||||
url: '/authority/setDataScope',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 获取角色自定义部门集(数据权限第5档)
|
||||
// @Router /authority/getDataScopeDepts [get]
|
||||
export const getDataScopeDepts = (authorityId) => {
|
||||
return service({
|
||||
url: '/authority/getDataScopeDepts',
|
||||
method: 'get',
|
||||
params: { authorityId }
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 修改角色
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysAuthority true "修改角色"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
|
||||
// @Router /authority/updateAuthority [put]
|
||||
export const updateAuthority = (data) => {
|
||||
return service({
|
||||
url: '/authority/updateAuthority',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拥有指定角色的用户ID列表
|
||||
* @param {number} authorityId 角色ID
|
||||
* @returns {Promise<number[]>} 用户ID数组
|
||||
*/
|
||||
export const getUsersByAuthorityId = (authorityId) => {
|
||||
return service({
|
||||
url: '/authority/getUsersByAuthority',
|
||||
method: 'get',
|
||||
params: { authorityId }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 全量覆盖某角色关联的用户列表
|
||||
* @param {Object} data
|
||||
* @param {number} data.authorityId 角色ID
|
||||
* @param {number[]} data.userIds 用户ID列表
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export const setRoleUsers = (data) => {
|
||||
return service({
|
||||
url: '/authority/setRoleUsers',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
export const getAuthorityBtnApi = (data) => {
|
||||
return service({
|
||||
url: '/authorityBtn/getAuthorityBtn',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const setAuthorityBtnApi = (data) => {
|
||||
return service({
|
||||
url: '/authorityBtn/setAuthorityBtn',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const canRemoveAuthorityBtnApi = (params) => {
|
||||
return service({
|
||||
url: '/authorityBtn/canRemoveAuthorityBtn',
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import service from '@/utils/request'
|
||||
// @Tags authority
|
||||
// @Summary 更改角色api权限
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body api.CreateAuthorityPatams true "更改角色api权限"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /casbin/UpdateCasbin [post]
|
||||
export const UpdateCasbin = (data) => {
|
||||
return service({
|
||||
url: '/casbin/updateCasbin',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags casbin
|
||||
// @Summary 获取权限列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body api.CreateAuthorityPatams true "获取权限列表"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /casbin/getPolicyPathByAuthorityId [post]
|
||||
export const getPolicyPathByAuthorityId = (data) => {
|
||||
return service({
|
||||
url: '/casbin/getPolicyPathByAuthorityId',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
// 分页获取数据权限审计日志 @Router /dataAccessLog/getDataAccessLogList [post]
|
||||
export const getDataAccessLogList = (data) => {
|
||||
return service({
|
||||
url: '/dataAccessLog/getDataAccessLogList',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 批量删除数据权限审计日志 @Router /dataAccessLog/deleteDataAccessLogByIds [delete]
|
||||
export const deleteDataAccessLogByIds = (data) => {
|
||||
return service({
|
||||
url: '/dataAccessLog/deleteDataAccessLogByIds',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
// @Router /department/getDepartmentList [post]
|
||||
export const getDepartmentList = (data) => {
|
||||
return service({
|
||||
url: '/department/getDepartmentList',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Router /department/createDepartment [post]
|
||||
export const createDepartment = (data) => {
|
||||
return service({
|
||||
url: '/department/createDepartment',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Router /department/updateDepartment [put]
|
||||
export const updateDepartment = (data) => {
|
||||
return service({
|
||||
url: '/department/updateDepartment',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Router /department/deleteDepartment [delete]
|
||||
export const deleteDepartment = (data) => {
|
||||
return service({
|
||||
url: '/department/deleteDepartment',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Router /department/findDepartment [get]
|
||||
export const findDepartment = (params) => {
|
||||
return service({
|
||||
url: '/department/findDepartment',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取部门成员ID列表 @Router /department/getDepartmentUsers [get]
|
||||
export const getDepartmentUsers = (params) => {
|
||||
return service({
|
||||
url: '/department/getDepartmentUsers',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 设置部门成员(反向分配) @Router /department/setDepartmentUsers [post]
|
||||
export const setDepartmentUsers = (data) => {
|
||||
return service({
|
||||
url: '/department/setDepartmentUsers',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import service from '@/utils/request'
|
||||
// @Tags email
|
||||
// @Summary 发送测试邮件
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
|
||||
// @Router /email/emailTest [post]
|
||||
export const emailTest = (data) => {
|
||||
return service({
|
||||
url: '/email/emailTest',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
// @Tags SysExportTemplate
|
||||
// @Summary 创建导出模板
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysExportTemplate true "创建导出模板"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
||||
// @Router /sysExportTemplate/createSysExportTemplate [post]
|
||||
export const createSysExportTemplate = (data) => {
|
||||
return service({
|
||||
url: '/sysExportTemplate/createSysExportTemplate',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysExportTemplate
|
||||
// @Summary 删除导出模板
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysExportTemplate true "删除导出模板"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysExportTemplate/deleteSysExportTemplate [delete]
|
||||
export const deleteSysExportTemplate = (data) => {
|
||||
return service({
|
||||
url: '/sysExportTemplate/deleteSysExportTemplate',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysExportTemplate
|
||||
// @Summary 批量删除导出模板
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.IdsReq true "批量删除导出模板"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysExportTemplate/deleteSysExportTemplate [delete]
|
||||
export const deleteSysExportTemplateByIds = (data) => {
|
||||
return service({
|
||||
url: '/sysExportTemplate/deleteSysExportTemplateByIds',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysExportTemplate
|
||||
// @Summary 更新导出模板
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysExportTemplate true "更新导出模板"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
||||
// @Router /sysExportTemplate/updateSysExportTemplate [put]
|
||||
export const updateSysExportTemplate = (data) => {
|
||||
return service({
|
||||
url: '/sysExportTemplate/updateSysExportTemplate',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysExportTemplate
|
||||
// @Summary 用id查询导出模板
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query model.SysExportTemplate true "用id查询导出模板"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
||||
// @Router /sysExportTemplate/findSysExportTemplate [get]
|
||||
export const findSysExportTemplate = (params) => {
|
||||
return service({
|
||||
url: '/sysExportTemplate/findSysExportTemplate',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysExportTemplate
|
||||
// @Summary 分页获取导出模板列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query request.PageInfo true "分页获取导出模板列表"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysExportTemplate/getSysExportTemplateList [get]
|
||||
export const getSysExportTemplateList = (params) => {
|
||||
return service({
|
||||
url: '/sysExportTemplate/getSysExportTemplateList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// ExportExcel 导出表格token
|
||||
// @Tags SysExportTemplate
|
||||
// @Summary 导出表格
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Router /sysExportTemplate/exportExcel [get]
|
||||
export const exportExcel = (params) => {
|
||||
return service({
|
||||
url: '/sysExportTemplate/exportExcel',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// ExportTemplate 导出表格模板
|
||||
// @Tags SysExportTemplate
|
||||
// @Summary 导出表格模板
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Router /sysExportTemplate/exportTemplate [get]
|
||||
export const exportTemplate = (params) => {
|
||||
return service({
|
||||
url: '/sysExportTemplate/exportTemplate',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// PreviewSQL 预览最终生成的SQL
|
||||
// @Tags SysExportTemplate
|
||||
// @Summary 预览最终生成的SQL
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Router /sysExportTemplate/previewSQL [get]
|
||||
// @Param templateID query string true "导出模板ID"
|
||||
// @Param params query string false "查询参数编码字符串,参考 ExportExcel 组件"
|
||||
export const previewSQL = (params) => {
|
||||
return service({
|
||||
url: '/sysExportTemplate/previewSQL',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
import service from '@/utils/request'
|
||||
// @Tags FileUploadAndDownload
|
||||
// @Summary 分页文件列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body modelInterface.PageInfo true "分页获取文件户列表"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /fileUploadAndDownload/getFileList [post]
|
||||
export const getFileList = (data) => {
|
||||
return service({
|
||||
url: '/fileUploadAndDownload/getFileList',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags FileUploadAndDownload
|
||||
// @Summary 删除文件
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Param data body dbModel.FileUploadAndDownload true "传入文件里面id即可"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"返回成功"}"
|
||||
// @Router /fileUploadAndDownload/deleteFile [post]
|
||||
export const deleteFile = (data) => {
|
||||
return service({
|
||||
url: '/fileUploadAndDownload/deleteFile',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑文件名或者备注
|
||||
* @param data
|
||||
* @returns {*}
|
||||
*/
|
||||
export const editFileName = (data) => {
|
||||
return service({
|
||||
url: '/fileUploadAndDownload/editFileName',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入URL
|
||||
* @param data
|
||||
* @returns {*}
|
||||
*/
|
||||
export const importURL = (data) => {
|
||||
return service({
|
||||
url: '/fileUploadAndDownload/importURL',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 上传文件 暂时用于头像上传
|
||||
export const uploadFile = (data) => {
|
||||
return service({
|
||||
url: "/fileUploadAndDownload/upload",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import service from '@/utils/request'
|
||||
// @Tags InitDB
|
||||
// @Summary 初始化用户数据库
|
||||
// @Produce application/json
|
||||
// @Param data body request.InitDB true "初始化数据库参数"
|
||||
// @Success 200 {string} string "{"code":0,"data":{},"msg":"自动创建数据库成功"}"
|
||||
// @Router /init/initdb [post]
|
||||
export const initDB = (data) => {
|
||||
return service({
|
||||
url: '/init/initdb',
|
||||
method: 'post',
|
||||
data,
|
||||
donNotShowLoading: true
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags CheckDB
|
||||
// @Summary 初始化用户数据库
|
||||
// @Produce application/json
|
||||
// @Success 200 {string} string "{"code":0,"data":{},"msg":"探测完成"}"
|
||||
// @Router /init/checkdb [post]
|
||||
export const checkDB = () => {
|
||||
return service({
|
||||
url: '/init/checkdb',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import service from '@/utils/request'
|
||||
// @Tags jwt
|
||||
// @Summary jwt加入黑名单
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"拉黑成功"}"
|
||||
// @Router /jwt/jsonInBlacklist [post]
|
||||
export const jsonInBlacklist = () => {
|
||||
return service({
|
||||
url: '/jwt/jsonInBlacklist',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
// @Summary 获取指定月份存在日志的日期
|
||||
// @Router /logViewer/dates [get]
|
||||
export const getLogDates = (params) => {
|
||||
return service({
|
||||
url: '/logViewer/dates',
|
||||
method: 'get',
|
||||
params,
|
||||
donNotShowLoading: true
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 获取指定日期的日志文件
|
||||
// @Router /logViewer/files [get]
|
||||
export const getLogFiles = (params) => {
|
||||
return service({
|
||||
url: '/logViewer/files',
|
||||
method: 'get',
|
||||
params,
|
||||
donNotShowLoading: true
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 分块读取日志文件内容
|
||||
// @Router /logViewer/content [get]
|
||||
export const getLogContent = (params) => {
|
||||
return service({
|
||||
url: '/logViewer/content',
|
||||
method: 'get',
|
||||
params,
|
||||
donNotShowLoading: true
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
export const uploadInit = (data) =>
|
||||
service({ url: '/mediaUpload/init', method: 'post', data })
|
||||
|
||||
export const uploadChunk = (formData, signal) =>
|
||||
service({ url: '/mediaUpload/chunk', method: 'post', data: formData, signal, headers: { 'Content-Type': 'multipart/form-data' } })
|
||||
|
||||
export const uploadComplete = (data) =>
|
||||
service({ url: '/mediaUpload/complete', method: 'post', data })
|
||||
|
||||
export const uploadCancel = (uploadId) =>
|
||||
service({ url: `/mediaUpload/${uploadId}`, method: 'delete' })
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
import service from '@/utils/request'
|
||||
// @Summary 用户登录 获取动态路由
|
||||
// @Produce application/json
|
||||
// @Param 可以什么都不填 调一下即可
|
||||
// @Router /menu/getMenu [post]
|
||||
export const asyncMenu = () => {
|
||||
return service({
|
||||
url: '/menu/getMenu',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 获取menu列表
|
||||
// @Produce application/json
|
||||
// @Param {
|
||||
// page int
|
||||
// pageSize int
|
||||
// }
|
||||
// @Router /menu/getMenuList [post]
|
||||
export const getMenuList = (data) => {
|
||||
return service({
|
||||
url: '/menu/getMenuList',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 新增基础menu
|
||||
// @Produce application/json
|
||||
// @Param menu Object
|
||||
// @Router /menu/getMenuList [post]
|
||||
export const addBaseMenu = (data) => {
|
||||
return service({
|
||||
url: '/menu/addBaseMenu',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 获取基础路由列表
|
||||
// @Produce application/json
|
||||
// @Param 可以什么都不填 调一下即可
|
||||
// @Router /menu/getBaseMenuTree [post]
|
||||
export const getBaseMenuTree = () => {
|
||||
return service({
|
||||
url: '/menu/getBaseMenuTree',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 添加用户menu关联关系
|
||||
// @Produce application/json
|
||||
// @Param menus Object authorityId string
|
||||
// @Router /menu/getMenuList [post]
|
||||
export const addMenuAuthority = (data) => {
|
||||
return service({
|
||||
url: '/menu/addMenuAuthority',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 获取用户menu关联关系
|
||||
// @Produce application/json
|
||||
// @Param authorityId string
|
||||
// @Router /menu/getMenuAuthority [post]
|
||||
export const getMenuAuthority = (data) => {
|
||||
return service({
|
||||
url: '/menu/getMenuAuthority',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 删除menu
|
||||
// @Produce application/json
|
||||
// @Param ID float64
|
||||
// @Router /menu/deleteBaseMenu [post]
|
||||
export const deleteBaseMenu = (data) => {
|
||||
return service({
|
||||
url: '/menu/deleteBaseMenu',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 修改menu列表
|
||||
// @Produce application/json
|
||||
// @Param menu Object
|
||||
// @Router /menu/updateBaseMenu [post]
|
||||
export const updateBaseMenu = (data) => {
|
||||
return service({
|
||||
url: '/menu/updateBaseMenu',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags menu
|
||||
// @Summary 根据id获取菜单
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body api.GetById true "根据id获取菜单"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /menu/getBaseMenuById [post]
|
||||
export const getBaseMenuById = (data) => {
|
||||
return service({
|
||||
url: '/menu/getBaseMenuById',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拥有指定菜单的角色ID列表
|
||||
* @param {number} menuId 菜单ID
|
||||
* @returns {Promise<number[]>} 角色ID数组
|
||||
*/
|
||||
export const getMenuRoles = (menuId) => {
|
||||
return service({
|
||||
url: '/menu/getMenuRoles',
|
||||
method: 'get',
|
||||
params: { menuId }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 全量覆盖某菜单关联的角色列表
|
||||
* @param {Object} data
|
||||
* @param {number} data.menuId 菜单ID
|
||||
* @param {number[]} data.authorityIds 角色ID列表
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export const setMenuRoles = (data) => {
|
||||
return service({
|
||||
url: '/menu/setMenuRoles',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
// @Router /position/getPositionList [post]
|
||||
export const getPositionList = (data) => {
|
||||
return service({
|
||||
url: '/position/getPositionList',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Router /position/createPosition [post]
|
||||
export const createPosition = (data) => {
|
||||
return service({
|
||||
url: '/position/createPosition',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Router /position/updatePosition [put]
|
||||
export const updatePosition = (data) => {
|
||||
return service({
|
||||
url: '/position/updatePosition',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Router /position/deletePosition [delete]
|
||||
export const deletePosition = (data) => {
|
||||
return service({
|
||||
url: '/position/deletePosition',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Router /position/findPosition [get]
|
||||
export const findPosition = (params) => {
|
||||
return service({
|
||||
url: '/position/findPosition',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取岗位成员ID列表 @Router /position/getPositionUsers [get]
|
||||
export const getPositionUsers = (params) => {
|
||||
return service({
|
||||
url: '/position/getPositionUsers',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 设置岗位成员(反向分配) @Router /position/setPositionUsers [post]
|
||||
export const setPositionUsers = (data) => {
|
||||
return service({
|
||||
url: '/position/setPositionUsers',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
// @Tags SecurityConfig
|
||||
// @Summary 获取安全配置
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=system.SysSecurityConfig,msg=string} "获取安全配置"
|
||||
// @Router /securityConfig/getSecurityConfig [get]
|
||||
export const getSecurityConfig = () => {
|
||||
return service({
|
||||
url: '/securityConfig/getSecurityConfig',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SecurityConfig
|
||||
// @Summary 设置安全配置
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Param data body system.SysSecurityConfig true "安全配置"
|
||||
// @Success 200 {object} response.Response{data=system.SysSecurityConfig,msg=string} "设置安全配置"
|
||||
// @Router /securityConfig/setSecurityConfig [post]
|
||||
export const setSecurityConfig = (data) => {
|
||||
return service({
|
||||
url: '/securityConfig/setSecurityConfig',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
export const createApiToken = (data) => {
|
||||
return service({
|
||||
url: '/sysApiToken/createApiToken',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const getApiTokenList = (data) => {
|
||||
return service({
|
||||
url: '/sysApiToken/getApiTokenList',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteApiToken = (data) => {
|
||||
return service({
|
||||
url: '/sysApiToken/deleteApiToken',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
import service from '@/utils/request'
|
||||
// @Tags SysDictionary
|
||||
// @Summary 创建SysDictionary
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysDictionary true "创建SysDictionary"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysDictionary/createSysDictionary [post]
|
||||
export const createSysDictionary = (data) => {
|
||||
return service({
|
||||
url: '/sysDictionary/createSysDictionary',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionary
|
||||
// @Summary 删除SysDictionary
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysDictionary true "删除SysDictionary"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysDictionary/deleteSysDictionary [delete]
|
||||
export const deleteSysDictionary = (data) => {
|
||||
return service({
|
||||
url: '/sysDictionary/deleteSysDictionary',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionary
|
||||
// @Summary 更新SysDictionary
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysDictionary true "更新SysDictionary"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
||||
// @Router /sysDictionary/updateSysDictionary [put]
|
||||
export const updateSysDictionary = (data) => {
|
||||
return service({
|
||||
url: '/sysDictionary/updateSysDictionary',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionary
|
||||
// @Summary 用id查询SysDictionary
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysDictionary true "用id查询SysDictionary"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
||||
// @Router /sysDictionary/findSysDictionary [get]
|
||||
export const findSysDictionary = (params) => {
|
||||
return service({
|
||||
url: '/sysDictionary/findSysDictionary',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionary
|
||||
// @Summary 分页获取SysDictionary列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.PageInfo true "分页获取SysDictionary列表"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysDictionary/getSysDictionaryList [get]
|
||||
export const getSysDictionaryList = (params) => {
|
||||
return service({
|
||||
url: '/sysDictionary/getSysDictionaryList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionary
|
||||
// @Summary 导出字典JSON(包含字典详情)
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query model.SysDictionary true "字典ID"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"导出成功"}"
|
||||
// @Router /sysDictionary/exportSysDictionary [get]
|
||||
export const exportSysDictionary = (params) => {
|
||||
return service({
|
||||
url: '/sysDictionary/exportSysDictionary',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionary
|
||||
// @Summary 导入字典JSON(包含字典详情)
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body object true "字典JSON数据"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"导入成功"}"
|
||||
// @Router /sysDictionary/importSysDictionary [post]
|
||||
export const importSysDictionary = (data) => {
|
||||
return service({
|
||||
url: '/sysDictionary/importSysDictionary',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
import service from '@/utils/request'
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 创建SysDictionaryDetail
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysDictionaryDetail true "创建SysDictionaryDetail"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysDictionaryDetail/createSysDictionaryDetail [post]
|
||||
export const createSysDictionaryDetail = (data) => {
|
||||
return service({
|
||||
url: '/sysDictionaryDetail/createSysDictionaryDetail',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 删除SysDictionaryDetail
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysDictionaryDetail true "删除SysDictionaryDetail"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysDictionaryDetail/deleteSysDictionaryDetail [delete]
|
||||
export const deleteSysDictionaryDetail = (data) => {
|
||||
return service({
|
||||
url: '/sysDictionaryDetail/deleteSysDictionaryDetail',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 更新SysDictionaryDetail
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysDictionaryDetail true "更新SysDictionaryDetail"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
||||
// @Router /sysDictionaryDetail/updateSysDictionaryDetail [put]
|
||||
export const updateSysDictionaryDetail = (data) => {
|
||||
return service({
|
||||
url: '/sysDictionaryDetail/updateSysDictionaryDetail',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 用id查询SysDictionaryDetail
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysDictionaryDetail true "用id查询SysDictionaryDetail"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
||||
// @Router /sysDictionaryDetail/findSysDictionaryDetail [get]
|
||||
export const findSysDictionaryDetail = (params) => {
|
||||
return service({
|
||||
url: '/sysDictionaryDetail/findSysDictionaryDetail',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 分页获取SysDictionaryDetail列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.PageInfo true "分页获取SysDictionaryDetail列表"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysDictionaryDetail/getSysDictionaryDetailList [get]
|
||||
export const getSysDictionaryDetailList = (params) => {
|
||||
return service({
|
||||
url: '/sysDictionaryDetail/getSysDictionaryDetailList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 获取层级字典详情树形结构(根据字典ID)
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param sysDictionaryID query string true "字典ID"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysDictionaryDetail/getDictionaryTreeList [get]
|
||||
export const getDictionaryTreeList = (params) => {
|
||||
return service({
|
||||
url: '/sysDictionaryDetail/getDictionaryTreeList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 获取层级字典详情树形结构(根据字典类型)
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param dictType query string true "字典类型"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysDictionaryDetail/getDictionaryTreeListByType [get]
|
||||
export const getDictionaryTreeListByType = (params) => {
|
||||
return service({
|
||||
url: '/sysDictionaryDetail/getDictionaryTreeListByType',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 根据父级ID获取字典详情
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param parentID query string true "父级ID"
|
||||
// @Param includeChildren query boolean false "是否包含子级"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysDictionaryDetail/getDictionaryDetailsByParent [get]
|
||||
export const getDictionaryDetailsByParent = (params) => {
|
||||
return service({
|
||||
url: '/sysDictionaryDetail/getDictionaryDetailsByParent',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysDictionaryDetail
|
||||
// @Summary 获取字典详情的完整路径
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param ID query string true "字典详情ID"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysDictionaryDetail/getDictionaryPath [get]
|
||||
export const getDictionaryPath = (params) => {
|
||||
return service({
|
||||
url: '/sysDictionaryDetail/getDictionaryPath',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
export const deleteLoginLog = (data) => {
|
||||
return service({
|
||||
url: '/sysLoginLog/deleteLoginLog',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteLoginLogByIds = (data) => {
|
||||
return service({
|
||||
url: '/sysLoginLog/deleteLoginLogByIds',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const getLoginLogList = (params) => {
|
||||
return service({
|
||||
url: '/sysLoginLog/getLoginLogList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export const findLoginLog = (params) => {
|
||||
return service({
|
||||
url: '/sysLoginLog/findLoginLog',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
import service from '@/utils/request'
|
||||
// @Tags SysOperationRecord
|
||||
// @Summary 删除SysOperationRecord
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysOperationRecord true "删除SysOperationRecord"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
|
||||
export const deleteSysOperationRecord = (data) => {
|
||||
return service({
|
||||
url: '/sysOperationRecord/deleteSysOperationRecord',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysOperationRecord
|
||||
// @Summary 删除SysOperationRecord
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.IdsReq true "删除SysOperationRecord"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
|
||||
export const deleteSysOperationRecordByIds = (data) => {
|
||||
return service({
|
||||
url: '/sysOperationRecord/deleteSysOperationRecordByIds',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysOperationRecord
|
||||
// @Summary 分页获取SysOperationRecord列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.PageInfo true "分页获取SysOperationRecord列表"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysOperationRecord/getSysOperationRecordList [get]
|
||||
export const getSysOperationRecordList = (params) => {
|
||||
return service({
|
||||
url: '/sysOperationRecord/getSysOperationRecordList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
import service from '@/utils/request'
|
||||
// @Tags SysParams
|
||||
// @Summary 创建参数
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysParams true "创建参数"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
||||
// @Router /sysParams/createSysParams [post]
|
||||
export const createSysParams = (data) => {
|
||||
return service({
|
||||
url: '/sysParams/createSysParams',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysParams
|
||||
// @Summary 删除参数
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysParams true "删除参数"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysParams/deleteSysParams [delete]
|
||||
export const deleteSysParams = (params) => {
|
||||
return service({
|
||||
url: '/sysParams/deleteSysParams',
|
||||
method: 'delete',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysParams
|
||||
// @Summary 批量删除参数
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.IdsReq true "批量删除参数"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysParams/deleteSysParams [delete]
|
||||
export const deleteSysParamsByIds = (params) => {
|
||||
return service({
|
||||
url: '/sysParams/deleteSysParamsByIds',
|
||||
method: 'delete',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysParams
|
||||
// @Summary 更新参数
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysParams true "更新参数"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
||||
// @Router /sysParams/updateSysParams [put]
|
||||
export const updateSysParams = (data) => {
|
||||
return service({
|
||||
url: '/sysParams/updateSysParams',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysParams
|
||||
// @Summary 用id查询参数
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query model.SysParams true "用id查询参数"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
||||
// @Router /sysParams/findSysParams [get]
|
||||
export const findSysParams = (params) => {
|
||||
return service({
|
||||
url: '/sysParams/findSysParams',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysParams
|
||||
// @Summary 分页获取参数列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query request.PageInfo true "分页获取参数列表"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysParams/getSysParamsList [get]
|
||||
export const getSysParamsList = (params) => {
|
||||
return service({
|
||||
url: '/sysParams/getSysParamsList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysParams
|
||||
// @Summary 不需要鉴权的参数接口
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query systemReq.SysParamsSearch true "分页获取参数列表"
|
||||
// @Success 200 {object} response.Response{data=object,msg=string} "获取成功"
|
||||
// @Router /sysParams/getSysParam [get]
|
||||
export const getSysParam = (params) => {
|
||||
return service({
|
||||
url: '/sysParams/getSysParam',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
import service from '@/utils/request'
|
||||
// @Tags systrm
|
||||
// @Summary 获取配置文件内容
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
|
||||
// @Router /system/getSystemConfig [post]
|
||||
export const getSystemConfig = () => {
|
||||
return service({
|
||||
url: '/system/getSystemConfig',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags system
|
||||
// @Summary 设置配置文件内容
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Param data body sysModel.System true
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
|
||||
// @Router /system/setSystemConfig [post]
|
||||
export const setSystemConfig = (data) => {
|
||||
return service({
|
||||
url: '/system/setSystemConfig',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags system
|
||||
// @Summary 获取服务器运行状态
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
|
||||
// @Router /system/getServerInfo [post]
|
||||
export const getSystemState = () => {
|
||||
return service({
|
||||
url: '/system/getServerInfo',
|
||||
method: 'post',
|
||||
donNotShowLoading: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 重载服务
|
||||
* @param data
|
||||
* @returns {*}
|
||||
*/
|
||||
export const reloadSystem = (data) => {
|
||||
return service({
|
||||
url: '/system/reloadSystem',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
import service from '@/utils/request'
|
||||
// @Tags SysError
|
||||
// @Summary 创建错误日志
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysError true "创建错误日志"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
||||
// @Router /sysError/createSysError [post]
|
||||
export const createSysError = (data) => {
|
||||
return service({
|
||||
url: '/sysError/createSysError',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysError
|
||||
// @Summary 删除错误日志
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysError true "删除错误日志"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysError/deleteSysError [delete]
|
||||
export const deleteSysError = (params) => {
|
||||
return service({
|
||||
url: '/sysError/deleteSysError',
|
||||
method: 'delete',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysError
|
||||
// @Summary 批量删除错误日志
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.IdsReq true "批量删除错误日志"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysError/deleteSysError [delete]
|
||||
export const deleteSysErrorByIds = (params) => {
|
||||
return service({
|
||||
url: '/sysError/deleteSysErrorByIds',
|
||||
method: 'delete',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysError
|
||||
// @Summary 更新错误日志
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysError true "更新错误日志"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
|
||||
// @Router /sysError/updateSysError [put]
|
||||
export const updateSysError = (data) => {
|
||||
return service({
|
||||
url: '/sysError/updateSysError',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysError
|
||||
// @Summary 用id查询错误日志
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query model.SysError true "用id查询错误日志"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
||||
// @Router /sysError/findSysError [get]
|
||||
export const findSysError = (params) => {
|
||||
return service({
|
||||
url: '/sysError/findSysError',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysError
|
||||
// @Summary 分页获取错误日志列表
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query request.PageInfo true "分页获取错误日志列表"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysError/getSysErrorList [get]
|
||||
export const getSysErrorList = (params) => {
|
||||
return service({
|
||||
url: '/sysError/getSysErrorList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysError
|
||||
// @Summary 不需要鉴权的错误日志接口
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query systemReq.SysErrorSearch true "分页获取错误日志列表"
|
||||
// @Success 200 {object} response.Response{data=object,msg=string} "获取成功"
|
||||
// @Router /sysError/getSysErrorPublic [get]
|
||||
export const getSysErrorPublic = () => {
|
||||
return service({
|
||||
url: '/sysError/getSysErrorPublic',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
export const createTimedTask = (data) => {
|
||||
return service({ url: '/timedTask/createTimedTask', method: 'post', data })
|
||||
}
|
||||
|
||||
export const updateTimedTask = (data) => {
|
||||
return service({ url: '/timedTask/updateTimedTask', method: 'put', data })
|
||||
}
|
||||
|
||||
export const deleteTimedTask = (data) => {
|
||||
return service({ url: '/timedTask/deleteTimedTask', method: 'delete', data })
|
||||
}
|
||||
|
||||
export const toggleTimedTask = (data) => {
|
||||
return service({ url: '/timedTask/toggleTimedTask', method: 'post', data })
|
||||
}
|
||||
|
||||
export const triggerTimedTask = (data) => {
|
||||
return service({ url: '/timedTask/triggerTimedTask', method: 'post', data })
|
||||
}
|
||||
|
||||
export const getTimedTaskList = (params) => {
|
||||
return service({ url: '/timedTask/getTimedTaskList', method: 'get', params })
|
||||
}
|
||||
|
||||
export const getTimedTaskLogList = (params) => {
|
||||
return service({ url: '/timedTask/getTimedTaskLogList', method: 'get', params })
|
||||
}
|
||||
|
||||
export const getRegisteredMethods = () => {
|
||||
return service({ url: '/timedTask/getRegisteredMethods', method: 'get' })
|
||||
}
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
import service from '@/utils/request'
|
||||
// @Summary 用户登录
|
||||
// @Produce application/json
|
||||
// @Param data body {username:"string",password:"string"}
|
||||
// @Router /base/login [post]
|
||||
export const login = (data) => {
|
||||
return service({
|
||||
url: '/base/login',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 获取验证码
|
||||
// @Produce application/json
|
||||
// @Param data body {username:"string",password:"string"}
|
||||
// @Router /base/captcha [post]
|
||||
export const captcha = () => {
|
||||
return service({
|
||||
url: '/base/captcha',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 用户注册
|
||||
// @Produce application/json
|
||||
// @Param data body {username:"string",password:"string"}
|
||||
// @Router /base/resige [post]
|
||||
export const register = (data) => {
|
||||
return service({
|
||||
url: '/user/admin_register',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary 修改密码
|
||||
// @Produce application/json
|
||||
// @Param data body {username:"string",password:"string",newPassword:"string"}
|
||||
// @Router /user/changePassword [post]
|
||||
export const changePassword = (data) => {
|
||||
return service({
|
||||
url: '/user/changePassword',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags User
|
||||
// @Summary 分页获取用户列表
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body modelInterface.PageInfo true "分页获取用户列表"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /user/getUserList [post]
|
||||
export const getUserList = (data) => {
|
||||
return service({
|
||||
url: '/user/getUserList',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags User
|
||||
// @Summary 设置用户权限
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body api.SetUserAuth true "设置用户权限"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"修改成功"}"
|
||||
// @Router /user/setUserAuthority [post]
|
||||
export const setUserAuthority = (data) => {
|
||||
return service({
|
||||
url: '/user/setUserAuthority',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 删除用户
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.SetUserAuth true "删除用户"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
|
||||
// @Router /user/deleteUser [delete]
|
||||
export const deleteUser = (data) => {
|
||||
return service({
|
||||
url: '/user/deleteUser',
|
||||
method: 'delete',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 设置用户信息
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysUser true "设置用户信息"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
|
||||
// @Router /user/setUserInfo [put]
|
||||
export const setUserInfo = (data) => {
|
||||
return service({
|
||||
url: '/user/setUserInfo',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 设置用户信息
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysUser true "设置用户信息"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
|
||||
// @Router /user/setSelfInfo [put]
|
||||
export const setSelfInfo = (data) => {
|
||||
return service({
|
||||
url: '/user/setSelfInfo',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysUser
|
||||
// @Summary 设置自身界面配置
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysUser true "设置自身界面配置"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
|
||||
// @Router /user/setSelfSetting [put]
|
||||
export const setSelfSetting = (data) => {
|
||||
return service({
|
||||
url: '/user/setSelfSetting',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags User
|
||||
// @Summary 设置用户权限
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body api.setUserAuthorities true "设置用户权限"
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"修改成功"}"
|
||||
// @Router /user/setUserAuthorities [post]
|
||||
export const setUserAuthorities = (data) => {
|
||||
return service({
|
||||
url: '/user/setUserAuthorities',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags User
|
||||
// @Summary 设置用户归属部门
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /user/setUserDepartments [post]
|
||||
export const setUserDepartments = (data) => {
|
||||
return service({
|
||||
url: '/user/setUserDepartments',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags User
|
||||
// @Summary 设置用户岗位
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /user/setUserPositions [post]
|
||||
export const setUserPositions = (data) => {
|
||||
return service({
|
||||
url: '/user/setUserPositions',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags User
|
||||
// @Summary 获取用户信息
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /user/getUserInfo [get]
|
||||
export const getUserInfo = () => {
|
||||
return service({
|
||||
url: '/user/getUserInfo',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export const resetPassword = (data) => {
|
||||
return service({
|
||||
url: '/user/resetPassword',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
import service from '@/utils/request'
|
||||
|
||||
// @Tags SysVersion
|
||||
// @Summary 删除版本管理
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.SysVersion true "删除版本管理"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysVersion/deleteSysVersion [delete]
|
||||
export const deleteSysVersion = (params) => {
|
||||
return service({
|
||||
url: '/sysVersion/deleteSysVersion',
|
||||
method: 'delete',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysVersion
|
||||
// @Summary 批量删除版本管理
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.IdsReq true "批量删除版本管理"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
|
||||
// @Router /sysVersion/deleteSysVersion [delete]
|
||||
export const deleteSysVersionByIds = (params) => {
|
||||
return service({
|
||||
url: '/sysVersion/deleteSysVersionByIds',
|
||||
method: 'delete',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysVersion
|
||||
// @Summary 用id查询版本管理
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query model.SysVersion true "用id查询版本管理"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
|
||||
// @Router /sysVersion/findSysVersion [get]
|
||||
export const findSysVersion = (params) => {
|
||||
return service({
|
||||
url: '/sysVersion/findSysVersion',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysVersion
|
||||
// @Summary 分页获取版本管理列表
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data query request.PageInfo true "分页获取版本管理列表"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
|
||||
// @Router /sysVersion/getSysVersionList [get]
|
||||
export const getSysVersionList = (params) => {
|
||||
return service({
|
||||
url: '/sysVersion/getSysVersionList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysVersion
|
||||
// @Summary 导出版本数据
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body object true "导出版本数据"
|
||||
// @Success 200 {string} string "{\"success\":true,\"data\":{},\"msg\":\"导出成功\"}"
|
||||
// @Router /sysVersion/exportVersion [post]
|
||||
export const exportVersion = (data) => {
|
||||
return service({
|
||||
url: '/sysVersion/exportVersion',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysVersion
|
||||
// @Summary 下载版本JSON数据
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param ID query string true "版本ID"
|
||||
// @Success 200 {string} string "{\"success\":true,\"data\":{},\"msg\":\"下载成功\"}"
|
||||
// @Router /sysVersion/downloadVersionJson [get]
|
||||
export const downloadVersionJson = (params) => {
|
||||
return service({
|
||||
url: '/sysVersion/downloadVersionJson',
|
||||
method: 'get',
|
||||
params,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SysVersion
|
||||
// @Summary 导入版本数据
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body object true "版本JSON数据"
|
||||
// @Success 200 {string} string "{\"success\":true,\"data\":{},\"msg\":\"导入成功\"}"
|
||||
// @Router /sysVersion/importVersion [post]
|
||||
export const importVersion = (data) => {
|
||||
return service({
|
||||
url: '/sysVersion/importVersion',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
143
web/src/app.tsx
|
|
@ -1,143 +0,0 @@
|
|||
import {
|
||||
AvatarDropdown,
|
||||
AvatarName,
|
||||
Footer,
|
||||
Question,
|
||||
SelectLang,
|
||||
} from "@/components";
|
||||
import { type Admin, services } from "@/services";
|
||||
import type { Settings as LayoutSettings } from "@ant-design/pro-components";
|
||||
import { SettingDrawer } from "@ant-design/pro-components";
|
||||
import type { RequestConfig, RunTimeLayoutConfig } from "@umijs/max";
|
||||
import { history } from "@umijs/max";
|
||||
import defaultSettings from "../config/defaultSettings";
|
||||
import { errorConfig } from "./requestErrorConfig";
|
||||
|
||||
const isDev = process.env.NODE_ENV === "development";
|
||||
const isDevOrTest = isDev || process.env.CI;
|
||||
const loginPath = "/user/login";
|
||||
|
||||
/**
|
||||
* @see https://umijs.org/docs/api/runtime-config#getinitialstate
|
||||
* */
|
||||
export async function getInitialState(): Promise<{
|
||||
settings?: Partial<LayoutSettings>;
|
||||
currentUser?: Admin;
|
||||
loading?: boolean;
|
||||
fetchUserInfo?: () => Promise<Admin | undefined>;
|
||||
}> {
|
||||
const fetchUserInfo = async () => {
|
||||
try {
|
||||
return await services.admin.Current({});
|
||||
} catch {
|
||||
// Redirecting on 401 is handled globally in requestErrorConfig.
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
// 如果不是登录页面,执行
|
||||
const { location } = history;
|
||||
if (
|
||||
![loginPath, "/user/register", "/user/register-result"].includes(
|
||||
location.pathname
|
||||
)
|
||||
) {
|
||||
const currentUser = await fetchUserInfo();
|
||||
return {
|
||||
fetchUserInfo,
|
||||
currentUser,
|
||||
settings: defaultSettings as Partial<LayoutSettings>,
|
||||
};
|
||||
}
|
||||
return {
|
||||
fetchUserInfo,
|
||||
settings: defaultSettings as Partial<LayoutSettings>,
|
||||
};
|
||||
}
|
||||
|
||||
// ProLayout 支持的api https://procomponents.ant.design/components/layout
|
||||
export const layout: RunTimeLayoutConfig = ({
|
||||
initialState,
|
||||
setInitialState,
|
||||
}) => {
|
||||
return {
|
||||
actionsRender: () => [
|
||||
<Question key="doc" />,
|
||||
<SelectLang key="SelectLang" />,
|
||||
],
|
||||
avatarProps: {
|
||||
src: initialState?.currentUser?.avatar,
|
||||
title: <AvatarName />,
|
||||
render: (_, avatarChildren) => (
|
||||
<AvatarDropdown>{avatarChildren}</AvatarDropdown>
|
||||
),
|
||||
},
|
||||
waterMarkProps: {
|
||||
content: initialState?.currentUser?.name,
|
||||
},
|
||||
footerRender: () => <Footer />,
|
||||
onPageChange: () => {
|
||||
const { location } = history;
|
||||
// 如果没有登录,重定向到 login
|
||||
if (!initialState?.currentUser && location.pathname !== loginPath) {
|
||||
history.push(loginPath);
|
||||
}
|
||||
},
|
||||
bgLayoutImgList: [
|
||||
{
|
||||
src: "https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/D2LWSqNny4sAAAAAAAAAAAAAFl94AQBr",
|
||||
left: 85,
|
||||
bottom: 100,
|
||||
height: "303px",
|
||||
},
|
||||
{
|
||||
src: "https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/C2TWRpJpiC0AAAAAAAAAAAAAFl94AQBr",
|
||||
bottom: -68,
|
||||
right: -45,
|
||||
height: "303px",
|
||||
},
|
||||
{
|
||||
src: "https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/F6vSTbj8KpYAAAAAAAAAAAAAFl94AQBr",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
width: "331px",
|
||||
},
|
||||
],
|
||||
links: [],
|
||||
menuHeaderRender: undefined,
|
||||
// 自定义 403 页面
|
||||
// unAccessible: <div>unAccessible</div>,
|
||||
// 增加一个 loading 的状态
|
||||
childrenRender: (children) => {
|
||||
// if (initialState?.loading) return <PageLoading />;
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
{isDevOrTest && (
|
||||
<SettingDrawer
|
||||
disableUrlParams
|
||||
enableDarkTheme
|
||||
settings={initialState?.settings}
|
||||
onSettingChange={(settings) => {
|
||||
setInitialState((preInitialState) => ({
|
||||
...preInitialState,
|
||||
settings,
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
},
|
||||
...initialState?.settings,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @name request 配置,可以配置错误处理
|
||||
* 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
|
||||
* @doc https://umijs.org/docs/max/request#配置
|
||||
*/
|
||||
export const request: RequestConfig = {
|
||||
baseURL: isDev ? "" : "https://proapi.azurewebsites.net",
|
||||
...errorConfig,
|
||||
};
|
||||
|
After Width: | Height: | Size: 43 KiB |
|
|
@ -0,0 +1,208 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1080 1350"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
role="img" aria-label="KRA cover">
|
||||
|
||||
<!-- ════════════════════════════════════════════════
|
||||
GIN Cover Redesign — SVG 版
|
||||
品牌色 #2264f2 · viewBox 矢量缩放,2K/4K 无损
|
||||
字体:JetBrains Mono(页面已加载则自动继承,
|
||||
否则回退到系统等宽字体)
|
||||
═════════════════════════════════════════════════ -->
|
||||
|
||||
<style>
|
||||
text {
|
||||
font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular,
|
||||
'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
|
||||
}
|
||||
.cursor { animation: blink 1.2s steps(1) infinite; }
|
||||
@keyframes blink { 50% { opacity: 0; } }
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.cursor { animation: none; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<!-- 整体圆角裁切(对应 overflow:hidden + border-radius:4px) -->
|
||||
<clipPath id="posterClip">
|
||||
<rect x="0" y="0" width="1080" height="1350" rx="4"/>
|
||||
</clipPath>
|
||||
|
||||
<!-- 细网格 30px -->
|
||||
<pattern id="gridFine" width="30" height="30" patternUnits="userSpaceOnUse">
|
||||
<path d="M 30 0 L 0 0 0 30" fill="none"
|
||||
stroke="rgba(255,255,255,.07)" stroke-width="1"/>
|
||||
</pattern>
|
||||
<!-- 粗网格 150px -->
|
||||
<pattern id="gridCoarse" width="150" height="150" patternUnits="userSpaceOnUse">
|
||||
<path d="M 150 0 L 0 0 0 150" fill="none"
|
||||
stroke="rgba(255,255,255,.12)" stroke-width="1"/>
|
||||
</pattern>
|
||||
|
||||
<!-- 网格径向渐隐遮罩
|
||||
mask: radial-gradient(85% 75% at 50% 45%, #000 30%, transparent 100%) -->
|
||||
<radialGradient id="gridMaskGrad" gradientUnits="userSpaceOnUse"
|
||||
cx="540" cy="607.5" r="918"
|
||||
gradientTransform="translate(540 607.5) scale(1 1.103) translate(-540 -607.5)">
|
||||
<stop offset="0%" stop-color="#ffffff"/>
|
||||
<stop offset="30%" stop-color="#ffffff"/>
|
||||
<stop offset="100%" stop-color="#000000"/>
|
||||
</radialGradient>
|
||||
<mask id="gridMask">
|
||||
<rect x="0" y="0" width="1080" height="1350" fill="url(#gridMaskGrad)"/>
|
||||
</mask>
|
||||
|
||||
<!-- 环境光斑
|
||||
radial-gradient(50% 50%, rgba(120,165,255,.25), transparent 70%) -->
|
||||
<radialGradient id="glowGrad">
|
||||
<stop offset="0%" stop-color="rgba(120,165,255,.25)"/>
|
||||
<stop offset="70%" stop-color="rgba(120,165,255,0)"/>
|
||||
</radialGradient>
|
||||
|
||||
<!-- 编辑器卡片渐变
|
||||
linear-gradient(160deg, rgba(10,24,64,.92), rgba(13,30,80,.88)) -->
|
||||
<linearGradient id="editorGrad" x1="0" y1="0" x2="0.342" y2="0.94">
|
||||
<stop offset="0%" stop-color="rgba(10,24,64,.92)"/>
|
||||
<stop offset="100%" stop-color="rgba(13,30,80,.88)"/>
|
||||
</linearGradient>
|
||||
|
||||
<!-- 编辑器投影:单层贴身软阴影(纯色块上不分层) -->
|
||||
<filter id="editorShadow" x="-30%" y="-30%" width="160%" height="170%">
|
||||
<feDropShadow dx="0" dy="20" stdDeviation="24"
|
||||
flood-color="#08143c" flood-opacity="0.35"/>
|
||||
</filter>
|
||||
|
||||
<!-- 基线水平渐变
|
||||
linear-gradient(90deg, transparent, w40 20%, w40 80%, transparent) -->
|
||||
<linearGradient id="baselineGrad" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="rgba(255,255,255,0)"/>
|
||||
<stop offset="20%" stop-color="rgba(255,255,255,.4)"/>
|
||||
<stop offset="80%" stop-color="rgba(255,255,255,.4)"/>
|
||||
<stop offset="100%" stop-color="rgba(255,255,255,0)"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- ═══ 全部内容裁切在圆角画布内 ═══ -->
|
||||
<g clip-path="url(#posterClip)">
|
||||
|
||||
<!-- ── 透明底:背景渐变已移除,元素直接叠在页面色块上 ── -->
|
||||
|
||||
<!-- ── 蓝图网格(细 + 粗,径向渐隐)── -->
|
||||
<g mask="url(#gridMask)">
|
||||
<rect x="0" y="0" width="1080" height="1350" fill="url(#gridFine)"/>
|
||||
<rect x="0" y="0" width="1080" height="1350" fill="url(#gridCoarse)"/>
|
||||
</g>
|
||||
|
||||
<!-- ── 环境光斑 ── -->
|
||||
<ellipse cx="540" cy="540" rx="450" ry="250" fill="url(#glowGrad)"/>
|
||||
|
||||
<!-- ── 工程图角标(26×26,1.5px,w40)── -->
|
||||
<path d="M 44 70 V 44 H 70" fill="none" stroke="rgba(255,255,255,.4)" stroke-width="1.5"/>
|
||||
<path d="M 1010 44 H 1036 V 70" fill="none" stroke="rgba(255,255,255,.4)" stroke-width="1.5"/>
|
||||
<path d="M 44 1280 V 1306 H 70" fill="none" stroke="rgba(255,255,255,.4)" stroke-width="1.5"/>
|
||||
<path d="M 1010 1306 H 1036 V 1280" fill="none" stroke="rgba(255,255,255,.4)" stroke-width="1.5"/>
|
||||
|
||||
<!-- ── 顶部元信息行 ── -->
|
||||
<text x="96" y="63" font-size="12.5" letter-spacing="2.75"
|
||||
fill="rgba(255,255,255,.6)">KRA</text>
|
||||
<text x="984" y="63" text-anchor="end" font-size="12.5" letter-spacing="2.75"
|
||||
fill="rgba(255,255,255,.6)">KRA 3.0</text>
|
||||
|
||||
<!-- ── 中央视觉簇(标题 + 代码卡片 + 基线)整体下移 112px,
|
||||
使其落在画面光学中心附近 ── -->
|
||||
<g transform="translate(0 112)">
|
||||
|
||||
<!-- ── 标题区 ── -->
|
||||
<!-- [GIN] 主标:92px / 700 / ls .04em -->
|
||||
<text x="540" y="243" text-anchor="middle"
|
||||
font-size="92" font-weight="700" letter-spacing="3.68"
|
||||
fill="#ffffff"><tspan fill="rgba(255,255,255,.4)" font-weight="400">[</tspan>GIN<tspan fill="rgba(255,255,255,.4)" font-weight="400">]</tspan></text>
|
||||
|
||||
<!-- 副标:HELLO, WORLD + 两侧短线 + 闪烁光标 -->
|
||||
<line x1="365" y1="290" x2="421" y2="290"
|
||||
stroke="rgba(255,255,255,.25)" stroke-width="1"/>
|
||||
<text x="533" y="296" text-anchor="middle"
|
||||
font-size="17" letter-spacing="5.78"
|
||||
fill="rgba(255,255,255,.6)">HELLO, WORLD</text>
|
||||
<rect class="cursor" x="633" y="280" width="9" height="19"
|
||||
fill="rgba(255,255,255,.9)"/>
|
||||
<line x1="660" y1="290" x2="716" y2="290"
|
||||
stroke="rgba(255,255,255,.25)" stroke-width="1"/>
|
||||
|
||||
<!-- ── 主视觉:代码编辑器窗口(680×380)── -->
|
||||
<g filter="url(#editorShadow)">
|
||||
<rect x="200" y="420" width="680" height="380" rx="14"
|
||||
fill="url(#editorGrad)"
|
||||
stroke="rgba(255,255,255,.25)" stroke-width="1"/>
|
||||
</g>
|
||||
<!-- 内侧 1px 高光 -->
|
||||
<rect x="201.5" y="421.5" width="677" height="377" rx="13"
|
||||
fill="none" stroke="rgba(255,255,255,.04)" stroke-width="1"/>
|
||||
|
||||
<!-- 标题栏 -->
|
||||
<g>
|
||||
<!-- 三个圆点 -->
|
||||
<circle cx="228" cy="447" r="6" fill="rgba(255,255,255,.25)"/>
|
||||
<circle cx="248" cy="447" r="6" fill="rgba(255,255,255,.25)"/>
|
||||
<circle cx="268" cy="447" r="6" fill="rgba(255,255,255,.25)"/>
|
||||
<!-- GO 徽标 -->
|
||||
<rect x="290" y="437" width="33" height="20" rx="4"
|
||||
fill="rgba(255,255,255,.12)"/>
|
||||
<text x="306.5" y="451.5" text-anchor="middle"
|
||||
font-size="11" font-weight="700" letter-spacing="0.9"
|
||||
fill="rgba(255,255,255,.9)">GO</text>
|
||||
<!-- 文件路径 -->
|
||||
<text x="333" y="452" font-size="14" letter-spacing="0.7"
|
||||
fill="rgba(255,255,255,.6)">images / GinVueAdmin.go</text>
|
||||
<!-- 分隔线 -->
|
||||
<line x1="201" y1="474" x2="879" y2="474"
|
||||
stroke="rgba(255,255,255,.12)" stroke-width="1"/>
|
||||
</g>
|
||||
|
||||
<!-- 代码区:19px · 行距 44 -->
|
||||
<g font-size="19">
|
||||
<!-- 行号列 -->
|
||||
<text x="270" y="530" text-anchor="end" fill="rgba(255,255,255,.25)">1</text>
|
||||
<text x="270" y="574" text-anchor="end" fill="rgba(255,255,255,.25)">2</text>
|
||||
<text x="270" y="618" text-anchor="end" fill="rgba(255,255,255,.25)">3</text>
|
||||
<text x="270" y="662" text-anchor="end" fill="rgba(255,255,255,.25)">4</text>
|
||||
<text x="270" y="706" text-anchor="end" fill="rgba(255,255,255,.25)">5</text>
|
||||
|
||||
<!-- 代码行 -->
|
||||
<text x="298" y="530" xml:space="preserve"><tspan fill="#9db8ff">type</tspan><tspan fill="#ffffff" font-weight="500"> GinVueAdmin </tspan><tspan fill="#9db8ff">struct</tspan><tspan fill="rgba(220,230,255,.75)"> {</tspan></text>
|
||||
|
||||
<text x="298" y="574" xml:space="preserve"><tspan fill="#7fa5ff"> gorm.Model</tspan></text>
|
||||
|
||||
<text x="298" y="618" xml:space="preserve"><tspan fill="#e8eeff"> Name </tspan><tspan fill="#7fa5ff">string</tspan><tspan fill="rgba(190,208,255,.55)" font-style="italic"> `mapstructure:"name"`</tspan></text>
|
||||
|
||||
<text x="298" y="662" xml:space="preserve"><tspan fill="#e8eeff"> Version </tspan><tspan fill="#7fa5ff">string</tspan><tspan fill="rgba(190,208,255,.55)" font-style="italic"> `mapstructure:"version"`</tspan></text>
|
||||
|
||||
<text x="298" y="706" xml:space="preserve"><tspan fill="rgba(220,230,255,.75)">}</tspan></text>
|
||||
</g>
|
||||
|
||||
<!-- ── 基线 + 尺寸标注 ── -->
|
||||
<rect x="200" y="844" width="680" height="1" fill="url(#baselineGrad)"/>
|
||||
<line x1="336" y1="839.5" x2="336" y2="850.5"
|
||||
stroke="rgba(255,255,255,.4)" stroke-width="1"/>
|
||||
<line x1="744" y1="839.5" x2="744" y2="850.5"
|
||||
stroke="rgba(255,255,255,.4)" stroke-width="1"/>
|
||||
<text x="540" y="872" text-anchor="middle"
|
||||
font-size="11.5" letter-spacing="3.45"
|
||||
fill="rgba(255,255,255,.4)">STRUCT · 5 LINES · UTF-8</text>
|
||||
|
||||
</g>
|
||||
<!-- ── 中央视觉簇结束 ── -->
|
||||
|
||||
<!-- ── 底部信息 ── -->
|
||||
<text x="96" y="1291" font-size="13" letter-spacing="2.34"
|
||||
fill="rgba(255,255,255,.6)">GIN <tspan fill="rgba(255,255,255,.9)" font-weight="500">+</tspan> VUE <tspan fill="rgba(255,255,255,.9)" font-weight="500">+</tspan> GORM</text>
|
||||
|
||||
<!-- v2.x 胶囊徽标 -->
|
||||
<rect x="911" y="1261" width="73" height="33" rx="16.5"
|
||||
fill="none" stroke="rgba(255,255,255,.25)" stroke-width="1"/>
|
||||
<text x="947.5" y="1282.5" text-anchor="middle"
|
||||
font-size="13" letter-spacing="2.34"
|
||||
fill="rgba(255,255,255,.6)">3.0</text>
|
||||
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.8 KiB |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="m18 16l4-4l-4-4M6 8l-4 4l4 4m8.5-12l-5 16"/></svg>
|
||||
|
After Width: | Height: | Size: 224 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024"><path fill="currentColor" d="M195.2 195.2a64 64 0 0 1 90.496 0L512 421.504L738.304 195.2a64 64 0 0 1 90.496 90.496L602.496 512L828.8 738.304a64 64 0 0 1-90.496 90.496L512 602.496L285.696 828.8a64 64 0 0 1-90.496-90.496L421.504 512L195.2 285.696a64 64 0 0 1 0-90.496"/></svg>
|
||||
|
After Width: | Height: | Size: 366 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M15 8a1 1 0 0 1-1-1V2a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8zm5 0v12a2 2 0 0 1-2 2h-4.182M3.305 19.53l.923-.382M4 10.592V4a2 2 0 0 1 2-2h8M4.228 16.852l-.924-.383m2.548-1.241l-.383-.923m.383 6.467l-.383.924m2.679-6.468l.383-.923m-.001 7.391l-.382-.924m1.625-3.92l.922-.383m-.922 2.679l.922.383"/><circle cx="7" cy="18" r="3"/></svg>
|
||||
|
After Width: | Height: | Size: 522 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0a2.34 2.34 0 0 0 3.319 1.915a2.34 2.34 0 0 1 2.33 4.033a2.34 2.34 0 0 0 0 3.831a2.34 2.34 0 0 1-2.33 4.033a2.34 2.34 0 0 0-3.319 1.915a2.34 2.34 0 0 1-4.659 0a2.34 2.34 0 0 0-3.32-1.915a2.34 2.34 0 0 1-2.33-4.033a2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"/><circle cx="12" cy="12" r="3"/></svg>
|
||||
|
After Width: | Height: | Size: 541 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="m10.586 5.414l-5.172 5.172m13.172 2.828l-5.172 5.172M6 12h12"/><circle cx="12" cy="20" r="2"/><circle cx="12" cy="4" r="2"/><circle cx="20" cy="12" r="2"/><circle cx="4" cy="12" r="2"/></svg>
|
||||
|
After Width: | Height: | Size: 365 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Zm-3 7v4m0 4h.01"/></svg>
|
||||
|
After Width: | Height: | Size: 256 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><rect width="7" height="7" x="3" y="3" rx="1"/><rect width="7" height="7" x="14" y="3" rx="1"/><rect width="7" height="7" x="14" y="14" rx="1"/><rect width="7" height="7" x="3" y="14" rx="1"/></svg>
|
||||
|
After Width: | Height: | Size: 363 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M6.09 14.999a6.9 6.9 0 0 1-.59-2.794C5.5 8.5 8.41 5.499 12 5.499s6.5 3.002 6.5 6.706a6.9 6.9 0 0 1-.59 2.794m-5.91-13v1m10 9h-1m-18 0H2m17.07-7.071l-.707.707m-12.726.001l-.707-.707m9.587 14.377c1.01-.327 1.416-1.252 1.53-2.182c.034-.278-.195-.509-.475-.509H8.477a.483.483 0 0 0-.488.534c.112.928.394 1.606 1.464 2.156m5.064 0H9.453m5.064 0c-.121 1.945-.683 2.716-2.51 2.694c-1.954.036-2.404-.916-2.554-2.693"/></svg>
|
||||
|
After Width: | Height: | Size: 590 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M12 2a5 5 0 0 1 5 5v3a3 3 0 0 1 3 3v6a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3v-6a3 3 0 0 1 3-3V7a5 5 0 0 1 5-5m0 12a2 2 0 0 0-1.995 1.85L10 16a2 2 0 1 0 2-2m0-10a3 3 0 0 0-3 3v3h6V7a3 3 0 0 0-3-3"/></svg>
|
||||
|
After Width: | Height: | Size: 307 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"/></svg>
|
||||
|
After Width: | Height: | Size: 305 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="14" x="2" y="3" rx="2"/><path d="M8 21h8m-4-4v4"/></svg>
|
||||
|
After Width: | Height: | Size: 246 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12l2 2l4-4"/></svg>
|
||||
|
After Width: | Height: | Size: 370 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M16 3.128a4 4 0 0 1 0 7.744M22 21v-2a4 4 0 0 0-3-3.87"/><circle cx="9" cy="7" r="4"/></svg>
|
||||
|
After Width: | Height: | Size: 306 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
|
||||
|
After Width: | Height: | Size: 264 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"/><rect width="20" height="8" x="2" y="14" rx="2" ry="2"/><path d="M6 6h.01M6 18h.01"/></svg>
|
||||
|
After Width: | Height: | Size: 311 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="m8.59 13.51l6.83 3.98m-.01-10.98l-6.82 3.98"/></svg>
|
||||
|
After Width: | Height: | Size: 317 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5m8.774-10.69a1.12 1.12 0 0 0-1.549 0a2.5 2.5 0 0 1-3.451 0a1.12 1.12 0 0 0-1.548 0a2.5 2.5 0 0 1-3.452 0a1.12 1.12 0 0 0-1.549 0a2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244"/><path d="M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M15 6a9 9 0 0 0-9 9V3"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/></svg>
|
||||
|
After Width: | Height: | Size: 264 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024"><path fill="currentColor" d="M928.99 755.83L574.6 203.25c-12.89-20.16-36.76-32.58-62.6-32.58s-49.71 12.43-62.6 32.58L95.01 755.83c-12.91 20.12-12.9 44.91.01 65.03c12.92 20.12 36.78 32.51 62.59 32.49h708.78c25.82.01 49.68-12.37 62.59-32.49s12.92-44.91.01-65.03M554.67 768h-85.33v-85.33h85.33zm0-426.67v298.66h-85.33V341.32z"/></svg>
|
||||
|
After Width: | Height: | Size: 423 B |
|
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="Kra">
|
||||
<rect width="128" height="128" rx="28" fill="#2264f2"/>
|
||||
<path d="M34 26v76h16V72l33 30h22L65 64l38-38H82L50 59V26H34z" fill="#fff"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 235 B |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 19 KiB |