From 10a2c19cdf364398187a0d441209063dad2981f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A5=9E=E4=BB=99=E9=83=BD=E6=B2=A1=E7=94=A8?= <615206459@qq.com> Date: Tue, 31 Dec 2024 14:10:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/base/views/menu/index.vue | 4 +- src/modules/dict/utils/index.ts | 20 ++- src/plugins/crud/components/dict/index.tsx | 147 +++++++++++++++++++ src/plugins/crud/components/switch/index.tsx | 69 +++++---- src/plugins/crud/config.ts | 4 +- src/plugins/crud/utils/index.ts | 15 ++ 6 files changed, 224 insertions(+), 35 deletions(-) create mode 100644 src/plugins/crud/components/dict/index.tsx create mode 100644 src/plugins/crud/utils/index.ts diff --git a/src/modules/base/views/menu/index.vue b/src/modules/base/views/menu/index.vue index 1b1a292..812c314 100644 --- a/src/modules/base/views/menu/index.vue +++ b/src/modules/base/views/menu/index.vue @@ -220,7 +220,9 @@ const Table = useTable({ label: '权限', headerAlign: 'center', minWidth: 300, - dict: [] + component: { + name: 'cl-dict' + } }, { prop: 'orderNum', diff --git a/src/modules/dict/utils/index.ts b/src/modules/dict/utils/index.ts index f0907ce..cf19f63 100644 --- a/src/modules/dict/utils/index.ts +++ b/src/modules/dict/utils/index.ts @@ -1,10 +1,20 @@ -export function deepFind(value: any, list: any[]) { - function deep(arr: any[]): any | undefined { +export function deepFind(value: any, list: any[], options?: { allLevels: boolean }) { + const { allLevels = true } = options || {}; + + function deep(arr: any[], name: string[]): any | undefined { for (const e of arr) { if (e.value === value) { - return e; + if (allLevels) { + return { + ...e, + label: [...name, e.label].join(' / ') + }; + } else { + return e; + } } else if (e.children) { - const d = deep(e.children); + const d = deep(e.children, [...name, e.label]); + if (d !== undefined) { return d; } @@ -13,7 +23,7 @@ export function deepFind(value: any, list: any[]) { return undefined; } - return deep(list); + return deep(list, []); } export function isEmpty(val: any) { diff --git a/src/plugins/crud/components/dict/index.tsx b/src/plugins/crud/components/dict/index.tsx new file mode 100644 index 0000000..12519ea --- /dev/null +++ b/src/plugins/crud/components/dict/index.tsx @@ -0,0 +1,147 @@ +import { defineComponent, h, ref, type PropType } from 'vue'; +import { CrudProps } from '../..'; +import { cloneDeep, isArray, isString } from 'lodash-es'; +import { getValue } from '../../utils'; +import { deepFind } from '/$/dict/utils'; + +export default defineComponent({ + name: 'cl-dict', + + props: { + ...CrudProps, + // 绑定值 + modelValue: [String, Array] as PropType, + // 选项列表 + options: { + type: Array as PropType, + default: () => [] + }, + // 格式化返回 + formatter: Function as PropType<(arr: DictOptions[]) => any>, + // 颜色组 + color: { + type: Array as PropType, + default: () => [] + }, + // 分割符号 + separator: { + type: String, + default: ',' + }, + // 展示所有层级 + allLevels: Boolean, + // 超出几个隐藏 + hideOver: { + type: Number, + default: 5 + }, + // 纯文字显示 + text: Boolean + }, + + setup(props) { + // 选项列表 + const list: DictOptions = cloneDeep(getValue(props.options || [])); + + // 设置颜色 + if (props.color) { + list.forEach((e, i) => { + if (!e.color) { + e.color = props.color[i]; + } + }); + } + + // 是否展开 + const isExpand = ref(false); + + return () => { + const value = props.modelValue; + + // 绑定值 + let values: any[] = []; + + // 格式化值 + if (isArray(value)) { + values = value; + } else if (isString(value)) { + if (props.separator) { + values = value.split(props.separator); + } else { + values = [value]; + } + } else { + values = [value]; + } + + // 数据 + const data = values + .filter(e => e !== undefined && e !== null && e !== '') + .map(v => { + let d = deepFind(v, list, { allLevels: props.allLevels }); + + if (!d) { + d = { + label: v, + value: v + }; + } + + return { + ...d, + children: [] + }; + }); + + // 是否隐藏部分 + const isHide = data.length > props.hideOver && !isExpand.value; + + // 自定义返回 + if (props.formatter) { + return props.formatter(data); + } + + // 文字返回 + if (props.text) { + return data.map(e => e.label).join(props.separator); + } + + // el-tag 渲染 + return [ + data + .filter((_, i) => { + return !isHide || i < props.hideOver; + }) + .map(e => { + return h( + , + { + type: e.type, + closable: e.closable, + hit: e.hit, + color: e.color, + size: e.size, + effect: e.effect || 'dark', + round: e.round, + disableTransitions: true + }, + { + default: () => e.label + } + ); + }), + isHide && + h( + { + isExpand.value = true; + }} + />, + {}, + { default: () => '...' } + ) + ]; + }; + } +}); diff --git a/src/plugins/crud/components/switch/index.tsx b/src/plugins/crud/components/switch/index.tsx index 1fd8e1c..19b81c5 100644 --- a/src/plugins/crud/components/switch/index.tsx +++ b/src/plugins/crud/components/switch/index.tsx @@ -1,14 +1,14 @@ import { useCrud } from '@cool-vue/crud'; -import { ElMessage } from 'element-plus'; +import { ElMessage, ElMessageBox } from 'element-plus'; import { defineComponent, ref, watch } from 'vue'; import { isBoolean, isFunction } from 'lodash-es'; +import { CrudProps } from '../..'; export default defineComponent({ name: 'cl-switch', props: { - scope: null, - column: null, + ...CrudProps, modelValue: [Number, String, Boolean], activeValue: { type: [Number, String, Boolean], @@ -18,7 +18,8 @@ export default defineComponent({ type: [Number, String, Boolean], default: 0 }, - api: Function + api: Function, + isCheck: Boolean }, emits: ['update:modelValue', 'change'], @@ -59,35 +60,49 @@ export default defineComponent({ // 监听改变 function onChange(val: boolean | string | number) { - if (props.column && props.scope) { - if (val !== undefined) { - if ( - status.value === activeValue.value || - status.value === inactiveValue.value - ) { - const params = { - id: props.scope.id, - [props.column.property]: val - }; + const next = () => { + if (props.column && props.scope) { + if (val !== undefined) { + if ( + status.value === activeValue.value || + status.value === inactiveValue.value + ) { + const params = { + id: props.scope.id, + [props.column.property]: val + }; - const req: Promise = isFunction(props.api) - ? props.api(params) - : Crud.value?.service.update(params); + const req: Promise = isFunction(props.api) + ? props.api(params) + : Crud.value?.service.update(params); - if (req) { - req.then(() => { - emit('update:modelValue', val); - emit('change', val); - ElMessage.success('更新成功'); - }).catch(err => { - ElMessage.error(err.message); - }); + if (req) { + req.then(() => { + emit('update:modelValue', val); + emit('change', val); + ElMessage.success('更新成功'); + }).catch(err => { + ElMessage.error(err.message); + }); + } } } + } else { + emit('update:modelValue', val); + emit('change', val); } + } + + if (props.isCheck) { + ElMessageBox.confirm(`确定要${val ? '开启' : '关闭'}吗?`, '提示', { + type: 'warning' + }) + .then(() => { + next() + }) + .catch(() => null) } else { - emit('update:modelValue', val); - emit('change', val); + next() } } diff --git a/src/plugins/crud/config.ts b/src/plugins/crud/config.ts index 734cb8c..60c7861 100644 --- a/src/plugins/crud/config.ts +++ b/src/plugins/crud/config.ts @@ -14,8 +14,8 @@ export default (): Merge => { label: 'CRUD', description: '快速增删改查及一系列辅助组件', author: 'COOL', - version: '1.1.0', - updateTime: '2024-12-26', + version: '1.1.2', + updateTime: '2024-12-31', demo: '/demo/crud', // 组件全注册 diff --git a/src/plugins/crud/utils/index.ts b/src/plugins/crud/utils/index.ts new file mode 100644 index 0000000..5e0fb25 --- /dev/null +++ b/src/plugins/crud/utils/index.ts @@ -0,0 +1,15 @@ +import { isFunction } from 'lodash-es'; +import { isRef } from 'vue'; + +// 获取值 +export function getValue(data: any, params?: any) { + if (isRef(data)) { + return data.value; + } else { + if (isFunction(data)) { + return data(params); + } else { + return data; + } + } +}