hello world
1
.env.development
Normal file
@@ -0,0 +1 @@
|
|||||||
|
VITE_API_BASE_URL= 'http://localhost:8000'
|
1
.env.production
Normal file
@@ -0,0 +1 @@
|
|||||||
|
VITE_API_BASE_URL= 'https://api.charles7c.top'
|
3
.eslintignore
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
/*.json
|
||||||
|
/*.js
|
||||||
|
dist
|
72
.eslintrc.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
parser: 'vue-eslint-parser',
|
||||||
|
parserOptions: {
|
||||||
|
// Parser that checks the content of the <script> tag
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
'browser': true,
|
||||||
|
'node': true,
|
||||||
|
'vue/setup-compiler-macros': true,
|
||||||
|
},
|
||||||
|
plugins: ['@typescript-eslint'],
|
||||||
|
extends: [
|
||||||
|
// Airbnb JavaScript Style Guide https://github.com/airbnb/javascript
|
||||||
|
'airbnb-base',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:import/recommended',
|
||||||
|
'plugin:import/typescript',
|
||||||
|
'plugin:vue/vue3-recommended',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
],
|
||||||
|
settings: {
|
||||||
|
'import/resolver': {
|
||||||
|
typescript: {
|
||||||
|
project: path.resolve(__dirname, './tsconfig.json'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'import/prefer-default-export': 'off',
|
||||||
|
'prettier/prettier': 1,
|
||||||
|
// Vue: Recommended rules to be closed or modify
|
||||||
|
'vue/require-default-prop': 0,
|
||||||
|
'vue/singleline-html-element-content-newline': 0,
|
||||||
|
'vue/max-attributes-per-line': 0,
|
||||||
|
// Vue: Add extra rules
|
||||||
|
'vue/custom-event-name-casing': [2, 'camelCase'],
|
||||||
|
'vue/no-v-text': 1,
|
||||||
|
'vue/padding-line-between-blocks': 1,
|
||||||
|
'vue/require-direct-export': 1,
|
||||||
|
'vue/multi-word-component-names': 0,
|
||||||
|
// Allow @ts-ignore comment
|
||||||
|
'@typescript-eslint/ban-ts-comment': 0,
|
||||||
|
'@typescript-eslint/no-unused-vars': 1,
|
||||||
|
'@typescript-eslint/no-empty-function': 1,
|
||||||
|
'@typescript-eslint/no-explicit-any': 0,
|
||||||
|
'import/extensions': [
|
||||||
|
2,
|
||||||
|
'ignorePackages',
|
||||||
|
{
|
||||||
|
js: 'never',
|
||||||
|
jsx: 'never',
|
||||||
|
ts: 'never',
|
||||||
|
tsx: 'never',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
||||||
|
'no-param-reassign': 0,
|
||||||
|
'prefer-regex-literals': 0,
|
||||||
|
'import/no-extraneous-dependencies': 0,
|
||||||
|
'camelcase': 'off',
|
||||||
|
},
|
||||||
|
};
|
46
.gitee/ISSUE_TEMPLATE.zh-CN.md
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<!--
|
||||||
|
感谢您使用 ContiNew Admin!请您花些时间填写这份 Issue 调查,非常感谢您的反馈!
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- 在 [] 中输入 x 来勾选) -->
|
||||||
|
|
||||||
|
## Issue 类型
|
||||||
|
|
||||||
|
- [ ] 缺陷报告(Bug)
|
||||||
|
- [ ] 需求建议(Feature)
|
||||||
|
|
||||||
|
## Issue 描述
|
||||||
|
|
||||||
|
<!-- 清楚而简洁地描述您遇到的问题。例如:在使用 xxx 功能时发现 xxx 问题。另外,非常欢迎您对此 Issue 提交 PR。 -->
|
||||||
|
|
||||||
|
## 复现步骤(如果是提交 Feature Issue,请删除本项)
|
||||||
|
|
||||||
|
<!-- 条理清晰的步骤或演示视频可以帮助快速定位问题。例如:1、xxx; 2、xxx; -->
|
||||||
|
|
||||||
|
## 预期结果(如果是提交 Feature Issue,请删除本项)
|
||||||
|
|
||||||
|
<!-- 清楚而简洁地描述您期望的结果。 -->
|
||||||
|
|
||||||
|
## 环境信息(如果是提交 Feature Issue,请删除本项)
|
||||||
|
|
||||||
|
<!-- 描述清楚您所使用的相关环境,例如:JDK 版本:1.8.0_202;框架版本:v1.0.0;其他可能与该 issue 相关的依赖版本。 -->
|
||||||
|
|
||||||
|
## 解决方案(如果是提交 Bug Issue,请删除本项)
|
||||||
|
|
||||||
|
<!-- 清楚而简洁地描述您想要的解决方案。 -->
|
||||||
|
|
||||||
|
## 替代方案(如果是提交 Bug Issue,请删除本项)
|
||||||
|
|
||||||
|
<!-- 清楚而简洁地描述您考虑过的任何替代解决方案或功能。 -->
|
||||||
|
|
||||||
|
## 额外补充
|
||||||
|
|
||||||
|
<!-- Bug:添加您的完整报错信息或屏幕截图,以及一切能帮助定位问题的信息。 -->
|
||||||
|
<!-- Feature:添加您在其他框架或场景遇见的效果截图或链接,以及一切能帮助理解 Feature 的信息。 -->
|
||||||
|
|
||||||
|
## 提交前确认
|
||||||
|
|
||||||
|
<!-- 在提交 issue 之前,请确保执行过以下操作。 -->
|
||||||
|
|
||||||
|
- [ ] 阅读[文档](https://doc.charles7c.top/admin/other/faq.html)
|
||||||
|
- [ ] 搜索是否有其他人提交过类似的 issue,如果对应 issue 尚未解决,您可以先订阅关注该 issue(为了方便后来者查找问题解决方法,请尽量避免创建重复的 issue)
|
53
.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<!--
|
||||||
|
非常感谢您的 PR!在提交之前,请务必确保您 PR 的代码经过了完整测试,并且通过了代码规范检查。
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- 在 [] 中输入 x 来勾选) -->
|
||||||
|
|
||||||
|
## PR 类型
|
||||||
|
|
||||||
|
<!-- 您的 PR 引入了哪种类型的变更? -->
|
||||||
|
<!-- 只支持选择一种类型,如果有多种类型,可以在更新日志中增加 “类型” 列。 -->
|
||||||
|
|
||||||
|
- [ ] 新 feature
|
||||||
|
- [ ] Bug 修复
|
||||||
|
- [ ] 功能增强
|
||||||
|
- [ ] 文档变更
|
||||||
|
- [ ] 代码样式变更
|
||||||
|
- [ ] 重构
|
||||||
|
- [ ] 性能改进
|
||||||
|
- [ ] 单元测试
|
||||||
|
- [ ] CI/CD
|
||||||
|
- [ ] 其他
|
||||||
|
|
||||||
|
## PR 目的
|
||||||
|
|
||||||
|
<!-- 描述一下您的 PR 解决了什么问题。如果可以,请链接到相关 issues。 -->
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
<!-- 详细描述您是如何解决的问题 -->
|
||||||
|
|
||||||
|
## PR 测试
|
||||||
|
|
||||||
|
<!-- 如果可以,请为您的 PR 添加或更新单元测试。 -->
|
||||||
|
<!-- 请描述一下您是如何测试 PR 的。例如:创建/更新单元测试或添加相关的截图。 -->
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
| 模块 | Changelog | Related issues |
|
||||||
|
|-----|-----------| -------------- |
|
||||||
|
| | | |
|
||||||
|
|
||||||
|
<!-- 如果有多种类型的变更,可以在变更日志表中增加 “类型” 列,该列的值与上方 “PR 类型” 相同。 -->
|
||||||
|
<!-- Related issues 格式为 fixes #<issue号>,或者 resolves #<issue号>。 -->
|
||||||
|
|
||||||
|
## 其他信息
|
||||||
|
|
||||||
|
<!-- 请描述一下还有哪些注意事项。例如:如果引入了一个不向下兼容的变更,请描述其影响。 -->
|
||||||
|
|
||||||
|
## 提交前确认
|
||||||
|
|
||||||
|
- [ ] PR 代码经过了完整测试,并且通过了代码规范检查
|
||||||
|
- [ ] 已经完整填写 Changelog,并链接到了相关 issues
|
||||||
|
- [ ] PR 代码将要提交到 dev 分支
|
57
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
name: "\U0001F41E Bug 报告"
|
||||||
|
description: Create a report to help us improve
|
||||||
|
labels: ['bug: pending triage']
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
感谢您使用 ContiNew Admin!请您花些时间填写这份 Bug 报告。
|
||||||
|
- type: textarea
|
||||||
|
id: bug-description
|
||||||
|
attributes:
|
||||||
|
label: Bug 描述
|
||||||
|
description: 清楚而简洁地描述您遇到的 Bug。另外,非常欢迎您对此 Bug 提交 PR。
|
||||||
|
placeholder: 例如:在使用 xxx 功能时出现异常
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: reproduction
|
||||||
|
attributes:
|
||||||
|
label: 复现步骤
|
||||||
|
description: 条理清晰的步骤或演示视频可以帮助快速定位问题。
|
||||||
|
placeholder: 例如:1、xxx; 2、xxx;
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: expected
|
||||||
|
attributes:
|
||||||
|
label: 预期结果
|
||||||
|
description: 清楚而简洁地描述您期望的结果。
|
||||||
|
placeholder: 预期结果
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: environment-info
|
||||||
|
attributes:
|
||||||
|
label: 环境信息
|
||||||
|
description: 描述清楚您所使用的相关环境,例如:JDK 版本:1.8.0_202;框架版本:v1.0.0;其他可能与该 issue 相关的依赖版本。
|
||||||
|
placeholder: JDK 版本, 框架版本等
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: additional-context
|
||||||
|
attributes:
|
||||||
|
label: 额外补充
|
||||||
|
description: 添加您的完整报错信息或屏幕截图,以及一切能帮助定位问题的信息。
|
||||||
|
- type: checkboxes
|
||||||
|
id: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: 确认
|
||||||
|
description: 在提交 issue 之前,请确保执行过以下操作。
|
||||||
|
options:
|
||||||
|
- label: 阅读[文档](https://doc.charles7c.top/admin/other/faq.html)
|
||||||
|
required: true
|
||||||
|
- label: 根据报错信息百度或 Google 一下
|
||||||
|
required: true
|
||||||
|
- label: 搜索是否有其他人提交过类似的 issue,如果对应 issue 尚未解决,您可以先订阅关注该 issue(为了方便后来者查找问题解决方法,请尽量避免创建重复的 issue)
|
||||||
|
required: true
|
42
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
name: "\U0001F680 新 Feature 建议"
|
||||||
|
description: Suggest an idea for this project
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
感谢您使用 ContiNew Admin!请您花些时间填写这份 Feature 调查。
|
||||||
|
- type: textarea
|
||||||
|
id: feature-description
|
||||||
|
attributes:
|
||||||
|
label: Feature 描述
|
||||||
|
description: 清楚而简洁地描述您的 Feature。另外,非常欢迎您对此 Feature 提交 PR。
|
||||||
|
placeholder: 例如:我希望增加 xxx 功能;现有的 xxx 功能不好用...
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: suggested-solution
|
||||||
|
attributes:
|
||||||
|
label: 描述一下您想要的解决方案
|
||||||
|
description: 清楚而简洁地描述您想要的解决方案。
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: alternative
|
||||||
|
attributes:
|
||||||
|
label: 描述一下您考虑过的替代方案
|
||||||
|
description: 清楚而简洁地描述您考虑过的任何替代解决方案或功能。
|
||||||
|
- type: textarea
|
||||||
|
id: additional-context
|
||||||
|
attributes:
|
||||||
|
label: 额外补充
|
||||||
|
description: 添加您在其他框架或场景遇见的效果截图或链接,以及一切能帮助理解 Feature 的信息。
|
||||||
|
- type: checkboxes
|
||||||
|
id: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: 确认
|
||||||
|
description: 在提交 issue 之前,请确保执行过以下操作。
|
||||||
|
options:
|
||||||
|
- label: 阅读[文档](https://doc.charles7c.top/admin/intro/require.html)
|
||||||
|
required: true
|
||||||
|
- label: 搜索是否有其他人提交过类似的 issue,如果对应 issue 尚未解决,您可以先订阅关注该 issue(为了方便后来者查找问题解决方法,请尽量避免创建重复的 issue)
|
||||||
|
required: true
|
53
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<!--
|
||||||
|
非常感谢您的 PR!在提交之前,请务必确保您 PR 的代码经过了完整测试,并且通过了代码规范检查。
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- 在 [] 中输入 x 来勾选) -->
|
||||||
|
|
||||||
|
## PR 类型
|
||||||
|
|
||||||
|
<!-- 您的 PR 引入了哪种类型的变更? -->
|
||||||
|
<!-- 只支持选择一种类型,如果有多种类型,可以在更新日志中增加 “类型” 列。 -->
|
||||||
|
|
||||||
|
- [ ] 新 feature
|
||||||
|
- [ ] Bug 修复
|
||||||
|
- [ ] 功能增强
|
||||||
|
- [ ] 文档变更
|
||||||
|
- [ ] 代码样式变更
|
||||||
|
- [ ] 重构
|
||||||
|
- [ ] 性能改进
|
||||||
|
- [ ] 单元测试
|
||||||
|
- [ ] CI/CD
|
||||||
|
- [ ] 其他
|
||||||
|
|
||||||
|
## PR 目的
|
||||||
|
|
||||||
|
<!-- 描述一下您的 PR 解决了什么问题。如果可以,请链接到相关 issues。 -->
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
<!-- 详细描述您是如何解决的问题 -->
|
||||||
|
|
||||||
|
## PR 测试
|
||||||
|
|
||||||
|
<!-- 如果可以,请为您的 PR 添加或更新单元测试。 -->
|
||||||
|
<!-- 请描述一下您是如何测试 PR 的。例如:创建/更新单元测试或添加相关的截图。 -->
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
| 模块 | Changelog | Related issues |
|
||||||
|
|-----|-----------| -------------- |
|
||||||
|
| | | |
|
||||||
|
|
||||||
|
<!-- 如果有多种类型的变更,可以在变更日志表中增加 “类型” 列,该列的值与上方 “PR 类型” 相同。 -->
|
||||||
|
<!-- Related issues 格式为 Closes #<issue号>,或者 Fixes #<issue号>,或者 Resolves #<issue号>。 -->
|
||||||
|
|
||||||
|
## 其他信息
|
||||||
|
|
||||||
|
<!-- 请描述一下还有哪些注意事项。例如:如果引入了一个不向下兼容的变更,请描述其影响。 -->
|
||||||
|
|
||||||
|
## 提交前确认
|
||||||
|
|
||||||
|
- [ ] PR 代码经过了完整测试,并且通过了代码规范检查
|
||||||
|
- [ ] 已经完整填写 Changelog,并链接到了相关 issues
|
||||||
|
- [ ] PR 代码将要提交到 dev 分支
|
56
.github/workflows/deploy.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
name: Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
# 推送时执行
|
||||||
|
push:
|
||||||
|
branches: [dev]
|
||||||
|
# 可手动执行
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy-web:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
# 1、检出源码
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@master
|
||||||
|
# 2、安装 PNPM
|
||||||
|
- name: Setup PNPM
|
||||||
|
uses: pnpm/action-setup@v2
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
# 3、安装 Node 环境
|
||||||
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
cache: pnpm
|
||||||
|
cache-dependency-path: ./pnpm-lock.yaml
|
||||||
|
# 4、安装依赖
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: pnpm i --frozen-lockfile
|
||||||
|
# 5、打包
|
||||||
|
- name: Build
|
||||||
|
run: pnpm build
|
||||||
|
# 6、拷贝到服务器
|
||||||
|
- name: Copy
|
||||||
|
uses: garygrossgarten/github-action-scp@release
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
port: ${{ secrets.SERVER_PORT }}
|
||||||
|
username: ${{ secrets.SERVER_USERNAME }}
|
||||||
|
password: ${{ secrets.SERVER_PASSWORD }}
|
||||||
|
local: ./dist
|
||||||
|
remote: /docker/continew-admin/tmp
|
||||||
|
# 7、重启 Nginx
|
||||||
|
- name: Restart
|
||||||
|
uses: appleboy/ssh-action@master
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
port: ${{ secrets.SERVER_PORT }}
|
||||||
|
username: ${{ secrets.SERVER_USERNAME }}
|
||||||
|
password: ${{ secrets.SERVER_PASSWORD }}
|
||||||
|
script: |
|
||||||
|
rm -rf /docker/continew-admin/html/*
|
||||||
|
mv /docker/continew-admin/tmp/* /docker/continew-admin/html
|
||||||
|
docker restart nginx
|
20
.gitignore
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
**/*.log
|
||||||
|
|
||||||
|
tests/**/coverage/
|
||||||
|
tests/e2e/reports
|
||||||
|
selenium-debug.log
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.local
|
7
.prettierignore
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/dist/*
|
||||||
|
.local
|
||||||
|
.output.js
|
||||||
|
/node_modules/**
|
||||||
|
|
||||||
|
**/*.svg
|
||||||
|
**/*.sh
|
10
.prettierrc.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
module.exports = {
|
||||||
|
tabWidth: 2,
|
||||||
|
semi: true,
|
||||||
|
printWidth: 80,
|
||||||
|
singleQuote: true,
|
||||||
|
quoteProps: 'consistent',
|
||||||
|
htmlWhitespaceSensitivity: 'strict',
|
||||||
|
vueIndentScriptAndStyle: true,
|
||||||
|
endOfLine: 'auto',
|
||||||
|
};
|
30
.stylelintrc.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: [
|
||||||
|
'stylelint-config-standard',
|
||||||
|
'stylelint-config-rational-order',
|
||||||
|
'stylelint-config-prettier',
|
||||||
|
'stylelint-config-recommended-vue',
|
||||||
|
],
|
||||||
|
defaultSeverity: 'warning',
|
||||||
|
plugins: ['stylelint-order'],
|
||||||
|
rules: {
|
||||||
|
'at-rule-no-unknown': [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
ignoreAtRules: ['plugin'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'rule-empty-line-before': [
|
||||||
|
'always',
|
||||||
|
{
|
||||||
|
except: ['after-single-line-comment', 'first-nested'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'selector-pseudo-class-no-unknown': [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
ignorePseudoClasses: ['deep'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
202
LICENSE
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
191
README.md
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
# ContiNew UI
|
||||||
|
|
||||||
|
<a href="https://github.com/Charles7c/continew-admin-ui/blob/dev/LICENSE" target="_blank">
|
||||||
|
<img src="https://img.shields.io/badge/License-Apache--2.0-blue.svg" alt="License" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/Charles7c/continew-admin-ui" target="_blank">
|
||||||
|
<img src="https://img.shields.io/badge/RELEASE-v2.2.0-%23ff3f59.svg" alt="Release" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/Charles7c/continew-admin-ui" target="_blank">
|
||||||
|
<img src="https://img.shields.io/github/stars/Charles7c/continew-admin-ui?style=social" alt="GitHub stars" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/Charles7c/continew-admin-ui" target="_blank">
|
||||||
|
<img src="https://img.shields.io/github/forks/Charles7c/continew-admin-ui?style=social" alt="GitHub forks" />
|
||||||
|
</a>
|
||||||
|
<a href="https://gitee.com/Charles7c/continew-admin-ui" target="_blank">
|
||||||
|
<img src="https://gitee.com/Charles7c/continew-admin-ui/badge/star.svg?theme=white" alt="Gitee stars" />
|
||||||
|
</a>
|
||||||
|
<a href="https://gitee.com/Charles7c/continew-admin-ui" target="_blank">
|
||||||
|
<img src="https://gitee.com/Charles7c/continew-admin-ui/badge/fork.svg?theme=white" alt="Gitee forks" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/Charles7c/continew-admin-ui" target="_blank">
|
||||||
|
<img src="https://img.shields.io/badge/Vue-3.3.7-%236CB52D.svg" alt="Release" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/Charles7c/continew-admin-ui" target="_blank">
|
||||||
|
<img src="https://img.shields.io/badge/Arco Design Vue-2.53.3-%236CB52D.svg" alt="Release" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/Charles7c/continew-admin-ui" target="_blank">
|
||||||
|
<img src="https://img.shields.io/badge/Vite-4.5.1-%236CB52D.svg" alt="Release" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/Charles7c/continew-admin-ui" target="_blank">
|
||||||
|
<img src="https://img.shields.io/badge/TypeScript-5.3.3-%236CB52D.svg" alt="Release" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
📚 [在线文档](https://doc.charles7c.top) | 🚀 [演示地址](https://cnadmin.charles7c.top)(账号/密码:admin/admin123)
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
基于 Arco Design Pro 前端模板开发的 ContiNew Admin 前端适配项目。
|
||||||
|
|
||||||
|
ContiNew Admin (Continue New Admin)中后台管理框架/脚手架,持续以最新流行技术栈构建,拥抱变化,迭代优化。依托开源协作模式,提升技术透明度、放大集体智慧、共创优秀实践,源源不断地为企业级项目开发提供助力。当前采用的技术栈:Spring Boot3(Java17)、Vue3 & Arco Design、Sa-Token、MyBatis Plus、Redisson、Liquibase、JustAuth、Easy Excel、Hutool、TypeScript、Vite4 等。
|
||||||
|
|
||||||
|
## 项目源码
|
||||||
|
|
||||||
|
| 开源平台 | 前端源码地址 | 后端源码地址 |
|
||||||
|
| ------------- | ---------------------------------------------- | ------------------------------------------- |
|
||||||
|
| GitHub | https://github.com/Charles7c/continew-admin-ui | https://github.com/Charles7c/continew-admin |
|
||||||
|
| Gitee(码云) | https://gitee.com/Charles7c/continew-admin-ui | https://gitee.com/Charles7c/continew-admin |
|
||||||
|
|
||||||
|
## 系统功能
|
||||||
|
|
||||||
|
> **Note**
|
||||||
|
> 更多功能和优化正在赶来💦,最新项目计划、进展请进群或关注 [任务清单](https://doc.charles7c.top/admin/intro/require.html#任务清单) 和 [更新日志](https://doc.charles7c.top/admin/other/changelog.html)。
|
||||||
|
|
||||||
|
- 个人中心:支持基础信息修改、安全设置(密码修改、邮箱绑定、手机号绑定、第三方账号绑定/解绑)、头像裁剪上传、个人操作日志查看
|
||||||
|
- 用户管理:提供用户的相关配置,新增用户后,默认密码为 123456
|
||||||
|
- 部门管理:可配置系统组织架构,树形表格展示
|
||||||
|
- 角色管理:对权限与菜单进行分配,可根据部门设置角色的数据权限
|
||||||
|
- 菜单管理:已实现菜单动态路由,后端可配置化,支持多级菜单
|
||||||
|
- 公告管理:提供公告的发布、查看和删除等功能。管理员可以在后台发布公告,并可以设置公告的生效时间、终止时间,以 markdown-it 为内核渲染 Markdown 格式内容显示
|
||||||
|
- 消息管理:提供消息查看、标记已读、全部已读、删除等功能(适配对接导航栏站内信功能)
|
||||||
|
- 字典管理:提供对系统公用数据字典的维护,例如:公告类型,支持字典标签背景色和排序等配置
|
||||||
|
- 文件管理:提供文件上传、下载、预览(目前支持图片、音视频)、重命名、切换视图(列表、网格)等功能
|
||||||
|
- 存储库管理:提供文件存储库新增、编辑、删除、导出等功能
|
||||||
|
- 系统配置:提供修改系统标题、Logo、favicon 等基础配置功能,以方便用户系统与其自身品牌形象保持一致(暂未开放高级配置)
|
||||||
|
- 代码生成:提供根据数据库表自动生成相应的前后端 CRUD 代码的功能
|
||||||
|
- 在线用户:管理当前登录用户,可一键踢下线
|
||||||
|
- 日志管理:提供在线用户监控、登录日志监控、操作日志监控和系统日志监控等监控功能
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
> **Note**
|
||||||
|
> 更详细的流程,请查看在线文档[《快速开始》](https://doc.charles7c.top/admin/intro/quick-start.html#%E5%89%8D%E7%AB%AF)。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1.克隆本项目
|
||||||
|
git clone https://github.com/Charles7c/continew-admin.git
|
||||||
|
|
||||||
|
# 2.在 IDE(Visual Studio Code/WebStorm)中打开前端项目 continew-admin-ui
|
||||||
|
|
||||||
|
# 3.安装 pnpm,配置淘宝源
|
||||||
|
npm install -g pnpm
|
||||||
|
pnpm config set registry https://registry.npm.taobao.org
|
||||||
|
|
||||||
|
# 4.安装依赖
|
||||||
|
pnpm i
|
||||||
|
|
||||||
|
# 5.启动程序
|
||||||
|
# 5.1 启动成功:访问 http://localhost:5173/
|
||||||
|
pnpm dev
|
||||||
|
|
||||||
|
# 6.部署
|
||||||
|
# 6.1 Docker 部署
|
||||||
|
# 6.1.1 服务器安装好 docker 及 docker-compose(参考:https://blog.charles7c.top/categories/fragments/2022/10/31/CentOS%E5%AE%89%E8%A3%85Docker)
|
||||||
|
# 6.1.2 执行 pnpm build 进行项目打包,将 dist 目录下的所有文件放到 /docker/continew-admin/html 目录下
|
||||||
|
# 6.1.3 将 docker 目录上传到服务器 / 目录下,并授权(chmod -R 777 /docker)
|
||||||
|
# 6.1.4 修改 docker-compose.yml 中的 MySQL 配置、Redis 配置、continew-admin-server 配置、Nginx 配置
|
||||||
|
# 6.1.5 执行 docker-compose up -d 创建并后台运行所有容器
|
||||||
|
# 6.2 其他方式部署
|
||||||
|
```
|
||||||
|
|
||||||
|
## 核心技术栈
|
||||||
|
|
||||||
|
| 名称 | 版本 | 简介 |
|
||||||
|
| :----------------------------------------------------------- | :----- | :----------------------------------------------------------- |
|
||||||
|
| <a href="https://cn.vuejs.org/" target="_blank">Vue</a> | 3.3.7 | 渐进式 JavaScript 框架,易学易用,性能出色,适用场景丰富的 Web 前端框架。 |
|
||||||
|
| <a href="https://arco.design/vue/docs/start" target="_blank">Arco Design</a> | 2.53.3 | 字节跳动推出的前端 UI 框架,年轻化的色彩和组件设计。 |
|
||||||
|
| <a href="https://www.typescriptlang.org/zh/" target="_blank">TypeScript</a> | 5.3.3 | TypeScript 是微软开发的一个开源的编程语言,通过在 JavaScript 的基础上添加静态类型定义构建而成。 |
|
||||||
|
| <a href="https://cn.vitejs.dev/" target="_blank">Vite</a> | 4.5.1 | 下一代的前端工具链,为开发提供极速响应。 |
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```bash
|
||||||
|
continew-admin-ui
|
||||||
|
├─ config # 全局 Vite 配置
|
||||||
|
├─ public # 公共静态资源(favicon.ico、logo.svg)
|
||||||
|
├─ src
|
||||||
|
│ ├─ api # 请求接口
|
||||||
|
│ │ ├─ demo # 示例模块
|
||||||
|
│ │ ├─ auth # 认证模块
|
||||||
|
│ │ ├─ common # 公共模块
|
||||||
|
│ │ ├─ monitor # 系统监控模块
|
||||||
|
│ │ ├─ system # 系统管理模块
|
||||||
|
│ │ └─ tool # 系统工具模块
|
||||||
|
│ ├─ assets # 静态资源
|
||||||
|
│ │ ├─ icons # 图标资源
|
||||||
|
│ │ ├─ images # 图片资源
|
||||||
|
│ │ └─ style # 样式资源
|
||||||
|
│ ├─ components # 通用业务组件
|
||||||
|
│ ├─ config # 全局配置(包含 echarts 主题)
|
||||||
|
│ │ └─ settings.json # 配置文件
|
||||||
|
│ ├─ directives # 指令集(如需,可自行补充)
|
||||||
|
│ ├─ hooks # 全局 hooks
|
||||||
|
│ ├─ layout # 布局
|
||||||
|
│ ├─ locale # 国际化语言包
|
||||||
|
│ ├─ mock # 模拟数据
|
||||||
|
│ ├─ router # 路由配置
|
||||||
|
│ ├─ store # 状态管理中心
|
||||||
|
│ ├─ types # TypeScript 类型
|
||||||
|
│ ├─ utils # 工具库(mock 全局开启/关闭)
|
||||||
|
│ ├─ views # 页面模板
|
||||||
|
│ │ ├─ demo # Arco Design 相关示例模块
|
||||||
|
│ │ ├─ dashboard # 仪表盘模块
|
||||||
|
│ │ ├─ login # 登录模块
|
||||||
|
│ │ ├─ monitor # 系统监控模块
|
||||||
|
│ │ │ ├─ log # 日志管理
|
||||||
|
│ │ │ │ ├─ login # 登录日志
|
||||||
|
│ │ │ │ ├─ operation # 操作日志
|
||||||
|
│ │ │ │ └─ system # 系统日志
|
||||||
|
│ │ │ └─ online # 在线用户
|
||||||
|
│ │ └─ system # 系统管理模块
|
||||||
|
│ │ ├─ announcement # 公告管理
|
||||||
|
│ │ ├─ config # 系统配置
|
||||||
|
│ │ ├─ dept # 部门管理
|
||||||
|
│ │ ├─ dict # 字典管理
|
||||||
|
│ │ ├─ menu # 菜单管理
|
||||||
|
│ │ ├─ message # 消息管理
|
||||||
|
│ │ ├─ role # 角色管理
|
||||||
|
│ │ └─ user # 用户模块
|
||||||
|
│ │ └─ center # 个人中心
|
||||||
|
│ ├─ App.vue
|
||||||
|
│ └─ main.ts # 入口文件
|
||||||
|
├─ .env.development
|
||||||
|
├─ .env.production
|
||||||
|
├─ index.html
|
||||||
|
├─ package.json
|
||||||
|
└─ tsconfig.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## 鸣谢
|
||||||
|
|
||||||
|
### 鸣谢
|
||||||
|
|
||||||
|
感谢参与贡献的每一位小伙伴🥰
|
||||||
|
|
||||||
|
<a href="https://github.com/Charles7c/continew-admin-ui/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=Charles7c/continew-admin-ui" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
### 特别鸣谢
|
||||||
|
|
||||||
|
- 感谢 <a href="https://www.jetbrains.com/" target="_blank">JetBrains</a> 提供的 <a href="https://www.jetbrains.com/shop/eform/opensource" target="_blank">非商业开源软件开发授权</a>
|
||||||
|
- 感谢 <a href="http://pro.arco.design/" target="_blank">Arco Design Pro</a> 开箱即用的中后台前端解决方案
|
||||||
|
- 感谢 [Gi Admin Pro](https://gitee.com/lin0716/gi-demo),致敬各位作者为开源前端模板领域作出的贡献
|
||||||
|
- e.g. 扩展于 Gi Admin Pro 项目开源的文件管理组件
|
||||||
|
|
||||||
|
- 感谢项目使用或未使用到的每一款开源组件,致敬各位开源先驱 :fire:
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
- 遵循 <a href="https://github.com/Charles7c/continew-admin-ui/blob/dev/LICENSE" target="_blank">Apache-2.0</a> 开源许可协议
|
||||||
|
- Copyright © 2022-present <a href="https://blog.charles7c.top" target="_blank">Charles7c</a>
|
3
babel.config.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: ['@vue/babel-plugin-jsx'],
|
||||||
|
};
|
3
commitlint.config.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: ['@commitlint/config-conventional'],
|
||||||
|
};
|
15
components.d.ts
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// Generated by unplugin-vue-components
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
import '@vue/runtime-core'
|
||||||
|
|
||||||
|
export {}
|
||||||
|
|
||||||
|
declare module '@vue/runtime-core' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
}
|
||||||
|
}
|
19
config/plugin/arcoResolver.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* If you use the template method for development, you can use the unplugin-vue-components plugin to enable on-demand loading support.
|
||||||
|
* 按需引入
|
||||||
|
* https://github.com/antfu/unplugin-vue-components
|
||||||
|
* https://arco.design/vue/docs/start
|
||||||
|
* Although the Pro project is full of imported components, this plugin will be used by default.
|
||||||
|
* 虽然Pro项目中是全量引入组件,但此插件会默认使用。
|
||||||
|
*/
|
||||||
|
import Components from 'unplugin-vue-components/vite';
|
||||||
|
import { ArcoResolver } from 'unplugin-vue-components/resolvers';
|
||||||
|
|
||||||
|
export default function configArcoResolverPlugin() {
|
||||||
|
const arcoResolverPlugin = Components({
|
||||||
|
dirs: [], // Avoid parsing src/components. 避免解析到src/components
|
||||||
|
deep: false,
|
||||||
|
resolvers: [ArcoResolver()],
|
||||||
|
});
|
||||||
|
return arcoResolverPlugin;
|
||||||
|
}
|
12
config/plugin/arcoStyleImport.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Theme import
|
||||||
|
* 样式按需引入
|
||||||
|
* https://github.com/arco-design/arco-plugins/blob/main/packages/plugin-vite-vue/README.md
|
||||||
|
* https://arco.design/vue/docs/start
|
||||||
|
*/
|
||||||
|
import { vitePluginForArco } from '@arco-plugins/vite-vue';
|
||||||
|
|
||||||
|
export default function configArcoStyleImportPlugin() {
|
||||||
|
const arcoResolverPlugin = vitePluginForArco({});
|
||||||
|
return arcoResolverPlugin;
|
||||||
|
}
|
34
config/plugin/compress.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated
|
||||||
|
* gzip压缩
|
||||||
|
* https://github.com/anncwb/vite-plugin-compression
|
||||||
|
*/
|
||||||
|
import type { Plugin } from 'vite';
|
||||||
|
import compressPlugin from 'vite-plugin-compression';
|
||||||
|
|
||||||
|
export default function configCompressPlugin(
|
||||||
|
compress: 'gzip' | 'brotli',
|
||||||
|
deleteOriginFile = false
|
||||||
|
): Plugin | Plugin[] {
|
||||||
|
const plugins: Plugin[] = [];
|
||||||
|
|
||||||
|
if (compress === 'gzip') {
|
||||||
|
plugins.push(
|
||||||
|
compressPlugin({
|
||||||
|
ext: '.gz',
|
||||||
|
deleteOriginFile,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compress === 'brotli') {
|
||||||
|
plugins.push(
|
||||||
|
compressPlugin({
|
||||||
|
ext: '.br',
|
||||||
|
algorithm: 'brotliCompress',
|
||||||
|
deleteOriginFile,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return plugins;
|
||||||
|
}
|
37
config/plugin/imagemin.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Image resource files used to compress the output of the production environment
|
||||||
|
* 图片压缩
|
||||||
|
* https://github.com/anncwb/vite-plugin-imagemin
|
||||||
|
*/
|
||||||
|
import viteImagemin from 'vite-plugin-imagemin';
|
||||||
|
|
||||||
|
export default function configImageminPlugin() {
|
||||||
|
const imageminPlugin = viteImagemin({
|
||||||
|
gifsicle: {
|
||||||
|
optimizationLevel: 7,
|
||||||
|
interlaced: false,
|
||||||
|
},
|
||||||
|
optipng: {
|
||||||
|
optimizationLevel: 7,
|
||||||
|
},
|
||||||
|
mozjpeg: {
|
||||||
|
quality: 20,
|
||||||
|
},
|
||||||
|
pngquant: {
|
||||||
|
quality: [0.8, 0.9],
|
||||||
|
speed: 4,
|
||||||
|
},
|
||||||
|
svgo: {
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
name: 'removeViewBox',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'removeEmptyAttrs',
|
||||||
|
active: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return imageminPlugin;
|
||||||
|
}
|
10
config/plugin/svg-icon.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
export default function createSvgIcon(isBuild: boolean) {
|
||||||
|
return createSvgIconsPlugin({
|
||||||
|
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/svg')],
|
||||||
|
symbolId: 'icon-[dir]-[name]',
|
||||||
|
svgoOptions: isBuild,
|
||||||
|
});
|
||||||
|
}
|
18
config/plugin/visualizer.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Generation packaging analysis
|
||||||
|
* 生成打包分析
|
||||||
|
*/
|
||||||
|
import visualizer from 'rollup-plugin-visualizer';
|
||||||
|
import { isReportMode } from '../utils';
|
||||||
|
|
||||||
|
export default function configVisualizerPlugin() {
|
||||||
|
if (isReportMode()) {
|
||||||
|
return visualizer({
|
||||||
|
filename: './node_modules/.cache/visualizer/stats.html',
|
||||||
|
open: true,
|
||||||
|
gzipSize: true,
|
||||||
|
brotliSize: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
9
config/utils/index.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Whether to generate package preview
|
||||||
|
* 是否生成打包报告
|
||||||
|
*/
|
||||||
|
export default {};
|
||||||
|
|
||||||
|
export function isReportMode(): boolean {
|
||||||
|
return process.env.REPORT === 'true';
|
||||||
|
}
|
51
config/vite.config.base.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { resolve } from 'path';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import vue from '@vitejs/plugin-vue';
|
||||||
|
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||||
|
import svgLoader from 'vite-svg-loader';
|
||||||
|
// import configArcoStyleImportPlugin from './plugin/arcoStyleImport';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
vue(),
|
||||||
|
vueJsx(),
|
||||||
|
svgLoader({ svgoConfig: {} }),
|
||||||
|
// configArcoStyleImportPlugin(),
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: [
|
||||||
|
{
|
||||||
|
find: '@',
|
||||||
|
replacement: resolve(__dirname, '../src'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: 'assets',
|
||||||
|
replacement: resolve(__dirname, '../src/assets'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: 'vue-i18n',
|
||||||
|
replacement: 'vue-i18n/dist/vue-i18n.cjs.js', // Resolve the i18n warning issue
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: 'vue',
|
||||||
|
replacement: 'vue/dist/vue.esm-bundler.js', // compile template
|
||||||
|
},
|
||||||
|
],
|
||||||
|
extensions: ['.ts', '.js'],
|
||||||
|
},
|
||||||
|
define: {
|
||||||
|
'process.env': {},
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
preprocessorOptions: {
|
||||||
|
less: {
|
||||||
|
modifyVars: {
|
||||||
|
hack: `true; @import (reference) "${resolve(
|
||||||
|
'src/assets/style/breakpoint.less'
|
||||||
|
)}";`,
|
||||||
|
},
|
||||||
|
javascriptEnabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
25
config/vite.config.dev.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { mergeConfig } from 'vite';
|
||||||
|
import eslint from 'vite-plugin-eslint';
|
||||||
|
import baseConfig from './vite.config.base';
|
||||||
|
import createSvgIcon from './plugin/svg-icon';
|
||||||
|
|
||||||
|
export default mergeConfig(
|
||||||
|
{
|
||||||
|
mode: 'development',
|
||||||
|
server: {
|
||||||
|
open: true,
|
||||||
|
fs: {
|
||||||
|
strict: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
eslint({
|
||||||
|
cache: false,
|
||||||
|
include: ['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.vue'],
|
||||||
|
exclude: ['node_modules'],
|
||||||
|
}),
|
||||||
|
createSvgIcon(false),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
baseConfig
|
||||||
|
);
|
33
config/vite.config.prod.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { mergeConfig } from 'vite';
|
||||||
|
import baseConfig from './vite.config.base';
|
||||||
|
import configCompressPlugin from './plugin/compress';
|
||||||
|
import configVisualizerPlugin from './plugin/visualizer';
|
||||||
|
// import configArcoResolverPlugin from './plugin/arcoResolver';
|
||||||
|
import configImageminPlugin from './plugin/imagemin';
|
||||||
|
import createSvgIcon from './plugin/svg-icon';
|
||||||
|
|
||||||
|
export default mergeConfig(
|
||||||
|
{
|
||||||
|
mode: 'production',
|
||||||
|
plugins: [
|
||||||
|
configCompressPlugin('gzip'),
|
||||||
|
configVisualizerPlugin(),
|
||||||
|
// configArcoResolverPlugin(),
|
||||||
|
configImageminPlugin(),
|
||||||
|
createSvgIcon(true),
|
||||||
|
],
|
||||||
|
build: {
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
manualChunks: {
|
||||||
|
arco: ['@arco-design/web-vue'],
|
||||||
|
chart: ['echarts', 'vue-echarts'],
|
||||||
|
vue: ['vue', 'vue-router', 'pinia', '@vueuse/core', 'vue-i18n'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
chunkSizeWarningLimit: 2000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
baseConfig
|
||||||
|
);
|
31
index.html
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/* 百度统计代码 */
|
||||||
|
var _hmt = _hmt || [];
|
||||||
|
(function() {
|
||||||
|
var hm = document.createElement("script");
|
||||||
|
hm.src = "https://hm.baidu.com/hm.js?b0d02b5db5f47cd1ecb885dd33781f21";
|
||||||
|
var s = document.getElementsByTagName("script")[0];
|
||||||
|
s.parentNode.insertBefore(hm, s);
|
||||||
|
|
||||||
|
/* 百度统计 => 规则设置 => 单页设置 => 启用单页应用数据统计 */
|
||||||
|
_hmt.push(['_requirePlugin', 'UrlChangeTracker', {
|
||||||
|
shouldTrackUrlChange: function (newPath, oldPath) {
|
||||||
|
return newPath && oldPath;
|
||||||
|
}}
|
||||||
|
]);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
113
package.json
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
{
|
||||||
|
"name": "continew-admin-ui",
|
||||||
|
"description": "ContiNew Admin 中后台管理框架,Continue New Admin,持续以最新流行技术栈构建,拥抱变化,迭代优化。",
|
||||||
|
"version": "2.2.0",
|
||||||
|
"private": true,
|
||||||
|
"author": "Charles7c",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite --host --config ./config/vite.config.dev.ts",
|
||||||
|
"build": "vue-tsc --noEmit && vite build --config ./config/vite.config.prod.ts",
|
||||||
|
"report": "cross-env REPORT=true npm run build",
|
||||||
|
"preview": "npm run build && vite preview --host",
|
||||||
|
"type:check": "vue-tsc --noEmit --skipLibCheck",
|
||||||
|
"lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix",
|
||||||
|
"lint-staged": "npx lint-staged"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{js,ts,jsx,tsx}": [
|
||||||
|
"prettier --write",
|
||||||
|
"eslint --fix"
|
||||||
|
],
|
||||||
|
"*.vue": [
|
||||||
|
"stylelint --fix",
|
||||||
|
"prettier --write",
|
||||||
|
"eslint --fix"
|
||||||
|
],
|
||||||
|
"*.{less,css}": [
|
||||||
|
"stylelint --fix",
|
||||||
|
"prettier --write"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@arco-design/web-vue": "^2.53.3",
|
||||||
|
"@codemirror/lang-java": "^6.0.1",
|
||||||
|
"@codemirror/lang-javascript": "^6.2.1",
|
||||||
|
"@kangc/v-md-editor": "^2.3.18",
|
||||||
|
"@vueuse/core": "^10.7.0",
|
||||||
|
"axios": "^0.24.0",
|
||||||
|
"codemirror": "^6.0.1",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
|
"dayjs": "^1.11.10",
|
||||||
|
"echarts": "^5.4.3",
|
||||||
|
"highlight.js": "^11.9.0",
|
||||||
|
"jsencrypt": "^3.3.2",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"mitt": "^3.0.1",
|
||||||
|
"nprogress": "^0.2.0",
|
||||||
|
"pinia": "^2.1.7",
|
||||||
|
"query-string": "^8.1.0",
|
||||||
|
"sortablejs": "^1.15.1",
|
||||||
|
"v-viewer": "^3.0.10",
|
||||||
|
"viewerjs": "^1.11.6",
|
||||||
|
"vue": "3.3.7",
|
||||||
|
"vue-codemirror": "^6.1.1",
|
||||||
|
"vue-cropper": "^1.1.1",
|
||||||
|
"vue-echarts": "^6.6.5",
|
||||||
|
"vue-i18n": "^9.8.0",
|
||||||
|
"vue-json-pretty": "^2.3.0",
|
||||||
|
"vue-router": "^4.2.5",
|
||||||
|
"vue3-colorpicker": "^2.2.3",
|
||||||
|
"xgplayer": "^2.31.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@arco-plugins/vite-vue": "^1.4.5",
|
||||||
|
"@commitlint/cli": "^18.4.3",
|
||||||
|
"@commitlint/config-conventional": "^18.4.3",
|
||||||
|
"@types/crypto-js": "^4.2.1",
|
||||||
|
"@types/lodash": "^4.14.202",
|
||||||
|
"@types/mockjs": "^1.0.10",
|
||||||
|
"@types/nprogress": "^0.2.3",
|
||||||
|
"@types/sortablejs": "^1.15.7",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
||||||
|
"@typescript-eslint/parser": "^6.15.0",
|
||||||
|
"@vitejs/plugin-vue": "^4.5.2",
|
||||||
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
|
"@vue/babel-plugin-jsx": "^1.1.5",
|
||||||
|
"consola": "^3.2.3",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"eslint": "^8.56.0",
|
||||||
|
"eslint-config-airbnb-base": "^15.0.0",
|
||||||
|
"eslint-config-prettier": "^9.1.0",
|
||||||
|
"eslint-import-resolver-typescript": "^3.6.1",
|
||||||
|
"eslint-plugin-import": "^2.29.1",
|
||||||
|
"eslint-plugin-prettier": "^5.1.2",
|
||||||
|
"eslint-plugin-vue": "^9.19.2",
|
||||||
|
"less": "^4.2.0",
|
||||||
|
"lint-staged": "^15.2.0",
|
||||||
|
"mockjs": "^1.1.0",
|
||||||
|
"postcss-html": "^1.5.0",
|
||||||
|
"prettier": "^3.1.1",
|
||||||
|
"rollup": "^4.9.1",
|
||||||
|
"rollup-plugin-visualizer": "^5.11.0",
|
||||||
|
"sass": "^1.69.5",
|
||||||
|
"stylelint": "^16.0.2",
|
||||||
|
"stylelint-config-prettier": "^9.0.5",
|
||||||
|
"stylelint-config-rational-order": "^0.1.2",
|
||||||
|
"stylelint-config-recommended-vue": "^1.5.0",
|
||||||
|
"stylelint-config-standard": "^35.0.0",
|
||||||
|
"stylelint-order": "^6.0.4",
|
||||||
|
"typescript": "^5.3.3",
|
||||||
|
"unplugin-vue-components": "^0.26.0",
|
||||||
|
"vite": "^4.5.1",
|
||||||
|
"vite-plugin-compression": "^0.5.1",
|
||||||
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
|
"vite-plugin-imagemin": "^0.6.1",
|
||||||
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
|
"vite-svg-loader": "^4.0.0",
|
||||||
|
"vue-tsc": "^1.8.26"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
}
|
||||||
|
}
|
10641
pnpm-lock.yaml
generated
Normal file
BIN
public/favicon.ico
Normal file
After Width: | Height: | Size: 66 KiB |
9
public/logo.svg
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<svg width="33" height="33" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 174.8 204">
|
||||||
|
<path fill="#307AF2" d="M86.7,0l88,51v.2l-16.3,9.4v-.2L86.7,18.9Zm71.8,143.5,16.3,9.4v.2L86.8,204h0l-16.3-9.4,16.3-9.4h0l71.7-41.5v-.2Z"/>
|
||||||
|
<path fill="#12D2AC" d="M16.3,143.5v.2L58,167.8l-16.3,9.4L0,153.1v-.2Z"/>
|
||||||
|
<path fill="#12D2AC" d="M104.1,93,15.9,143.8l-.2-.1V124.9l.2.1L87.7,83.6,104.1,93Z"/>
|
||||||
|
<path fill="#0057FE" d="M88.1,0,.1,51v.2l16.3,9.4v-.2L88.1,18.9Z"/>
|
||||||
|
<path fill="#307AF2" d="M.1,50.9.2,152.6l.2.1,16.3-9.4-.2-.1-.1-82.9L.1,50.9Z"/>
|
||||||
|
<path fill="#0057FE" d="M174.7,50.9l-.1,101.7-.2.1-16.3-9.4.2-.1.1-82.9Z"/>
|
||||||
|
<path fill="#12D2AC" d="M41.7,158.5l16.1,9.4,100.6-58.7V90.4Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 683 B |
2
public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
User-agent: *
|
||||||
|
Disallow: /
|
26
src/App.vue
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<template>
|
||||||
|
<a-config-provider :locale="locale">
|
||||||
|
<router-view />
|
||||||
|
<global-setting />
|
||||||
|
</a-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import enUS from '@arco-design/web-vue/es/locale/lang/en-us';
|
||||||
|
import zhCN from '@arco-design/web-vue/es/locale/lang/zh-cn';
|
||||||
|
import GlobalSetting from '@/components/global-setting/index.vue';
|
||||||
|
import useLocale from '@/hooks/locale';
|
||||||
|
|
||||||
|
const { currentLocale } = useLocale();
|
||||||
|
const locale = computed(() => {
|
||||||
|
switch (currentLocale.value) {
|
||||||
|
case 'zh-CN':
|
||||||
|
return zhCN;
|
||||||
|
case 'en-US':
|
||||||
|
return enUS;
|
||||||
|
default:
|
||||||
|
return enUS;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
58
src/api/auth/index.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import type { RouteRecordNormalized } from 'vue-router';
|
||||||
|
import { UserState } from '@/store/modules/user/types';
|
||||||
|
|
||||||
|
const BASE_URL = '/auth';
|
||||||
|
|
||||||
|
export interface AccountLoginReq {
|
||||||
|
username?: string;
|
||||||
|
password?: string;
|
||||||
|
captcha: string;
|
||||||
|
uuid?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LoginRes {
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function accountLogin(req: AccountLoginReq) {
|
||||||
|
return axios.post<LoginRes>(`${BASE_URL}/account`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EmailLoginReq {
|
||||||
|
email: string;
|
||||||
|
captcha: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function emailLogin(req: EmailLoginReq) {
|
||||||
|
return axios.post<LoginRes>(`${BASE_URL}/email`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PhoneLoginReq {
|
||||||
|
phone: string;
|
||||||
|
captcha: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function phoneLogin(req: PhoneLoginReq) {
|
||||||
|
return axios.post<LoginRes>(`${BASE_URL}/phone`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function logout() {
|
||||||
|
return axios.post(`${BASE_URL}/logout`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getUserInfo() {
|
||||||
|
return axios.get<UserState>(`${BASE_URL}/user/info`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listRoute() {
|
||||||
|
return axios.get<RouteRecordNormalized[]>(`${BASE_URL}/route`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function socialAuth(source: string) {
|
||||||
|
return axios.get<string>(`/oauth/${source}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function socialLogin(source: string, req: any) {
|
||||||
|
return axios.post<LoginRes>(`/oauth/${source}`, req);
|
||||||
|
}
|
63
src/api/common/captcha.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/captcha';
|
||||||
|
|
||||||
|
export interface ImageCaptchaRes {
|
||||||
|
uuid: string;
|
||||||
|
img: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BehaviorCaptchaRes {
|
||||||
|
originalImageBase64: string;
|
||||||
|
point: {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
};
|
||||||
|
jigsawImageBase64: string;
|
||||||
|
token: string;
|
||||||
|
secretKey: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BehaviorCaptchaReq {
|
||||||
|
captchaType?: string;
|
||||||
|
captchaVerification?: string;
|
||||||
|
clientUid?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CheckBehaviorCaptchaRes {
|
||||||
|
repCode: string;
|
||||||
|
repMsg: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getImageCaptcha() {
|
||||||
|
return axios.get<ImageCaptchaRes>(`${BASE_URL}/img`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMailCaptcha(email: string) {
|
||||||
|
return axios.get(`${BASE_URL}/mail?email=${email}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSmsCaptcha(
|
||||||
|
phone: string,
|
||||||
|
behaviorCaptcha: BehaviorCaptchaReq,
|
||||||
|
) {
|
||||||
|
return axios.get(
|
||||||
|
`${BASE_URL}/sms?phone=${phone}&captchaVerification=${encodeURIComponent(
|
||||||
|
behaviorCaptcha.captchaVerification || '',
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBehaviorCaptcha(params: any) {
|
||||||
|
return axios.get<BehaviorCaptchaRes>(`${BASE_URL}/behavior`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkBehaviorCaptcha(params: any) {
|
||||||
|
return axios.post<CheckBehaviorCaptchaRes>(`${BASE_URL}/behavior`, params);
|
||||||
|
}
|
65
src/api/common/dashboard.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const BASE_URL = '/dashboard';
|
||||||
|
|
||||||
|
export interface DashboardTotalRecord {
|
||||||
|
pvCount: number;
|
||||||
|
ipCount: number;
|
||||||
|
todayPvCount: number;
|
||||||
|
newPvFromYesterday: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DashboardAccessTrendRecord {
|
||||||
|
date: string;
|
||||||
|
pvCount: number;
|
||||||
|
ipCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DashboardPopularModuleRecord {
|
||||||
|
module: string;
|
||||||
|
pvCount: number;
|
||||||
|
newPvFromYesterday: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DashboardGeoDistributionRecord {
|
||||||
|
locations: string[];
|
||||||
|
locationIpStatistics: [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DashboardAnnouncementRecord {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
type: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DashboardRecentlyVisitedRecord {
|
||||||
|
title?: string;
|
||||||
|
path: string;
|
||||||
|
icon?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTotal() {
|
||||||
|
return axios.get<DashboardTotalRecord>(`${BASE_URL}/total`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listAccessTrend(days: number) {
|
||||||
|
return axios.get<DashboardAccessTrendRecord[]>(
|
||||||
|
`${BASE_URL}/access/trend/${days}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listPopularModule() {
|
||||||
|
return axios.get<DashboardPopularModuleRecord[]>(
|
||||||
|
`${BASE_URL}/popular/module`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGeoDistribution() {
|
||||||
|
return axios.get<DashboardGeoDistributionRecord>(
|
||||||
|
`${BASE_URL}/geo/distribution`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listAnnouncement() {
|
||||||
|
return axios.get<DashboardAnnouncementRecord[]>(`${BASE_URL}/announcement`);
|
||||||
|
}
|
54
src/api/common/index.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
import { ListParam as DeptParam } from '@/api/system/dept';
|
||||||
|
import { ListParam as MenuParam } from '@/api/system/menu';
|
||||||
|
import { ListParam as RoleParam } from '@/api/system/role';
|
||||||
|
import { ListParam as OptionParam } from '@/api/system/config';
|
||||||
|
import { TreeNodeData } from '@arco-design/web-vue';
|
||||||
|
import { LabelValueState } from '@/store/modules/dict/types';
|
||||||
|
|
||||||
|
const BASE_URL = '/common';
|
||||||
|
|
||||||
|
export function listDeptTree(params: DeptParam) {
|
||||||
|
return axios.get<TreeNodeData[]>(`${BASE_URL}/tree/dept`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listMenuTree(params: MenuParam) {
|
||||||
|
return axios.get<TreeNodeData[]>(`${BASE_URL}/tree/menu`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listRoleDict(params: RoleParam) {
|
||||||
|
return axios.get<LabelValueState[]>(`${BASE_URL}/dict/role`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listDict(code: string) {
|
||||||
|
return axios.get<LabelValueState[]>(`${BASE_URL}/dict/${code}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listOption(params: OptionParam) {
|
||||||
|
return axios.get<LabelValueState[]>(`${BASE_URL}/option`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function upload(data: FormData) {
|
||||||
|
return axios.post(`${BASE_URL}/file`, data);
|
||||||
|
}
|
21
src/api/demo/form.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export interface BaseInfoModel {
|
||||||
|
activityName: string;
|
||||||
|
channelType: string;
|
||||||
|
promotionTime: string[];
|
||||||
|
promoteLink: string;
|
||||||
|
}
|
||||||
|
export interface ChannelInfoModel {
|
||||||
|
advertisingSource: string;
|
||||||
|
advertisingMedia: string;
|
||||||
|
keyword: string[];
|
||||||
|
pushNotify: boolean;
|
||||||
|
advertisingContent: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UnitChannelModel = BaseInfoModel & ChannelInfoModel;
|
||||||
|
|
||||||
|
export function submitChannelForm(data: UnitChannelModel) {
|
||||||
|
return axios.post('/api/channel-form/submit', { data });
|
||||||
|
}
|
56
src/api/demo/list.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
import type { DescData } from '@arco-design/web-vue/es/descriptions/interface';
|
||||||
|
|
||||||
|
export interface PolicyRecord {
|
||||||
|
id: string;
|
||||||
|
number: number;
|
||||||
|
name: string;
|
||||||
|
contentType: 'img' | 'horizontalVideo' | 'verticalVideo';
|
||||||
|
filterType: 'artificial' | 'rules';
|
||||||
|
count: number;
|
||||||
|
status: 'online' | 'offline';
|
||||||
|
createdTime: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PolicyParams extends Partial<PolicyRecord> {
|
||||||
|
current: number;
|
||||||
|
pageSize: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PolicyListRes {
|
||||||
|
list: PolicyRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function queryPolicyList(params: PolicyParams) {
|
||||||
|
return axios.get<PolicyListRes>('/api/list/policy', {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceRecord {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
name?: string;
|
||||||
|
actionType?: string;
|
||||||
|
icon?: string;
|
||||||
|
data?: DescData[];
|
||||||
|
enable?: boolean;
|
||||||
|
expires?: boolean;
|
||||||
|
}
|
||||||
|
export function queryInspectionList() {
|
||||||
|
return axios.get('/api/list/quality-inspection');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function queryTheServiceList() {
|
||||||
|
return axios.get('/api/list/the-service');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function queryRulesPresetList() {
|
||||||
|
return axios.get('/api/list/rules-preset');
|
||||||
|
}
|
38
src/api/demo/message.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export interface MessageRecord {
|
||||||
|
id: number;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
subTitle: string;
|
||||||
|
avatar?: string;
|
||||||
|
content: string;
|
||||||
|
time: string;
|
||||||
|
status: 0 | 1;
|
||||||
|
messageType?: number;
|
||||||
|
}
|
||||||
|
export type MessageListType = MessageRecord[];
|
||||||
|
|
||||||
|
export function queryMessageList() {
|
||||||
|
return axios.get<MessageListType>('/api/message/list');
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MessageStatus {
|
||||||
|
ids: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setMessageStatus(data: MessageStatus) {
|
||||||
|
return axios.post<MessageListType>('/api/message/read', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChatRecord {
|
||||||
|
id: number;
|
||||||
|
username: string;
|
||||||
|
content: string;
|
||||||
|
time: string;
|
||||||
|
isCollect: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function queryChatList() {
|
||||||
|
return axios.get<ChatRecord[]>('/api/chat/list');
|
||||||
|
}
|
49
src/api/demo/profile.ts
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export interface ProfileBasicRes {
|
||||||
|
status: number;
|
||||||
|
video: {
|
||||||
|
mode: string;
|
||||||
|
acquisition: {
|
||||||
|
resolution: string;
|
||||||
|
frameRate: number;
|
||||||
|
};
|
||||||
|
encoding: {
|
||||||
|
resolution: string;
|
||||||
|
rate: {
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
default: number;
|
||||||
|
};
|
||||||
|
frameRate: number;
|
||||||
|
profile: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
audio: {
|
||||||
|
mode: string;
|
||||||
|
acquisition: {
|
||||||
|
channels: number;
|
||||||
|
};
|
||||||
|
encoding: {
|
||||||
|
channels: number;
|
||||||
|
rate: number;
|
||||||
|
profile: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function queryProfileBasic() {
|
||||||
|
return axios.get<ProfileBasicRes>('/api/profile/basic');
|
||||||
|
}
|
||||||
|
|
||||||
|
export type operationLogRes = Array<{
|
||||||
|
key: string;
|
||||||
|
contentNumber: string;
|
||||||
|
updateContent: string;
|
||||||
|
status: number;
|
||||||
|
updateTime: string;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export function queryOperationLog() {
|
||||||
|
return axios.get<operationLogRes>('/api/operation/log');
|
||||||
|
}
|
73
src/api/demo/visualization.ts
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { GeneralChart } from '@/types/global';
|
||||||
|
|
||||||
|
export interface ChartDataRecord {
|
||||||
|
x: string;
|
||||||
|
y: number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
export interface DataChainGrowth {
|
||||||
|
quota: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DataChainGrowthRes {
|
||||||
|
count: number;
|
||||||
|
growth: number;
|
||||||
|
chartData: {
|
||||||
|
xAxis: string[];
|
||||||
|
data: { name: string; value: number[] };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export function queryDataChainGrowth(data: DataChainGrowth) {
|
||||||
|
return axios.post<DataChainGrowthRes>('/api/data-chain-growth', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PopularAuthorRes {
|
||||||
|
list: {
|
||||||
|
ranking: number;
|
||||||
|
author: string;
|
||||||
|
contentCount: number;
|
||||||
|
clickCount: number;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function queryPopularAuthor() {
|
||||||
|
return axios.get<PopularAuthorRes>('/api/popular-author/list');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContentPublishRecord {
|
||||||
|
x: string[];
|
||||||
|
y: number[];
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function queryContentPublish() {
|
||||||
|
return axios.get<ContentPublishRecord[]>('/api/content-publish');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function queryContentPeriodAnalysis() {
|
||||||
|
return axios.get<GeneralChart>('/api/content-period-analysis');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PublicOpinionAnalysis {
|
||||||
|
quota: string;
|
||||||
|
}
|
||||||
|
export interface PublicOpinionAnalysisRes {
|
||||||
|
count: number;
|
||||||
|
growth: number;
|
||||||
|
chartData: ChartDataRecord[];
|
||||||
|
}
|
||||||
|
export function queryPublicOpinionAnalysis(data: DataChainGrowth) {
|
||||||
|
return axios.post<PublicOpinionAnalysisRes>(
|
||||||
|
'/api/public-opinion-analysis',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export interface DataOverviewRes {
|
||||||
|
xAxis: string[];
|
||||||
|
data: Array<{ name: string; value: number[]; count: number }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function queryDataOverview() {
|
||||||
|
return axios.get<DataOverviewRes>('/api/data-overview');
|
||||||
|
}
|
107
src/api/monitor/log.ts
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/monitor/log';
|
||||||
|
|
||||||
|
export interface LogRecord {
|
||||||
|
id?: number;
|
||||||
|
ip: string;
|
||||||
|
address: string;
|
||||||
|
browser: string;
|
||||||
|
os: string;
|
||||||
|
createTime: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LoginLogRecord extends LogRecord {
|
||||||
|
description: string;
|
||||||
|
status: number;
|
||||||
|
errorMsg: string;
|
||||||
|
createUserString: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OperationLogRecord extends LogRecord {
|
||||||
|
module: string;
|
||||||
|
description: string;
|
||||||
|
status: number;
|
||||||
|
errorMsgString: string;
|
||||||
|
createUserString: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SystemLogRecord extends LogRecord {
|
||||||
|
statusCode: number;
|
||||||
|
requestMethod: string;
|
||||||
|
requestUrl: string;
|
||||||
|
timeTaken: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SystemLogDetailRecord extends SystemLogRecord {
|
||||||
|
requestHeaders: string;
|
||||||
|
requestBody: string;
|
||||||
|
responseHeaders: string;
|
||||||
|
responseBody: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LoginLogParam extends Partial<LoginLogRecord> {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
sort: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LoginLogListRes {
|
||||||
|
list: LoginLogRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listLoginLog(params: LoginLogParam) {
|
||||||
|
return axios.get<LoginLogListRes>(`${BASE_URL}/login`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OperationLogParam extends Partial<OperationLogRecord> {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
sort: Array<string>;
|
||||||
|
uid?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OperationLogListRes {
|
||||||
|
list: OperationLogRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listOperationLog(params: OperationLogParam) {
|
||||||
|
return axios.get<OperationLogListRes>(`${BASE_URL}/operation`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SystemLogParam extends Partial<SystemLogRecord> {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
sort: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SystemLogListRes {
|
||||||
|
list: SystemLogRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listSystemLog(params: SystemLogParam) {
|
||||||
|
return axios.get<SystemLogListRes>(`${BASE_URL}/system`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSystemLog(id: number) {
|
||||||
|
return axios.get<SystemLogDetailRecord>(`${BASE_URL}/system/${id}`);
|
||||||
|
}
|
39
src/api/monitor/online.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/monitor/online/user';
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
token: string;
|
||||||
|
username: string;
|
||||||
|
nickname: string;
|
||||||
|
ip: string;
|
||||||
|
address: string;
|
||||||
|
browser: string;
|
||||||
|
os: string;
|
||||||
|
loginTime: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam extends Partial<DataRecord> {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
sort: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListRes {
|
||||||
|
list: DataRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<ListRes>(BASE_URL, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kickout(token: string) {
|
||||||
|
return axios.delete(`${BASE_URL}/${token}`);
|
||||||
|
}
|
59
src/api/system/announcement.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/announcement';
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
id?: number;
|
||||||
|
title?: string;
|
||||||
|
content?: string;
|
||||||
|
status?: number;
|
||||||
|
type?: string;
|
||||||
|
effectiveTime?: string;
|
||||||
|
terminateTime?: string;
|
||||||
|
createUser?: string;
|
||||||
|
createTime?: string;
|
||||||
|
updateUser?: string;
|
||||||
|
updateTime?: string;
|
||||||
|
createUserString?: string;
|
||||||
|
updateUserString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
title?: string;
|
||||||
|
status?: number;
|
||||||
|
type?: string;
|
||||||
|
page?: number;
|
||||||
|
size?: number;
|
||||||
|
sort?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListRes {
|
||||||
|
list: DataRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<ListRes>(`${BASE_URL}`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get(id: number) {
|
||||||
|
return axios.get<DataRecord>(`${BASE_URL}/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function add(req: DataRecord) {
|
||||||
|
return axios.post(BASE_URL, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function update(req: DataRecord, id: number) {
|
||||||
|
return axios.put(`${BASE_URL}/${id}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids: number | Array<number>) {
|
||||||
|
return axios.delete(`${BASE_URL}/${ids}`);
|
||||||
|
}
|
39
src/api/system/config.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/option';
|
||||||
|
|
||||||
|
export interface BasicConfigRecord {
|
||||||
|
site_title?: string;
|
||||||
|
site_copyright?: string;
|
||||||
|
site_logo?: string;
|
||||||
|
site_favicon?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
name?: string;
|
||||||
|
code: string;
|
||||||
|
value: string;
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
code?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<DataRecord[]>(`${BASE_URL}`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function save(req: DataRecord[]) {
|
||||||
|
return axios.patch(`${BASE_URL}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetValue(params: ListParam) {
|
||||||
|
return axios.patch(`${BASE_URL}/value`, params);
|
||||||
|
}
|
51
src/api/system/dept.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/dept';
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
id?: number;
|
||||||
|
name?: string;
|
||||||
|
parentId?: number;
|
||||||
|
description?: string;
|
||||||
|
sort?: number;
|
||||||
|
status?: number;
|
||||||
|
isSystem?: boolean;
|
||||||
|
createUserString?: string;
|
||||||
|
createTime?: string;
|
||||||
|
updateUserString?: string;
|
||||||
|
updateTime?: string;
|
||||||
|
children?: Array<DataRecord>;
|
||||||
|
parentName?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
name?: string;
|
||||||
|
status?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<DataRecord[]>(`${BASE_URL}/tree`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get(id: number) {
|
||||||
|
return axios.get<DataRecord>(`${BASE_URL}/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function add(req: DataRecord) {
|
||||||
|
return axios.post(BASE_URL, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function update(req: DataRecord, id: number) {
|
||||||
|
return axios.put(`${BASE_URL}/${id}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids: number | Array<number>) {
|
||||||
|
return axios.delete(`${BASE_URL}/${ids}`);
|
||||||
|
}
|
57
src/api/system/dict-item.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/dict/item';
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
id?: number;
|
||||||
|
label?: string;
|
||||||
|
value?: string;
|
||||||
|
color?: string;
|
||||||
|
sort?: number;
|
||||||
|
description?: string;
|
||||||
|
dictId?: number;
|
||||||
|
createUser?: string;
|
||||||
|
createTime?: string;
|
||||||
|
updateUser?: string;
|
||||||
|
updateTime?: string;
|
||||||
|
createUserString?: string;
|
||||||
|
updateUserString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
dictId?: number;
|
||||||
|
page?: number;
|
||||||
|
size?: number;
|
||||||
|
sort?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListRes {
|
||||||
|
list: DataRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<ListRes>(`${BASE_URL}`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get(id: number) {
|
||||||
|
return axios.get<DataRecord>(`${BASE_URL}/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function add(req: DataRecord) {
|
||||||
|
return axios.post(BASE_URL, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function update(req: DataRecord, id: number) {
|
||||||
|
return axios.put(`${BASE_URL}/${id}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids: number | Array<number>) {
|
||||||
|
return axios.delete(`${BASE_URL}/${ids}`);
|
||||||
|
}
|
55
src/api/system/dict.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/dict';
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
id?: number;
|
||||||
|
name?: string;
|
||||||
|
code?: string;
|
||||||
|
description?: string;
|
||||||
|
isSystem?: boolean;
|
||||||
|
createUser?: string;
|
||||||
|
createTime?: string;
|
||||||
|
updateUser?: string;
|
||||||
|
updateTime?: string;
|
||||||
|
createUserString?: string;
|
||||||
|
updateUserString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
name?: string;
|
||||||
|
page?: number;
|
||||||
|
size?: number;
|
||||||
|
sort?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListRes {
|
||||||
|
list: DataRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<ListRes>(`${BASE_URL}`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get(id: number) {
|
||||||
|
return axios.get<DataRecord>(`${BASE_URL}/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function add(req: DataRecord) {
|
||||||
|
return axios.post(BASE_URL, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function update(req: DataRecord, id: number) {
|
||||||
|
return axios.put(`${BASE_URL}/${id}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids: number | Array<number>) {
|
||||||
|
return axios.delete(`${BASE_URL}/${ids}`);
|
||||||
|
}
|
47
src/api/system/file.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/file';
|
||||||
|
|
||||||
|
export interface FileItem {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
size: number;
|
||||||
|
url: string;
|
||||||
|
extension: string;
|
||||||
|
type?: string;
|
||||||
|
storageId?: string;
|
||||||
|
createUser?: string;
|
||||||
|
createTime?: string;
|
||||||
|
updateUser?: string;
|
||||||
|
updateTime: string;
|
||||||
|
createUserString?: string;
|
||||||
|
updateUserString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
name?: string;
|
||||||
|
type?: string;
|
||||||
|
sort?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<FileItem[]>(`${BASE_URL}/list`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FileItemUpdate {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function update(req: FileItemUpdate, id: string) {
|
||||||
|
return axios.put(`${BASE_URL}/${id}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids: string | Array<string>) {
|
||||||
|
return axios.delete(`${BASE_URL}/${ids}`);
|
||||||
|
}
|
57
src/api/system/menu.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/menu';
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
id?: number;
|
||||||
|
title?: string;
|
||||||
|
parentId?: number;
|
||||||
|
type?: number;
|
||||||
|
path?: string;
|
||||||
|
name?: string;
|
||||||
|
component?: string;
|
||||||
|
icon?: string;
|
||||||
|
isExternal?: boolean;
|
||||||
|
isCache?: boolean;
|
||||||
|
isHidden?: boolean;
|
||||||
|
permission?: string;
|
||||||
|
sort?: number;
|
||||||
|
status?: number;
|
||||||
|
createUserString?: string;
|
||||||
|
createTime?: string;
|
||||||
|
updateUserString?: string;
|
||||||
|
updateTime?: string;
|
||||||
|
children?: Array<DataRecord>;
|
||||||
|
parentName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
name?: string;
|
||||||
|
status?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<DataRecord[]>(`${BASE_URL}/tree`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get(id: number) {
|
||||||
|
return axios.get<DataRecord>(`${BASE_URL}/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function add(req: DataRecord) {
|
||||||
|
return axios.post(BASE_URL, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function update(req: DataRecord, id: number) {
|
||||||
|
return axios.put(`${BASE_URL}/${id}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids: number | Array<number>) {
|
||||||
|
return axios.delete(`${BASE_URL}/${ids}`);
|
||||||
|
}
|
60
src/api/system/message.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/message';
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
content: string;
|
||||||
|
type: number;
|
||||||
|
createUserString?: string;
|
||||||
|
createTime: string;
|
||||||
|
isRead: boolean;
|
||||||
|
readTime: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
title?: string;
|
||||||
|
type?: number;
|
||||||
|
isRead?: boolean;
|
||||||
|
page?: number;
|
||||||
|
size?: number;
|
||||||
|
sort?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListRes {
|
||||||
|
list: DataRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<ListRes>(`${BASE_URL}`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids: number | Array<number>) {
|
||||||
|
return axios.delete(`${BASE_URL}/${ids}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function read(ids: Array<number>) {
|
||||||
|
return axios.patch(`${BASE_URL}/read?ids=${ids}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MessageTypeUnreadRes {
|
||||||
|
type: number;
|
||||||
|
count: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MessageUnreadRes {
|
||||||
|
total: number;
|
||||||
|
details: MessageTypeUnreadRes[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function countUnread(detail: boolean) {
|
||||||
|
return axios.get<MessageUnreadRes>(`${BASE_URL}/unread?detail=${detail}`);
|
||||||
|
}
|
60
src/api/system/role.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/role';
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
id?: number;
|
||||||
|
name?: string;
|
||||||
|
code?: string;
|
||||||
|
sort?: number;
|
||||||
|
description?: string;
|
||||||
|
menuIds?: Array<number>;
|
||||||
|
dataScope?: number;
|
||||||
|
deptIds?: Array<number>;
|
||||||
|
status?: number;
|
||||||
|
isSystem?: boolean;
|
||||||
|
createUserString?: string;
|
||||||
|
createTime?: string;
|
||||||
|
updateUserString?: string;
|
||||||
|
updateTime?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
name?: string;
|
||||||
|
status?: number;
|
||||||
|
page?: number;
|
||||||
|
size?: number;
|
||||||
|
sort?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListRes {
|
||||||
|
list: DataRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<ListRes>(`${BASE_URL}`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get(id: number) {
|
||||||
|
return axios.get<DataRecord>(`${BASE_URL}/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function add(req: DataRecord) {
|
||||||
|
return axios.post(BASE_URL, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function update(req: DataRecord, id: number) {
|
||||||
|
return axios.put(`${BASE_URL}/${id}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids: number | Array<number>) {
|
||||||
|
return axios.delete(`${BASE_URL}/${ids}`);
|
||||||
|
}
|
64
src/api/system/storage.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/storage';
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
id?: number;
|
||||||
|
name?: string;
|
||||||
|
code?: string;
|
||||||
|
type?: number;
|
||||||
|
accessKey?: string;
|
||||||
|
secretKey?: string;
|
||||||
|
endpoint?: string;
|
||||||
|
bucketName?: string;
|
||||||
|
domain?: string;
|
||||||
|
description?: string;
|
||||||
|
isDefault?: boolean;
|
||||||
|
sort?: number;
|
||||||
|
status?: number;
|
||||||
|
createUser?: string;
|
||||||
|
createTime?: string;
|
||||||
|
updateUser?: string;
|
||||||
|
updateTime?: string;
|
||||||
|
createUserString?: string;
|
||||||
|
updateUserString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
name?: string;
|
||||||
|
status?: string;
|
||||||
|
page?: number;
|
||||||
|
size?: number;
|
||||||
|
sort?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PageRes<T> {
|
||||||
|
total: number;
|
||||||
|
list: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<PageRes<DataRecord[]>>(`${BASE_URL}`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get(id: number) {
|
||||||
|
return axios.get<DataRecord>(`${BASE_URL}/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function add(req: DataRecord) {
|
||||||
|
return axios.post(BASE_URL, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function update(req: DataRecord, id: number) {
|
||||||
|
return axios.put(`${BASE_URL}/${id}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids: number | Array<number>) {
|
||||||
|
return axios.delete(`${BASE_URL}/${ids}`);
|
||||||
|
}
|
86
src/api/system/user-center.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/user';
|
||||||
|
|
||||||
|
export interface BasicInfoModel {
|
||||||
|
username: string;
|
||||||
|
nickname: string;
|
||||||
|
gender: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AvatarRes {
|
||||||
|
avatar: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface cropperOptions {
|
||||||
|
autoCrop: boolean; // 是否默认生成截图框
|
||||||
|
autoCropWidth: number; // 默认生成截图框宽度
|
||||||
|
autoCropHeight: number; // 默认生成截图框高度
|
||||||
|
canMove: boolean; // 上传图片是否可以移动 (默认:true)
|
||||||
|
centerBox: boolean; // 截图框是否被限制在图片里面 (默认:false)
|
||||||
|
full: boolean; // 是否输出原图比例的截图 选true生成的图片会非常大 (默认:false)
|
||||||
|
fixed: boolean; // 是否开启截图框宽高固定比例 (默认:false)
|
||||||
|
fixedBox: boolean; // 固定截图框大小 不允许改变
|
||||||
|
img: string | ArrayBuffer | null; // 裁剪图片的地址
|
||||||
|
outputSize: number; // 裁剪生成图片的质量 (默认:1)
|
||||||
|
outputType: string; // 默认生成截图为PNG格式
|
||||||
|
}
|
||||||
|
|
||||||
|
export function uploadAvatar(data: FormData) {
|
||||||
|
return axios.post<AvatarRes>(`${BASE_URL}/avatar`, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserBasicInfoUpdateReq {
|
||||||
|
nickname: string;
|
||||||
|
gender: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateBasicInfo(req: UserBasicInfoUpdateReq) {
|
||||||
|
return axios.patch(`${BASE_URL}/basic/info`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserPasswordUpdateReq {
|
||||||
|
oldPassword: string;
|
||||||
|
newPassword: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updatePassword(req: UserPasswordUpdateReq) {
|
||||||
|
return axios.patch(`${BASE_URL}/password`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserPhoneUpdateReq {
|
||||||
|
newPhone: string;
|
||||||
|
captcha: string;
|
||||||
|
currentPassword: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updatePhone(req: UserPhoneUpdateReq) {
|
||||||
|
return axios.patch(`${BASE_URL}/phone`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserEmailUpdateReq {
|
||||||
|
newEmail: string;
|
||||||
|
captcha: string;
|
||||||
|
currentPassword: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateEmail(req: UserEmailUpdateReq) {
|
||||||
|
return axios.patch(`${BASE_URL}/email`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserSocialBindRecord {
|
||||||
|
source: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listSocial() {
|
||||||
|
return axios.get<UserSocialBindRecord[]>(`${BASE_URL}/social`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function bindSocial(source: string, req: any) {
|
||||||
|
return axios.post(`${BASE_URL}/social/${source}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unbindSocial(source: string) {
|
||||||
|
return axios.delete(`${BASE_URL}/social/${source}`);
|
||||||
|
}
|
77
src/api/system/user.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/user';
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
id?: number;
|
||||||
|
username?: string;
|
||||||
|
nickname?: string;
|
||||||
|
gender?: number;
|
||||||
|
email?: string;
|
||||||
|
phone?: string;
|
||||||
|
description?: string;
|
||||||
|
status?: number;
|
||||||
|
isSystem?: boolean;
|
||||||
|
pwdResetTime?: string;
|
||||||
|
createUserString?: string;
|
||||||
|
createTime?: string;
|
||||||
|
updateUserString?: string;
|
||||||
|
updateTime?: string;
|
||||||
|
deptId?: number;
|
||||||
|
deptName?: string;
|
||||||
|
roleIds?: Array<number>;
|
||||||
|
roleNames?: Array<string>;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
username?: string;
|
||||||
|
status?: number;
|
||||||
|
createTime?: Array<string>;
|
||||||
|
page?: number;
|
||||||
|
size?: number;
|
||||||
|
sort?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListRes {
|
||||||
|
list: DataRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<ListRes>(`${BASE_URL}`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get(id: number) {
|
||||||
|
return axios.get<DataRecord>(`${BASE_URL}/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function add(req: DataRecord) {
|
||||||
|
return axios.post(BASE_URL, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function update(req: DataRecord, id: number) {
|
||||||
|
return axios.put(`${BASE_URL}/${id}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids: number | Array<number>) {
|
||||||
|
return axios.delete(`${BASE_URL}/${ids}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetPassword(id: number) {
|
||||||
|
return axios.patch(`${BASE_URL}/${id}/password`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateUserRoleReq {
|
||||||
|
roleIds?: Array<number>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateUserRole(req: UpdateUserRoleReq, id: number) {
|
||||||
|
return axios.patch(`${BASE_URL}/${id}/role`, req);
|
||||||
|
}
|
92
src/api/tool/generator.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/tool/generator';
|
||||||
|
|
||||||
|
export interface TableRecord {
|
||||||
|
tableName: string;
|
||||||
|
comment?: string;
|
||||||
|
engine: string;
|
||||||
|
charset: string;
|
||||||
|
createTime?: string;
|
||||||
|
isConfiged: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TableParam {
|
||||||
|
tableName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TableListRes {
|
||||||
|
list: TableRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listTable(params: TableParam) {
|
||||||
|
return axios.get<TableListRes>(`${BASE_URL}/table`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FieldConfigRecord {
|
||||||
|
tableName: string;
|
||||||
|
columnName: string;
|
||||||
|
columnType: string;
|
||||||
|
fieldName: string;
|
||||||
|
fieldType: string;
|
||||||
|
comment: string;
|
||||||
|
isRequired: boolean;
|
||||||
|
showInList: boolean;
|
||||||
|
showInForm: boolean;
|
||||||
|
showInQuery: boolean;
|
||||||
|
formType: string;
|
||||||
|
queryType: string;
|
||||||
|
createTime?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listFieldConfig(tableName: string, requireSync: boolean) {
|
||||||
|
return axios.get<FieldConfigRecord[]>(
|
||||||
|
`${BASE_URL}/field/${tableName}?requireSync=${requireSync}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GenConfigRecord {
|
||||||
|
tableName: string;
|
||||||
|
moduleName: string;
|
||||||
|
packageName: string;
|
||||||
|
frontendPath: string;
|
||||||
|
businessName: string;
|
||||||
|
author: string;
|
||||||
|
tablePrefix: string;
|
||||||
|
isOverride: boolean;
|
||||||
|
createTime?: string;
|
||||||
|
updateTime?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGenConfig(tableName: string) {
|
||||||
|
return axios.get<GenConfigRecord>(`${BASE_URL}/config/${tableName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GeneratorConfigRecord {
|
||||||
|
genConfig: GenConfigRecord;
|
||||||
|
fieldConfigs: FieldConfigRecord[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function saveConfig(tableName: string, req: GeneratorConfigRecord) {
|
||||||
|
return axios.post(`${BASE_URL}/config/${tableName}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GeneratePreviewRecord {
|
||||||
|
fileName: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function preview(tableName: string) {
|
||||||
|
return axios.get<GeneratePreviewRecord[]>(`${BASE_URL}/preview/${tableName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generate(tableName: string) {
|
||||||
|
return axios.post(`${BASE_URL}/${tableName}`);
|
||||||
|
}
|
BIN
src/assets/icons/png/data.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
src/assets/icons/png/hot.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
src/assets/icons/png/popularity.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
src/assets/icons/png/same-city.png
Normal file
After Width: | Height: | Size: 13 KiB |
1
src/assets/icons/svg/account.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 48 48" fill="none" stroke="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="M43 42a1 1 0 011 1v2a1 1 0 01-1 1H29a1 1 0 01-1-1v-2a1 1 0 011-1h14zM24.05 26a1 1 0 01.993.883l.007.117v2a1 1 0 01-.884.993L24.05 30H16c-3.73 0-6.86 2.55-7.75 6a8.294 8.294 0 00-.24 1.588L8 38v2h16.05a1 1 0 01.993.883l.007.117v2a1 1 0 01-.884.993L24.05 44H6a2.003 2.003 0 01-1.994-1.85L4 42v-4c0-6.525 5.206-11.834 11.695-11.996L16 26h8.05zM43 34a1 1 0 011 1v2a1 1 0 01-1 1H29a1 1 0 01-1-1v-2a1 1 0 011-1h14zm0-8a1 1 0 011 1v2a1 1 0 01-1 1H29a1 1 0 01-1-1v-2a1 1 0 011-1h14zM21 3c5.52 0 10 4.477 10 10s-4.48 10-10 10-10-4.477-10-10S15.48 3 21 3zm0 4c-3.31 0-6 2.686-6 6s2.69 6 6 6 6-2.686 6-6-2.69-6-6-6z" fill="currentColor"/></svg>
|
After Width: | Height: | Size: 764 B |
1
src/assets/icons/svg/advertising.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="48" height="48" viewBox="0 0 32 32" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="M25.947 7.967a.835.835 0 00-1.17-.764L6.378 15.28a.665.665 0 01-.534-1.218l18.397-8.077a2.165 2.165 0 013.035 1.982v15.508a2.165 2.165 0 01-2.952 2.017L5.87 18.29a.665.665 0 01.484-1.239l18.455 7.202a.835.835 0 001.138-.778V7.967z" fill="currentColor"/><path fill-rule="evenodd" clip-rule="evenodd" d="M18.407 23.399a4.665 4.665 0 01-8.672-3.444l.038-.096a.665.665 0 111.236.491l-.038.096a3.335 3.335 0 006.2 2.462l.037-.096a.665.665 0 011.237.491l-.038.096zM5.734 11.306c.368 0 .665.297.665.665v8.5a.665.665 0 01-1.33 0v-8.5c0-.368.298-.665.665-.665z" fill="currentColor"/></svg>
|
After Width: | Height: | Size: 697 B |
1
src/assets/icons/svg/align-center.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M44 9H4m38 20H6m28-10H14m20 20H14"/></svg>
|
After Width: | Height: | Size: 127 B |
1
src/assets/icons/svg/align-left.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M44 9H4m36 20H4m21-10H4m21 20H4"/></svg>
|
After Width: | Height: | Size: 125 B |
1
src/assets/icons/svg/align-right.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M4 9h40M8 29h36M23 19h21M23 39h21"/></svg>
|
After Width: | Height: | Size: 127 B |
1
src/assets/icons/svg/announcement.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="48" height="48" viewBox="0 0 48 48" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="M25.657 3.69l.168.113L35.783 11H42a2 2 0 012 2v28a2 2 0 01-2 2H6a2 2 0 01-2-2V13a2 2 0 012-2h6.352l9.958-7.197a3 3 0 013.347-.114zM40 15H8v24h32V15zM25 30a1 1 0 00-1-1H13a1 1 0 00-1 1v2a1 1 0 001 1h11a1 1 0 001-1v-2zm10-9a1 1 0 011 1v2a1 1 0 01-1 1H13a1 1 0 01-1-1v-2a1 1 0 011-1h22zM19.18 11l4.888-3.532L28.954 11H19.18z" fill="currentColor"/></svg>
|
After Width: | Height: | Size: 467 B |
1
src/assets/icons/svg/anonymity.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="48" height="48" viewBox="0 0 28 28" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="M16.333 5.333a6 6 0 00-3.246 11.047c-2.308.562-4.32 1.746-6.025 3.548a2.667 2.667 0 00-.729 1.832v1.073l.006.165a2.5 2.5 0 002.494 2.335h7.642l.099-.007A.667.667 0 0016.475 24H8.833l-.127-.007a1.167 1.167 0 01-1.04-1.16V21.76l.009-.145c.031-.287.156-.558.356-.77 2.217-2.346 4.988-3.512 8.354-3.512h.026a6 6 0 00-.078-12zm0 1.334a4.667 4.667 0 110 9.333 4.667 4.667 0 010-9.333zm8.714 12.214a.667.667 0 00-1.008-.868l-4.1 4.1-2.138-2.139-.075-.064a.667.667 0 00-.868 1.007l2.61 2.61a.667.667 0 00.943 0l4.571-4.571.065-.075z" fill="currentColor"/></svg>
|
After Width: | Height: | Size: 670 B |
1
src/assets/icons/svg/apps.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path stroke="#4E5969" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M7 7h13v13H7zM28 7h13v13H28zM7 28h13v13H7zM28 28h13v13H28z"/></svg>
|
After Width: | Height: | Size: 233 B |
1
src/assets/icons/svg/archive.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><rect x="9" y="18" width="30" height="22" rx="1"/><path d="M6 9a1 1 0 011-1h34a1 1 0 011 1v8a1 1 0 01-1 1H7a1 1 0 01-1-1V9zM19 27h10"/></svg>
|
After Width: | Height: | Size: 217 B |
1
src/assets/icons/svg/arrow-down.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M11.27 27.728l12.728 12.728 12.728-12.728M24 5v34.295"/></svg>
|
After Width: | Height: | Size: 147 B |
1
src/assets/icons/svg/arrow-fall.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M24.008 41.99a.01.01 0 01-.016 0l-9.978-11.974A.01.01 0 0114.02 30H33.98a.01.01 0 01.007.016l-9.978 11.975z"/><path d="M24 42L14 30h20L24 42z" fill="#4E5969"/><path stroke="#4E5969" stroke-width="4" d="M22 6h4v26h-4z"/><path fill="#4E5969" d="M22 6h4v26h-4z"/></svg>
|
After Width: | Height: | Size: 351 B |
1
src/assets/icons/svg/arrow-left.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M20.272 11.27L7.544 23.998l12.728 12.728M43 24H8.705"/></svg>
|
After Width: | Height: | Size: 146 B |
1
src/assets/icons/svg/arrow-right.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M27.728 11.27l12.728 12.728-12.728 12.728M5 24h34.295"/></svg>
|
After Width: | Height: | Size: 147 B |
1
src/assets/icons/svg/arrow-rise.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M23.992 6.01a.01.01 0 01.016 0l9.978 11.974a.01.01 0 01-.007.016H14.02a.01.01 0 01-.007-.016l9.978-11.975z"/><path d="M24 6l10 12H14L24 6z" fill="#4E5969"/><path stroke="#4E5969" stroke-width="4" d="M26 42h-4V16h4z"/><path fill="#4E5969" d="M26 42h-4V16h4z"/></svg>
|
After Width: | Height: | Size: 350 B |
1
src/assets/icons/svg/arrow-up.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M11.27 20.272L23.998 7.544l12.728 12.728M24 43V8.705"/></svg>
|
After Width: | Height: | Size: 146 B |
1
src/assets/icons/svg/at.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M31 23a7 7 0 11-14 0 7 7 0 0114 0zm0 0c0 3.038 2.462 6.5 5.5 6.5A5.5 5.5 0 0042 24c0-9.941-8.059-18-18-18S6 14.059 6 24s8.059 18 18 18c4.244 0 8.145-1.469 11.222-3.925"/></svg>
|
After Width: | Height: | Size: 261 B |
1
src/assets/icons/svg/attachment.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M29.037 15.236s-9.174 9.267-11.48 11.594c-2.305 2.327-1.646 4.987-.329 6.316 1.317 1.33 3.994 1.953 6.258-.332L37.32 18.851c3.623-3.657 2.092-8.492 0-10.639-2.093-2.147-6.916-3.657-10.54 0L11.3 23.838c-3.623 3.657-3.953 10.638.329 14.96 4.282 4.322 11.115 4.105 14.821.333 3.706-3.773 8.74-8.822 11.224-11.33"/></svg>
|
After Width: | Height: | Size: 402 B |
1
src/assets/icons/svg/backward.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M38.293 36.293L26.707 24.707a1 1 0 010-1.414l11.586-11.586c.63-.63 1.707-.184 1.707.707v23.172c0 .89-1.077 1.337-1.707.707zM21 12.414v23.172c0 .89-1.077 1.337-1.707.707L7.707 24.707a1 1 0 010-1.414l11.586-11.586c.63-.63 1.707-.184 1.707.707z"/></svg>
|
After Width: | Height: | Size: 335 B |
1
src/assets/icons/svg/bar-chart.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M41 7H29v34h12V7ZM29 18H18v23h11V18ZM18 29H7v12h11V29Z"></path></svg>
|
After Width: | Height: | Size: 154 B |
1
src/assets/icons/svg/behavior-anal.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 48 48" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="M23.5 5C33.717 5 42 13.283 42 23.5c0 4.388-1.528 8.42-4.08 11.59l5.808 5.81a1 1 0 010 1.414l-1.414 1.414a1 1 0 01-1.414 0l-5.81-5.808A18.422 18.422 0 0123.5 42C13.283 42 5 33.717 5 23.5S13.283 5 23.5 5zm0 4C15.492 9 9 15.492 9 23.5S15.492 38 23.5 38 38 31.508 38 23.5 31.508 9 23.5 9zm7.832 6.391l1.732 1a1 1 0 01.366 1.366l-5.5 9.526a1 1 0 01-1.261.419l-.105-.053-5.196-3-4 6.928a1 1 0 01-1.366.366l-1.732-1a1 1 0 01-.366-1.366l5.5-9.526a1 1 0 011.366-.366l5.196 3 4-6.928a1 1 0 011.366-.366z" fill="currentColor"/></svg>
|
After Width: | Height: | Size: 639 B |
1
src/assets/icons/svg/bg-colors.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M19 5.25L22.75 9m0 0l12.043 12.043a1 1 0 010 1.414L32 25.25 21.221 36.029a1 1 0 01-1.428-.014L9.443 25.25l-.763-.793a1 1 0 01.013-1.4L22.75 9zM6 42h36"/><path d="M11.791 25.25c-.881 0-1.332 1.058-.72 1.693l8.722 9.072a1 1 0 001.428.014L32 25.25H11.791z" fill="#4E5969"/><path fill-rule="evenodd" clip-rule="evenodd" d="M40.013 29.812L37.201 27l-2.812 2.812a4 4 0 105.624 0z" fill="#4E5969"/></svg>
|
After Width: | Height: | Size: 482 B |
1
src/assets/icons/svg/bold.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M13 24h12a8 8 0 100-16H13.2a.2.2 0 00-.2.2V24zm0 0h16a8 8 0 110 16H13.2a.2.2 0 01-.2-.2V24z"/></svg>
|
After Width: | Height: | Size: 185 B |
1
src/assets/icons/svg/book.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M24 13L7 7v28l17 6 17-6V7l-17 6zm0 0v27.5M19 18l-7-2.5M19 25l-7-2.5M19 32l-7-2.5M29 18l7-2.5M29 25l7-2.5M29 32l7-2.5" stroke="#4E5969" stroke-width="4" stroke-linejoin="round"/></svg>
|
After Width: | Height: | Size: 268 B |
1
src/assets/icons/svg/bookmark.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M16 16h16M16 24h8"></path><path d="M24 41H8V6h32v17"></path><path d="M30 29h11v13l-5.5-3.5L30 42V29Z"/></svg>
|
After Width: | Height: | Size: 194 B |
1
src/assets/icons/svg/branch.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M19 10a4 4 0 11-8 0 4 4 0 018 0zM38 10a4 4 0 11-8 0 4 4 0 018 0zM19 38a4 4 0 11-8 0 4 4 0 018 0zM15 15v15m0 3.5V30m0 0c0-5 19-7 19-15"/></svg>
|
After Width: | Height: | Size: 227 B |
1
src/assets/icons/svg/brush.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M33 13h7a1 1 0 011 1v12.14a1 1 0 01-.85.99l-21.3 3.24a1 1 0 00-.85.99V43"/><path d="M7 18V8c0-.552.444-1 .997-1H32.01c.552 0 .99.447.99 1v10.002A.998.998 0 0132 19H8a1 1 0 01-1-1z"/></svg>
|
After Width: | Height: | Size: 273 B |
1
src/assets/icons/svg/bug.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M35 27h8M5 27h8m0-9h22v13c0 6.075-4.925 11-11 11s-11-4.925-11-11V18z" stroke="#4E5969" stroke-width="4" stroke-linejoin="round"/><path d="M7 42v-.5a6.5 6.5 0 016.5-6.5M7 42v-.5M41 42v-.5a6.5 6.5 0 00-6.5-6.5M13 18h22M7 14a4 4 0 004 4h26a4 4 0 004-4M24 42V23M17 14a7 7 0 1114 0" stroke="#4E5969" stroke-width="4" stroke-linejoin="round"/></svg>
|
After Width: | Height: | Size: 428 B |
1
src/assets/icons/svg/bulb.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M30.8 32.465c.585-2.576 2.231-4.75 3.77-6.897A12.94 12.94 0 0037 18c0-7.18-5.82-13-13-13s-13 5.82-13 13c0 2.823.9 5.437 2.43 7.568 1.539 2.147 3.185 4.32 3.77 6.897l.623 2.756A1 1 0 0018.8 36H29.2a1 1 0 00.976-.779l.624-2.756zM17 42h14"/></svg>
|
After Width: | Height: | Size: 329 B |
1
src/assets/icons/svg/calendar.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M7 22h34M8 41h32a1 1 0 001-1V10a1 1 0 00-1-1H8a1 1 0 00-1 1v30a1 1 0 001 1zM34 5v8M14 5v8"/></svg>
|
After Width: | Height: | Size: 183 B |
1
src/assets/icons/svg/calendar_clock.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M7 22h34V10a1 1 0 00-1-1H8a1 1 0 00-1 1v30a1 1 0 001 1h18M34 5v8M14 5v8"/><path fill-rule="evenodd" clip-rule="evenodd" d="M36 44a9 9 0 100-18 9 9 0 000 18zm1.5-9.75V29h-3v8.25H42v-3h-4.5z" fill="#4E5969"/></svg>
|
After Width: | Height: | Size: 297 B |
1
src/assets/icons/svg/camera.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M6 13a1 1 0 011-1h34a1 1 0 011 1v26a1 1 0 01-1 1H7a1 1 0 01-1-1V13z"/><path d="M31 26a7 7 0 11-14 0 7 7 0 0114 0zM33 12l-1.862-3.724A.5.5 0 0030.691 8H17.309a.5.5 0 00-.447.276L15 12"/></svg>
|
After Width: | Height: | Size: 276 B |
1
src/assets/icons/svg/caret-down.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M24.937 34.829a1.2 1.2 0 01-1.874 0L9.56 17.949C8.93 17.165 9.49 16 10.497 16h27.006c1.007 0 1.566 1.164.937 1.95L24.937 34.829z" fill="#4E5969"/></svg>
|
After Width: | Height: | Size: 237 B |
1
src/assets/icons/svg/caret-left.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M13.171 24.937a1.2 1.2 0 010-1.874L30.051 9.56c.785-.629 1.949-.07 1.949.937v27.006c0 1.007-1.164 1.566-1.95.937L13.171 24.937z" fill="#4E5969"/></svg>
|
After Width: | Height: | Size: 236 B |
1
src/assets/icons/svg/caret-right.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M34.829 23.063c.6.48.6 1.394 0 1.874L17.949 38.44c-.785.629-1.949.07-1.949-.937V10.497c0-1.006 1.164-1.566 1.95-.937l16.879 13.503z" fill="#4E5969"/></svg>
|
After Width: | Height: | Size: 240 B |
1
src/assets/icons/svg/caret-up.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M23.063 13.171a1.2 1.2 0 011.874 0l13.503 16.88c.629.785.07 1.949-.937 1.949H10.497c-1.006 0-1.566-1.164-.937-1.95l13.503-16.879z" fill="#4E5969"/></svg>
|
After Width: | Height: | Size: 238 B |
1
src/assets/icons/svg/check-circle-f.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="4"><path d="M42 24c0 9.941-8.059 18-18 18S6 33.941 6 24 14.059 6 24 6s18 8.059 18 18z" fill="#4E5969"/><path d="M15 22l7 7 11.5-11.5" stroke="#fff" stroke-width="4"/></svg>
|
After Width: | Height: | Size: 245 B |