diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index 1e85c0f..0000000
--- a/.eslintignore
+++ /dev/null
@@ -1,8 +0,0 @@
-/build/
-/config/
-/dist/
-/*.js
-/test/unit/coverage/
-/node_modules/*
-/dist*
-/src/main.ts
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
deleted file mode 100644
index 8068163..0000000
--- a/.eslintrc.cjs
+++ /dev/null
@@ -1,71 +0,0 @@
-// @ts-check
-const { defineConfig } = require('eslint-define-config')
-module.exports = defineConfig({
- root: true,
- env: {
- browser: true,
- node: true,
- es6: true
- },
- parser: 'vue-eslint-parser',
- parserOptions: {
- parser: '@typescript-eslint/parser',
- ecmaVersion: 2020,
- sourceType: 'module',
- jsxPragma: 'React',
- ecmaFeatures: {
- jsx: true
- }
- },
- extends: [
- 'plugin:vue/vue3-recommended',
- 'plugin:@typescript-eslint/recommended',
- 'prettier',
- 'plugin:prettier/recommended'
- ],
- rules: {
- 'vue/no-setup-props-destructure': 'off',
- 'vue/script-setup-uses-vars': 'error',
- 'vue/no-reserved-component-names': 'off',
- '@typescript-eslint/ban-ts-ignore': 'off',
- '@typescript-eslint/explicit-function-return-type': 'off',
- '@typescript-eslint/no-explicit-any': 'off',
- '@typescript-eslint/no-var-requires': 'off',
- '@typescript-eslint/no-empty-function': 'off',
- 'vue/custom-event-name-casing': 'off',
- 'no-use-before-define': 'off',
- '@typescript-eslint/no-use-before-define': 'off',
- '@typescript-eslint/ban-ts-comment': 'off',
- '@typescript-eslint/ban-types': 'off',
- '@typescript-eslint/no-non-null-assertion': 'off',
- '@typescript-eslint/explicit-module-boundary-types': 'off',
- '@typescript-eslint/no-unused-vars': 'off',
- 'no-unused-vars': 'off',
- 'space-before-function-paren': 'off',
-
- 'vue/attributes-order': 'off',
- 'vue/one-component-per-file': 'off',
- 'vue/html-closing-bracket-newline': 'off',
- 'vue/max-attributes-per-line': 'off',
- 'vue/multiline-html-element-content-newline': 'off',
- 'vue/singleline-html-element-content-newline': 'off',
- 'vue/attribute-hyphenation': 'off',
- 'vue/require-default-prop': 'off',
- 'vue/require-explicit-emits': 'off',
- 'vue/html-self-closing': [
- 'error',
- {
- html: {
- void: 'always',
- normal: 'never',
- component: 'always'
- },
- svg: 'always',
- math: 'always'
- }
- ],
- 'vue/multi-word-component-names': 'off',
- 'vue/no-v-html': 'off',
- 'vue/require-toggle-inside-transition': 'off'
- }
-})
diff --git a/.husky/commit-msg b/.husky/commit-msg
index 10cb551..34eed8b 100755
--- a/.husky/commit-msg
+++ b/.husky/commit-msg
@@ -1,4 +1 @@
-#!/bin/sh
-. "$(dirname "$0")/_/husky.sh"
-
-pnpm commitlint --edit "$1"
+npx --no -- commitlint --edit $1
\ No newline at end of file
diff --git a/.husky/pre-commit b/.husky/pre-commit
index a6a2318..d96ed69 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,8 +1,2 @@
-#!/bin/sh
-. "$(dirname "$0")/_/husky.sh"
-
-[ -n "$CI" ] && exit 0
-
-# Format and submit code according to lintstagedrc.js configuration
npm run ts:check
-npm run lint:lint-staged
+npm run lint:lint-staged
\ No newline at end of file
diff --git a/README.md b/README.md
index eaefcc0..ab94ab3 100644
--- a/README.md
+++ b/README.md
@@ -137,16 +137,10 @@ If you find this project helpful, welcome sponsorship to show your support~
-## Group
-
-If you want to join the technical communication group for discussion, please scan the code to join the group or add me as a friend
-
-### Group QR code
-
-
-
### My QR code
+If you have any project cooperation or outsourcing, please scan the code to add me as a friend and leave a note of your purpose.
+
## License
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 3bae52f..2b153a6 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -137,16 +137,10 @@ pnpm run build:pro
-## 交流群
-
-如果你想进入技术交流群讨论,请扫码加入或者添加我为好友邀请入群
-
-### 群二维码
-
-
-
### 我的二维码
+如有项目合作或项目外包,扫码加我好友,请备注来意。
+
## 许可证
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 0000000..6c8a81f
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,81 @@
+// 引入vue模版的eslint
+import pluginVue from 'eslint-plugin-vue'
+import eslint from '@eslint/js'
+// ts-eslint解析器,使 eslint 可以解析 ts 语法
+import tseslint from 'typescript-eslint'
+// vue文件解析器
+import vueParser from 'vue-eslint-parser'
+import prettier from 'eslint-plugin-prettier'
+
+export default tseslint.config({
+ // ignores: ['node_modules', 'prettier.config.cjs', 'dist*'],
+ files: ['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.vue'],
+ // tseslint.config添加了extends扁平函数,直接用。否则是eslint9.0版本是没有extends的
+ extends: [
+ eslint.configs.recommended,
+ ...tseslint.configs.recommended,
+ ...pluginVue.configs['flat/essential']
+ ],
+ plugins: {
+ prettier
+ },
+ languageOptions: {
+ parser: vueParser, // 使用vue解析器,这个可以识别vue文件
+ parserOptions: {
+ parser: tseslint.parser, // 在vue文件上使用ts解析器
+ sourceType: 'module',
+ ecmaVersion: 2020,
+ ecmaFeatures: {
+ jsx: true
+ }
+ }
+ },
+ rules: {
+ 'prettier/prettier': 'error',
+ 'no-useless-escape': 0,
+ 'no-undef': 0,
+ 'vue/no-setup-props-destructure': 0,
+ 'vue/script-setup-uses-vars': 1,
+ 'vue/no-reserved-component-names': 0,
+ '@typescript-eslint/ban-ts-ignore': 0,
+ '@typescript-eslint/explicit-function-return-type': 0,
+ '@typescript-eslint/no-explicit-any': 0,
+ '@typescript-eslint/no-var-requires': 0,
+ '@typescript-eslint/no-empty-function': 0,
+ 'vue/custom-event-name-casing': 0,
+ 'no-use-before-define': 0,
+ '@typescript-eslint/no-use-before-define': 0,
+ '@typescript-eslint/ban-ts-comment': 0,
+ '@typescript-eslint/ban-types': 0,
+ '@typescript-eslint/no-non-null-assertion': 0,
+ '@typescript-eslint/explicit-module-boundary-types': 0,
+ '@typescript-eslint/no-unused-vars': 0,
+ 'no-unused-vars': 0,
+ 'space-before-function-paren': 0,
+
+ 'vue/attributes-order': 0,
+ 'vue/one-component-per-file': 0,
+ 'vue/html-closing-bracket-newline': 0,
+ 'vue/max-attributes-per-line': 0,
+ 'vue/multiline-html-element-content-newline': 0,
+ 'vue/singleline-html-element-content-newline': 0,
+ 'vue/attribute-hyphenation': 0,
+ 'vue/require-default-prop': 0,
+ 'vue/require-explicit-emits': 0,
+ 'vue/html-self-closing': [
+ 1,
+ {
+ html: {
+ void: 'always',
+ normal: 'never',
+ component: 'always'
+ },
+ svg: 'always',
+ math: 'always'
+ }
+ ],
+ 'vue/multi-word-component-names': 0,
+ 'vue/no-v-html': 0,
+ 'vue/require-toggle-inside-transition': 0
+ }
+})
diff --git a/package.json b/package.json
index c5d80bf..9bed0cf 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"npm:check": "pnpx npm-check-updates -u",
"clean": "pnpx rimraf node_modules",
"clean:cache": "pnpx rimraf node_modules/.cache",
- "lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src",
+ "lint:eslint": "eslint . --fix \"src/**/*.{js,ts,tsx,vue,html}\"",
"lint:format": "prettier --write --loglevel warn \"src/**/*.{js,ts,json,tsx,css,less,vue,html,md}\"",
"lint:style": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
"lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.cjs",
@@ -30,7 +30,7 @@
"dependencies": {
"@iconify/iconify": "^3.1.1",
"@iconify/vue": "^4.1.2",
- "@vueuse/core": "^10.10.0",
+ "@vueuse/core": "^10.11.0",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.10",
"@zxcvbn-ts/core": "^3.0.4",
@@ -39,78 +39,79 @@
"cropperjs": "^1.6.2",
"dayjs": "^1.11.11",
"driver.js": "^1.3.1",
- "echarts": "^5.5.0",
+ "echarts": "^5.5.1",
"echarts-wordcloud": "^2.1.0",
- "element-plus": "2.7.4",
+ "element-plus": "2.7.7",
"lodash-es": "^4.17.21",
"mitt": "^3.0.1",
- "monaco-editor": "^0.49.0",
+ "monaco-editor": "^0.50.0",
"nprogress": "^0.2.0",
"pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.1",
"qrcode": "^1.5.3",
- "qs": "^6.12.1",
+ "qs": "^6.12.3",
"url": "^0.11.3",
- "vue": "3.4.27",
- "vue-draggable-plus": "^0.5.0",
+ "vue": "3.4.32",
+ "vue-draggable-plus": "^0.5.2",
"vue-i18n": "9.13.1",
"vue-json-pretty": "^2.4.0",
- "vue-router": "^4.3.2",
- "vue-types": "^5.1.2",
+ "vue-router": "^4.4.0",
+ "vue-types": "^5.1.3",
"xgplayer": "^3.0.18"
},
"devDependencies": {
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
- "@iconify/json": "^2.2.215",
+ "@iconify/json": "^2.2.229",
"@intlify/unplugin-vue-i18n": "^4.0.0",
"@types/fs-extra": "^11.0.4",
"@types/inquirer": "^9.0.7",
"@types/lodash-es": "^4.17.12",
"@types/mockjs": "^1.0.10",
- "@types/node": "^20.13.0",
+ "@types/node": "^20.14.11",
"@types/nprogress": "^0.2.3",
"@types/qrcode": "^1.5.5",
"@types/qs": "^6.9.15",
"@types/sortablejs": "^1.15.8",
- "@typescript-eslint/eslint-plugin": "^7.11.0",
- "@typescript-eslint/parser": "^7.11.0",
- "@unocss/transformer-variant-group": "^0.60.4",
+ "@typescript-eslint/eslint-plugin": "^7.16.1",
+ "@typescript-eslint/parser": "^7.16.1",
+ "@unocss/transformer-variant-group": "^0.61.5",
"@vitejs/plugin-legacy": "^5.4.1",
"@vitejs/plugin-vue": "^5.0.5",
"@vitejs/plugin-vue-jsx": "^4.0.0",
"autoprefixer": "^10.4.19",
"chalk": "^5.3.0",
"consola": "^3.2.3",
- "eslint": "^8.57.0",
+ "eslint": "^9.7.0",
"eslint-config-prettier": "^9.1.0",
"eslint-define-config": "^2.1.0",
- "eslint-plugin-prettier": "^5.1.3",
- "eslint-plugin-vue": "^9.26.0",
+ "eslint-plugin-prettier": "^5.2.1",
+ "eslint-plugin-vue": "^9.27.0",
"esno": "^4.7.0",
"fs-extra": "^11.2.0",
- "husky": "^9.0.11",
- "inquirer": "^9.2.23",
+ "husky": "^9.1.0",
+ "inquirer": "^10.0.3",
"less": "^4.2.0",
- "lint-staged": "^15.2.5",
+ "lint-staged": "^15.2.7",
"mockjs": "^1.1.0",
"plop": "^4.0.1",
- "postcss": "^8.4.38",
+ "postcss": "^8.4.39",
"postcss-html": "^1.7.0",
"postcss-less": "^6.0.0",
- "prettier": "^3.2.5",
- "rimraf": "^5.0.7",
- "rollup": "^4.18.0",
+ "prettier": "^3.3.3",
+ "rimraf": "^6.0.1",
+ "rollup": "^4.18.1",
"rollup-plugin-visualizer": "^5.12.0",
- "stylelint": "^16.6.1",
+ "stylelint": "^16.7.0",
"stylelint-config-html": "^1.1.0",
- "stylelint-config-recommended": "^14.0.0",
- "stylelint-config-standard": "^36.0.0",
+ "stylelint-config-recommended": "^14.0.1",
+ "stylelint-config-standard": "^36.0.1",
"stylelint-order": "^6.0.4",
- "terser": "^5.31.0",
- "typescript": "5.4.5",
- "unocss": "^0.60.4",
- "vite": "5.2.12",
+ "terser": "^5.31.3",
+ "typescript": "5.5.3",
+ "typescript-eslint": "^7.16.1",
+ "unocss": "^0.61.5",
+ "vite": "5.3.4",
"vite-plugin-ejs": "^1.7.0",
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-mock": "2.9.6",
@@ -119,7 +120,7 @@
"vite-plugin-style-import": "2.0.0",
"vite-plugin-svg-icons": "^2.0.1",
"vite-plugin-url-copy": "^1.1.4",
- "vue-tsc": "^2.0.19"
+ "vue-tsc": "^2.0.26"
},
"packageManager": "pnpm@8.1.0",
"engines": {
diff --git a/src/components/Button/src/Button.vue b/src/components/Button/src/Button.vue
index e5af71b..c20028c 100644
--- a/src/components/Button/src/Button.vue
+++ b/src/components/Button/src/Button.vue
@@ -90,16 +90,16 @@ const props = defineProps({
const emits = defineEmits(['click'])
const color = computed(() => {
- const { type } = props
- if (type === 'primary') {
+ const { type, link } = props
+ if (type === 'primary' && !link) {
return unref(getTheme).elColorPrimary
}
return ''
})
const style = computed(() => {
- const { type } = props
- if (type === 'primary') {
+ const { type, link } = props
+ if (type === 'primary' && !link) {
return '--el-button-text-color: #fff; --el-button-hover-text-color: #fff'
}
return ''
diff --git a/src/components/Descriptions/src/Descriptions.vue b/src/components/Descriptions/src/Descriptions.vue
index 2c773b8..a4b222b 100644
--- a/src/components/Descriptions/src/Descriptions.vue
+++ b/src/components/Descriptions/src/Descriptions.vue
@@ -133,7 +133,7 @@ export default defineComponent({
{item.slots?.default
? item.slots?.default(props.data)
- : get(props.data, item.field) ?? defaultData}
+ : (get(props.data, item.field) ?? defaultData)}
) : (
@@ -147,7 +147,7 @@ export default defineComponent({
{item.slots?.default
? item.slots?.default(props.data)
- : get(props.data, item.field) ?? defaultData}
+ : (get(props.data, item.field) ?? defaultData)}
)}
diff --git a/src/components/Dialog/hooks/useResize.ts b/src/components/Dialog/hooks/useResize.ts
new file mode 100644
index 0000000..d52b279
--- /dev/null
+++ b/src/components/Dialog/hooks/useResize.ts
@@ -0,0 +1,178 @@
+import { ref } from 'vue'
+
+export const useResize = (props?: {
+ minHeightPx?: number
+ minWidthPx?: number
+ initHeight?: number
+ initWidth?: number
+}) => {
+ const {
+ minHeightPx = 400,
+ minWidthPx = window.innerWidth / 2,
+ initHeight = 400,
+ initWidth = window.innerWidth / 2
+ } = props || {}
+ // 屏幕宽度的 50% 作为最小宽度
+ // const minWidthPx = window.innerWidth / 2
+ // 固定的最小高度 400px
+ // const minHeightPx = 400
+ // 初始高度限制为 400px
+ const maxHeight = ref(initHeight + 'px')
+ // 初始宽度限制为 50%
+ const minWidth = ref(initWidth + 'px')
+ const setupDrag = (elDialog: any, el: any) => {
+ // 获取对话框元素
+ // 是否正在调整大小的标志
+ let isResizing = false
+ // 当前调整的方向
+ let currentResizeDirection = ''
+
+ // 鼠标移动时的事件处理器,用于检测鼠标位置并设置相应的光标样式
+ const handleMouseMove = (e: any) => {
+ const rect = elDialog.getBoundingClientRect()
+ // 鼠标相对于对话框左侧的偏移量
+ const offsetX = e.clientX - rect.left
+ // 鼠标相对于对话框顶部的偏移量
+ const offsetY = e.clientY - rect.top
+ const width = elDialog.clientWidth
+ const height = elDialog.clientHeight
+
+ // 获取对话框的内边距
+ const computedStyle = window.getComputedStyle(elDialog)
+ const paddingLeft = parseFloat(computedStyle.paddingLeft)
+ const paddingRight = parseFloat(computedStyle.paddingRight)
+ const paddingBottom = parseFloat(computedStyle.paddingBottom)
+ const paddingTop = parseFloat(computedStyle.paddingTop)
+
+ // 根据鼠标位置设置相应的光标样式和调整方向
+ if (!isResizing) {
+ if (offsetX < paddingLeft && offsetY > paddingTop && offsetY < height - paddingBottom) {
+ elDialog.style.cursor = 'ew-resize' // 左右箭头
+ currentResizeDirection = 'left'
+ } else if (
+ offsetX > width - paddingRight &&
+ offsetY > paddingTop &&
+ offsetY < height - paddingBottom
+ ) {
+ elDialog.style.cursor = 'ew-resize' // 左右箭头
+ currentResizeDirection = 'right'
+ } else if (
+ offsetY < paddingTop &&
+ offsetX > paddingLeft &&
+ offsetX < width - paddingRight
+ ) {
+ elDialog.style.cursor = 'ns-resize' // 上下箭头
+ currentResizeDirection = 'top'
+ } else if (
+ offsetY > height - paddingBottom &&
+ offsetX > paddingLeft &&
+ offsetX < width - paddingRight
+ ) {
+ elDialog.style.cursor = 'ns-resize' // 上下箭头
+ currentResizeDirection = 'bottom'
+ } else if (offsetX < paddingLeft && offsetY < paddingTop) {
+ elDialog.style.cursor = 'nwse-resize' // 左上右下箭头
+ currentResizeDirection = 'top-left'
+ } else if (offsetX > width - paddingRight && offsetY < paddingTop) {
+ elDialog.style.cursor = 'nesw-resize' // 右上左下箭头
+ currentResizeDirection = 'top-right'
+ } else if (offsetX < paddingLeft && offsetY > height - paddingBottom) {
+ elDialog.style.cursor = 'nesw-resize' // 右上左下箭头
+ currentResizeDirection = 'bottom-left'
+ } else if (offsetX > width - paddingRight && offsetY > height - paddingBottom) {
+ elDialog.style.cursor = 'nwse-resize' // 左上右下箭头
+ currentResizeDirection = 'bottom-right'
+ } else {
+ elDialog.style.cursor = 'default'
+ currentResizeDirection = ''
+ }
+ }
+ }
+
+ // 鼠标按下时的事件处理器,开始调整对话框大小
+ const handleMouseDown = (e) => {
+ if (currentResizeDirection) {
+ isResizing = true
+
+ const initialX = e.clientX
+ const initialY = e.clientY
+ const initialWidth = elDialog.clientWidth
+ const initialHeight = el.querySelector('.el-dialog__body').clientHeight
+
+ // 调整大小的事件处理器
+ const handleResizing = (e: any) => {
+ if (!isResizing) return
+
+ let newWidth = initialWidth
+ let newHeight = initialHeight
+
+ // 根据当前调整方向计算新的宽度和高度
+ if (currentResizeDirection.includes('right')) {
+ newWidth = Math.max(minWidthPx, initialWidth + (e.clientX - initialX) * 2)
+ minWidth.value = `${newWidth}px`
+ }
+
+ if (currentResizeDirection.includes('left')) {
+ newWidth = Math.max(minWidthPx, initialWidth - (e.clientX - initialX) * 2)
+ minWidth.value = `${newWidth}px`
+ }
+
+ if (currentResizeDirection.includes('bottom')) {
+ newHeight = Math.max(minHeightPx, initialHeight + (e.clientY - initialY) * 2 - 20)
+ maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
+ }
+
+ if (currentResizeDirection.includes('top')) {
+ newHeight = Math.max(minHeightPx, initialHeight - (e.clientY - initialY) * 2 - 20)
+ maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
+ }
+
+ if (currentResizeDirection === 'top-left') {
+ newWidth = Math.max(minWidthPx, initialWidth - (e.clientX - initialX) * 2)
+ minWidth.value = `${newWidth}px`
+ newHeight = Math.max(minHeightPx, initialHeight - (e.clientY - initialY) * 2 - 20)
+ maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
+ }
+
+ if (currentResizeDirection === 'top-right') {
+ newWidth = Math.max(minWidthPx, initialWidth + (e.clientX - initialX) * 2)
+ minWidth.value = `${newWidth}px`
+ newHeight = Math.max(minHeightPx, initialHeight - (e.clientY - initialY) * 2 - 20)
+ maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
+ }
+
+ if (currentResizeDirection === 'bottom-left') {
+ newWidth = Math.max(minWidthPx, initialWidth - (e.clientX - initialX) * 2)
+ minWidth.value = `${newWidth}px`
+ newHeight = Math.max(minHeightPx, initialHeight + (e.clientY - initialY) * 2 - 20)
+ maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
+ }
+
+ if (currentResizeDirection === 'bottom-right') {
+ newWidth = Math.max(minWidthPx, initialWidth + (e.clientX - initialX) * 2)
+ minWidth.value = `${newWidth}px`
+ newHeight = Math.max(minHeightPx, initialHeight + (e.clientY - initialY) * 2 - 20)
+ maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
+ }
+ }
+ // 停止调整大小的事件处理器
+ const stopResizing = () => {
+ isResizing = false
+ document.removeEventListener('mousemove', handleResizing)
+ document.removeEventListener('mouseup', stopResizing)
+ }
+
+ document.addEventListener('mousemove', handleResizing)
+ document.addEventListener('mouseup', stopResizing)
+ }
+ }
+ elDialog.addEventListener('mousemove', handleMouseMove)
+ elDialog.addEventListener('mousedown', handleMouseDown)
+ }
+
+ return {
+ setupDrag,
+ maxHeight,
+ minWidth
+ }
+}
diff --git a/src/components/Dialog/src/Dialog.vue b/src/components/Dialog/src/Dialog.vue
index 9534db0..611d702 100644
--- a/src/components/Dialog/src/Dialog.vue
+++ b/src/components/Dialog/src/Dialog.vue
@@ -49,6 +49,13 @@ watch(
}
)
+watch(
+ () => props.maxHeight,
+ (val) => {
+ dialogHeight.value = isNumber(val) ? `${val}px` : val
+ }
+)
+
const dialogStyle = computed(() => {
return {
height: unref(dialogHeight)
diff --git a/src/components/Dialog/src/ResizeDialog.vue b/src/components/Dialog/src/ResizeDialog.vue
new file mode 100644
index 0000000..d604e12
--- /dev/null
+++ b/src/components/Dialog/src/ResizeDialog.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
diff --git a/src/components/Footer/src/Footer.vue b/src/components/Footer/src/Footer.vue
index c725e4b..50b7ce7 100644
--- a/src/components/Footer/src/Footer.vue
+++ b/src/components/Footer/src/Footer.vue
@@ -15,7 +15,7 @@ const title = computed(() => appStore.getTitle)
diff --git a/src/components/Form/src/helper/index.ts b/src/components/Form/src/helper/index.ts
index dc52589..3ddb1b4 100644
--- a/src/components/Form/src/helper/index.ts
+++ b/src/components/Form/src/helper/index.ts
@@ -161,7 +161,7 @@ export const initModel = (schema: FormSchema[], formModel: Recordable) => {
// 如果 schema 对应的 field 不存在,则删除 model 中的对应的 field
for (let i = 0; i < schema.length; i++) {
const key = schema[i].field
- if (!get(model, key)) {
+ if (!get(model, key) && get(model, key) !== 0) {
delete model[key]
}
}
diff --git a/src/components/Menu/src/Menu.vue b/src/components/Menu/src/Menu.vue
index d7c69ec..083d03c 100644
--- a/src/components/Menu/src/Menu.vue
+++ b/src/components/Menu/src/Menu.vue
@@ -98,7 +98,7 @@ export default defineComponent({
>
{{
default: () => {
- const { renderMenuItem } = useRenderMenuItem()
+ const { renderMenuItem } = useRenderMenuItem(menuMode)
return renderMenuItem(unref(routers))
}
}}
@@ -257,4 +257,22 @@ export default defineComponent({
}
}
}
+
+@submenu-prefix-cls: ~'@{adminNamespace}-submenu-popper';
+
+// 设置子菜单溢出时滚动样式
+.@{submenu-prefix-cls}--vertical {
+ max-height: 100%;
+ overflow-y: auto;
+
+ &::-webkit-scrollbar {
+ width: 6px;
+ background-color: transparent;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background-color: rgb(144 147 153 / 30%);
+ border-radius: 4px;
+ }
+}
diff --git a/src/components/Menu/src/components/useRenderMenuItem.tsx b/src/components/Menu/src/components/useRenderMenuItem.tsx
index 301313f..96914cc 100644
--- a/src/components/Menu/src/components/useRenderMenuItem.tsx
+++ b/src/components/Menu/src/components/useRenderMenuItem.tsx
@@ -1,12 +1,17 @@
import { ElSubMenu, ElMenuItem } from 'element-plus'
+import { unref } from 'vue'
import { hasOneShowingChild } from '../helper'
import { isUrl } from '@/utils/is'
import { useRenderMenuTitle } from './useRenderMenuTitle'
import { pathResolve } from '@/utils/routerHelper'
+import { useDesign } from '@/hooks/web/useDesign'
+
+const { getPrefixCls } = useDesign()
+const prefixCls = getPrefixCls('submenu')
const { renderMenuTitle } = useRenderMenuTitle()
-export const useRenderMenuItem = () =>
+export const useRenderMenuItem = (menuMode) =>
// allRouters: AppRouteRecordRaw[] = [],
{
const renderMenuItem = (routers: AppRouteRecordRaw[], parentPath = '/') => {
@@ -33,7 +38,11 @@ export const useRenderMenuItem = () =>
)
} else {
return (
-
+
{{
title: () => renderMenuTitle(meta),
default: () => renderMenuItem(v.children!, fullPath)
diff --git a/src/components/Table/src/components/ColumnSetting.vue b/src/components/Table/src/components/ColumnSetting.vue
index bda3545..35595f9 100644
--- a/src/components/Table/src/components/ColumnSetting.vue
+++ b/src/components/Table/src/components/ColumnSetting.vue
@@ -50,7 +50,7 @@ const handleCheckedColumnsChange = (value: string[]) => {
const confirm = () => {
const newColumns = cloneDeep(unref(settingColumns))?.map((item) => {
const fixed = unref(settingColumns)?.find((col) => col.field === item.field)?.fixed
- item.hidden = !!!unref(checkColumns)?.includes(item.field)
+ item.hidden = !unref(checkColumns)?.includes(item.field)
item.fixed = fixed ? fixed : undefined
return item
})
diff --git a/src/components/TagsView/src/TagsView.vue b/src/components/TagsView/src/TagsView.vue
index 8c64a50..da3336b 100644
--- a/src/components/TagsView/src/TagsView.vue
+++ b/src/components/TagsView/src/TagsView.vue
@@ -514,7 +514,7 @@ watch(
&__item {
position: relative;
- top: 2px;
+ top: 3px;
height: calc(~'100% - 6px');
padding-right: 25px;
margin-left: 4px;
diff --git a/src/components/UserInfo/src/components/LockPage.vue b/src/components/UserInfo/src/components/LockPage.vue
index cfa44cc..1e5c9ef 100644
--- a/src/components/UserInfo/src/components/LockPage.vue
+++ b/src/components/UserInfo/src/components/LockPage.vue
@@ -37,7 +37,7 @@ async function unLock() {
if (!password.value) {
return
}
- let pwd = password.value
+ const pwd = password.value
try {
loading.value = true
const res = await lockStore.unLock(pwd)
diff --git a/src/components/VideoPlayer/src/VideoPlayer.vue b/src/components/VideoPlayer/src/VideoPlayer.vue
index 4fd639a..83c8d30 100644
--- a/src/components/VideoPlayer/src/VideoPlayer.vue
+++ b/src/components/VideoPlayer/src/VideoPlayer.vue
@@ -21,7 +21,7 @@ const videoEl = ref()
const intiPlayer = () => {
if (!unref(videoEl)) return
- new Player({
+ playerRef.value = new Player({
autoplay: false,
...props,
el: unref(videoEl)
diff --git a/src/layout/Layout.vue b/src/layout/Layout.vue
index c807392..8f570c3 100644
--- a/src/layout/Layout.vue
+++ b/src/layout/Layout.vue
@@ -27,18 +27,15 @@ const handleClickOutside = () => {
}
const renderLayout = () => {
+ const { renderClassic, renderTopLeft, renderTop, renderCutMenu } = useRenderLayout()
switch (unref(layout)) {
case 'classic':
- const { renderClassic } = useRenderLayout()
return renderClassic()
case 'topLeft':
- const { renderTopLeft } = useRenderLayout()
return renderTopLeft()
case 'top':
- const { renderTop } = useRenderLayout()
return renderTop()
case 'cutMenu':
- const { renderCutMenu } = useRenderLayout()
return renderCutMenu()
default:
break
@@ -73,14 +70,5 @@ export default defineComponent({
.@{prefix-cls} {
background-color: var(--app-content-bg-color);
- .@{prefix-cls}-content-scrollbar {
- & > :deep(.el-scrollbar__wrap) {
- & > .@{elNamespace}-scrollbar__view {
- display: flex;
- height: 100% !important;
- flex-direction: column;
- }
- }
- }
}
diff --git a/src/layout/components/AppView.vue b/src/layout/components/AppView.vue
index 05d2ae6..c491f1e 100644
--- a/src/layout/components/AppView.vue
+++ b/src/layout/components/AppView.vue
@@ -18,7 +18,11 @@ const getCaches = computed((): string[] => {
diff --git a/src/locales/en.ts b/src/locales/en.ts
index f038abf..f26eb8f 100644
--- a/src/locales/en.ts
+++ b/src/locales/en.ts
@@ -480,6 +480,7 @@ export default {
},
dialogDemo: {
dialog: 'Dialog',
+ resizeDialog: 'Resize dialog',
dialogDes: 'Secondary packaging of Dialog components based on ElementPlus',
open: 'Open',
close: 'Close',
diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts
index a4df161..8f38c0a 100644
--- a/src/locales/zh-CN.ts
+++ b/src/locales/zh-CN.ts
@@ -471,6 +471,7 @@ export default {
},
dialogDemo: {
dialog: '弹窗',
+ resizeDialog: '可自定义调节弹窗大小的弹窗',
dialogDes: '基于 ElementPlus 的 Dialog 组件二次封装',
open: '打开',
close: '关闭',
diff --git a/src/styles/var.css b/src/styles/var.css
index f90fc68..fb869ec 100644
--- a/src/styles/var.css
+++ b/src/styles/var.css
@@ -59,3 +59,11 @@
.dark {
--app-content-bg-color: var(--el-bg-color);
}
+
+*,
+:after,
+:before {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
diff --git a/src/utils/index.ts b/src/utils/index.ts
index de17305..d91b679 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -54,7 +54,6 @@ export const getCssVar = (prop: string, dom = document.documentElement) => {
* @param {Array} ary 查找的数组
* @param {Functon} fn 判断的方法
*/
-// eslint-disable-next-line
export const findIndex = (ary: Array, fn: Fn): number => {
if (ary.findIndex) {
return ary.findIndex(fn)
diff --git a/src/utils/is.ts b/src/utils/is.ts
index 8ac2e50..1651420 100644
--- a/src/utils/is.ts
+++ b/src/utils/is.ts
@@ -95,9 +95,12 @@ export const isServer = typeof window === 'undefined'
export const isClient = !isServer
export const isUrl = (path: string): boolean => {
- const reg =
- /(((^https?:(?:\/\/)?)(?:[-:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&%@.\w_]*)#?(?:[\w]*))?)$/
- return reg.test(path)
+ try {
+ new URL(path)
+ return true
+ } catch (_error) {
+ return false
+ }
}
export const isDark = (): boolean => {
diff --git a/src/views/Authorization/Menu/components/AddButtonPermission.vue b/src/views/Authorization/Menu/components/AddButtonPermission.vue
index 606016a..32cb3c3 100644
--- a/src/views/Authorization/Menu/components/AddButtonPermission.vue
+++ b/src/views/Authorization/Menu/components/AddButtonPermission.vue
@@ -46,6 +46,7 @@ const confirm = async () => {
})
if (valid) {
const formData = await getFormData()
+ formData.id = Date.now()
emit('confirm', formData)
modelValue.value = false
}
diff --git a/src/views/Components/Dialog.vue b/src/views/Components/Dialog.vue
index cd7e16a..33726e4 100644
--- a/src/views/Components/Dialog.vue
+++ b/src/views/Components/Dialog.vue
@@ -8,6 +8,7 @@ import { useValidator } from '@/hooks/web/useValidator'
import { getDictOneApi } from '@/api/common'
import { useForm } from '@/hooks/web/useForm'
import Echart from './Echart.vue'
+import ResizeDialog from '@/components/Dialog/src/ResizeDialog.vue'
const { required } = useValidator()
@@ -17,6 +18,10 @@ const dialogVisible = ref(false)
const dialogVisible2 = ref(false)
+const dialogVisible3 = ref(false)
+
+const dialogVisible4 = ref(false)
+
const { formRegister, formMethods } = useForm()
const { getElFormExpose } = formMethods
@@ -128,4 +133,33 @@ const formSubmit = async () => {
+
+
+
+ {{ t('dialogDemo.open') }}
+
+
+
+ {{ t('dialogDemo.combineWithForm') }}
+
+
+
+
+
+ {{ t('dialogDemo.close') }}
+
+
+
+
+
+
+ {{ t('dialogDemo.submit') }}
+ {{ t('dialogDemo.close') }}
+
+
+
diff --git a/src/views/Components/Form/DefaultForm.vue b/src/views/Components/Form/DefaultForm.vue
index 90f7df5..4165c16 100644
--- a/src/views/Components/Form/DefaultForm.vue
+++ b/src/views/Components/Form/DefaultForm.vue
@@ -475,8 +475,8 @@ const schema = reactive([
label: `${t('formDemo.icon')}1`,
component: 'Input',
componentProps: {
- suffixIcon: ,
- prefixIcon:
+ suffixIcon: ,
+ prefixIcon:
}
},
{
@@ -486,9 +486,9 @@ const schema = reactive([
componentProps: {
slots: {
suffix: () => {
- return
+ return
},
- prefix: () =>
+ prefix: () =>
}
}
},
@@ -498,8 +498,8 @@ const schema = reactive([
component: 'Input',
componentProps: {
slots: {
- prepend: () => ,
- append: () =>
+ prepend: () => ,
+ append: () =>
}
}
},
@@ -636,7 +636,7 @@ const schema = reactive([
return null
}
},
- prefix: () =>
+ prefix: () =>
}
}
},
@@ -901,11 +901,11 @@ const schema = reactive([
component: 'Rate',
value: null,
componentProps: {
- voidIcon: ,
+ voidIcon: ,
icons: [
- ,
- ,
-
+ ,
+ ,
+
]
}
},
@@ -1768,7 +1768,7 @@ const schema = reactive([
field: 'field88',
component: 'IconPicker',
label: t('formDemo.default'),
- value: 'tdesign:archway'
+ value: 'vi-tdesign:archway'
},
{
field: 'field89',
diff --git a/src/views/Components/Table/CardTable.vue b/src/views/Components/Table/CardTable.vue
index 19849f1..f07059d 100644
--- a/src/views/Components/Table/CardTable.vue
+++ b/src/views/Components/Table/CardTable.vue
@@ -15,7 +15,7 @@ const { t } = useI18n()
const loading = ref(true)
-let tableDataList = ref([])
+const tableDataList = ref([])
const getTableList = async (params?: Params) => {
const res = await getCardTableListApi(
diff --git a/src/views/Components/Table/DefaultTable.vue b/src/views/Components/Table/DefaultTable.vue
index 974c896..1d9124a 100644
--- a/src/views/Components/Table/DefaultTable.vue
+++ b/src/views/Components/Table/DefaultTable.vue
@@ -68,7 +68,7 @@ const columns: TableColumn[] = [
const loading = ref(true)
-let tableDataList = ref([])
+const tableDataList = ref([])
const getTableList = async (params?: Params) => {
const res = await getTableListApi(
diff --git a/src/views/Components/Table/TableImagePreview.vue b/src/views/Components/Table/TableImagePreview.vue
index 97b6c17..ded2d6d 100644
--- a/src/views/Components/Table/TableImagePreview.vue
+++ b/src/views/Components/Table/TableImagePreview.vue
@@ -54,7 +54,7 @@ const columns: TableColumn[] = [
const loading = ref(true)
-let tableDataList = ref([])
+const tableDataList = ref([])
const getTableList = async (params?: Params) => {
const res = await getTableListApi(
diff --git a/src/views/Components/Table/TableVideoPreview.vue b/src/views/Components/Table/TableVideoPreview.vue
index 94aafc4..a6607b0 100644
--- a/src/views/Components/Table/TableVideoPreview.vue
+++ b/src/views/Components/Table/TableVideoPreview.vue
@@ -38,7 +38,7 @@ const columns: TableColumn[] = [
const loading = ref(true)
-let tableDataList = ref([])
+const tableDataList = ref([])
const getTableList = async (params?: Params) => {
const res = await getTableListApi(
diff --git a/src/views/Dashboard/Workplace.vue b/src/views/Dashboard/Workplace.vue
index d8adac7..4e0bd80 100644
--- a/src/views/Dashboard/Workplace.vue
+++ b/src/views/Dashboard/Workplace.vue
@@ -66,7 +66,7 @@ const getTeam = async () => {
}
// 获取指数
-let radarOptionData = reactive(radarOption) as EChartsOption
+const radarOptionData = reactive(radarOption) as EChartsOption
const getRadar = async () => {
const res = await getRadarApi().catch(() => {})
diff --git a/src/views/Example/Page/ExampleAdd.vue b/src/views/Example/Page/ExampleAdd.vue
index 1c4e3b8..fbe7460 100644
--- a/src/views/Example/Page/ExampleAdd.vue
+++ b/src/views/Example/Page/ExampleAdd.vue
@@ -49,4 +49,3 @@ const save = async () => {
-@/hooks/event/useEventBus
diff --git a/types/env.d.ts b/types/env.d.ts
index 6687edd..3811725 100644
--- a/types/env.d.ts
+++ b/types/env.d.ts
@@ -2,7 +2,7 @@
declare module '*.vue' {
import { DefineComponent } from 'vue'
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
+
const component: DefineComponent<{}, {}, any>
export default component
}
diff --git a/vite.config.ts b/vite.config.ts
index 72b788a..749c3c1 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -61,6 +61,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
: undefined,
EslintPlugin({
cache: false,
+ failOnWarning: false,
+ failOnError: false,
include: ['src/**/*.vue', 'src/**/*.ts', 'src/**/*.tsx'] // 检查的文件
}),
VueI18nPlugin({