mirror of
https://github.com/vbenjs/gf-vben-admin.git
synced 2025-01-23 11:50:20 +08:00
Merge remote-tracking branch 'vben/main' into Gf-Vben-Admin
# Conflicts: # .husky/pre-commit # package.json # yarn.lock
This commit is contained in:
commit
5b06412976
@ -74,5 +74,6 @@ module.exports = defineConfig({
|
||||
math: 'always',
|
||||
},
|
||||
],
|
||||
'vue/multi-word-component-names': 'off'
|
||||
},
|
||||
});
|
||||
|
@ -2,5 +2,5 @@ ports:
|
||||
- port: 3344
|
||||
onOpen: open-preview
|
||||
tasks:
|
||||
- init: yarn
|
||||
command: yarn dev
|
||||
- init: pnpm install
|
||||
command: pnpm run dev
|
||||
|
2
.vscode/extensions.json
vendored
2
.vscode/extensions.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"octref.vetur",
|
||||
"johnsoncodehk.volar",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"stylelint.vscode-stylelint",
|
||||
"esbenp.prettier-vscode",
|
||||
|
16
.vscode/settings.json
vendored
16
.vscode/settings.json
vendored
@ -6,15 +6,8 @@
|
||||
//===========================================
|
||||
//============= Editor ======================
|
||||
//===========================================
|
||||
"explorer.openEditors.visible": 0,
|
||||
"editor.tabSize": 2,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"diffEditor.ignoreTrimWhitespace": false,
|
||||
//===========================================
|
||||
//============= Other =======================
|
||||
//===========================================
|
||||
"breadcrumbs.enabled": true,
|
||||
"open-in-browser.default": "chrome",
|
||||
//===========================================
|
||||
//============= files =======================
|
||||
//===========================================
|
||||
@ -69,15 +62,9 @@
|
||||
},
|
||||
"stylelint.enable": true,
|
||||
"stylelint.packageManager": "yarn",
|
||||
"liveServer.settings.donotShowInfoMsg": true,
|
||||
"telemetry.enableCrashReporter": false,
|
||||
"workbench.settings.enableNaturalLanguageSearch": false,
|
||||
"path-intellisense.mappings": {
|
||||
"/@/": "${workspaceRoot}/src"
|
||||
},
|
||||
"prettier.requireConfig": true,
|
||||
"typescript.updateImportsOnFileMove.enabled": "always",
|
||||
"workbench.sideBar.location": "left",
|
||||
"[javascriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
@ -150,6 +137,7 @@
|
||||
"lintstagedrc",
|
||||
"brotli",
|
||||
"tailwindcss",
|
||||
"sider"
|
||||
"sider",
|
||||
"pnpm"
|
||||
]
|
||||
}
|
||||
|
48
.yarnclean
48
.yarnclean
@ -1,48 +0,0 @@
|
||||
# test directories
|
||||
__tests__
|
||||
test
|
||||
tests
|
||||
powered-test
|
||||
|
||||
# asset directories
|
||||
docs
|
||||
doc
|
||||
website
|
||||
images
|
||||
assets
|
||||
|
||||
# examples
|
||||
example
|
||||
examples
|
||||
|
||||
# code coverage directories
|
||||
coverage
|
||||
.nyc_output
|
||||
|
||||
# build scripts
|
||||
Makefile
|
||||
Gulpfile.js
|
||||
Gruntfile.js
|
||||
|
||||
# configs
|
||||
appveyor.yml
|
||||
circle.yml
|
||||
codeship-services.yml
|
||||
codeship-steps.yml
|
||||
wercker.yml
|
||||
.tern-project
|
||||
.gitattributes
|
||||
.editorconfig
|
||||
.*ignore
|
||||
.eslintrc
|
||||
.jshintrc
|
||||
.flowconfig
|
||||
.documentup.json
|
||||
.yarn-metadata.json
|
||||
.travis.yml
|
||||
|
||||
# misc
|
||||
*.md
|
||||
|
||||
!istanbul-reports/lib/html/assets
|
||||
!istanbul-api/node_modules/istanbul-reports/lib/html/assets
|
@ -1,3 +1,37 @@
|
||||
## 2.8.0(2021-11.03)
|
||||
|
||||
### Upgrade Instructions
|
||||
|
||||
- Package manager changed from `yarn` to `pnpm`
|
||||
- Delete `node_modules` and `yarn.lock`, install `pnpm` globally
|
||||
- Execute `pnpm install`
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **Others**
|
||||
- The `VITE_PROXY` configuration in the `.env` file supports single quotes
|
||||
- Remove warnings during build
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **BasicTable**
|
||||
- Fix the issue that editable cells cannot be submitted in some cases
|
||||
- Fix the problem that the `inset` attribute does not work
|
||||
- Fix the problem that the performance of `useTable` and `reload` method `await` of `BasicTable` instance are inconsistent
|
||||
- Fix the issue that `clickToRowSelect` would ignore the disabled state of the row selection box
|
||||
- Fix the problem that the page of `BasicTable` will be reset in some cases
|
||||
- Modify the `deleteTableDataRecord` method
|
||||
- **BasicModal**
|
||||
- Fixed the problem that `Modal` could not be closed even when clicking on the mask and pressing the `Esc` key
|
||||
- Fixed the issue that clicking the close button and the blank area next to the maximize button would also cause `Modal` to close
|
||||
- **BasicTree** Fix the problem that the node slot does not work
|
||||
- **CodeEditor** Fix the problem that may cause `Build` failure
|
||||
- **BasicForm** Fix the problem that the content width of the custom FormItem component may be out of range
|
||||
- **ApiTreeSelect** Fix the problem that the change of `params` failed to trigger the re-request of api data
|
||||
- **Others** -Fixed an issue where multiple tabs would not jump to routing when closing tabs in some cases
|
||||
- Fix the issue that some components may cause abnormal hot update
|
||||
- Fix the problem that some sub-components of `antdv` will be reported in the build process when directly `import` part of the `antdv`, such as: TabPane, RadioGroup
|
||||
|
||||
## 2.7.2(2021-09-14)
|
||||
|
||||
### ✨ Features
|
||||
|
@ -1,4 +1,4 @@
|
||||
## [2.7.2](https://github.com/anncwb/vue-vben-admin/compare/v2.7.1...v2.7.2) (2021-09-13)
|
||||
## [2.8.0](https://github.com/anncwb/vue-vben-admin/compare/v2.7.2...v2.8.0) (2021-11-03)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
|
@ -1,3 +1,11 @@
|
||||
## 2.8.0(2021-11.03)
|
||||
|
||||
### 升级说明
|
||||
|
||||
- 包管理器由`yarn`改为 `pnpm`
|
||||
- 删除`node_modules`和`yarn.lock`,全局安装`pnpm`
|
||||
- 执行`pnpm install`
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **其它**
|
||||
|
@ -70,20 +70,20 @@ git clone https://github.com/anncwb/vue-vben-admin.git
|
||||
```bash
|
||||
cd vue-vben-admin
|
||||
|
||||
yarn install
|
||||
pnpm install
|
||||
|
||||
```
|
||||
|
||||
- run
|
||||
|
||||
```bash
|
||||
yarn serve
|
||||
pnpm serve
|
||||
```
|
||||
|
||||
- build
|
||||
|
||||
```bash
|
||||
yarn build
|
||||
pnpm build
|
||||
```
|
||||
|
||||
## Change Log
|
||||
|
@ -70,20 +70,20 @@ git clone https://github.com/anncwb/vue-vben-admin.git
|
||||
```bash
|
||||
cd vue-vben-admin
|
||||
|
||||
yarn install
|
||||
pnpm install
|
||||
|
||||
```
|
||||
|
||||
- 运行
|
||||
|
||||
```bash
|
||||
yarn serve
|
||||
pnpm serve
|
||||
```
|
||||
|
||||
- 打包
|
||||
|
||||
```bash
|
||||
yarn build
|
||||
pnpm build
|
||||
```
|
||||
|
||||
## 更新日志
|
||||
|
@ -14,29 +14,15 @@ export function configStyleImportPlugin(isBuild: boolean) {
|
||||
libraryName: 'ant-design-vue',
|
||||
esModule: true,
|
||||
resolveStyle: (name) => {
|
||||
// 这里是“子组件”列表,无需额外引入样式文件
|
||||
// 这里是无需额外引入样式文件的“子组件”列表
|
||||
const ignoreList = [
|
||||
'typography-text',
|
||||
'typography-title',
|
||||
'typography-paragraph',
|
||||
'typography-link',
|
||||
'anchor-link',
|
||||
'sub-menu',
|
||||
'menu-item',
|
||||
'menu-item-group',
|
||||
'dropdown-button',
|
||||
'breadcrumb-item',
|
||||
'breadcrumb-separator',
|
||||
'input-password',
|
||||
'input-search',
|
||||
'input-group',
|
||||
'form-item',
|
||||
'radio-group',
|
||||
'checkbox-group',
|
||||
'layout-sider',
|
||||
'layout-content',
|
||||
'layout-footer',
|
||||
'layout-header',
|
||||
'step',
|
||||
'select-option',
|
||||
'select-opt-group',
|
||||
@ -59,7 +45,31 @@ export function configStyleImportPlugin(isBuild: boolean) {
|
||||
'skeleton-image',
|
||||
'skeleton-button',
|
||||
];
|
||||
return ignoreList.includes(name) ? '' : `ant-design-vue/es/${name}/style/index`;
|
||||
// 这里是需要额外引入样式的子组件列表
|
||||
// 单独引入子组件时需引入组件样式,否则会在打包后导致子组件样式丢失
|
||||
const replaceList = {
|
||||
'typography-text': 'typography',
|
||||
'typography-title': 'typography',
|
||||
'typography-paragraph': 'typography',
|
||||
'typography-link': 'typography',
|
||||
'dropdown-button': 'dropdown',
|
||||
'input-password': 'input',
|
||||
'input-search': 'input',
|
||||
'input-group': 'input',
|
||||
'radio-group': 'radio',
|
||||
'checkbox-group': 'checkbox',
|
||||
'layout-sider': 'layout',
|
||||
'layout-content': 'layout',
|
||||
'layout-footer': 'layout',
|
||||
'layout-header': 'layout',
|
||||
'month-picker': 'date-picker',
|
||||
};
|
||||
|
||||
return ignoreList.includes(name)
|
||||
? ''
|
||||
: replaceList.hasOwnProperty(name)
|
||||
? `ant-design-vue/es/${replaceList[name]}/style/index`
|
||||
: `ant-design-vue/es/${name}/style/index`;
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -7,6 +7,7 @@ module.exports = {
|
||||
'header-max-length': [2, 'always', 108],
|
||||
'subject-empty': [2, 'never'],
|
||||
'type-empty': [2, 'never'],
|
||||
'subject-case': [0],
|
||||
'type-enum': [
|
||||
2,
|
||||
'always',
|
||||
|
21
index.html
21
index.html
@ -8,7 +8,6 @@
|
||||
name="viewport"
|
||||
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
|
||||
/>
|
||||
|
||||
<title><%= title %></title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</head>
|
||||
@ -30,7 +29,7 @@
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .app-loading .app-loading-title {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
color: rgb(255 255 255 / 85%);
|
||||
}
|
||||
|
||||
.app-loading {
|
||||
@ -48,7 +47,6 @@
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
display: flex;
|
||||
-webkit-transform: translate3d(-50%, -50%, 0);
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@ -66,7 +64,7 @@
|
||||
display: flex;
|
||||
margin-top: 30px;
|
||||
font-size: 30px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
color: rgb(0 0 0 / 85%);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
@ -97,7 +95,7 @@
|
||||
height: 20px;
|
||||
background-color: #0065cc;
|
||||
border-radius: 100%;
|
||||
opacity: 0.3;
|
||||
opacity: 30%;
|
||||
transform: scale(0.75);
|
||||
animation: antSpinMove 1s infinite linear alternate;
|
||||
transform-origin: 50% 50%;
|
||||
@ -111,43 +109,38 @@
|
||||
.dot i:nth-child(2) {
|
||||
top: 0;
|
||||
right: 0;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
.dot i:nth-child(3) {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
-webkit-animation-delay: 0.8s;
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
|
||||
.dot i:nth-child(4) {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
-webkit-animation-delay: 1.2s;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
@keyframes antRotate {
|
||||
to {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes antRotate {
|
||||
@keyframes antRotate {
|
||||
to {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
}
|
||||
@keyframes antSpinMove {
|
||||
to {
|
||||
opacity: 1;
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes antSpinMove {
|
||||
@keyframes antSpinMove {
|
||||
to {
|
||||
opacity: 1;
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
325
mock/demo/api-cascader.ts
Normal file
325
mock/demo/api-cascader.ts
Normal file
@ -0,0 +1,325 @@
|
||||
import { MockMethod } from 'vite-plugin-mock';
|
||||
import { resultSuccess } from '../_util';
|
||||
|
||||
const areaList: any[] = [
|
||||
{
|
||||
id: '530825900854620160',
|
||||
code: '430000',
|
||||
parentCode: '100000',
|
||||
levelType: 1,
|
||||
name: '湖南省',
|
||||
province: '湖南省',
|
||||
city: null,
|
||||
district: null,
|
||||
town: null,
|
||||
village: null,
|
||||
parentPath: '430000',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 16:33:42',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530825900883980288',
|
||||
code: '430100',
|
||||
parentCode: '430000',
|
||||
levelType: 2,
|
||||
name: '长沙市',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: null,
|
||||
town: null,
|
||||
village: null,
|
||||
parentPath: '430000,430100',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 16:33:42',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530825900951089152',
|
||||
code: '430102',
|
||||
parentCode: '430100',
|
||||
levelType: 3,
|
||||
name: '芙蓉区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '芙蓉区',
|
||||
town: null,
|
||||
village: null,
|
||||
parentPath: '430000,430100,430102',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 16:33:42',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530825901014003712',
|
||||
code: '430104',
|
||||
parentCode: '430100',
|
||||
levelType: 3,
|
||||
name: '岳麓区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '岳麓区',
|
||||
town: null,
|
||||
village: null,
|
||||
parentPath: '430000,430100,430104',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 16:33:42',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530825900988837888',
|
||||
code: '430103',
|
||||
parentCode: '430100',
|
||||
levelType: 3,
|
||||
name: '天心区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: null,
|
||||
village: null,
|
||||
parentPath: '430000,430100,430103',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 16:33:42',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530826672489115648',
|
||||
code: '430103002',
|
||||
parentCode: '430103',
|
||||
levelType: 4,
|
||||
name: '坡子街街道',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: null,
|
||||
parentPath: '430000,430100,430103,430103002',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-12-14 15:26:43',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241171607552',
|
||||
code: '430103002001',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '八角亭社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '八角亭社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002001',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2021-01-20 14:07:23',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241200967680',
|
||||
code: '430103002002',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '西牌楼社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '西牌楼社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002002',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 17:30:41',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241230327808',
|
||||
code: '430103002003',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '太平街社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '太平街社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002003',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 17:30:41',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241259687936',
|
||||
code: '430103002005',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '坡子街社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '坡子街社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002005',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 17:30:41',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241284853760',
|
||||
code: '430103002006',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '青山祠社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '青山祠社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002006',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 17:30:41',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241310019584',
|
||||
code: '430103002007',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '沙河社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '沙河社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002007',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 17:30:41',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241381322752',
|
||||
code: '430103002008',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '碧湘社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '碧湘社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002008',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 17:30:41',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241410682880',
|
||||
code: '430103002009',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '创远社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '创远社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002009',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 17:30:41',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241431654400',
|
||||
code: '430103002010',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '楚湘社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '楚湘社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002010',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 17:30:41',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241465208832',
|
||||
code: '430103002011',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '西湖社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '西湖社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002011',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 17:30:41',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241502957568',
|
||||
code: '430103002012',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '登仁桥社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '登仁桥社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002012',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 17:30:41',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
{
|
||||
id: '530840241553289216',
|
||||
code: '430103002013',
|
||||
parentCode: '430103002',
|
||||
levelType: 5,
|
||||
name: '文庙坪社区',
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '天心区',
|
||||
town: '坡子街街道',
|
||||
village: '文庙坪社区',
|
||||
parentPath: '430000,430100,430103,430103002,430103002013',
|
||||
createTime: '2020-11-30 15:47:31',
|
||||
updateTime: '2020-11-30 17:30:41',
|
||||
customized: false,
|
||||
usable: true,
|
||||
},
|
||||
];
|
||||
export default [
|
||||
{
|
||||
url: '/basic-api/cascader/getAreaRecord',
|
||||
timeout: 1000,
|
||||
method: 'post',
|
||||
response: ({ body }) => {
|
||||
const { parentCode } = body || {};
|
||||
if (!parentCode) {
|
||||
return resultSuccess(areaList.filter((it) => it.code === '430000'));
|
||||
}
|
||||
return resultSuccess(areaList.filter((it) => it.parentCode === parentCode));
|
||||
},
|
||||
},
|
||||
] as MockMethod[];
|
125
package.json
125
package.json
@ -1,18 +1,18 @@
|
||||
{
|
||||
"name": "vben-admin",
|
||||
"version": "2.7.2",
|
||||
"version": "2.8.0",
|
||||
"author": {
|
||||
"name": "vben",
|
||||
"email": "anncwb@126.com",
|
||||
"url": "https://github.com/anncwb"
|
||||
},
|
||||
"scripts": {
|
||||
"bootstrap": "yarn install",
|
||||
"bootstrap": "pnpm install",
|
||||
"serve": "npm run dev",
|
||||
"dev": "vite",
|
||||
"build": "cross-env NODE_ENV=production vite build && esno ./build/script/postBuild.ts",
|
||||
"build:test": "cross-env vite build --mode test && esno ./build/script/postBuild.ts",
|
||||
"build:no-cache": "yarn clean:cache && npm run build",
|
||||
"build:no-cache": "pnpm clean:cache && npm run build",
|
||||
"report": "cross-env REPORT=true npm run build",
|
||||
"type:check": "vue-tsc --noEmit --skipLibCheck",
|
||||
"preview": "npm run build && vite preview",
|
||||
@ -23,51 +23,56 @@
|
||||
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
|
||||
"lint:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
|
||||
"lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
|
||||
"lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js",
|
||||
"lint:pretty": "pretty-quick --staged",
|
||||
"lint:lint-staged": "lint-staged",
|
||||
"test:unit": "jest",
|
||||
"test:unit-coverage": "jest --coverage",
|
||||
"test:gzip": "http-server dist --cors --gzip -c-1",
|
||||
"test:br": "http-server dist --cors --brotli -c-1",
|
||||
"reinstall": "rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
|
||||
"test:gzip": "npx http-server dist --cors --gzip -c-1",
|
||||
"test:br": "npx http-server dist --cors --brotli -c-1",
|
||||
"reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
|
||||
"prepare": "husky install",
|
||||
"gen:icon": "esno ./build/generate/icon/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "^6.0.0",
|
||||
"@ant-design/icons-vue": "^6.0.1",
|
||||
"@iconify/iconify": "^2.0.4",
|
||||
"@logicflow/core": "^0.7.0",
|
||||
"@logicflow/extension": "^0.7.0",
|
||||
"@vueuse/core": "^6.6.2",
|
||||
"@zxcvbn-ts/core": "^1.0.0-beta.0",
|
||||
"@logicflow/core": "^0.7.5",
|
||||
"@logicflow/extension": "^0.7.5",
|
||||
"@vueuse/core": "^6.8.0",
|
||||
"@vueuse/shared": "^6.8.0",
|
||||
"@zxcvbn-ts/core": "^1.0.0",
|
||||
"ant-design-vue": "2.2.8",
|
||||
"axios": "^0.23.0",
|
||||
"axios": "^0.24.0",
|
||||
"codemirror": "^5.63.3",
|
||||
"cropperjs": "^1.5.12",
|
||||
"crypto-js": "^4.1.1",
|
||||
"echarts": "^5.2.1",
|
||||
"intro.js": "^4.2.2",
|
||||
"echarts": "^5.2.2",
|
||||
"intro.js": "^4.3.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mockjs": "^1.1.0",
|
||||
"moment": "^2.29.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"path-to-regexp": "^6.2.0",
|
||||
"pinia": "2.0.0-rc.14",
|
||||
"pinia": "2.0.2",
|
||||
"print-js": "^1.6.0",
|
||||
"qrcode": "^1.4.4",
|
||||
"qs": "^6.10.1",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"showdown": "^1.9.1",
|
||||
"sortablejs": "^1.14.0",
|
||||
"tinymce": "^5.10.0",
|
||||
"tinymce": "^5.10.1",
|
||||
"vditor": "^3.8.7",
|
||||
"vue": "^3.2.20",
|
||||
"vue": "^3.2.21",
|
||||
"vue-i18n": "^9.1.9",
|
||||
"vue-json-pretty": "^2.0.4",
|
||||
"vue-json-pretty": "^2.0.5",
|
||||
"vue-router": "^4.0.12",
|
||||
"vue-types": "^4.1.1",
|
||||
"xlsx": "^0.17.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^13.2.1",
|
||||
"@commitlint/config-conventional": "^13.2.0",
|
||||
"@iconify/json": "^1.1.416",
|
||||
"@commitlint/cli": "^14.1.0",
|
||||
"@commitlint/config-conventional": "^14.1.0",
|
||||
"@iconify/json": "^1.1.426",
|
||||
"@purge-icons/generated": "^0.7.0",
|
||||
"@types/codemirror": "^5.60.5",
|
||||
"@types/crypto-js": "^4.0.2",
|
||||
@ -77,66 +82,66 @@
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/lodash-es": "^4.17.5",
|
||||
"@types/mockjs": "^1.0.4",
|
||||
"@types/node": "^16.11.1",
|
||||
"@types/node": "^16.11.7",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/qrcode": "^1.4.1",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/showdown": "^1.9.4",
|
||||
"@types/sortablejs": "^1.10.7",
|
||||
"@typescript-eslint/eslint-plugin": "^5.1.0",
|
||||
"@typescript-eslint/parser": "^5.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.3.1",
|
||||
"@typescript-eslint/parser": "^5.3.1",
|
||||
"@vitejs/plugin-legacy": "^1.6.2",
|
||||
"@vitejs/plugin-vue": "^1.9.3",
|
||||
"@vitejs/plugin-vue": "^1.9.4",
|
||||
"@vitejs/plugin-vue-jsx": "^1.2.0",
|
||||
"@vue/compiler-sfc": "3.2.20",
|
||||
"@vue/compiler-sfc": "3.2.21",
|
||||
"@vue/test-utils": "^2.0.0-rc.16",
|
||||
"autoprefixer": "^10.3.7",
|
||||
"autoprefixer": "^10.4.0",
|
||||
"commitizen": "^4.2.4",
|
||||
"conventional-changelog-cli": "^2.1.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^10.0.0",
|
||||
"eslint": "^8.0.1",
|
||||
"eslint": "^8.2.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-define-config": "^1.1.1",
|
||||
"eslint-plugin-jest": "^25.2.2",
|
||||
"eslint-define-config": "^1.1.3",
|
||||
"eslint-plugin-jest": "^25.2.4",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-vue": "^7.19.1",
|
||||
"esno": "^0.10.1",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"esno": "^0.12.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"http-server": "^14.0.0",
|
||||
"husky": "^7.0.2",
|
||||
"husky": "^7.0.4",
|
||||
"inquirer": "^8.2.0",
|
||||
"is-ci": "^3.0.0",
|
||||
"jest": "^27.3.1",
|
||||
"less": "^4.1.2",
|
||||
"lint-staged": "^11.2.3",
|
||||
"lint-staged": "11.2.6",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.3.9",
|
||||
"postcss": "^8.3.11",
|
||||
"postcss-html": "^1.2.0",
|
||||
"postcss-less": "^5.0.0",
|
||||
"prettier": "^2.4.1",
|
||||
"pretty-quick": "^3.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup-plugin-visualizer": "^5.5.2",
|
||||
"stylelint": "^13.13.1",
|
||||
"stylelint": "^14.0.1",
|
||||
"stylelint-config-html": "^1.0.0",
|
||||
"stylelint-config-prettier": "^9.0.3",
|
||||
"stylelint-config-standard": "^22.0.0",
|
||||
"stylelint-order": "^4.1.0",
|
||||
"stylelint-config-standard": "^23.0.0",
|
||||
"stylelint-order": "^5.0.0",
|
||||
"ts-jest": "^27.0.7",
|
||||
"ts-node": "^10.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typescript": "^4.4.4",
|
||||
"vite": "^2.6.10",
|
||||
"vite": "^2.6.14",
|
||||
"vite-plugin-compression": "^0.3.5",
|
||||
"vite-plugin-html": "^2.1.1",
|
||||
"vite-plugin-imagemin": "^0.4.6",
|
||||
"vite-plugin-mock": "^2.9.6",
|
||||
"vite-plugin-purge-icons": "^0.7.0",
|
||||
"vite-plugin-pwa": "^0.11.3",
|
||||
"vite-plugin-style-import": "^1.2.1",
|
||||
"vite-plugin-style-import": "^1.3.0",
|
||||
"vite-plugin-svg-icons": "^1.0.5",
|
||||
"vite-plugin-theme": "^0.8.1",
|
||||
"vite-plugin-vue-setup-extend": "^0.1.0",
|
||||
"vite-plugin-windicss": "^1.4.12",
|
||||
"vue-eslint-parser": "^8.0.0",
|
||||
"vue-tsc": "^0.28.7"
|
||||
"vite-plugin-windicss": "^1.5.1",
|
||||
"vue-eslint-parser": "^8.0.1",
|
||||
"vue-tsc": "^0.29.3"
|
||||
},
|
||||
"resolutions": {
|
||||
"//": "Used to install imagemin dependencies, because imagemin may not be installed in China. If it is abroad, you can delete it",
|
||||
@ -154,5 +159,29 @@
|
||||
"homepage": "https://github.com/anncwb/vue-vben-admin",
|
||||
"engines": {
|
||||
"node": "^12 || >=14"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx}": [
|
||||
"eslint --fix",
|
||||
"prettier --write"
|
||||
],
|
||||
"{!(package)*.json,*.code-snippets,.!(browserslist)*rc}": [
|
||||
"prettier --write--parser json"
|
||||
],
|
||||
"package.json": [
|
||||
"prettier --write"
|
||||
],
|
||||
"*.vue": [
|
||||
"eslint --fix",
|
||||
"prettier --write",
|
||||
"stylelint --fix"
|
||||
],
|
||||
"*.{scss,less,styl,html}": [
|
||||
"stylelint --fix",
|
||||
"prettier --write"
|
||||
],
|
||||
"*.md": [
|
||||
"prettier --write"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
12023
pnpm-lock.yaml
generated
Normal file
12023
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,17 +1,9 @@
|
||||
module.exports = {
|
||||
printWidth: 100,
|
||||
tabWidth: 2,
|
||||
useTabs: false,
|
||||
semi: true,
|
||||
vueIndentScriptAndStyle: true,
|
||||
singleQuote: true,
|
||||
quoteProps: 'as-needed',
|
||||
bracketSpacing: true,
|
||||
trailingComma: 'all',
|
||||
jsxSingleQuote: false,
|
||||
arrowParens: 'always',
|
||||
insertPragma: false,
|
||||
requirePragma: false,
|
||||
proseWrap: 'never',
|
||||
htmlWhitespaceSensitivity: 'strict',
|
||||
endOfLine: 'auto',
|
||||
|
9
src/api/demo/cascader.ts
Normal file
9
src/api/demo/cascader.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { AreaModel, AreaParams } from '/@/api/demo/model/areaModel';
|
||||
|
||||
enum Api {
|
||||
AREA_RECORD = '/cascader/getAreaRecord',
|
||||
}
|
||||
|
||||
export const areaRecord = (data: AreaParams) =>
|
||||
defHttp.post<AreaModel>({ url: Api.AREA_RECORD, data });
|
12
src/api/demo/model/areaModel.ts
Normal file
12
src/api/demo/model/areaModel.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export interface AreaModel {
|
||||
id: string;
|
||||
code: string;
|
||||
parentCode: string;
|
||||
name: string;
|
||||
levelType: number;
|
||||
[key: string]: string | number;
|
||||
}
|
||||
|
||||
export interface AreaParams {
|
||||
parentCode: string;
|
||||
}
|
@ -3,7 +3,7 @@ export interface BasicPageParams {
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
export interface BasicFetchResult<T extends any> {
|
||||
export interface BasicFetchResult<T> {
|
||||
items: T[];
|
||||
total: number;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
html[data-theme='dark'] {
|
||||
.@{prefix-cls} {
|
||||
border: 1px solid rgb(196, 188, 188);
|
||||
border: 1px solid rgb(196 188 188);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
background-color: linear-gradient(-225deg, #d5dbe4, #f8f8f8);
|
||||
border-radius: 2px;
|
||||
box-shadow: inset 0 -2px 0 0 #cdcde6, inset 0 0 1px 1px #fff,
|
||||
0 1px 2px 1px rgba(30, 35, 90, 0.4);
|
||||
0 1px 2px 1px rgb(30 35 90 / 40%);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
|
@ -125,7 +125,7 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 50px;
|
||||
background-color: rgba(0, 0, 0, 0.25);
|
||||
background-color: rgb(0 0 0 / 25%);
|
||||
justify-content: center;
|
||||
|
||||
&--mobile {
|
||||
@ -159,7 +159,7 @@
|
||||
|
||||
&__item {
|
||||
&-enter {
|
||||
opacity: 0 !important;
|
||||
opacity: 0% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -168,16 +168,16 @@
|
||||
&-content {
|
||||
position: relative;
|
||||
width: 632px;
|
||||
margin: 0 auto auto auto;
|
||||
margin: 0 auto auto;
|
||||
background-color: @component-background;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
||||
box-shadow: 0 25px 50px -12px rgb(0 0 0 / 25%);
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&-input__wrapper {
|
||||
display: flex;
|
||||
padding: 14px 14px 0 14px;
|
||||
padding: 14px 14px 0;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
@ -245,7 +245,7 @@
|
||||
background-color: @primary-color;
|
||||
|
||||
.@{prefix-cls}-list__item-enter {
|
||||
opacity: 1;
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,7 +259,7 @@
|
||||
|
||||
&-enter {
|
||||
width: 30px;
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<div class="bg-white mb-2 p-4">
|
||||
<div class="p-4 mb-2 bg-white">
|
||||
<BasicForm @register="registerForm" />
|
||||
</div>
|
||||
{{ sliderProp.width }}
|
||||
<div class="bg-white p-2">
|
||||
<div class="p-2 bg-white">
|
||||
<List
|
||||
:grid="{ gutter: 5, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: grid }"
|
||||
:data-source="data"
|
||||
@ -167,7 +167,7 @@
|
||||
pageSize.value = pz;
|
||||
fetch();
|
||||
}
|
||||
function pageSizeChange(current, size) {
|
||||
function pageSizeChange(_current, size) {
|
||||
pageSize.value = size;
|
||||
fetch();
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
.CodeMirror {
|
||||
--base: #545281;
|
||||
--comment: hsl(210, 25%, 60%);
|
||||
--comment: hsl(210deg 25% 60%);
|
||||
--keyword: #af4ab1;
|
||||
--variable: #0055d1;
|
||||
--function: #c25205;
|
||||
@ -53,7 +53,7 @@
|
||||
color: var(--comment);
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
opacity: 0.6;
|
||||
opacity: 60%;
|
||||
}
|
||||
|
||||
.CodeMirror-guttermarker {
|
||||
@ -90,7 +90,7 @@
|
||||
display: inline-block;
|
||||
font-size: 0.8em;
|
||||
content: '>';
|
||||
opacity: 0.8;
|
||||
opacity: 80%;
|
||||
transform: rotate(90deg);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
@ -125,9 +125,7 @@
|
||||
}
|
||||
|
||||
.cm-fat-cursor-mark {
|
||||
background-color: rgba(20, 255, 20, 0.5);
|
||||
-webkit-animation: blink 1.06s steps(1) infinite;
|
||||
-moz-animation: blink 1.06s steps(1) infinite;
|
||||
background-color: rgb(20 255 20 / 50%);
|
||||
animation: blink 1.06s steps(1) infinite;
|
||||
}
|
||||
|
||||
@ -135,16 +133,14 @@
|
||||
width: auto;
|
||||
background-color: #7e7;
|
||||
border: 0;
|
||||
-webkit-animation: blink 1.06s steps(1) infinite;
|
||||
-moz-animation: blink 1.06s steps(1) infinite;
|
||||
animation: blink 1.06s steps(1) infinite;
|
||||
}
|
||||
@-moz-keyframes blink {
|
||||
@keyframes blink {
|
||||
50% {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes blink {
|
||||
@keyframes blink {
|
||||
50% {
|
||||
background-color: transparent;
|
||||
}
|
||||
@ -294,7 +290,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {
|
||||
}
|
||||
|
||||
.CodeMirror-matchingtag {
|
||||
background: rgba(255, 150, 0, 0.3);
|
||||
background: rgb(255 150 0 / 30%);
|
||||
}
|
||||
|
||||
.CodeMirror-activeline-background {
|
||||
@ -394,7 +390,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.CodeMirror-gutter-wrapper ::-moz-selection {
|
||||
.CodeMirrorwrapper ::selection {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
@ -414,11 +410,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {
|
||||
border-width: 0;
|
||||
|
||||
/* Reset some styles that the rest of the page might have set */
|
||||
-moz-border-radius: 0;
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-font-variant-ligatures: contextual;
|
||||
font-variant-ligatures: contextual;
|
||||
}
|
||||
|
||||
@ -457,7 +450,6 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {
|
||||
.CodeMirror-gutter,
|
||||
.CodeMirror-gutters,
|
||||
.CodeMirror-linenumber {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
@ -505,15 +497,9 @@ div.CodeMirror-dragcursors {
|
||||
background: #d7d4f0;
|
||||
}
|
||||
|
||||
.CodeMirror-line::-moz-selection,
|
||||
.CodeMirror-line > span::-moz-selection,
|
||||
.CodeMirror-line > span > span::-moz-selection {
|
||||
background: #d7d4f0;
|
||||
}
|
||||
|
||||
.cm-searching {
|
||||
background-color: #ffa;
|
||||
background-color: rgba(255, 255, 0, 0.4);
|
||||
background-color: rgb(255 255 0 / 40%);
|
||||
}
|
||||
|
||||
/* Used to force a border model for a node */
|
||||
|
@ -178,22 +178,22 @@
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
background-color: @component-background;
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border: 1px solid rgb(0 0 0 / 8%);
|
||||
border-radius: 0.25rem;
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.1),
|
||||
0 1px 5px 0 rgba(0, 0, 0, 0.06);
|
||||
box-shadow: 0 2px 2px 0 rgb(0 0 0 / 14%), 0 3px 1px -2px rgb(0 0 0 / 10%),
|
||||
0 1px 5px 0 rgb(0 0 0 / 6%);
|
||||
background-clip: padding-box;
|
||||
user-select: none;
|
||||
|
||||
.item-style();
|
||||
|
||||
.ant-divider {
|
||||
margin: 0 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__popup {
|
||||
.ant-divider {
|
||||
margin: 0 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.item-style();
|
||||
|
@ -234,17 +234,17 @@
|
||||
background: #eee;
|
||||
background-image: linear-gradient(
|
||||
45deg,
|
||||
rgba(0, 0, 0, 0.25) 25%,
|
||||
rgb(0 0 0 / 25%) 25%,
|
||||
transparent 0,
|
||||
transparent 75%,
|
||||
rgba(0, 0, 0, 0.25) 0
|
||||
rgb(0 0 0 / 25%) 0
|
||||
),
|
||||
linear-gradient(
|
||||
45deg,
|
||||
rgba(0, 0, 0, 0.25) 25%,
|
||||
rgb(0 0 0 / 25%) 25%,
|
||||
transparent 0,
|
||||
transparent 75%,
|
||||
rgba(0, 0, 0, 0.25) 0
|
||||
rgb(0 0 0 / 25%) 0
|
||||
);
|
||||
background-position: 0 0, 12px 12px;
|
||||
background-size: 24px 24px;
|
||||
|
@ -135,15 +135,14 @@
|
||||
}
|
||||
|
||||
&-image-mask {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
position: absolute;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
border-radius: inherit;
|
||||
border: inherit;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
background: rgb(0 0 0 / 40%);
|
||||
cursor: pointer;
|
||||
-webkit-transition: opacity 0.4s;
|
||||
transition: opacity 0.4s;
|
||||
|
||||
::v-deep(svg) {
|
||||
@ -152,7 +151,7 @@
|
||||
}
|
||||
|
||||
&-image-mask:hover {
|
||||
opacity: 40;
|
||||
opacity: 4000%;
|
||||
}
|
||||
|
||||
&-upload-btn {
|
||||
|
@ -10,5 +10,6 @@ export { default as ApiSelect } from './src/components/ApiSelect.vue';
|
||||
export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue';
|
||||
export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue';
|
||||
export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue';
|
||||
export { default as ApiCascader } from './src/components/ApiCascader.vue';
|
||||
|
||||
export { BasicForm };
|
||||
|
@ -25,6 +25,7 @@ import ApiRadioGroup from './components/ApiRadioGroup.vue';
|
||||
import RadioButtonGroup from './components/RadioButtonGroup.vue';
|
||||
import ApiSelect from './components/ApiSelect.vue';
|
||||
import ApiTreeSelect from './components/ApiTreeSelect.vue';
|
||||
import ApiCascader from './components/ApiCascader.vue';
|
||||
import { BasicUpload } from '/@/components/Upload';
|
||||
import { StrengthMeter } from '/@/components/StrengthMeter';
|
||||
import { IconPicker } from '/@/components/Icon';
|
||||
@ -50,6 +51,7 @@ componentMap.set('RadioButtonGroup', RadioButtonGroup);
|
||||
componentMap.set('RadioGroup', Radio.Group);
|
||||
componentMap.set('Checkbox', Checkbox);
|
||||
componentMap.set('CheckboxGroup', Checkbox.Group);
|
||||
componentMap.set('ApiCascader', ApiCascader);
|
||||
componentMap.set('Cascader', Cascader);
|
||||
componentMap.set('Slider', Slider);
|
||||
componentMap.set('Rate', Rate);
|
||||
|
197
src/components/Form/src/components/ApiCascader.vue
Normal file
197
src/components/Form/src/components/ApiCascader.vue
Normal file
@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<a-cascader
|
||||
v-model:value="state"
|
||||
:options="options"
|
||||
:load-data="loadData"
|
||||
change-on-select
|
||||
@change="handleChange"
|
||||
:displayRender="handleRenderDisplay"
|
||||
>
|
||||
<template #suffixIcon v-if="loading">
|
||||
<LoadingOutlined spin />
|
||||
</template>
|
||||
<template #notFoundContent v-if="loading">
|
||||
<span>
|
||||
<LoadingOutlined spin class="mr-1" />
|
||||
{{ t('component.form.apiSelectNotFound') }}
|
||||
</span>
|
||||
</template>
|
||||
</a-cascader>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType, ref, unref, watch, watchEffect } from 'vue';
|
||||
import { Cascader } from 'ant-design-vue';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { get, omit } from 'lodash-es';
|
||||
import { useRuleFormItem } from '/@/hooks/component/useFormItem';
|
||||
import { LoadingOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
loading?: boolean;
|
||||
isLeaf?: boolean;
|
||||
children?: Option[];
|
||||
}
|
||||
export default defineComponent({
|
||||
name: 'ApiCascader',
|
||||
components: {
|
||||
LoadingOutlined,
|
||||
[Cascader.name]: Cascader,
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
},
|
||||
api: {
|
||||
type: Function as PropType<(arg?: Recordable) => Promise<Option[]>>,
|
||||
default: null,
|
||||
},
|
||||
numberToString: propTypes.bool,
|
||||
resultField: propTypes.string.def(''),
|
||||
labelField: propTypes.string.def('label'),
|
||||
valueField: propTypes.string.def('value'),
|
||||
childrenField: propTypes.string.def('children'),
|
||||
asyncFetchParamKey: propTypes.string.def('parentCode'),
|
||||
immediate: propTypes.bool.def(true),
|
||||
// init fetch params
|
||||
initFetchParams: {
|
||||
type: Object as PropType<Recordable>,
|
||||
default: () => ({}),
|
||||
},
|
||||
// 是否有下级,默认是
|
||||
isLeaf: {
|
||||
type: Function as PropType<(arg: Recordable) => boolean>,
|
||||
default: null,
|
||||
},
|
||||
displayRenderArray: {
|
||||
type: Array,
|
||||
},
|
||||
},
|
||||
emits: ['change', 'defaultChange'],
|
||||
setup(props, { emit }) {
|
||||
const apiData = ref<any[]>([]);
|
||||
const options = ref<Option[]>([]);
|
||||
const loading = ref<boolean>(false);
|
||||
const emitData = ref<any[]>([]);
|
||||
const isFirstLoad = ref(true);
|
||||
|
||||
// Embedded in the form, just use the hook binding to perform form verification
|
||||
const [state] = useRuleFormItem(props, 'value', 'change', emitData);
|
||||
|
||||
watch(
|
||||
apiData,
|
||||
(data) => {
|
||||
const opts = generatorOptions(data);
|
||||
options.value = opts;
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
function generatorOptions(options: any[]): Option[] {
|
||||
const { labelField, valueField, numberToString, childrenField, isLeaf } = props;
|
||||
return options.reduce((prev, next: Recordable) => {
|
||||
if (next) {
|
||||
const value = next[valueField];
|
||||
const item = {
|
||||
...omit(next, [labelField, valueField]),
|
||||
label: next[labelField],
|
||||
value: numberToString ? `${value}` : value,
|
||||
isLeaf: isLeaf && typeof isLeaf === 'function' ? isLeaf(next) : false,
|
||||
};
|
||||
const children = Reflect.get(next, childrenField);
|
||||
if (children) {
|
||||
Reflect.set(item, childrenField, generatorOptions(children));
|
||||
}
|
||||
prev.push(item);
|
||||
}
|
||||
return prev;
|
||||
}, [] as Option[]);
|
||||
}
|
||||
|
||||
async function initialFetch() {
|
||||
const api = props.api;
|
||||
if (!api || !isFunction(api)) return;
|
||||
apiData.value = [];
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await api(props.initFetchParams);
|
||||
if (Array.isArray(res)) {
|
||||
apiData.value = res;
|
||||
return;
|
||||
}
|
||||
if (props.resultField) {
|
||||
apiData.value = get(res, props.resultField) || [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadData(selectedOptions: Option[]) {
|
||||
const targetOption = selectedOptions[selectedOptions.length - 1];
|
||||
targetOption.loading = true;
|
||||
|
||||
const api = props.api;
|
||||
if (!api || !isFunction(api)) return;
|
||||
try {
|
||||
const res = await api({
|
||||
[props.asyncFetchParamKey]: Reflect.get(targetOption, 'value'),
|
||||
});
|
||||
if (Array.isArray(res)) {
|
||||
const children = generatorOptions(res);
|
||||
targetOption.children = children;
|
||||
return;
|
||||
}
|
||||
if (props.resultField) {
|
||||
const children = generatorOptions(get(res, props.resultField) || []);
|
||||
targetOption.children = children;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
targetOption.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
props.immediate && initialFetch();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.initFetchParams,
|
||||
() => {
|
||||
!unref(isFirstLoad) && initialFetch();
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
function handleChange(keys, args) {
|
||||
emitData.value = keys;
|
||||
emit('defaultChange', keys, args);
|
||||
}
|
||||
|
||||
function handleRenderDisplay({ labels, selectedOptions }) {
|
||||
if (unref(emitData).length === selectedOptions.length) {
|
||||
return labels.join(' / ');
|
||||
}
|
||||
if (props.displayRenderArray) {
|
||||
return props.displayRenderArray.join(' / ');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
return {
|
||||
state,
|
||||
options,
|
||||
loading,
|
||||
handleChange,
|
||||
loadData,
|
||||
handleRenderDisplay,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
@ -125,9 +125,6 @@ export function useFormEvents({
|
||||
const schemaList: FormSchema[] = cloneDeep(unref(getSchema));
|
||||
|
||||
const index = schemaList.findIndex((schema) => schema.field === prefixField);
|
||||
const hasInList = schemaList.some((item) => item.field === prefixField || schema.field);
|
||||
|
||||
if (!hasInList) return;
|
||||
|
||||
if (!prefixField || index === -1 || first) {
|
||||
first ? schemaList.unshift(schema) : schemaList.push(schema);
|
||||
@ -242,7 +239,7 @@ export function useFormEvents({
|
||||
const values = await validate();
|
||||
const res = handleFormValues(values);
|
||||
emit('submit', res);
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
throw new Error(error);
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ export type ComponentType =
|
||||
| 'Checkbox'
|
||||
| 'CheckboxGroup'
|
||||
| 'AutoComplete'
|
||||
| 'ApiCascader'
|
||||
| 'Cascader'
|
||||
| 'DatePicker'
|
||||
| 'MonthPicker'
|
||||
|
@ -57,7 +57,7 @@
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: rgba(240, 242, 245, 0.4);
|
||||
background-color: rgb(240 242 245 / 40%);
|
||||
|
||||
&.absolute {
|
||||
position: absolute;
|
||||
|
@ -1,4 +1,5 @@
|
||||
<template>
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<div v-html="getHtmlData" :class="$props.class" class="markdown-viewer"></div>
|
||||
</template>
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
}
|
||||
|
||||
&-content {
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%), 0 6px 20px 0 rgb(0 0 0 / 19%);
|
||||
}
|
||||
|
||||
&-footer {
|
||||
|
@ -39,8 +39,8 @@
|
||||
line-height: 44px;
|
||||
background-color: @component-background;
|
||||
border-top: 1px solid @border-color-base;
|
||||
box-shadow: 0 -6px 16px -8px rgba(0, 0, 0, 0.08), 0 -9px 28px 0 rgba(0, 0, 0, 0.05),
|
||||
0 -12px 48px 16px rgba(0, 0, 0, 0.03);
|
||||
box-shadow: 0 -6px 16px -8px rgb(0 0 0 / 8%), 0 -9px 28px 0 rgb(0 0 0 / 5%),
|
||||
0 -12px 48px 16px rgb(0 0 0 / 3%);
|
||||
transition: width 0.2s;
|
||||
|
||||
&__left {
|
||||
|
@ -432,7 +432,7 @@
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: @preview-comp-z-index;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
background: rgb(0 0 0 / 50%);
|
||||
user-select: none;
|
||||
|
||||
&-content {
|
||||
@ -458,7 +458,7 @@
|
||||
overflow: hidden;
|
||||
color: @white;
|
||||
cursor: pointer;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
background-color: rgb(0 0 0 / 50%);
|
||||
border-radius: 50%;
|
||||
transition: all 0.2s;
|
||||
|
||||
@ -470,7 +470,7 @@
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
background-color: rgb(0 0 0 / 80%);
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,7 +480,7 @@
|
||||
left: 50%;
|
||||
padding: 0 22px;
|
||||
font-size: 16px;
|
||||
background: rgba(109, 109, 109, 0.6);
|
||||
background: rgb(109 109 109 / 60%);
|
||||
border-radius: 15px;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
@ -494,7 +494,7 @@
|
||||
height: 44px;
|
||||
padding: 0 22px;
|
||||
margin-left: -139px;
|
||||
background: rgba(109, 109, 109, 0.6);
|
||||
background: rgb(109 109 109 / 60%);
|
||||
border-radius: 22px;
|
||||
justify-content: center;
|
||||
|
||||
@ -526,12 +526,12 @@
|
||||
height: 50px;
|
||||
font-size: 28px;
|
||||
cursor: pointer;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
background-color: rgb(0 0 0 / 50%);
|
||||
border-radius: 50%;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
background-color: rgb(0 0 0 / 80%);
|
||||
}
|
||||
|
||||
&.left {
|
||||
|
@ -88,7 +88,7 @@
|
||||
}
|
||||
|
||||
.ant-image-preview-operations {
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
background-color: rgb(0 0 0 / 40%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -148,7 +148,7 @@
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -159,12 +159,12 @@
|
||||
width: 0;
|
||||
height: 0;
|
||||
cursor: pointer;
|
||||
background-color: rgba(144, 147, 153, 0.3);
|
||||
background-color: rgb(144 147 153 / 30%);
|
||||
border-radius: inherit;
|
||||
transition: 0.3s background-color;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(144, 147, 153, 0.5);
|
||||
background-color: rgb(144 147 153 / 50%);
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,8 +174,7 @@
|
||||
bottom: 2px;
|
||||
z-index: 1;
|
||||
border-radius: 4px;
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 80ms ease;
|
||||
opacity: 0%;
|
||||
transition: opacity 80ms ease;
|
||||
|
||||
&.is-vertical {
|
||||
@ -201,7 +200,7 @@
|
||||
.scrollbar:active > .scrollbar__bar,
|
||||
.scrollbar:focus > .scrollbar__bar,
|
||||
.scrollbar:hover > .scrollbar__bar {
|
||||
opacity: 1;
|
||||
opacity: 100%;
|
||||
transition: opacity 340ms ease-out;
|
||||
}
|
||||
</style>
|
||||
|
@ -188,7 +188,7 @@
|
||||
|
||||
&-vertical&-collapse &-item,
|
||||
&-vertical&-collapse &-submenu-title {
|
||||
padding: 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&-vertical &-submenu-title-icon {
|
||||
|
@ -92,7 +92,7 @@
|
||||
background-color: transparent;
|
||||
border-color: @white;
|
||||
border-style: solid;
|
||||
border-width: 0 5px 0 5px;
|
||||
border-width: 0 5px;
|
||||
content: '';
|
||||
}
|
||||
|
||||
|
@ -357,7 +357,7 @@
|
||||
padding: 16px;
|
||||
|
||||
.ant-form {
|
||||
padding: 12px 10px 6px 10px;
|
||||
padding: 12px 10px 6px;
|
||||
margin-bottom: 16px;
|
||||
background-color: @component-background;
|
||||
border-radius: 2px;
|
||||
@ -375,7 +375,7 @@
|
||||
|
||||
.ant-table-title {
|
||||
min-height: 40px;
|
||||
padding: 0 0 8px 0 !important;
|
||||
padding: 0 0 8px !important;
|
||||
}
|
||||
|
||||
.ant-table.ant-table-bordered .ant-table-title {
|
||||
@ -401,7 +401,7 @@
|
||||
}
|
||||
|
||||
.ant-pagination {
|
||||
margin: 10px 0 0 0;
|
||||
margin: 10px 0 0;
|
||||
}
|
||||
|
||||
.ant-table-footer {
|
||||
|
@ -42,7 +42,7 @@
|
||||
.@{prefix-cls} {
|
||||
&__help {
|
||||
margin-left: 8px;
|
||||
color: rgba(0, 0, 0, 0.65) !important;
|
||||
color: rgb(0 0 0 / 65%) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -104,11 +104,10 @@
|
||||
});
|
||||
|
||||
const getDropdownList = computed((): any[] => {
|
||||
return (toRaw(props.dropDownActions) || [])
|
||||
.filter((action) => {
|
||||
const list = (toRaw(props.dropDownActions) || []).filter((action) => {
|
||||
return hasPermission(action.auth) && isIfShow(action);
|
||||
})
|
||||
.map((action, index) => {
|
||||
});
|
||||
return list.map((action, index) => {
|
||||
const { label, popConfirm } = action;
|
||||
return {
|
||||
...action,
|
||||
@ -116,7 +115,7 @@
|
||||
onConfirm: popConfirm?.confirm,
|
||||
onCancel: popConfirm?.cancel,
|
||||
text: label,
|
||||
divider: index < props.dropDownActions.length - 1 ? props.divider : false,
|
||||
divider: index < list.length - 1 ? props.divider : false,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
@ -265,7 +265,7 @@
|
||||
result = await beforeEditSubmit({
|
||||
record: pick(record, keys),
|
||||
index,
|
||||
key,
|
||||
key: key as string,
|
||||
value,
|
||||
});
|
||||
} catch (e) {
|
||||
|
@ -43,7 +43,7 @@
|
||||
<CheckboxGroup v-model:value="checkedList" @change="onChange" ref="columnListRef">
|
||||
<template v-for="item in plainOptions" :key="item.value">
|
||||
<div :class="`${prefixCls}__check-item`" v-if="!('ifShow' in item && !item.ifShow)">
|
||||
<DragOutlined class="table-coulmn-drag-icon" />
|
||||
<DragOutlined class="table-column-drag-icon" />
|
||||
<Checkbox :value="item.value">
|
||||
{{ item.label }}
|
||||
</Checkbox>
|
||||
@ -120,7 +120,7 @@
|
||||
import { useSortable } from '/@/hooks/web/useSortable';
|
||||
import { isFunction, isNullAndUnDef } from '/@/utils/is';
|
||||
import { getPopupContainer as getParentContainer } from '/@/utils';
|
||||
import { omit } from 'lodash-es';
|
||||
import { cloneDeep, omit } from 'lodash-es';
|
||||
|
||||
interface State {
|
||||
checkAll: boolean;
|
||||
@ -250,16 +250,15 @@
|
||||
|
||||
const indeterminate = computed(() => {
|
||||
const len = plainOptions.value.length;
|
||||
let checkdedLen = state.checkedList.length;
|
||||
unref(checkIndex) && checkdedLen--;
|
||||
return checkdedLen > 0 && checkdedLen < len;
|
||||
let checkedLen = state.checkedList.length;
|
||||
unref(checkIndex) && checkedLen--;
|
||||
return checkedLen > 0 && checkedLen < len;
|
||||
});
|
||||
|
||||
// Trigger when check/uncheck a column
|
||||
function onChange(checkedList: string[]) {
|
||||
const len = plainOptions.value.length;
|
||||
const len = plainSortOptions.value.length;
|
||||
state.checkAll = checkedList.length === len;
|
||||
|
||||
const sortList = unref(plainSortOptions).map((item) => item.value);
|
||||
checkedList.sort((prev, next) => {
|
||||
return sortList.indexOf(prev) - sortList.indexOf(next);
|
||||
@ -286,14 +285,14 @@
|
||||
if (!el) return;
|
||||
// Drag and drop sort
|
||||
const { initSortable } = useSortable(el, {
|
||||
handle: '.table-coulmn-drag-icon ',
|
||||
handle: '.table-column-drag-icon',
|
||||
onEnd: (evt) => {
|
||||
const { oldIndex, newIndex } = evt;
|
||||
if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || oldIndex === newIndex) {
|
||||
return;
|
||||
}
|
||||
// Sort column
|
||||
const columns = getColumns();
|
||||
const columns = cloneDeep(plainSortOptions.value);
|
||||
|
||||
if (oldIndex > newIndex) {
|
||||
columns.splice(newIndex, 0, columns[oldIndex]);
|
||||
@ -304,7 +303,6 @@
|
||||
}
|
||||
|
||||
plainSortOptions.value = columns;
|
||||
plainOptions.value = columns;
|
||||
setColumns(columns);
|
||||
},
|
||||
});
|
||||
@ -347,7 +345,7 @@
|
||||
|
||||
function setColumns(columns: BasicColumn[] | string[]) {
|
||||
table.setColumns(columns);
|
||||
const data: ColumnChangeParam[] = unref(plainOptions).map((col) => {
|
||||
const data: ColumnChangeParam[] = unref(plainSortOptions).map((col) => {
|
||||
const visible =
|
||||
columns.findIndex(
|
||||
(c: BasicColumn | string) =>
|
||||
@ -390,7 +388,7 @@
|
||||
<style lang="less">
|
||||
@prefix-cls: ~'@{namespace}-basic-column-setting';
|
||||
|
||||
.table-coulmn-drag-icon {
|
||||
.table-column-drag-icon {
|
||||
margin: 0 5px;
|
||||
cursor: move;
|
||||
}
|
||||
@ -420,7 +418,7 @@
|
||||
|
||||
&__fixed-left,
|
||||
&__fixed-right {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
color: rgb(0 0 0 / 45%);
|
||||
cursor: pointer;
|
||||
|
||||
&.active,
|
||||
|
@ -216,25 +216,17 @@ export function useColumns(
|
||||
const columnKeys = columns as string[];
|
||||
const newColumns: BasicColumn[] = [];
|
||||
cacheColumns.forEach((item) => {
|
||||
if (columnKeys.includes(item.dataIndex! || (item.key as string))) {
|
||||
newColumns.push({
|
||||
...item,
|
||||
defaultHidden: false,
|
||||
defaultHidden: !columnKeys.includes(item.dataIndex! || (item.key as string)),
|
||||
});
|
||||
} else {
|
||||
newColumns.push({
|
||||
...item,
|
||||
defaultHidden: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Sort according to another array
|
||||
if (!isEqual(cacheKeys, columns)) {
|
||||
newColumns.sort((prev, next) => {
|
||||
return (
|
||||
cacheKeys.indexOf(prev.dataIndex as string) -
|
||||
cacheKeys.indexOf(next.dataIndex as string)
|
||||
columnKeys.indexOf(prev.dataIndex as string) -
|
||||
columnKeys.indexOf(next.dataIndex as string)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
|
||||
import { buildUUID } from '/@/utils/uuid';
|
||||
import { isFunction, isBoolean } from '/@/utils/is';
|
||||
import { get, cloneDeep } from 'lodash-es';
|
||||
import { get, cloneDeep, merge } from 'lodash-es';
|
||||
import { FETCH_SETTING, ROW_KEY, PAGE_SIZE } from '../const';
|
||||
|
||||
interface ActionType {
|
||||
@ -241,8 +241,16 @@ export function useDataSource(
|
||||
}
|
||||
|
||||
async function fetch(opt?: FetchParams) {
|
||||
const { api, searchInfo, defSort, fetchSetting, beforeFetch, afterFetch, useSearchForm, pagination } =
|
||||
unref(propsRef);
|
||||
const {
|
||||
api,
|
||||
searchInfo,
|
||||
defSort,
|
||||
fetchSetting,
|
||||
beforeFetch,
|
||||
afterFetch,
|
||||
useSearchForm,
|
||||
pagination,
|
||||
} = unref(propsRef);
|
||||
if (!api || !isFunction(api)) return;
|
||||
try {
|
||||
setLoading(true);
|
||||
@ -264,17 +272,17 @@ export function useDataSource(
|
||||
|
||||
const { sortInfo = {}, filterInfo } = searchState;
|
||||
|
||||
let params: Recordable = {
|
||||
...pageParams,
|
||||
...(useSearchForm ? getFieldsValue() : {}),
|
||||
...searchInfo,
|
||||
...(opt?.searchInfo ?? {}),
|
||||
...defSort,
|
||||
...sortInfo,
|
||||
...filterInfo,
|
||||
...(opt?.sortInfo ?? {}),
|
||||
...(opt?.filterInfo ?? {}),
|
||||
};
|
||||
let params: Recordable = merge(
|
||||
pageParams,
|
||||
useSearchForm ? getFieldsValue() : {},
|
||||
searchInfo,
|
||||
opt?.searchInfo ?? {},
|
||||
defSort,
|
||||
sortInfo,
|
||||
filterInfo,
|
||||
opt?.sortInfo ?? {},
|
||||
opt?.filterInfo ?? {},
|
||||
);
|
||||
if (beforeFetch && isFunction(beforeFetch)) {
|
||||
params = (await beforeFetch(params)) || params;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ export function useTableScroll(
|
||||
propsRef: ComputedRef<BasicTableProps>,
|
||||
tableElRef: Ref<ComponentRef>,
|
||||
columnsRef: ComputedRef<BasicColumn[]>,
|
||||
rowSelectionRef: ComputedRef<TableRowSelection<any> | null>,
|
||||
rowSelectionRef: ComputedRef<TableRowSelection | null>,
|
||||
getDataSourceRef: ComputedRef<Recordable[]>,
|
||||
) {
|
||||
const tableHeightRef: Ref<Nullable<number>> = ref(null);
|
||||
@ -43,8 +43,8 @@ export function useTableScroll(
|
||||
});
|
||||
}
|
||||
|
||||
function setHeight(heigh: number) {
|
||||
tableHeightRef.value = heigh;
|
||||
function setHeight(height: number) {
|
||||
tableHeightRef.value = height;
|
||||
// Solve the problem of modal adaptive height calculation when the form is placed in the modal
|
||||
modalFn?.redoModalHeight?.();
|
||||
}
|
||||
|
@ -23,4 +23,17 @@ export interface PopConfirm {
|
||||
confirm: Fn;
|
||||
cancel?: Fn;
|
||||
icon?: string;
|
||||
placement?:
|
||||
| 'top'
|
||||
| 'left'
|
||||
| 'right'
|
||||
| 'bottom'
|
||||
| 'topLeft'
|
||||
| 'topRight'
|
||||
| 'leftTop'
|
||||
| 'leftBottom'
|
||||
| 'rightTop'
|
||||
| 'rightBottom'
|
||||
| 'bottomLeft'
|
||||
| 'bottomRight';
|
||||
}
|
||||
|
@ -399,7 +399,7 @@
|
||||
const children = get(item, childrenField) || [];
|
||||
const title = get(item, titleField);
|
||||
|
||||
const searchIdx = title.indexOf(searchText);
|
||||
const searchIdx = searchText ? title.indexOf(searchText) : -1;
|
||||
const isHighlight =
|
||||
searchState.startSearch && !isEmpty(searchText) && highlight && searchIdx !== -1;
|
||||
const highlightStyle = `color: ${isBoolean(highlight) ? '#f50' : highlight}`;
|
||||
@ -408,7 +408,7 @@
|
||||
<span class={unref(getBindValues)?.blockNode ? `${prefixCls}__content` : ''}>
|
||||
<span>{title.substr(0, searchIdx)}</span>
|
||||
<span style={highlightStyle}>{searchText}</span>
|
||||
<span>{title.substr(searchIdx + searchText.length)}</span>
|
||||
<span>{title.substr(searchIdx + (searchText as string).length)}</span>
|
||||
</span>
|
||||
) : (
|
||||
title
|
||||
|
@ -54,7 +54,7 @@
|
||||
import { basicProps } from './props';
|
||||
import { createTableColumns, createActionColumn } from './data';
|
||||
// utils
|
||||
import { checkFileType, checkImgType, getBase64WithFile } from './helper';
|
||||
import { checkImgType, getBase64WithFile } from './helper';
|
||||
import { buildUUID } from '/@/utils/uuid';
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { warn } from '/@/utils/log';
|
||||
@ -84,7 +84,7 @@
|
||||
const { t } = useI18n();
|
||||
const [register, { closeModal }] = useModalInner();
|
||||
|
||||
const { getAccept, getStringAccept, getHelpText } = useUploadType({
|
||||
const { getStringAccept, getHelpText } = useUploadType({
|
||||
acceptRef: accept,
|
||||
helpTextRef: helpText,
|
||||
maxNumberRef: maxNumber,
|
||||
@ -124,18 +124,12 @@
|
||||
function beforeUpload(file: File) {
|
||||
const { size, name } = file;
|
||||
const { maxSize } = props;
|
||||
const accept = unref(getAccept);
|
||||
// 设置最大值,则判断
|
||||
if (maxSize && file.size / 1024 / 1024 >= maxSize) {
|
||||
createMessage.error(t('component.upload.maxSizeMultiple', [maxSize]));
|
||||
return false;
|
||||
}
|
||||
|
||||
// 设置类型,则判断
|
||||
if (accept.length > 0 && !checkFileType(file, accept)) {
|
||||
createMessage.error!(t('component.upload.acceptUpload', [accept.join(',')]));
|
||||
return false;
|
||||
}
|
||||
const commonItem = {
|
||||
uuid: buildUUID(),
|
||||
file,
|
||||
|
@ -292,7 +292,7 @@
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
background-color: rgb(238, 238, 238);
|
||||
background-color: rgb(238 238 238);
|
||||
border: 1px solid #ddd;
|
||||
border-radius: @radius;
|
||||
|
||||
@ -313,7 +313,7 @@
|
||||
position: absolute;
|
||||
top: 0;
|
||||
font-size: 12px;
|
||||
-webkit-text-size-adjust: none;
|
||||
text-size-adjust: none;
|
||||
background-color: -webkit-gradient(
|
||||
linear,
|
||||
left top,
|
||||
|
@ -209,7 +209,7 @@
|
||||
}
|
||||
|
||||
&.normal {
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
background-color: rgb(0 0 0 / 30%);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@
|
||||
}
|
||||
|
||||
[data-theme='light'] &.ant-btn-link.is-disabled {
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
color: rgb(0 0 0 / 25%);
|
||||
text-shadow: none;
|
||||
cursor: not-allowed !important;
|
||||
background-color: transparent !important;
|
||||
@ -76,7 +76,7 @@
|
||||
}
|
||||
|
||||
[data-theme='dark'] &.ant-btn-link.is-disabled {
|
||||
color: rgba(255, 255, 255, 0.25) !important;
|
||||
color: rgb(255 255 255 / 25%) !important;
|
||||
text-shadow: none;
|
||||
cursor: not-allowed !important;
|
||||
background-color: transparent !important;
|
||||
|
@ -30,12 +30,12 @@ span.anticon:not(.app-iconify) {
|
||||
}
|
||||
|
||||
.ant-image-preview-operations {
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
background-color: rgb(0 0 0 / 30%);
|
||||
}
|
||||
|
||||
.ant-popover {
|
||||
&-content {
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
@import './theme.less';
|
||||
|
||||
input:-webkit-autofill {
|
||||
-webkit-box-shadow: 0 0 0 1000px white inset !important;
|
||||
box-shadow: 0 0 0 1000px white inset !important;
|
||||
}
|
||||
|
||||
:-webkit-autofill {
|
||||
@ -14,7 +14,7 @@ input:-webkit-autofill {
|
||||
|
||||
html {
|
||||
overflow: hidden;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
html,
|
||||
|
@ -17,15 +17,15 @@
|
||||
// }
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
background-color: rgb(0 0 0 / 5%);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
// background: rgba(0, 0, 0, 0.6);
|
||||
background-color: rgba(144, 147, 153, 0.3);
|
||||
background-color: rgb(144 147 153 / 30%);
|
||||
// background-color: rgba(144, 147, 153, 0.3);
|
||||
border-radius: 2px;
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: inset 0 0 6px rgb(0 0 0 / 20%);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
@ -46,6 +46,6 @@
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background-color: @primary-color;
|
||||
opacity: 0.75;
|
||||
opacity: 75%;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
html[data-theme='light'] {
|
||||
.text-secondary {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
color: rgb(0 0 0 / 45%);
|
||||
}
|
||||
|
||||
.ant-alert-success {
|
||||
@ -43,10 +43,10 @@ html[data-theme='light'] {
|
||||
}
|
||||
|
||||
.ant-calendar-selected-day .ant-calendar-date {
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
color: rgb(0 0 0 / 80%);
|
||||
}
|
||||
|
||||
.ant-select-tree li .ant-select-tree-node-content-wrapper.ant-select-tree-node-selected {
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
color: rgb(0 0 0 / 90%);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
}
|
||||
|
||||
/* fade-slide */
|
||||
@ -15,12 +15,12 @@
|
||||
}
|
||||
|
||||
.fade-slide-enter-from {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: translateX(-30px);
|
||||
}
|
||||
|
||||
.fade-slide-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: translateX(30px);
|
||||
}
|
||||
|
||||
@ -35,12 +35,12 @@
|
||||
}
|
||||
|
||||
.fade-bottom-enter-from {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: translateY(-10%);
|
||||
}
|
||||
|
||||
.fade-bottom-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: translateY(10%);
|
||||
}
|
||||
|
||||
@ -51,12 +51,12 @@
|
||||
}
|
||||
|
||||
.fade-scale-enter-from {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.fade-scale-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
@ -71,11 +71,11 @@
|
||||
}
|
||||
|
||||
.fade-top-enter-from {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: translateY(8%);
|
||||
}
|
||||
|
||||
.fade-top-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: translateY(-8%);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
&-enter-from,
|
||||
&-leave,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: scale(0);
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,7 @@
|
||||
&-enter-from,
|
||||
&-leave,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: scale(0) rotate(-45deg);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
&-enter-from,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
}
|
||||
|
||||
&-enter-from {
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
&-enter-from,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
}
|
||||
|
||||
&-enter-from {
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
&-enter-from,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
}
|
||||
|
||||
&-enter-from {
|
||||
@ -54,7 +54,7 @@
|
||||
|
||||
&-enter-from,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
}
|
||||
|
||||
&-enter-from {
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
&-enter-from,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: translateY(-15px);
|
||||
}
|
||||
}
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
&-enter-from,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: translateY(15px);
|
||||
}
|
||||
}
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
&-enter-from,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: translateX(-15px);
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,7 @@
|
||||
|
||||
&-enter-from,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: translateX(15px);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
.zoom-out-enter-from,
|
||||
.zoom-out-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
@ -17,11 +17,11 @@
|
||||
}
|
||||
|
||||
.zoom-fade-enter-from {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: scale(0.92);
|
||||
}
|
||||
|
||||
.zoom-fade-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: scale(1.06);
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { ref, unref } from 'vue';
|
||||
|
||||
export function useLockFn<P extends any[] = any[], V extends any = any>(
|
||||
fn: (...args: P) => Promise<V>,
|
||||
) {
|
||||
export function useLockFn<P extends any[] = any[], V = any>(fn: (...args: P) => Promise<V>) {
|
||||
const lockRef = ref(false);
|
||||
return async function (...args: P) {
|
||||
if (unref(lockRef)) return;
|
||||
|
@ -51,7 +51,7 @@ export function copyTextToClipboard(input: string, { target = document.body }: O
|
||||
let isSuccess = false;
|
||||
try {
|
||||
isSuccess = document.execCommand('copy');
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
throw new Error(e);
|
||||
}
|
||||
|
||||
|
@ -101,8 +101,8 @@
|
||||
if (!meta) {
|
||||
return !!name;
|
||||
}
|
||||
const { title, hideBreadcrumb } = meta;
|
||||
if (!title || hideBreadcrumb) {
|
||||
const { title, hideBreadcrumb, hideMenu } = meta;
|
||||
if (!title || hideBreadcrumb || hideMenu) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -169,7 +169,7 @@
|
||||
color: @breadcrumb-item-normal-color;
|
||||
|
||||
a {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
color: rgb(0 0 0 / 65%);
|
||||
|
||||
&:hover {
|
||||
color: @primary-color;
|
||||
@ -184,10 +184,10 @@
|
||||
|
||||
&--dark {
|
||||
.ant-breadcrumb-link {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
color: rgb(255 255 255 / 60%);
|
||||
|
||||
a {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
color: rgb(255 255 255 / 80%);
|
||||
|
||||
&:hover {
|
||||
color: @white;
|
||||
@ -197,7 +197,7 @@
|
||||
|
||||
.ant-breadcrumb-separator,
|
||||
.anticon {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
color: rgb(255 255 255 / 80%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@
|
||||
&__entry {
|
||||
position: relative;
|
||||
//height: 240px;
|
||||
padding: 130px 30px 30px 30px;
|
||||
padding: 130px 30px 30px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@
|
||||
.@{header-trigger-prefix-cls} {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding: 1px 10px 0 10px;
|
||||
padding: 1px 10px 0;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
|
||||
|
@ -189,7 +189,7 @@
|
||||
&--mobile {
|
||||
.@{logo-prefix-cls} {
|
||||
&__title {
|
||||
opacity: 1;
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@
|
||||
updateColorWeak(colorWeak);
|
||||
updateGrayMode(grayMode);
|
||||
createMessage.success(t('layout.setting.resetSuccess'));
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
createMessage.error(error);
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@
|
||||
cursor: pointer;
|
||||
background-color: #f0f2f5;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 2.5px 0 rgba(0, 0, 0, 0.18);
|
||||
box-shadow: 0 1px 2.5px 0 rgb(0 0 0 / 18%);
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
|
@ -60,7 +60,7 @@
|
||||
|
||||
&:hover {
|
||||
background-color: @primary-color;
|
||||
box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.15);
|
||||
box-shadow: 0 0 4px 0 rgb(28 36 56 / 15%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -80,13 +80,14 @@
|
||||
<script lang="ts">
|
||||
import type { Menu } from '/@/router/types';
|
||||
import type { CSSProperties } from 'vue';
|
||||
import { computed, defineComponent, onMounted, ref, unref } from 'vue';
|
||||
import { computed, defineComponent, onMounted, ref, unref, watch } from 'vue';
|
||||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
import { ScrollContainer } from '/@/components/Container';
|
||||
import { SimpleMenu, SimpleMenuTag } from '/@/components/SimpleMenu';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { AppLogo } from '/@/components/Application';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { usePermissionStore } from '/@/store/modules/permission';
|
||||
import { useDragLine } from './useLayoutSider';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
@ -138,6 +139,7 @@
|
||||
} = useMenuSetting();
|
||||
|
||||
const { title } = useGlobSetting();
|
||||
const permissionStore = usePermissionStore();
|
||||
|
||||
useDragLine(sideRef, dragBarRef, true);
|
||||
|
||||
@ -191,6 +193,17 @@
|
||||
menuModules.value = await getShallowMenus();
|
||||
});
|
||||
|
||||
// Menu changes
|
||||
watch(
|
||||
[() => permissionStore.getLastBuildMenuTime, () => permissionStore.getBackMenuList],
|
||||
async () => {
|
||||
menuModules.value = await getShallowMenus();
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
listenerRouteChange((route) => {
|
||||
currentRoute.value = route;
|
||||
setActive(true);
|
||||
@ -362,19 +375,19 @@
|
||||
|
||||
&.light {
|
||||
.@{prefix-cls}-logo {
|
||||
border-bottom: 1px solid rgb(238, 238, 238);
|
||||
border-bottom: 1px solid rgb(238 238 238);
|
||||
}
|
||||
|
||||
&.open {
|
||||
> .scrollbar {
|
||||
border-right: 1px solid rgb(238, 238, 238);
|
||||
border-right: 1px solid rgb(238 238 238);
|
||||
}
|
||||
}
|
||||
|
||||
.@{prefix-cls}-module {
|
||||
&__item {
|
||||
font-weight: normal;
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
color: rgb(0 0 0 / 65%);
|
||||
|
||||
&--active {
|
||||
color: @primary-color;
|
||||
@ -384,15 +397,15 @@
|
||||
}
|
||||
.@{prefix-cls}-menu-list {
|
||||
&__content {
|
||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 0 4px 0 rgb(0 0 0 / 10%);
|
||||
}
|
||||
|
||||
&__title {
|
||||
.pushpin {
|
||||
color: rgba(0, 0, 0, 0.35);
|
||||
color: rgb(0 0 0 / 35%);
|
||||
|
||||
&:hover {
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
color: rgb(0 0 0 / 85%);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -442,7 +455,7 @@
|
||||
&__item {
|
||||
position: relative;
|
||||
padding: 12px 0;
|
||||
color: rgba(255, 255, 255, 0.65);
|
||||
color: rgb(255 255 255 / 65%);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
@ -487,7 +500,7 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.65);
|
||||
color: rgb(255 255 255 / 65%);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
background-color: @trigger-dark-bg-color;
|
||||
@ -496,7 +509,7 @@
|
||||
}
|
||||
|
||||
&.light &-trigger {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
color: rgb(0 0 0 / 65%);
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
@ -515,21 +528,21 @@
|
||||
// margin-left: -6px;
|
||||
font-size: 18px;
|
||||
color: @primary-color;
|
||||
border-bottom: 1px solid rgb(238, 238, 238);
|
||||
opacity: 0;
|
||||
border-bottom: 1px solid rgb(238 238 238);
|
||||
opacity: 0%;
|
||||
transition: unset;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
&.show {
|
||||
min-width: 130px;
|
||||
opacity: 1;
|
||||
opacity: 100%;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.pushpin {
|
||||
margin-right: 6px;
|
||||
color: rgba(255, 255, 255, 0.65);
|
||||
color: rgb(255 255 255 / 65%);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
@ -572,7 +585,7 @@
|
||||
background-color: #f8f8f9;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.15);
|
||||
box-shadow: 0 0 4px 0 rgb(28 36 56 / 15%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -50,7 +50,7 @@ html[data-theme='light'] {
|
||||
|
||||
&:hover {
|
||||
.ant-tabs-close-x {
|
||||
opacity: 1;
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ html[data-theme='light'] {
|
||||
height: 12px;
|
||||
font-size: 12px;
|
||||
color: inherit;
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transition: none;
|
||||
|
||||
&:hover {
|
||||
@ -95,7 +95,7 @@ html[data-theme='light'] {
|
||||
transition: none;
|
||||
|
||||
.ant-tabs-close-x {
|
||||
opacity: 1;
|
||||
opacity: 100%;
|
||||
}
|
||||
|
||||
svg {
|
||||
@ -135,7 +135,7 @@ html[data-theme='light'] {
|
||||
|
||||
&--hide-close {
|
||||
.ant-tabs-close-x {
|
||||
opacity: 0 !important;
|
||||
opacity: 0% !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ import type { RouteRecordRaw, RouteMeta } from 'vue-router';
|
||||
import { RoleEnum } from '/@/enums/roleEnum';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export type Component<T extends any = any> =
|
||||
export type Component<T = any> =
|
||||
| ReturnType<typeof defineComponent>
|
||||
| (() => Promise<typeof import('*.vue')>)
|
||||
| (() => Promise<T>);
|
||||
|
@ -3,8 +3,8 @@
|
||||
*/
|
||||
import moment from 'moment';
|
||||
|
||||
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm';
|
||||
const DATE_FORMAT = 'YYYY-MM-DD ';
|
||||
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';
|
||||
const DATE_FORMAT = 'YYYY-MM-DD';
|
||||
|
||||
export function formatToDateTime(
|
||||
date: moment.MomentInput = undefined,
|
||||
|
@ -5,7 +5,7 @@ export function dataURLtoBlob(base64Buf: string): Blob {
|
||||
const arr = base64Buf.split(',');
|
||||
const typeItem = arr[0];
|
||||
const mime = typeItem.match(/:(.*?);/)![1];
|
||||
const bstr = atob(arr[1]);
|
||||
const bstr = window.atob(arr[1]);
|
||||
let n = bstr.length;
|
||||
const u8arr = new Uint8Array(n);
|
||||
while (n--) {
|
||||
|
@ -36,9 +36,7 @@ export function downloadByBase64(buf: string, filename: string, mime?: string, b
|
||||
export function downloadByData(data: BlobPart, filename: string, mime?: string, bom?: BlobPart) {
|
||||
const blobData = typeof bom !== 'undefined' ? [bom, data] : [data];
|
||||
const blob = new Blob(blobData, { type: mime || 'application/octet-stream' });
|
||||
if (typeof window.navigator.msSaveBlob !== 'undefined') {
|
||||
window.navigator.msSaveBlob(blob, filename);
|
||||
} else {
|
||||
|
||||
const blobURL = window.URL.createObjectURL(blob);
|
||||
const tempLink = document.createElement('a');
|
||||
tempLink.style.display = 'none';
|
||||
@ -51,7 +49,6 @@ export function downloadByData(data: BlobPart, filename: string, mime?: string,
|
||||
tempLink.click();
|
||||
document.body.removeChild(tempLink);
|
||||
window.URL.revokeObjectURL(blobURL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,6 +81,7 @@ export class VAxios {
|
||||
this.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {
|
||||
// If cancel repeat request is turned on, then cancel repeat request is prohibited
|
||||
const {
|
||||
// @ts-ignore
|
||||
headers: { ignoreCancelToken },
|
||||
} = config;
|
||||
const ignoreCancel =
|
||||
@ -149,6 +150,7 @@ export class VAxios {
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-type': ContentTypeEnum.FORM_DATA,
|
||||
// @ts-ignore
|
||||
ignoreCancelToken: true,
|
||||
},
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { isObject, isString } from '/@/utils/is';
|
||||
|
||||
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm';
|
||||
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';
|
||||
|
||||
export function joinTimestamp<T extends boolean>(
|
||||
join: boolean,
|
||||
@ -35,7 +35,7 @@ export function formatRequestDate(params: Recordable) {
|
||||
if (value) {
|
||||
try {
|
||||
params[key] = isString(value) ? value.trim() : value;
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
throw new Error(error);
|
||||
}
|
||||
}
|
||||
|
@ -47,12 +47,12 @@
|
||||
}
|
||||
|
||||
.custom-enter {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: scale(0.4) translate(100%);
|
||||
}
|
||||
|
||||
.custom-enter-to {
|
||||
opacity: 1;
|
||||
opacity: 100%;
|
||||
}
|
||||
|
||||
.custom-enter-active {
|
||||
@ -63,11 +63,11 @@
|
||||
}
|
||||
|
||||
.custom-leave {
|
||||
opacity: 1;
|
||||
opacity: 100%;
|
||||
}
|
||||
|
||||
.custom-leave-to {
|
||||
opacity: 0;
|
||||
opacity: 0%;
|
||||
transform: scale(0.4) translate(-100%);
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,6 @@
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
margin-top: 20px;
|
||||
background-color: rgb(126, 170, 236);
|
||||
background-color: rgb(126 170 236);
|
||||
}
|
||||
</style>
|
||||
|
@ -52,6 +52,7 @@
|
||||
>
|
||||
修改查询按钮
|
||||
</a-button>
|
||||
<a-button @click="handleLoad" class="mr-2"> 联动回显 </a-button>
|
||||
</div>
|
||||
<CollapseContainer title="useForm示例">
|
||||
<BasicForm @register="register" @submit="handleSubmit" />
|
||||
@ -64,6 +65,7 @@
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { PageWrapper } from '/@/components/Page';
|
||||
import { areaRecord } from '/@/api/demo/cascader';
|
||||
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
@ -166,6 +168,48 @@
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field8',
|
||||
component: 'ApiCascader',
|
||||
label: '联动',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
api: areaRecord,
|
||||
apiParamKey: 'parentCode',
|
||||
dataField: 'data',
|
||||
labelField: 'name',
|
||||
valueField: 'code',
|
||||
initFetchParams: {
|
||||
parentCode: '',
|
||||
},
|
||||
isLeaf: (record) => {
|
||||
return !(record.levelType < 3);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field9',
|
||||
component: 'ApiCascader',
|
||||
label: '联动回显',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
api: areaRecord,
|
||||
apiParamKey: 'parentCode',
|
||||
dataField: 'data',
|
||||
labelField: 'name',
|
||||
valueField: 'code',
|
||||
initFetchParams: {
|
||||
parentCode: '',
|
||||
},
|
||||
isLeaf: (record) => {
|
||||
return !(record.levelType < 3);
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default defineComponent({
|
||||
@ -173,7 +217,7 @@
|
||||
setup() {
|
||||
const { createMessage } = useMessage();
|
||||
|
||||
const [register, { setProps }] = useForm({
|
||||
const [register, { setProps, setFieldsValue, updateSchema }] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas,
|
||||
actionColOptions: {
|
||||
@ -181,6 +225,35 @@
|
||||
},
|
||||
fieldMapToTime: [['fieldTime', ['startTime', 'endTime'], 'YYYY-MM']],
|
||||
});
|
||||
|
||||
async function handleLoad() {
|
||||
const promiseFn = function () {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
field9: ['430000', '430100', '430102'],
|
||||
province: '湖南省',
|
||||
city: '长沙市',
|
||||
district: '岳麓区',
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
};
|
||||
|
||||
const item = await promiseFn();
|
||||
|
||||
const { field9, province, city, district } = item as any;
|
||||
await updateSchema({
|
||||
field: 'field9',
|
||||
componentProps: {
|
||||
displayRenderArray: [province, city, district],
|
||||
},
|
||||
});
|
||||
await setFieldsValue({
|
||||
field9,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
register,
|
||||
schemas,
|
||||
@ -188,6 +261,7 @@
|
||||
createMessage.success('click search,values:' + JSON.stringify(values));
|
||||
},
|
||||
setProps,
|
||||
handleLoad,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -70,17 +70,17 @@
|
||||
}
|
||||
|
||||
&__content {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
color: rgb(0 0 0 / 65%);
|
||||
}
|
||||
|
||||
&__action {
|
||||
display: inline-block;
|
||||
padding: 0 16px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
color: rgb(0 0 0 / 45%);
|
||||
|
||||
&:nth-child(1),
|
||||
&:nth-child(2) {
|
||||
border-right: 1px solid rgba(206, 206, 206, 0.4);
|
||||
border-right: 1px solid rgb(206 206 206 / 40%);
|
||||
}
|
||||
|
||||
&-icon {
|
||||
@ -91,7 +91,7 @@
|
||||
&__time {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
color: rgb(0 0 0 / 45%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -48,7 +48,7 @@
|
||||
width: 100%;
|
||||
|
||||
.ant-card-body {
|
||||
padding: 0 0 24px 0;
|
||||
padding: 0 0 24px;
|
||||
}
|
||||
|
||||
img {
|
||||
@ -60,7 +60,7 @@
|
||||
margin: 5px 10px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
color: rgb(0 0 0 / 85%);
|
||||
}
|
||||
|
||||
&-content {
|
||||
|
@ -98,13 +98,13 @@
|
||||
padding: 0 10px;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-right: 1px dashed rgb(206, 206, 206, 0.5);
|
||||
border-right: 1px dashed rgb(206 206 206 / 50%);
|
||||
}
|
||||
}
|
||||
|
||||
&-top {
|
||||
padding: 10px;
|
||||
margin: 16px 16px 12px 16px;
|
||||
margin: 16px 16px 12px;
|
||||
background-color: @component-background;
|
||||
border-radius: 3px;
|
||||
|
||||
@ -147,7 +147,7 @@
|
||||
|
||||
&-bottom {
|
||||
padding: 10px;
|
||||
margin: 0 16px 16px 16px;
|
||||
margin: 0 16px 16px;
|
||||
background-color: @component-background;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
@ -129,7 +129,7 @@
|
||||
&__time {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
color: rgb(0 0 0 / 45%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -210,7 +210,7 @@
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
background-color: rgb(0 0 0 / 50%);
|
||||
backdrop-filter: blur(8px);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
@ -1,8 +1,10 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
plugins: ['stylelint-order'],
|
||||
customSyntax: 'postcss-less',
|
||||
extends: ['stylelint-config-standard', 'stylelint-config-prettier'],
|
||||
rules: {
|
||||
'selector-class-pattern': null,
|
||||
'selector-pseudo-class-no-unknown': [
|
||||
true,
|
||||
{
|
||||
@ -67,4 +69,25 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts'],
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.vue', '**/*.vue', '*.html', '**/*.html'],
|
||||
extends: ['stylelint-config-recommended', 'stylelint-config-html'],
|
||||
rules: {
|
||||
'keyframes-name-pattern': null,
|
||||
'selector-pseudo-class-no-unknown': [
|
||||
true,
|
||||
{
|
||||
ignorePseudoClasses: ['deep', 'global'],
|
||||
},
|
||||
],
|
||||
'selector-pseudo-element-no-unknown': [
|
||||
true,
|
||||
{
|
||||
ignorePseudoElements: ['v-deep', 'v-global', 'v-slotted'],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
@ -8,8 +8,8 @@ It is used to start the test interface service, which can test the upload, webso
|
||||
|
||||
cd ./test/server
|
||||
|
||||
yarn
|
||||
pnpm install
|
||||
|
||||
yarn start
|
||||
pnpm run start
|
||||
|
||||
```
|
||||
|
@ -24,13 +24,13 @@
|
||||
"@types/koa": "^2.13.4",
|
||||
"@types/koa-bodyparser": "^5.0.2",
|
||||
"@types/koa-router": "^7.4.4",
|
||||
"@types/node": "^16.11.1",
|
||||
"nodemon": "^2.0.14",
|
||||
"@types/node": "^16.11.7",
|
||||
"nodemon": "^2.0.15",
|
||||
"pm2": "^5.1.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-node": "^10.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"tsconfig-paths": "^3.11.0",
|
||||
"tsup": "^5.4.2",
|
||||
"tsup": "^5.6.0",
|
||||
"typescript": "^4.4.4"
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ export default defineConfig({
|
||||
* Used for animation when the element is displayed
|
||||
* @param maxOutput The larger the maxOutput output, the larger the generated css volume
|
||||
*/
|
||||
function createEnterPlugin(maxOutput = 8) {
|
||||
function createEnterPlugin(maxOutput = 6) {
|
||||
const createCss = (index: number, d = 'x') => {
|
||||
const upd = d.toUpperCase();
|
||||
return {
|
||||
|
Loading…
Reference in New Issue
Block a user