Merge pull request #139 from cshaptx4869/patch-95
refactor: ♻️ 规整CURD组件
This commit is contained in:
@@ -472,160 +472,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import ExcelJS from "exceljs";
|
|
||||||
import { ref, reactive } from "vue";
|
|
||||||
import { useDateFormat, useThrottleFn } from "@vueuse/core";
|
|
||||||
import { hasAuth } from "@/plugins/permission";
|
|
||||||
import SvgIcon from "@/components/SvgIcon/index.vue";
|
import SvgIcon from "@/components/SvgIcon/index.vue";
|
||||||
|
import { hasAuth } from "@/plugins/permission";
|
||||||
|
import { useDateFormat, useThrottleFn } from "@vueuse/core";
|
||||||
import {
|
import {
|
||||||
type TableProps,
|
genFileId,
|
||||||
type PaginationProps,
|
|
||||||
type FormInstance,
|
type FormInstance,
|
||||||
type FormRules,
|
type FormRules,
|
||||||
type UploadInstance,
|
type UploadInstance,
|
||||||
type UploadUserFile,
|
|
||||||
type UploadRawFile,
|
type UploadRawFile,
|
||||||
genFileId,
|
type UploadUserFile,
|
||||||
} from "element-plus";
|
} from "element-plus";
|
||||||
|
import ExcelJS from "exceljs";
|
||||||
|
import { reactive, ref } from "vue";
|
||||||
|
import type { IContentConfig, IObject, IOperatData } from "./types";
|
||||||
|
|
||||||
// 对象类型
|
|
||||||
export type IObject = Record<string, any>;
|
|
||||||
// 定义接收的属性
|
// 定义接收的属性
|
||||||
export interface IOperatData {
|
|
||||||
name: string;
|
|
||||||
row: any;
|
|
||||||
column: any;
|
|
||||||
$index: number;
|
|
||||||
}
|
|
||||||
export interface IContentConfig<T = any> {
|
|
||||||
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
|
||||||
pageName: string;
|
|
||||||
// table组件属性
|
|
||||||
table?: Omit<TableProps<any>, "data">;
|
|
||||||
// pagination组件属性
|
|
||||||
pagination?:
|
|
||||||
| boolean
|
|
||||||
| Partial<
|
|
||||||
Omit<
|
|
||||||
PaginationProps,
|
|
||||||
"v-model:page-size" | "v-model:current-page" | "total" | "currentPage"
|
|
||||||
>
|
|
||||||
>;
|
|
||||||
// 列表的网络请求函数(需返回promise)
|
|
||||||
indexAction: (queryParams: T) => Promise<any>;
|
|
||||||
// 默认的分页相关的请求参数
|
|
||||||
request?: {
|
|
||||||
pageName: string;
|
|
||||||
limitName: string;
|
|
||||||
};
|
|
||||||
// 数据格式解析的回调函数
|
|
||||||
parseData?: (res: any) => {
|
|
||||||
total: number;
|
|
||||||
list: IObject[];
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
// 修改属性的网络请求函数(需返回promise)
|
|
||||||
modifyAction?: (data: {
|
|
||||||
[key: string]: any;
|
|
||||||
field: string;
|
|
||||||
value: boolean | string | number;
|
|
||||||
}) => Promise<any>;
|
|
||||||
// 删除的网络请求函数(需返回promise)
|
|
||||||
deleteAction?: (ids: string) => Promise<any>;
|
|
||||||
// 后端导出的网络请求函数(需返回promise)
|
|
||||||
exportAction?: (queryParams: T) => Promise<any>;
|
|
||||||
// 前端全量导出的网络请求函数(需返回promise)
|
|
||||||
exportsAction?: (queryParams: T) => Promise<IObject[]>;
|
|
||||||
// 前端导入模板
|
|
||||||
importsTemplate?: string | (() => Promise<any>);
|
|
||||||
// 前端导入的网络请求函数(需返回promise)
|
|
||||||
importsAction?: (data: IObject[]) => Promise<any>;
|
|
||||||
// 主键名(默认为id)
|
|
||||||
pk?: string;
|
|
||||||
// 表格工具栏(默认支持add,delete,export,也可自定义)
|
|
||||||
toolbar?: Array<
|
|
||||||
| "add"
|
|
||||||
| "delete"
|
|
||||||
| "export"
|
|
||||||
| {
|
|
||||||
auth: string;
|
|
||||||
icon?: string;
|
|
||||||
name: string;
|
|
||||||
text: string;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
// 表格工具栏右侧图标
|
|
||||||
defaultToolbar?: Array<
|
|
||||||
| "refresh"
|
|
||||||
| "filter"
|
|
||||||
| "imports"
|
|
||||||
| "exports"
|
|
||||||
| "search"
|
|
||||||
| {
|
|
||||||
name: string;
|
|
||||||
icon: string;
|
|
||||||
title?: string;
|
|
||||||
auth?: string;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
// table组件列属性(额外的属性templet,operat,slotName)
|
|
||||||
cols: Array<{
|
|
||||||
type?: "default" | "selection" | "index" | "expand";
|
|
||||||
label?: string;
|
|
||||||
prop?: string;
|
|
||||||
width?: string | number;
|
|
||||||
align?: "left" | "center" | "right";
|
|
||||||
columnKey?: string;
|
|
||||||
reserveSelection?: boolean;
|
|
||||||
// 列是否显示
|
|
||||||
show?: boolean;
|
|
||||||
// 模板
|
|
||||||
templet?:
|
|
||||||
| "image"
|
|
||||||
| "list"
|
|
||||||
| "url"
|
|
||||||
| "switch"
|
|
||||||
| "input"
|
|
||||||
| "price"
|
|
||||||
| "percent"
|
|
||||||
| "icon"
|
|
||||||
| "date"
|
|
||||||
| "tool"
|
|
||||||
| "custom";
|
|
||||||
// image模板相关参数
|
|
||||||
imageWidth?: number;
|
|
||||||
imageHeight?: number;
|
|
||||||
// list模板相关参数
|
|
||||||
selectList?: Record<string, any>;
|
|
||||||
// switch模板相关参数
|
|
||||||
activeValue?: boolean | string | number;
|
|
||||||
inactiveValue?: boolean | string | number;
|
|
||||||
activeText?: string;
|
|
||||||
inactiveText?: string;
|
|
||||||
// input模板相关参数
|
|
||||||
inputType?: string;
|
|
||||||
// price模板相关参数
|
|
||||||
priceFormat?: string;
|
|
||||||
// date模板相关参数
|
|
||||||
dateFormat?: string;
|
|
||||||
// tool模板相关参数
|
|
||||||
operat?: Array<
|
|
||||||
| "edit"
|
|
||||||
| "delete"
|
|
||||||
| {
|
|
||||||
auth: string;
|
|
||||||
icon?: string;
|
|
||||||
name: string;
|
|
||||||
text: string;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
// filter值拼接符
|
|
||||||
filterJoin?: string;
|
|
||||||
[key: string]: any;
|
|
||||||
// 初始化数据函数
|
|
||||||
initFn?: (item: IObject) => void;
|
|
||||||
}>;
|
|
||||||
}
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
contentConfig: IContentConfig;
|
contentConfig: IContentConfig;
|
||||||
}>();
|
}>();
|
||||||
@@ -676,8 +538,6 @@ const cols = ref(
|
|||||||
);
|
);
|
||||||
// 加载状态
|
// 加载状态
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
// 删除ID集合 用于批量删除
|
|
||||||
const removeIds = ref<(number | string)[]>([]);
|
|
||||||
// 列表数据
|
// 列表数据
|
||||||
const pageData = ref<IObject[]>([]);
|
const pageData = ref<IObject[]>([]);
|
||||||
// 显示分页
|
// 显示分页
|
||||||
@@ -704,14 +564,18 @@ const request = props.contentConfig.request ?? {
|
|||||||
|
|
||||||
// 行选中
|
// 行选中
|
||||||
const selectionData = ref<IObject[]>([]);
|
const selectionData = ref<IObject[]>([]);
|
||||||
|
// 删除ID集合 用于批量删除
|
||||||
|
const removeIds = ref<(number | string)[]>([]);
|
||||||
function handleSelectionChange(selection: any[]) {
|
function handleSelectionChange(selection: any[]) {
|
||||||
selectionData.value = selection;
|
selectionData.value = selection;
|
||||||
removeIds.value = selection.map((item) => item[pk]);
|
removeIds.value = selection.map((item) => item[pk]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 刷新
|
// 刷新
|
||||||
function handleRefresh() {
|
function handleRefresh() {
|
||||||
fetchPageData(lastFormData);
|
fetchPageData(lastFormData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
function handleDelete(id?: number | string) {
|
function handleDelete(id?: number | string) {
|
||||||
const ids = [id || removeIds.value].join(",");
|
const ids = [id || removeIds.value].join(",");
|
||||||
@@ -735,6 +599,7 @@ function handleDelete(id?: number | string) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出表单
|
// 导出表单
|
||||||
const fields: string[] = [];
|
const fields: string[] = [];
|
||||||
cols.value.forEach((item) => {
|
cols.value.forEach((item) => {
|
||||||
@@ -825,6 +690,7 @@ function handleExports() {
|
|||||||
.catch((error) => console.log(error));
|
.catch((error) => console.log(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导入表单
|
// 导入表单
|
||||||
const uploadRef = ref<UploadInstance>();
|
const uploadRef = ref<UploadInstance>();
|
||||||
const importsModalVisible = ref(false);
|
const importsModalVisible = ref(false);
|
||||||
@@ -943,6 +809,7 @@ function handleImports() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 操作栏
|
// 操作栏
|
||||||
function handleToolbar(name: string) {
|
function handleToolbar(name: string) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
@@ -972,6 +839,7 @@ function handleToolbar(name: string) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 操作列
|
// 操作列
|
||||||
function handleOperat(data: IOperatData) {
|
function handleOperat(data: IOperatData) {
|
||||||
switch (data.name) {
|
switch (data.name) {
|
||||||
@@ -986,6 +854,7 @@ function handleOperat(data: IOperatData) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 属性修改
|
// 属性修改
|
||||||
function handleModify(
|
function handleModify(
|
||||||
field: string,
|
field: string,
|
||||||
@@ -1002,6 +871,7 @@ function handleModify(
|
|||||||
ElMessage.error("未配置modifyAction");
|
ElMessage.error("未配置modifyAction");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页切换
|
// 分页切换
|
||||||
function handleSizeChange(value: number) {
|
function handleSizeChange(value: number) {
|
||||||
pagination.pageSize = value;
|
pagination.pageSize = value;
|
||||||
@@ -1011,6 +881,7 @@ function handleCurrentChange(value: number) {
|
|||||||
pagination.currentPage = value;
|
pagination.currentPage = value;
|
||||||
fetchPageData(lastFormData);
|
fetchPageData(lastFormData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 远程数据筛选
|
// 远程数据筛选
|
||||||
let filterParams: IObject = {};
|
let filterParams: IObject = {};
|
||||||
function handleFilterChange(newFilters: any) {
|
function handleFilterChange(newFilters: any) {
|
||||||
@@ -1033,6 +904,7 @@ function handleFilterChange(newFilters: any) {
|
|||||||
function getFilterParams() {
|
function getFilterParams() {
|
||||||
return filterParams;
|
return filterParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取分页数据
|
// 获取分页数据
|
||||||
let lastFormData = {};
|
let lastFormData = {};
|
||||||
function fetchPageData(formData: IObject = {}, isRestart = false) {
|
function fetchPageData(formData: IObject = {}, isRestart = false) {
|
||||||
@@ -1069,6 +941,7 @@ function fetchPageData(formData: IObject = {}, isRestart = false) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
fetchPageData();
|
fetchPageData();
|
||||||
|
|
||||||
// 导出Excel
|
// 导出Excel
|
||||||
function exportPageData(formData: IObject = {}) {
|
function exportPageData(formData: IObject = {}) {
|
||||||
if (props.contentConfig.exportAction) {
|
if (props.contentConfig.exportAction) {
|
||||||
@@ -1083,6 +956,7 @@ function exportPageData(formData: IObject = {}) {
|
|||||||
ElMessage.error("未配置exportAction");
|
ElMessage.error("未配置exportAction");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 浏览器保存文件
|
// 浏览器保存文件
|
||||||
function saveXlsx(fileData: BlobPart, fileName: string) {
|
function saveXlsx(fileData: BlobPart, fileName: string) {
|
||||||
const fileType =
|
const fileType =
|
||||||
@@ -84,30 +84,19 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { FormInstance, FormRules } from "element-plus";
|
import type { FormInstance, FormRules } from "element-plus";
|
||||||
import { reactive, ref, watch, computed, watchEffect } from "vue";
|
import { reactive, ref, watch, watchEffect } from "vue";
|
||||||
import { IForm, IFormItems, IObject } from "./types";
|
import { IObject, IPageForm } from "./types";
|
||||||
|
|
||||||
// 定义接收的属性
|
// 定义接收的属性
|
||||||
const props = withDefaults(
|
const props = withDefaults(defineProps<IPageForm>(), {
|
||||||
defineProps<{
|
|
||||||
// 主键名(主要用于编辑数据,默认为id)
|
|
||||||
pk?: string;
|
|
||||||
// form组件属性
|
|
||||||
form?: IForm;
|
|
||||||
// 表单项
|
|
||||||
formItems: IFormItems;
|
|
||||||
}>(),
|
|
||||||
{
|
|
||||||
pk: "id",
|
pk: "id",
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>();
|
||||||
const formItems = reactive(props.formItems);
|
const formItems = reactive(props.formItems);
|
||||||
const formData = reactive<IObject>({});
|
const formData = reactive<IObject>({});
|
||||||
const formRules: FormRules = {};
|
const formRules: FormRules = {};
|
||||||
const prepareFuncs = [];
|
const prepareFuncs = [];
|
||||||
// 初始化
|
|
||||||
for (const item of formItems) {
|
for (const item of formItems) {
|
||||||
item.initFn && item.initFn(item);
|
item.initFn && item.initFn(item);
|
||||||
formData[item.prop] = item.initialValue ?? "";
|
formData[item.prop] = item.initialValue ?? "";
|
||||||
@@ -126,12 +115,8 @@ for (const item of formItems) {
|
|||||||
|
|
||||||
if (item.computed !== undefined) {
|
if (item.computed !== undefined) {
|
||||||
prepareFuncs.push(() => {
|
prepareFuncs.push(() => {
|
||||||
formData[item.prop] = computed({
|
watchEffect(() => {
|
||||||
get() {
|
item.computed && (formData[item.prop] = item.computed(formData));
|
||||||
return item.computed ? item.computed(formData) : undefined;
|
|
||||||
},
|
|
||||||
// TODO
|
|
||||||
set() {},
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -145,10 +130,12 @@ for (const item of formItems) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
prepareFuncs.forEach((func) => func());
|
prepareFuncs.forEach((func) => func());
|
||||||
|
|
||||||
// 获取表单数据
|
// 获取表单数据
|
||||||
function getFormData(key?: string) {
|
function getFormData(key?: string) {
|
||||||
return key === undefined ? formData : formData[key] ?? undefined;
|
return key === undefined ? formData : formData[key] ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置表单值
|
// 设置表单值
|
||||||
function setFormData(data: IObject) {
|
function setFormData(data: IObject) {
|
||||||
for (const key in formData) {
|
for (const key in formData) {
|
||||||
@@ -160,6 +147,7 @@ function setFormData(data: IObject) {
|
|||||||
formData[props.pk] = data[props.pk];
|
formData[props.pk] = data[props.pk];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置表单项值
|
// 设置表单项值
|
||||||
function setFormItemData(key: string, value: any) {
|
function setFormItemData(key: string, value: any) {
|
||||||
formData[key] = value;
|
formData[key] = value;
|
||||||
@@ -244,83 +244,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type {
|
|
||||||
FormInstance,
|
|
||||||
FormRules,
|
|
||||||
FormItemRule,
|
|
||||||
FormProps,
|
|
||||||
DialogProps,
|
|
||||||
DrawerProps,
|
|
||||||
} from "element-plus";
|
|
||||||
import { useThrottleFn } from "@vueuse/core";
|
import { useThrottleFn } from "@vueuse/core";
|
||||||
import { reactive, ref, watch, watchEffect, nextTick } from "vue";
|
import type { FormInstance, FormRules } from "element-plus";
|
||||||
|
import { nextTick, reactive, ref, watch, watchEffect } from "vue";
|
||||||
|
import type { IModalConfig, IObject } from "./types";
|
||||||
|
|
||||||
// 对象类型
|
|
||||||
export type IObject = Record<string, any>;
|
|
||||||
// 定义接收的属性
|
// 定义接收的属性
|
||||||
export interface IModalConfig<T = any> {
|
|
||||||
// 页面名称
|
|
||||||
pageName?: string;
|
|
||||||
// 主键名(主要用于编辑数据,默认为id)
|
|
||||||
pk?: string;
|
|
||||||
// 组件类型
|
|
||||||
component?: "dialog" | "drawer";
|
|
||||||
// dialog组件属性
|
|
||||||
dialog?: Partial<Omit<DialogProps, "modelValue">>;
|
|
||||||
// drawer组件属性
|
|
||||||
drawer?: Partial<Omit<DrawerProps, "modelValue">>;
|
|
||||||
// form组件属性
|
|
||||||
form?: Partial<Omit<FormProps, "model" | "rules">>;
|
|
||||||
// 表单项
|
|
||||||
formItems: Array<{
|
|
||||||
// 组件类型(如input,select,radio,custom等,默认input)
|
|
||||||
type?:
|
|
||||||
| "input"
|
|
||||||
| "select"
|
|
||||||
| "radio"
|
|
||||||
| "checkbox"
|
|
||||||
| "tree-select"
|
|
||||||
| "date-picker"
|
|
||||||
| "input-number"
|
|
||||||
| "text"
|
|
||||||
| "custom";
|
|
||||||
// 组件属性
|
|
||||||
attrs?: IObject;
|
|
||||||
// 组件可选项(适用于select,radio,checkbox组件)
|
|
||||||
options?: Array<{
|
|
||||||
label: string;
|
|
||||||
value: any;
|
|
||||||
disabled?: boolean;
|
|
||||||
[key: string]: any;
|
|
||||||
}>;
|
|
||||||
// 插槽名(适用于组件类型为custom)
|
|
||||||
slotName?: string;
|
|
||||||
// 标签文本
|
|
||||||
label: string;
|
|
||||||
// 标签提示
|
|
||||||
tips?: string;
|
|
||||||
// 键名
|
|
||||||
prop: string;
|
|
||||||
// 验证规则
|
|
||||||
rules?: FormItemRule[];
|
|
||||||
// 初始值
|
|
||||||
initialValue?: any;
|
|
||||||
// 是否隐藏
|
|
||||||
hidden?: boolean;
|
|
||||||
// 监听函数
|
|
||||||
watch?: (newValue: any, oldValue: any, data: T, items: IObject[]) => void;
|
|
||||||
// 计算属性函数
|
|
||||||
computed?: (data: T) => any;
|
|
||||||
// 监听收集函数
|
|
||||||
watchEffect?: (data: T) => void;
|
|
||||||
// 初始化数据函数扩展
|
|
||||||
initFn?: (item: IObject) => void;
|
|
||||||
}>;
|
|
||||||
// 提交之前处理
|
|
||||||
beforeSubmit?: (data: T) => void;
|
|
||||||
// 提交的网络请求函数(需返回promise)
|
|
||||||
formAction: (data: T) => Promise<any>;
|
|
||||||
}
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modalConfig: IModalConfig;
|
modalConfig: IModalConfig;
|
||||||
}>();
|
}>();
|
||||||
@@ -336,7 +265,6 @@ const formItems = reactive(props.modalConfig.formItems);
|
|||||||
const formData = reactive<IObject>({});
|
const formData = reactive<IObject>({});
|
||||||
const formRules: FormRules = {};
|
const formRules: FormRules = {};
|
||||||
const prepareFuncs = [];
|
const prepareFuncs = [];
|
||||||
// 初始化
|
|
||||||
for (const item of formItems) {
|
for (const item of formItems) {
|
||||||
item.initFn && item.initFn(item);
|
item.initFn && item.initFn(item);
|
||||||
formData[item.prop] = item.initialValue ?? "";
|
formData[item.prop] = item.initialValue ?? "";
|
||||||
@@ -371,6 +299,37 @@ for (const item of formItems) {
|
|||||||
}
|
}
|
||||||
prepareFuncs.forEach((func) => func());
|
prepareFuncs.forEach((func) => func());
|
||||||
|
|
||||||
|
// 获取表单数据
|
||||||
|
function getFormData(key?: string) {
|
||||||
|
return key === undefined ? formData : formData[key] ?? undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置表单值
|
||||||
|
function setFormData(data: IObject) {
|
||||||
|
for (const key in formData) {
|
||||||
|
if (Object.hasOwn(formData, key) && key in data) {
|
||||||
|
formData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Object.hasOwn(data, pk)) {
|
||||||
|
formData[pk] = data[pk];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置表单项值
|
||||||
|
function setFormItemData(key: string, value: any) {
|
||||||
|
formData[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示modal
|
||||||
|
function setModalVisible(data: IObject = {}) {
|
||||||
|
modalVisible.value = true;
|
||||||
|
// nextTick解决赋值后重置表单无效问题
|
||||||
|
nextTick(() => {
|
||||||
|
Object.values(data).length > 0 && setFormData(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 表单提交
|
// 表单提交
|
||||||
const handleSubmit = useThrottleFn(() => {
|
const handleSubmit = useThrottleFn(() => {
|
||||||
formRef.value?.validate((valid: boolean) => {
|
formRef.value?.validate((valid: boolean) => {
|
||||||
@@ -396,6 +355,7 @@ const handleSubmit = useThrottleFn(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
function handleCloseModal() {
|
function handleCloseModal() {
|
||||||
modalVisible.value = false;
|
modalVisible.value = false;
|
||||||
@@ -404,33 +364,6 @@ function handleCloseModal() {
|
|||||||
formRef.value?.clearValidate();
|
formRef.value?.clearValidate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 显示modal
|
|
||||||
function setModalVisible(data: IObject = {}) {
|
|
||||||
modalVisible.value = true;
|
|
||||||
// nextTick解决赋值后重置表单无效问题
|
|
||||||
nextTick(() => {
|
|
||||||
Object.values(data).length > 0 && setFormData(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 获取表单数据
|
|
||||||
function getFormData(key?: string) {
|
|
||||||
return key === undefined ? formData : formData[key] ?? undefined;
|
|
||||||
}
|
|
||||||
// 设置表单值
|
|
||||||
function setFormData(data: IObject) {
|
|
||||||
for (const key in formData) {
|
|
||||||
if (Object.hasOwn(formData, key) && key in data) {
|
|
||||||
formData[key] = data[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Object.hasOwn(data, pk)) {
|
|
||||||
formData[pk] = data[pk];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 设置表单项值
|
|
||||||
function setFormItemData(key: string, value: any) {
|
|
||||||
formData[key] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 暴露的属性和方法
|
// 暴露的属性和方法
|
||||||
defineExpose({ setModalVisible, getFormData, setFormData, setFormItemData });
|
defineExpose({ setModalVisible, getFormData, setFormData, setFormItemData });
|
||||||
@@ -116,42 +116,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { FormInstance } from "element-plus";
|
import type { FormInstance } from "element-plus";
|
||||||
import { reactive, ref } from "vue";
|
import { reactive, ref } from "vue";
|
||||||
|
import type { IObject, ISearchConfig } from "./types";
|
||||||
|
|
||||||
// 对象类型
|
|
||||||
type IObject = Record<string, any>;
|
|
||||||
// 定义接收的属性
|
// 定义接收的属性
|
||||||
export interface ISearchConfig {
|
const props = defineProps<{
|
||||||
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
|
||||||
pageName: string;
|
|
||||||
// 表单项
|
|
||||||
formItems: Array<{
|
|
||||||
// 组件类型(如input,select等)
|
|
||||||
type?: "input" | "select" | "tree-select" | "date-picker" | "input-tag";
|
|
||||||
// 标签文本
|
|
||||||
label: string;
|
|
||||||
// 标签提示
|
|
||||||
tips?: string;
|
|
||||||
// 键名
|
|
||||||
prop: string;
|
|
||||||
// 组件属性(input-tag组件支持join,btnText,size属性)
|
|
||||||
attrs?: IObject;
|
|
||||||
// 初始值
|
|
||||||
initialValue?: any;
|
|
||||||
// 可选项(适用于select组件)
|
|
||||||
options?: { label: string; value: any }[];
|
|
||||||
// 初始化数据函数扩展
|
|
||||||
initFn?: (formItem: IObject) => void;
|
|
||||||
}>;
|
|
||||||
// 是否开启展开和收缩
|
|
||||||
isExpandable?: boolean;
|
|
||||||
// 默认展示的表单项数量
|
|
||||||
showNumber?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IProps {
|
|
||||||
searchConfig: ISearchConfig;
|
searchConfig: ISearchConfig;
|
||||||
}
|
}>();
|
||||||
const props = defineProps<IProps>();
|
|
||||||
// 自定义事件
|
// 自定义事件
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
queryClick: [queryParams: IObject];
|
queryClick: [queryParams: IObject];
|
||||||
@@ -218,23 +188,28 @@ for (const item of formItems) {
|
|||||||
queryParams[item.prop] = item.initialValue ?? "";
|
queryParams[item.prop] = item.initialValue ?? "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置操作
|
// 重置操作
|
||||||
function handleReset() {
|
function handleReset() {
|
||||||
queryFormRef.value?.resetFields();
|
queryFormRef.value?.resetFields();
|
||||||
emit("resetClick", queryParams);
|
emit("resetClick", queryParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询操作
|
// 查询操作
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
emit("queryClick", queryParams);
|
emit("queryClick", queryParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取分页数据
|
// 获取分页数据
|
||||||
function getQueryParams() {
|
function getQueryParams() {
|
||||||
return queryParams;
|
return queryParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示/隐藏 SearchForm
|
// 显示/隐藏 SearchForm
|
||||||
function toggleVisible() {
|
function toggleVisible() {
|
||||||
visible.value = !visible.value;
|
visible.value = !visible.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭标签
|
// 关闭标签
|
||||||
function handleCloseTag(prop: string, tag: string) {
|
function handleCloseTag(prop: string, tag: string) {
|
||||||
inputTagMap[prop].data.splice(inputTagMap[prop].data.indexOf(tag), 1);
|
inputTagMap[prop].data.splice(inputTagMap[prop].data.indexOf(tag), 1);
|
||||||
262
src/components/CURD/types.ts
Normal file
262
src/components/CURD/types.ts
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
import type {
|
||||||
|
DialogProps,
|
||||||
|
DrawerProps,
|
||||||
|
FormItemRule,
|
||||||
|
FormProps,
|
||||||
|
PaginationProps,
|
||||||
|
TableProps,
|
||||||
|
} from "element-plus";
|
||||||
|
import PageContent from "./PageContent.vue";
|
||||||
|
import PageForm from "./PageForm.vue";
|
||||||
|
import PageModal from "./PageModal.vue";
|
||||||
|
import PageSearch from "./PageSearch.vue";
|
||||||
|
|
||||||
|
export type PageSearchInstance = InstanceType<typeof PageSearch>;
|
||||||
|
export type PageContentInstance = InstanceType<typeof PageContent>;
|
||||||
|
export type PageModalInstance = InstanceType<typeof PageModal>;
|
||||||
|
export type PageFormInstance = InstanceType<typeof PageForm>;
|
||||||
|
|
||||||
|
export type IObject = Record<string, any>;
|
||||||
|
|
||||||
|
export interface IOperatData {
|
||||||
|
name: string;
|
||||||
|
row: any;
|
||||||
|
column: any;
|
||||||
|
$index: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ISearchConfig {
|
||||||
|
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
||||||
|
pageName: string;
|
||||||
|
// 表单项
|
||||||
|
formItems: Array<{
|
||||||
|
// 组件类型(如input,select等)
|
||||||
|
type?: "input" | "select" | "tree-select" | "date-picker" | "input-tag";
|
||||||
|
// 标签文本
|
||||||
|
label: string;
|
||||||
|
// 标签提示
|
||||||
|
tips?: string;
|
||||||
|
// 键名
|
||||||
|
prop: string;
|
||||||
|
// 组件属性(input-tag组件支持join,btnText,size属性)
|
||||||
|
attrs?: IObject;
|
||||||
|
// 初始值
|
||||||
|
initialValue?: any;
|
||||||
|
// 可选项(适用于select组件)
|
||||||
|
options?: { label: string; value: any }[];
|
||||||
|
// 初始化数据函数扩展
|
||||||
|
initFn?: (formItem: IObject) => void;
|
||||||
|
}>;
|
||||||
|
// 是否开启展开和收缩
|
||||||
|
isExpandable?: boolean;
|
||||||
|
// 默认展示的表单项数量
|
||||||
|
showNumber?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IContentConfig<T = any> {
|
||||||
|
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
||||||
|
pageName: string;
|
||||||
|
// table组件属性
|
||||||
|
table?: Omit<TableProps<any>, "data">;
|
||||||
|
// pagination组件属性
|
||||||
|
pagination?:
|
||||||
|
| boolean
|
||||||
|
| Partial<
|
||||||
|
Omit<
|
||||||
|
PaginationProps,
|
||||||
|
"v-model:page-size" | "v-model:current-page" | "total" | "currentPage"
|
||||||
|
>
|
||||||
|
>;
|
||||||
|
// 列表的网络请求函数(需返回promise)
|
||||||
|
indexAction: (queryParams: T) => Promise<any>;
|
||||||
|
// 默认的分页相关的请求参数
|
||||||
|
request?: {
|
||||||
|
pageName: string;
|
||||||
|
limitName: string;
|
||||||
|
};
|
||||||
|
// 数据格式解析的回调函数
|
||||||
|
parseData?: (res: any) => {
|
||||||
|
total: number;
|
||||||
|
list: IObject[];
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
// 修改属性的网络请求函数(需返回promise)
|
||||||
|
modifyAction?: (data: {
|
||||||
|
[key: string]: any;
|
||||||
|
field: string;
|
||||||
|
value: boolean | string | number;
|
||||||
|
}) => Promise<any>;
|
||||||
|
// 删除的网络请求函数(需返回promise)
|
||||||
|
deleteAction?: (ids: string) => Promise<any>;
|
||||||
|
// 后端导出的网络请求函数(需返回promise)
|
||||||
|
exportAction?: (queryParams: T) => Promise<any>;
|
||||||
|
// 前端全量导出的网络请求函数(需返回promise)
|
||||||
|
exportsAction?: (queryParams: T) => Promise<IObject[]>;
|
||||||
|
// 前端导入模板
|
||||||
|
importsTemplate?: string | (() => Promise<any>);
|
||||||
|
// 前端导入的网络请求函数(需返回promise)
|
||||||
|
importsAction?: (data: IObject[]) => Promise<any>;
|
||||||
|
// 主键名(默认为id)
|
||||||
|
pk?: string;
|
||||||
|
// 表格工具栏(默认支持add,delete,export,也可自定义)
|
||||||
|
toolbar?: Array<
|
||||||
|
| "add"
|
||||||
|
| "delete"
|
||||||
|
| "export"
|
||||||
|
| {
|
||||||
|
auth: string;
|
||||||
|
icon?: string;
|
||||||
|
name: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
// 表格工具栏右侧图标
|
||||||
|
defaultToolbar?: Array<
|
||||||
|
| "refresh"
|
||||||
|
| "filter"
|
||||||
|
| "imports"
|
||||||
|
| "exports"
|
||||||
|
| "search"
|
||||||
|
| {
|
||||||
|
name: string;
|
||||||
|
icon: string;
|
||||||
|
title?: string;
|
||||||
|
auth?: string;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
// table组件列属性(额外的属性templet,operat,slotName)
|
||||||
|
cols: Array<{
|
||||||
|
type?: "default" | "selection" | "index" | "expand";
|
||||||
|
label?: string;
|
||||||
|
prop?: string;
|
||||||
|
width?: string | number;
|
||||||
|
align?: "left" | "center" | "right";
|
||||||
|
columnKey?: string;
|
||||||
|
reserveSelection?: boolean;
|
||||||
|
// 列是否显示
|
||||||
|
show?: boolean;
|
||||||
|
// 模板
|
||||||
|
templet?:
|
||||||
|
| "image"
|
||||||
|
| "list"
|
||||||
|
| "url"
|
||||||
|
| "switch"
|
||||||
|
| "input"
|
||||||
|
| "price"
|
||||||
|
| "percent"
|
||||||
|
| "icon"
|
||||||
|
| "date"
|
||||||
|
| "tool"
|
||||||
|
| "custom";
|
||||||
|
// image模板相关参数
|
||||||
|
imageWidth?: number;
|
||||||
|
imageHeight?: number;
|
||||||
|
// list模板相关参数
|
||||||
|
selectList?: Record<string, any>;
|
||||||
|
// switch模板相关参数
|
||||||
|
activeValue?: boolean | string | number;
|
||||||
|
inactiveValue?: boolean | string | number;
|
||||||
|
activeText?: string;
|
||||||
|
inactiveText?: string;
|
||||||
|
// input模板相关参数
|
||||||
|
inputType?: string;
|
||||||
|
// price模板相关参数
|
||||||
|
priceFormat?: string;
|
||||||
|
// date模板相关参数
|
||||||
|
dateFormat?: string;
|
||||||
|
// tool模板相关参数
|
||||||
|
operat?: Array<
|
||||||
|
| "edit"
|
||||||
|
| "delete"
|
||||||
|
| {
|
||||||
|
auth: string;
|
||||||
|
icon?: string;
|
||||||
|
name: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
// filter值拼接符
|
||||||
|
filterJoin?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
// 初始化数据函数
|
||||||
|
initFn?: (item: IObject) => void;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IModalConfig<T = any> {
|
||||||
|
// 页面名称
|
||||||
|
pageName?: string;
|
||||||
|
// 主键名(主要用于编辑数据,默认为id)
|
||||||
|
pk?: string;
|
||||||
|
// 组件类型
|
||||||
|
component?: "dialog" | "drawer";
|
||||||
|
// dialog组件属性
|
||||||
|
dialog?: Partial<Omit<DialogProps, "modelValue">>;
|
||||||
|
// drawer组件属性
|
||||||
|
drawer?: Partial<Omit<DrawerProps, "modelValue">>;
|
||||||
|
// form组件属性
|
||||||
|
form?: IForm;
|
||||||
|
// 表单项
|
||||||
|
formItems: IFormItems<T>;
|
||||||
|
// 提交之前处理
|
||||||
|
beforeSubmit?: (data: T) => void;
|
||||||
|
// 提交的网络请求函数(需返回promise)
|
||||||
|
formAction: (data: T) => Promise<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IForm = Partial<Omit<FormProps, "model" | "rules">>;
|
||||||
|
|
||||||
|
// 表单项
|
||||||
|
export type IFormItems<T = any> = Array<{
|
||||||
|
// 组件类型(如input,select,radio,custom等,默认input)
|
||||||
|
type?:
|
||||||
|
| "input"
|
||||||
|
| "select"
|
||||||
|
| "radio"
|
||||||
|
| "checkbox"
|
||||||
|
| "tree-select"
|
||||||
|
| "date-picker"
|
||||||
|
| "input-number"
|
||||||
|
| "text"
|
||||||
|
| "custom";
|
||||||
|
// 组件属性
|
||||||
|
attrs?: IObject;
|
||||||
|
// 组件可选项(适用于select,radio,checkbox组件)
|
||||||
|
options?: Array<{
|
||||||
|
label: string;
|
||||||
|
value: any;
|
||||||
|
disabled?: boolean;
|
||||||
|
[key: string]: any;
|
||||||
|
}>;
|
||||||
|
// 插槽名(适用于组件类型为custom)
|
||||||
|
slotName?: string;
|
||||||
|
// 标签文本
|
||||||
|
label: string;
|
||||||
|
// 标签提示
|
||||||
|
tips?: string;
|
||||||
|
// 键名
|
||||||
|
prop: string;
|
||||||
|
// 验证规则
|
||||||
|
rules?: FormItemRule[];
|
||||||
|
// 初始值
|
||||||
|
initialValue?: any;
|
||||||
|
// 是否隐藏
|
||||||
|
hidden?: boolean;
|
||||||
|
// 监听函数
|
||||||
|
watch?: (newValue: any, oldValue: any, data: T, items: IObject[]) => void;
|
||||||
|
// 计算属性函数
|
||||||
|
computed?: (data: T) => any;
|
||||||
|
// 监听收集函数
|
||||||
|
watchEffect?: (data: T) => void;
|
||||||
|
// 初始化数据函数扩展
|
||||||
|
initFn?: (item: IObject) => void;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export interface IPageForm {
|
||||||
|
// 主键名(主要用于编辑数据,默认为id)
|
||||||
|
pk?: string;
|
||||||
|
// form组件属性
|
||||||
|
form?: IForm;
|
||||||
|
// 表单项
|
||||||
|
formItems: IFormItems;
|
||||||
|
}
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import type PageSearch from "@/components/PageSearch/index.vue";
|
import type {
|
||||||
import type PageContent from "@/components/PageContent/index.vue";
|
IObject,
|
||||||
import type PageModal from "@/components/PageModal/index.vue";
|
PageContentInstance,
|
||||||
import type { IOperatData, IObject } from "@/components/PageContent/index.vue";
|
PageModalInstance,
|
||||||
export type { IOperatData, IObject };
|
PageSearchInstance,
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
function usePage() {
|
function usePage() {
|
||||||
const searchRef = ref<InstanceType<typeof PageSearch>>();
|
const searchRef = ref<PageSearchInstance>();
|
||||||
const contentRef = ref<InstanceType<typeof PageContent>>();
|
const contentRef = ref<PageContentInstance>();
|
||||||
const addModalRef = ref<InstanceType<typeof PageModal>>();
|
const addModalRef = ref<PageModalInstance>();
|
||||||
const editModalRef = ref<InstanceType<typeof PageModal>>();
|
const editModalRef = ref<PageModalInstance>();
|
||||||
|
|
||||||
// 搜索
|
// 搜索
|
||||||
function handleQueryClick(queryParams: IObject) {
|
function handleQueryClick(queryParams: IObject) {
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
import type {
|
|
||||||
DialogProps,
|
|
||||||
DrawerProps,
|
|
||||||
FormProps,
|
|
||||||
FormItemRule,
|
|
||||||
} from "element-plus";
|
|
||||||
|
|
||||||
// dialog组件属性
|
|
||||||
export type IDialog = Partial<Omit<DialogProps, "modelValue">>;
|
|
||||||
|
|
||||||
// drawer组件属性
|
|
||||||
export type IDrawer = Partial<Omit<DrawerProps, "modelValue">>;
|
|
||||||
|
|
||||||
// form组件属性
|
|
||||||
export type IForm = Partial<Omit<FormProps, "model" | "rules">>;
|
|
||||||
|
|
||||||
// 对象类型
|
|
||||||
export type IObject = Record<string, any>;
|
|
||||||
|
|
||||||
// 表单项
|
|
||||||
export type IFormItems<T = any> = Array<{
|
|
||||||
// 组件类型(如input,select,radio,custom等,默认input)
|
|
||||||
type?:
|
|
||||||
| "input"
|
|
||||||
| "select"
|
|
||||||
| "radio"
|
|
||||||
| "checkbox"
|
|
||||||
| "tree-select"
|
|
||||||
| "date-picker"
|
|
||||||
| "input-number"
|
|
||||||
| "text"
|
|
||||||
| "custom";
|
|
||||||
// 组件属性
|
|
||||||
attrs?: IObject;
|
|
||||||
// 组件可选项(适用于select,radio,checkbox组件)
|
|
||||||
options?: Array<{
|
|
||||||
label: string;
|
|
||||||
value: any;
|
|
||||||
disabled?: boolean;
|
|
||||||
[key: string]: any;
|
|
||||||
}>;
|
|
||||||
// 插槽名(适用于组件类型为custom)
|
|
||||||
slotName?: string;
|
|
||||||
// 标签文本
|
|
||||||
label: string;
|
|
||||||
// 标签提示
|
|
||||||
tips?: string;
|
|
||||||
// 键名
|
|
||||||
prop: string;
|
|
||||||
// 验证规则
|
|
||||||
rules?: FormItemRule[];
|
|
||||||
// 初始值
|
|
||||||
initialValue?: any;
|
|
||||||
// 是否隐藏
|
|
||||||
hidden?: boolean;
|
|
||||||
// 监听函数
|
|
||||||
watch?: (newValue: any, oldValue: any, data: T, items: IObject[]) => void;
|
|
||||||
// 计算属性函数
|
|
||||||
computed?: (data: T) => any;
|
|
||||||
// 监听收集函数
|
|
||||||
watchEffect?: (data: T) => void;
|
|
||||||
// 初始化数据函数扩展
|
|
||||||
initFn?: (item: IObject) => void;
|
|
||||||
}>;
|
|
||||||
4
src/typings/auto-imports.d.ts
vendored
4
src/typings/auto-imports.d.ts
vendored
@@ -325,14 +325,12 @@ declare module "vue" {
|
|||||||
interface GlobalComponents {}
|
interface GlobalComponents {}
|
||||||
interface ComponentCustomProperties {
|
interface ComponentCustomProperties {
|
||||||
readonly EffectScope: UnwrapRef<(typeof import("vue"))["EffectScope"]>;
|
readonly EffectScope: UnwrapRef<(typeof import("vue"))["EffectScope"]>;
|
||||||
readonly ElForm: UnwrapRef<(typeof import("element-plus/es"))["ElForm"]>;
|
|
||||||
readonly ElMessage: UnwrapRef<
|
readonly ElMessage: UnwrapRef<
|
||||||
(typeof import("element-plus/es"))["ElMessage"]
|
(typeof import("element-plus/es"))["ElMessage"]
|
||||||
>;
|
>;
|
||||||
readonly ElMessageBox: UnwrapRef<
|
readonly ElMessageBox: UnwrapRef<
|
||||||
(typeof import("element-plus/es"))["ElMessageBox"]
|
(typeof import("element-plus/es"))["ElMessageBox"]
|
||||||
>;
|
>;
|
||||||
readonly ElTree: UnwrapRef<(typeof import("element-plus/es"))["ElTree"]>;
|
|
||||||
readonly acceptHMRUpdate: UnwrapRef<
|
readonly acceptHMRUpdate: UnwrapRef<
|
||||||
(typeof import("pinia"))["acceptHMRUpdate"]
|
(typeof import("pinia"))["acceptHMRUpdate"]
|
||||||
>;
|
>;
|
||||||
@@ -1055,14 +1053,12 @@ declare module "@vue/runtime-core" {
|
|||||||
interface GlobalComponents {}
|
interface GlobalComponents {}
|
||||||
interface ComponentCustomProperties {
|
interface ComponentCustomProperties {
|
||||||
readonly EffectScope: UnwrapRef<(typeof import("vue"))["EffectScope"]>;
|
readonly EffectScope: UnwrapRef<(typeof import("vue"))["EffectScope"]>;
|
||||||
readonly ElForm: UnwrapRef<(typeof import("element-plus/es"))["ElForm"]>;
|
|
||||||
readonly ElMessage: UnwrapRef<
|
readonly ElMessage: UnwrapRef<
|
||||||
(typeof import("element-plus/es"))["ElMessage"]
|
(typeof import("element-plus/es"))["ElMessage"]
|
||||||
>;
|
>;
|
||||||
readonly ElMessageBox: UnwrapRef<
|
readonly ElMessageBox: UnwrapRef<
|
||||||
(typeof import("element-plus/es"))["ElMessageBox"]
|
(typeof import("element-plus/es"))["ElMessageBox"]
|
||||||
>;
|
>;
|
||||||
readonly ElTree: UnwrapRef<(typeof import("element-plus/es"))["ElTree"]>;
|
|
||||||
readonly acceptHMRUpdate: UnwrapRef<
|
readonly acceptHMRUpdate: UnwrapRef<
|
||||||
(typeof import("pinia"))["acceptHMRUpdate"]
|
(typeof import("pinia"))["acceptHMRUpdate"]
|
||||||
>;
|
>;
|
||||||
|
|||||||
23
src/typings/components.d.ts
vendored
23
src/typings/components.d.ts
vendored
@@ -11,6 +11,7 @@ declare module "vue" {
|
|||||||
AppMain: (typeof import("./../layout/components/AppMain/index.vue"))["default"];
|
AppMain: (typeof import("./../layout/components/AppMain/index.vue"))["default"];
|
||||||
BarChart: (typeof import("./../views/dashboard/components/BarChart.vue"))["default"];
|
BarChart: (typeof import("./../views/dashboard/components/BarChart.vue"))["default"];
|
||||||
Breadcrumb: (typeof import("./../components/Breadcrumb/index.vue"))["default"];
|
Breadcrumb: (typeof import("./../components/Breadcrumb/index.vue"))["default"];
|
||||||
|
CURD: (typeof import("./../components/CURD/index.vue"))["default"];
|
||||||
DeptTree: (typeof import("./../views/system/user/components/dept-tree.vue"))["default"];
|
DeptTree: (typeof import("./../views/system/user/components/dept-tree.vue"))["default"];
|
||||||
Dictionary: (typeof import("./../components/Dictionary/index.vue"))["default"];
|
Dictionary: (typeof import("./../components/Dictionary/index.vue"))["default"];
|
||||||
DictItem: (typeof import("./../views/system/dict/components/dict-item.vue"))["default"];
|
DictItem: (typeof import("./../views/system/dict/components/dict-item.vue"))["default"];
|
||||||
@@ -53,16 +54,13 @@ declare module "vue" {
|
|||||||
ElSwitch: (typeof import("element-plus/es"))["ElSwitch"];
|
ElSwitch: (typeof import("element-plus/es"))["ElSwitch"];
|
||||||
ElTable: (typeof import("element-plus/es"))["ElTable"];
|
ElTable: (typeof import("element-plus/es"))["ElTable"];
|
||||||
ElTableColumn: (typeof import("element-plus/es"))["ElTableColumn"];
|
ElTableColumn: (typeof import("element-plus/es"))["ElTableColumn"];
|
||||||
ElTabPane: (typeof import("element-plus/es"))["ElTabPane"];
|
|
||||||
ElTabs: (typeof import("element-plus/es"))["ElTabs"];
|
|
||||||
ElTag: (typeof import("element-plus/es"))["ElTag"];
|
ElTag: (typeof import("element-plus/es"))["ElTag"];
|
||||||
ElText: (typeof import("element-plus/es"))["ElText"];
|
ElText: (typeof import("element-plus/es"))["ElText"];
|
||||||
ElTooltip: (typeof import("element-plus/es"))["ElTooltip"];
|
ElTooltip: (typeof import("element-plus/es"))["ElTooltip"];
|
||||||
ElTree: (typeof import("element-plus/es"))["ElTree"];
|
|
||||||
ElTreeSelect: (typeof import("element-plus/es"))["ElTreeSelect"];
|
ElTreeSelect: (typeof import("element-plus/es"))["ElTreeSelect"];
|
||||||
ElUpload: (typeof import("element-plus/es"))["ElUpload"];
|
ElUpload: (typeof import("element-plus/es"))["ElUpload"];
|
||||||
ElWatermark: (typeof import("element-plus/es"))["ElWatermark"];
|
ElWatermark: (typeof import("element-plus/es"))["ElWatermark"];
|
||||||
Form: (typeof import("./../components/PageModal/Form.vue"))["default"];
|
Form: (typeof import("./../components/CURD/Form.vue"))["default"];
|
||||||
FunnelChart: (typeof import("./../views/dashboard/components/FunnelChart.vue"))["default"];
|
FunnelChart: (typeof import("./../views/dashboard/components/FunnelChart.vue"))["default"];
|
||||||
GithubCorner: (typeof import("./../components/GithubCorner/index.vue"))["default"];
|
GithubCorner: (typeof import("./../components/GithubCorner/index.vue"))["default"];
|
||||||
Hamburger: (typeof import("./../components/Hamburger/index.vue"))["default"];
|
Hamburger: (typeof import("./../components/Hamburger/index.vue"))["default"];
|
||||||
@@ -70,26 +68,17 @@ declare module "vue" {
|
|||||||
IEpArrowDown: (typeof import("~icons/ep/arrow-down"))["default"];
|
IEpArrowDown: (typeof import("~icons/ep/arrow-down"))["default"];
|
||||||
IEpArrowUp: (typeof import("~icons/ep/arrow-up"))["default"];
|
IEpArrowUp: (typeof import("~icons/ep/arrow-up"))["default"];
|
||||||
IEpClose: (typeof import("~icons/ep/close"))["default"];
|
IEpClose: (typeof import("~icons/ep/close"))["default"];
|
||||||
IEpDelete: (typeof import("~icons/ep/delete"))["default"];
|
|
||||||
IEpDownload: (typeof import("~icons/ep/download"))["default"];
|
IEpDownload: (typeof import("~icons/ep/download"))["default"];
|
||||||
IEpEdit: (typeof import("~icons/ep/edit"))["default"];
|
|
||||||
IEpPlus: (typeof import("~icons/ep/plus"))["default"];
|
|
||||||
IEpPosition: (typeof import("~icons/ep/position"))["default"];
|
|
||||||
IEpQuestionFilled: (typeof import("~icons/ep/question-filled"))["default"];
|
|
||||||
IEpRefresh: (typeof import("~icons/ep/refresh"))["default"];
|
|
||||||
IEpRefreshLeft: (typeof import("~icons/ep/refresh-left"))["default"];
|
|
||||||
IEpSearch: (typeof import("~icons/ep/search"))["default"];
|
|
||||||
IEpTop: (typeof import("~icons/ep/top"))["default"];
|
|
||||||
IEpUploadFilled: (typeof import("~icons/ep/upload-filled"))["default"];
|
|
||||||
LangSelect: (typeof import("./../components/LangSelect/index.vue"))["default"];
|
LangSelect: (typeof import("./../components/LangSelect/index.vue"))["default"];
|
||||||
LayoutSelect: (typeof import("./../layout/components/Settings/components/LayoutSelect.vue"))["default"];
|
LayoutSelect: (typeof import("./../layout/components/Settings/components/LayoutSelect.vue"))["default"];
|
||||||
MultiUpload: (typeof import("./../components/Upload/MultiUpload.vue"))["default"];
|
MultiUpload: (typeof import("./../components/Upload/MultiUpload.vue"))["default"];
|
||||||
NavBar: (typeof import("./../layout/components/NavBar/index.vue"))["default"];
|
NavBar: (typeof import("./../layout/components/NavBar/index.vue"))["default"];
|
||||||
NavbarLeft: (typeof import("./../layout/components/NavBar/components/NavbarLeft.vue"))["default"];
|
NavbarLeft: (typeof import("./../layout/components/NavBar/components/NavbarLeft.vue"))["default"];
|
||||||
NavbarRight: (typeof import("./../layout/components/NavBar/components/NavbarRight.vue"))["default"];
|
NavbarRight: (typeof import("./../layout/components/NavBar/components/NavbarRight.vue"))["default"];
|
||||||
PageContent: (typeof import("./../components/PageContent/index.vue"))["default"];
|
PageContent: (typeof import("./../components/CURD/PageContent.vue"))["default"];
|
||||||
PageModal: (typeof import("./../components/PageModal/index.vue"))["default"];
|
PageForm: (typeof import("./../components/CURD/PageForm.vue"))["default"];
|
||||||
PageSearch: (typeof import("./../components/PageSearch/index.vue"))["default"];
|
PageModal: (typeof import("./../components/CURD/PageModal.vue"))["default"];
|
||||||
|
PageSearch: (typeof import("./../components/CURD/PageSearch.vue"))["default"];
|
||||||
Pagination: (typeof import("./../components/Pagination/index.vue"))["default"];
|
Pagination: (typeof import("./../components/Pagination/index.vue"))["default"];
|
||||||
PieChart: (typeof import("./../views/dashboard/components/PieChart.vue"))["default"];
|
PieChart: (typeof import("./../views/dashboard/components/PieChart.vue"))["default"];
|
||||||
RadarChart: (typeof import("./../views/dashboard/components/RadarChart.vue"))["default"];
|
RadarChart: (typeof import("./../views/dashboard/components/RadarChart.vue"))["default"];
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import DeptAPI from "@/api/dept";
|
|||||||
import RoleAPI from "@/api/role";
|
import RoleAPI from "@/api/role";
|
||||||
import UserAPI from "@/api/user";
|
import UserAPI from "@/api/user";
|
||||||
import type { UserForm } from "@/api/user/model";
|
import type { UserForm } from "@/api/user/model";
|
||||||
import type { IModalConfig } from "@/components/PageModal/index.vue";
|
import type { IModalConfig } from "@/components/CURD/types";
|
||||||
|
|
||||||
const modalConfig: IModalConfig<UserForm> = {
|
const modalConfig: IModalConfig<UserForm> = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import UserAPI from "@/api/user";
|
import UserAPI from "@/api/user";
|
||||||
import RoleAPI from "@/api/role";
|
import RoleAPI from "@/api/role";
|
||||||
import type { UserQuery } from "@/api/user/model";
|
import type { UserQuery } from "@/api/user/model";
|
||||||
import type { IContentConfig } from "@/components/PageContent/index.vue";
|
import type { IContentConfig } from "@/components/CURD/types";
|
||||||
|
|
||||||
const contentConfig: IContentConfig<UserQuery> = {
|
const contentConfig: IContentConfig<UserQuery> = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import type { IContentConfig } from "@/components/PageContent/index.vue";
|
import type { IContentConfig } from "@/components/CURD/types";
|
||||||
|
|
||||||
const contentConfig: IContentConfig = {
|
const contentConfig: IContentConfig = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
table: {
|
table: {
|
||||||
showOverflowTooltip: true,
|
showOverflowTooltip: true,
|
||||||
},
|
},
|
||||||
|
toolbar: [],
|
||||||
indexAction: function (params) {
|
indexAction: function (params) {
|
||||||
|
// 模拟发起网络请求获取列表数据
|
||||||
// console.log("indexAction:", params);
|
// console.log("indexAction:", params);
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
total: 2,
|
total: 2,
|
||||||
@@ -44,11 +46,13 @@ const contentConfig: IContentConfig = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
modifyAction(data) {
|
modifyAction(data) {
|
||||||
console.log("modifyAction:", data);
|
// 模拟发起网络请求修改字段
|
||||||
|
// console.log("modifyAction:", data);
|
||||||
|
ElMessage.success(JSON.stringify(data));
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
},
|
},
|
||||||
cols: [
|
cols: [
|
||||||
{ type: "selection", width: 50, align: "center" },
|
{ type: "index", width: 50, align: "center" },
|
||||||
{ label: "ID", align: "center", prop: "id", show: false },
|
{ label: "ID", align: "center", prop: "id", show: false },
|
||||||
{ label: "用户名", align: "center", prop: "username" },
|
{ label: "用户名", align: "center", prop: "username" },
|
||||||
{ label: "图片", align: "center", prop: "avatar", templet: "image" },
|
{ label: "图片", align: "center", prop: "avatar", templet: "image" },
|
||||||
@@ -106,14 +110,6 @@ const contentConfig: IContentConfig = {
|
|||||||
templet: "date",
|
templet: "date",
|
||||||
dateFormat: "YYYY/MM/DD HH:mm:ss",
|
dateFormat: "YYYY/MM/DD HH:mm:ss",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: "操作",
|
|
||||||
align: "center",
|
|
||||||
fixed: "right",
|
|
||||||
width: 150,
|
|
||||||
templet: "tool",
|
|
||||||
operat: ["edit", "delete"],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import DeptAPI from "@/api/dept";
|
|||||||
import RoleAPI from "@/api/role";
|
import RoleAPI from "@/api/role";
|
||||||
import UserAPI from "@/api/user";
|
import UserAPI from "@/api/user";
|
||||||
import type { UserForm } from "@/api/user/model";
|
import type { UserForm } from "@/api/user/model";
|
||||||
import type { IModalConfig } from "@/components/PageModal/index.vue";
|
import type { IModalConfig } from "@/components/CURD/types";
|
||||||
import { DeviceEnum } from "@/enums/DeviceEnum";
|
import { DeviceEnum } from "@/enums/DeviceEnum";
|
||||||
import { useAppStore } from "@/store";
|
import { useAppStore } from "@/store";
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import DeptAPI from "@/api/dept";
|
import DeptAPI from "@/api/dept";
|
||||||
import type { ISearchConfig } from "@/components/PageSearch/index.vue";
|
import type { ISearchConfig } from "@/components/CURD/types";
|
||||||
|
|
||||||
const searchConfig: ISearchConfig = {
|
const searchConfig: ISearchConfig = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
|
<div class="flex-x-between mb-10">
|
||||||
<el-link
|
<el-link
|
||||||
href="https://gitee.com/youlaiorg/vue3-element-admin/blob/master/src/views/demo/curd/index.vue"
|
href="https://gitee.com/youlaiorg/vue3-element-admin/blob/master/src/views/demo/curd/index.vue"
|
||||||
type="primary"
|
type="primary"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="mb-10"
|
|
||||||
>
|
>
|
||||||
示例源码 请点击>>>>
|
示例源码 请点击>>>>
|
||||||
</el-link>
|
</el-link>
|
||||||
|
<el-button type="primary" plain round size="small" @click="isA = !isA">
|
||||||
|
切换示例
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<template v-if="isA">
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<page-search
|
<page-search
|
||||||
ref="searchRef"
|
ref="searchRef"
|
||||||
@@ -57,16 +63,26 @@
|
|||||||
<dictionary v-model="scope.formData[scope.prop]" type-code="gender" />
|
<dictionary v-model="scope.formData[scope.prop]" type-code="gender" />
|
||||||
</template>
|
</template>
|
||||||
</page-modal>
|
</page-modal>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<page-content ref="contentRef" :content-config="contentConfig2">
|
||||||
|
<template #status="scope">
|
||||||
|
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||||
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</page-content>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import UserAPI from "@/api/user";
|
import UserAPI from "@/api/user";
|
||||||
import type { IObject, IOperatData } from "@/hooks/usePage";
|
import type { IObject, IOperatData } from "@/components/CURD/types";
|
||||||
import usePage from "@/hooks/usePage";
|
import usePage from "@/components/CURD/usePage";
|
||||||
import addModalConfig from "./config/add";
|
import addModalConfig from "./config/add";
|
||||||
import contentConfig from "./config/content";
|
import contentConfig from "./config/content";
|
||||||
// import contentConfig from "./config/content2";
|
import contentConfig2 from "./config/content2";
|
||||||
import editModalConfig from "./config/edit";
|
import editModalConfig from "./config/edit";
|
||||||
import searchConfig from "./config/search";
|
import searchConfig from "./config/search";
|
||||||
|
|
||||||
@@ -120,4 +136,7 @@ function handleOperatClick(data: IOperatData) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 切换示例
|
||||||
|
const isA = ref(true);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user