From c8e3ecac54b116de3b16114e05f9304b96a13f6d Mon Sep 17 00:00:00 2001
From: yinqi <18774398105@163.com>
Date: Tue, 10 Feb 2026 14:59:33 +0800
Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E4=BA=8Eelement-plus=E4=BA=8C?=
=?UTF-8?q?=E6=AC=A1=E5=B0=81=E8=A3=85=E9=80=9A=E7=94=A8=E8=A1=A8=E6=A0=BC?=
=?UTF-8?q?=E3=80=81=E6=90=9C=E7=B4=A2=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
package.json | 3 +-
src/assets/styles/ruoyi.scss | 1 +
src/components/FormTable/index.vue | 370 +++++++++++++++++++++++++
src/components/SearchForm/exSlot.tsx | 34 +++
src/components/SearchForm/formElem.vue | 215 ++++++++++++++
src/components/SearchForm/index.vue | 185 +++++++++++++
src/components/SearchPanel/index.vue | 95 +++++++
src/components/ToolbarButton/index.vue | 115 ++++++++
src/layout/components/AppMain.vue | 4 +-
src/plugins/auth.ts | 5 +
src/utils/index.ts | 18 ++
src/utils/validate.ts | 23 ++
src/views/test/index.vue | 310 +++++++++++++++++++++
vite/plugins/index.ts | 11 +-
14 files changed, 1385 insertions(+), 4 deletions(-)
create mode 100644 src/components/FormTable/index.vue
create mode 100644 src/components/SearchForm/exSlot.tsx
create mode 100644 src/components/SearchForm/formElem.vue
create mode 100644 src/components/SearchForm/index.vue
create mode 100644 src/components/SearchPanel/index.vue
create mode 100644 src/components/ToolbarButton/index.vue
create mode 100644 src/views/test/index.vue
diff --git a/package.json b/package.json
index dc3bd550..d58bfb7f 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,8 @@
"@element-plus/icons-vue": "2.3.2",
"@highlightjs/vue-plugin": "2.1.2",
"@vueup/vue-quill": "1.2.0",
- "@vueuse/core": "13.9.0",
+ "@vueuse/core": "13.1.0",
+ "@vitejs/plugin-vue-jsx": "^4.1.2",
"animate.css": "4.1.1",
"await-to-js": "3.0.0",
"axios": "1.13.1",
diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss
index 95260178..a836e3cb 100644
--- a/src/assets/styles/ruoyi.scss
+++ b/src/assets/styles/ruoyi.scss
@@ -193,6 +193,7 @@ h6 {
}
.el-card__body {
+ height: 100%;
padding: 15px 20px 20px 20px !important;
}
diff --git a/src/components/FormTable/index.vue b/src/components/FormTable/index.vue
new file mode 100644
index 00000000..3593e920
--- /dev/null
+++ b/src/components/FormTable/index.vue
@@ -0,0 +1,370 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row[child.prop] ?? '--' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row[column.prop] ?? '--' }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/SearchForm/exSlot.tsx b/src/components/SearchForm/exSlot.tsx
new file mode 100644
index 00000000..e5467c01
--- /dev/null
+++ b/src/components/SearchForm/exSlot.tsx
@@ -0,0 +1,34 @@
+import { defineComponent } from 'vue';
+
+export default defineComponent({
+ name: 'ex-slot',
+ props: {
+ value: [String, Number],
+ row: Object,
+ render: Function,
+ rowIndex: Number,
+ column: Object,
+ columnIndex: Number,
+ class: [String, Array, Object],
+ style: [String, Array, Object],
+ dict: [Array]
+ },
+ render() {
+ const value = this.render({
+ value: this.value,
+ row: this.row,
+ column: this.column,
+ rowIndex: this.rowIndex,
+ columnIndex: this.columnIndex,
+ dict: this.dict
+ });
+ if (this.style || this.class) {
+ return (
+
+ {value}
+
+ );
+ }
+ return value;
+ }
+});
diff --git a/src/components/SearchForm/formElem.vue b/src/components/SearchForm/formElem.vue
new file mode 100644
index 00000000..ed204408
--- /dev/null
+++ b/src/components/SearchForm/formElem.vue
@@ -0,0 +1,215 @@
+
+ typeof config.click == 'function' && config.click(value, $event)"
+ @mousewheel.prevent
+ @keydown.up.prevent
+ @keydown.down.prevent
+ >
+
+
+
+
+
+
+
+ typeof config.change == 'function' && config.change($event, $refs.select)"
+ @visible-change="$event => typeof config.visibleChange == 'function' && config.visibleChange($event, $refs.select)"
+ >
+
+
+ typeof config.change == 'function' && config.change($event)"
+ />
+ typeof config.change == 'function' && config.change($event)"
+ />
+
+
+ typeof config.select == 'function' && config.select($event)"
+ />
+
+
+
+
+
diff --git a/src/components/SearchForm/index.vue b/src/components/SearchForm/index.vue
new file mode 100644
index 00000000..ae9860df
--- /dev/null
+++ b/src/components/SearchForm/index.vue
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ visible ? '折叠' : '更多' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/SearchPanel/index.vue b/src/components/SearchPanel/index.vue
new file mode 100644
index 00000000..e16ecded
--- /dev/null
+++ b/src/components/SearchPanel/index.vue
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/ToolbarButton/index.vue b/src/components/ToolbarButton/index.vue
new file mode 100644
index 00000000..2969a696
--- /dev/null
+++ b/src/components/ToolbarButton/index.vue
@@ -0,0 +1,115 @@
+
+
+
+
+ {{ addName }}
+
+
+
+ {{ editName }}
+
+
+
+ {{ delName }}
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue
index b6c7b61c..6fe4ff4d 100644
--- a/src/layout/components/AppMain.vue
+++ b/src/layout/components/AppMain.vue
@@ -55,9 +55,10 @@ function addIframe() {
.app-main {
/* 50= navbar 50 */
min-height: calc(100vh - 50px);
+ height: calc(100vh - 50px);
width: 100%;
position: relative;
- overflow: hidden;
+ overflow: auto;
}
.fixed-header + .app-main {
@@ -68,6 +69,7 @@ function addIframe() {
.app-main {
/* 84 = navbar + tags-view = 50 + 34 */
min-height: calc(100vh - 84px);
+ height: calc(100vh - 84px);
}
.fixed-header + .app-main {
diff --git a/src/plugins/auth.ts b/src/plugins/auth.ts
index a5aaef94..464d08c9 100644
--- a/src/plugins/auth.ts
+++ b/src/plugins/auth.ts
@@ -24,6 +24,11 @@ const authRole = (role: string): boolean => {
}
};
+export const havePermi = (permission: string): boolean => {
+ // 你的权限校验逻辑
+ return authPermission(permission);
+};
+
export default {
// 验证用户是否具备某权限
hasPermi(permission: string): boolean {
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 2b0aad5f..aecc49ac 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -316,3 +316,21 @@ export const removeClass = (ele: HTMLElement, cls: string) => {
export const isExternal = (path: string) => {
return /^(https?:|http?:|mailto:|tel:)/.test(path);
};
+
+/**
+ * Check if a variable is a string
+ * @param str
+ * @returns {boolean}
+ */
+export const isString = (str: any): str is string => {
+ return typeof str === 'string' || str instanceof String;
+};
+
+/**
+ * Check if a variable is a function
+ * @param func
+ * @returns {boolean}
+ */
+export const isFunction = (func: any): func is Function => {
+ return typeof func === 'function' || func instanceof Function;
+};
diff --git a/src/utils/validate.ts b/src/utils/validate.ts
index e2886e45..8f9bdb9f 100644
--- a/src/utils/validate.ts
+++ b/src/utils/validate.ts
@@ -106,3 +106,26 @@ export const isArray = (arg: string | string[]) => {
}
return Array.isArray(arg);
};
+
+/**
+ * 判断是否为空
+ */
+export function validatenull(val) {
+ if (typeof val == 'boolean') {
+ return false;
+ }
+ if (typeof val == 'number') {
+ return false;
+ }
+ if (val instanceof Array) {
+ if (val.length == 0) return true;
+ } else if (val instanceof Object) {
+ if (JSON.stringify(val) === '{}') return true;
+ } else {
+ if (val == 'null' || val == null || val == 'undefined' || val == undefined || val == ''){
+ return true;
+ }
+ return false;
+ }
+ return false;
+}
diff --git a/src/views/test/index.vue b/src/views/test/index.vue
new file mode 100644
index 00000000..57b60ccb
--- /dev/null
+++ b/src/views/test/index.vue
@@ -0,0 +1,310 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 自定义 {{ column.label }}
+
+
+
+
+ {{ row.name }}
+
+
+
+
+
+
+
+
+
+
diff --git a/vite/plugins/index.ts b/vite/plugins/index.ts
index 9ef8faf1..ffc93dda 100644
--- a/vite/plugins/index.ts
+++ b/vite/plugins/index.ts
@@ -1,4 +1,5 @@
import vue from '@vitejs/plugin-vue';
+import vueJsx from '@vitejs/plugin-vue-jsx';
import vueDevTools from 'vite-plugin-vue-devtools';
import createUnoCss from './unocss';
@@ -11,8 +12,14 @@ import createSetupExtend from './setup-extend';
import path from 'path';
export default (viteEnv: any, isBuild = false): [] => {
- const vitePlugins: any = [];
- vitePlugins.push(vue());
+ const vitePlugins: any = [
+ vue({
+ script: {
+ defineModel: true
+ }
+ }),
+ vueJsx()
+ ];
vitePlugins.push(vueDevTools());
vitePlugins.push(createUnoCss());
vitePlugins.push(createAutoImport(path));