refactor: ♻️ 升级 3.x 版本,布局重构和代码规范调整
This commit is contained in:
@@ -33,6 +33,6 @@ const linkProps = (to: any) => {
|
||||
rel: "noopener noreferrer",
|
||||
};
|
||||
}
|
||||
return { to: to };
|
||||
return { to };
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
<div class="flex flex-col md:flex-row justify-between gap-y-2.5 mb-2.5">
|
||||
<!-- 左侧工具栏 -->
|
||||
<div class="toolbar-left flex gap-y-2.5 gap-x-2 md:gap-x-3 flex-wrap">
|
||||
<template v-for="btn in toolbarLeftBtn">
|
||||
<template v-for="(btn, index) in toolbarLeftBtn" :key="index">
|
||||
<el-button
|
||||
v-hasPerm="btn.perm ?? '*:*:*'"
|
||||
:disabled="btn.name === 'delete' && removeIds.length === 0"
|
||||
v-bind="btn.attrs"
|
||||
:disabled="btn.name === 'delete' && removeIds.length === 0"
|
||||
@click="handleToolbar(btn.name)"
|
||||
>
|
||||
{{ btn.text }}
|
||||
@@ -19,13 +19,13 @@
|
||||
</div>
|
||||
<!-- 右侧工具栏 -->
|
||||
<div class="toolbar-right flex gap-y-2.5 gap-x-2 md:gap-x-3 flex-wrap">
|
||||
<template v-for="btn in toolbarRightBtn">
|
||||
<template v-for="(btn, index) in toolbarRightBtn" :key="index">
|
||||
<el-popover v-if="btn.name === 'filter'" placement="bottom" trigger="click">
|
||||
<template #reference>
|
||||
<el-button v-bind="btn.attrs"></el-button>
|
||||
</template>
|
||||
<el-scrollbar max-height="350px">
|
||||
<template v-for="col in cols" :key="col">
|
||||
<template v-for="col in cols" :key="col.prop">
|
||||
<el-checkbox v-if="col.prop" v-model="col.show" :label="col.label" />
|
||||
</template>
|
||||
</el-scrollbar>
|
||||
@@ -51,7 +51,7 @@
|
||||
@selection-change="handleSelectionChange"
|
||||
@filter-change="handleFilterChange"
|
||||
>
|
||||
<template v-for="col in cols" :key="col">
|
||||
<template v-for="col in cols" :key="col.prop">
|
||||
<el-table-column v-if="col.show" v-bind="col">
|
||||
<template #default="scope">
|
||||
<!-- 显示图片 -->
|
||||
@@ -158,7 +158,7 @@
|
||||
</template>
|
||||
<!-- 列操作栏 -->
|
||||
<template v-else-if="col.templet === 'tool'">
|
||||
<template v-for="btn in tableToolbarBtn">
|
||||
<template v-for="(btn, index) in tableToolbarBtn" :key="index">
|
||||
<el-button
|
||||
v-if="btn.render === undefined || btn.render(scope.row)"
|
||||
v-hasPerm="btn.perm ?? '*:*:*'"
|
||||
@@ -237,7 +237,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="字段" prop="fields">
|
||||
<el-checkbox-group v-model="exportsFormData.fields">
|
||||
<template v-for="col in cols" :key="col">
|
||||
<template v-for="col in cols" :key="col.prop">
|
||||
<el-checkbox v-if="col.prop" :value="col.prop" :label="col.label" />
|
||||
</template>
|
||||
</el-checkbox-group>
|
||||
@@ -430,7 +430,9 @@ const tableToolbarBtn = createToolbar(tableToolbar, { link: true, size: "small"
|
||||
// 表格列
|
||||
const cols = ref(
|
||||
props.contentConfig.cols.map((col) => {
|
||||
col.initFn && col.initFn(col);
|
||||
if (col.initFn) {
|
||||
col.initFn(col);
|
||||
}
|
||||
if (col.show === undefined) {
|
||||
col.show = true;
|
||||
}
|
||||
@@ -544,7 +546,7 @@ const exportsFormRef = ref<FormInstance>();
|
||||
const exportsFormData = reactive({
|
||||
filename: "",
|
||||
sheetname: "",
|
||||
fields: fields,
|
||||
fields,
|
||||
origin: ExportsOriginEnum.CURRENT,
|
||||
});
|
||||
const exportsFormRules: FormRules = {
|
||||
@@ -805,8 +807,8 @@ function handleModify(field: string, value: boolean | string | number, row: Reco
|
||||
if (props.contentConfig.modifyAction) {
|
||||
props.contentConfig.modifyAction({
|
||||
[pk]: row[pk],
|
||||
field: field,
|
||||
value: value,
|
||||
field,
|
||||
value,
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("未配置modifyAction");
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
<component
|
||||
:is="childrenMap.get(item.type)"
|
||||
v-for="opt in item.options"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></component>
|
||||
@@ -104,6 +105,7 @@
|
||||
<component
|
||||
:is="childrenMap.get(item.type)"
|
||||
v-for="opt in item.options"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></component>
|
||||
@@ -224,7 +226,9 @@ const handleSubmit = useThrottleFn(() => {
|
||||
|
||||
onMounted(() => {
|
||||
formItems.forEach((item) => {
|
||||
item.initFn && item.initFn(item);
|
||||
if (item.initFn) {
|
||||
item.initFn(item);
|
||||
}
|
||||
formRules[item.prop] = item?.rules ?? [];
|
||||
props.modalConfig.form = { labelWidth: "auto", ...props.modalConfig?.form };
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
v-on="item.events || {}"
|
||||
>
|
||||
<template v-if="item.type === 'select'">
|
||||
<template v-for="opt in item.options">
|
||||
<template v-for="opt in item.options" :key="opt.value">
|
||||
<el-option :label="opt.label" :value="opt.value" />
|
||||
</template>
|
||||
</template>
|
||||
@@ -72,7 +72,6 @@ const emit = defineEmits<{
|
||||
}>();
|
||||
// 组件映射表
|
||||
const componentMap = new Map<ISearchComponent, any>([
|
||||
/* eslint-disable */
|
||||
// @ts-ignore
|
||||
["input", markRaw(ElInput)], // @ts-ignore
|
||||
["select", markRaw(ElSelect)], // @ts-ignore
|
||||
@@ -84,7 +83,6 @@ const componentMap = new Map<ISearchComponent, any>([
|
||||
["tree-select", markRaw(ElTreeSelect)], // @ts-ignore
|
||||
["input-tag", markRaw(ElInputTag)], // @ts-ignore
|
||||
["custom-tag", markRaw(InputTag)],
|
||||
/* eslint-enable */
|
||||
]);
|
||||
|
||||
// 存储表单实例
|
||||
@@ -131,7 +129,9 @@ const handleReset = () => {
|
||||
|
||||
onMounted(() => {
|
||||
formItems.forEach((item) => {
|
||||
item?.initFn && item.initFn(item);
|
||||
if (item?.initFn) {
|
||||
item.initFn(item);
|
||||
}
|
||||
if (["input-tag", "custom-tag", "cascader"].includes(item?.type ?? "")) {
|
||||
queryParams[item.prop] = Array.isArray(item.initialValue) ? item.initialValue : [];
|
||||
} else if (item.type === "input-number") {
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { FormProps, TableProps, ColProps, ButtonProps, CardProps } from "el
|
||||
import type PageContent from "./PageContent.vue";
|
||||
import type PageModal from "./PageModal.vue";
|
||||
import type PageSearch from "./PageSearch.vue";
|
||||
import { CSSProperties } from "vue";
|
||||
import type { CSSProperties } from "vue";
|
||||
|
||||
export type PageSearchInstance = InstanceType<typeof PageSearch>;
|
||||
export type PageContentInstance = InstanceType<typeof PageContent>;
|
||||
|
||||
@@ -36,12 +36,12 @@ function usePage() {
|
||||
if (RefImpl) {
|
||||
RefImpl.value?.setModalVisible();
|
||||
RefImpl.value?.handleDisabled(false);
|
||||
let from = await (callback?.(row) ?? Promise.resolve(row));
|
||||
const from = await (callback?.(row) ?? Promise.resolve(row));
|
||||
RefImpl.value?.setFormData(from ? from : row);
|
||||
} else {
|
||||
editModalRef.value?.setModalVisible();
|
||||
editModalRef.value?.handleDisabled(false);
|
||||
let from = await (callback?.(row) ?? Promise.resolve(row));
|
||||
const from = await (callback?.(row) ?? Promise.resolve(row));
|
||||
editModalRef.value?.setFormData(from ? from : row);
|
||||
}
|
||||
}
|
||||
@@ -54,12 +54,12 @@ function usePage() {
|
||||
if (RefImpl) {
|
||||
RefImpl.value?.setModalVisible();
|
||||
RefImpl.value?.handleDisabled(true);
|
||||
let from = await (callback?.(row) ?? Promise.resolve(row));
|
||||
const from = await (callback?.(row) ?? Promise.resolve(row));
|
||||
RefImpl.value?.setFormData(from ? from : row);
|
||||
} else {
|
||||
editModalRef.value?.setModalVisible();
|
||||
editModalRef.value?.handleDisabled(true);
|
||||
let from = await (callback?.(row) ?? Promise.resolve(row));
|
||||
const from = await (callback?.(row) ?? Promise.resolve(row));
|
||||
editModalRef.value?.setFormData(from ? from : row);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,6 @@ const theneList = [
|
||||
];
|
||||
|
||||
const handleDarkChange = (theme: ThemeMode) => {
|
||||
settingsStore.changeTheme(theme);
|
||||
settingsStore.updateTheme(theme);
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -31,6 +31,9 @@ const hamburgerClass = computed(() => {
|
||||
) {
|
||||
return "hamburger--white";
|
||||
}
|
||||
|
||||
// 默认返回空字符串
|
||||
return "";
|
||||
});
|
||||
|
||||
function toggleClick() {
|
||||
|
||||
@@ -1,83 +1,81 @@
|
||||
<template>
|
||||
<div class="notification">
|
||||
<el-dropdown class="h-full flex-center" trigger="click">
|
||||
<el-badge v-if="noticeList.length > 0" :offset="[0, 15]" :value="noticeList.length" :max="99">
|
||||
<div class="i-svg:bell" />
|
||||
</el-badge>
|
||||
<el-dropdown trigger="click">
|
||||
<el-badge v-if="noticeList.length > 0" :value="noticeList.length" :max="99">
|
||||
<div class="i-svg:bell" />
|
||||
</el-badge>
|
||||
|
||||
<div v-else class="i-svg:bell" />
|
||||
<div v-else class="i-svg:bell" />
|
||||
|
||||
<template #dropdown>
|
||||
<div class="p-5">
|
||||
<template v-if="noticeList.length > 0">
|
||||
<div v-for="(item, index) in noticeList" :key="index" class="w-500px py-3">
|
||||
<div class="flex-y-center">
|
||||
<DictLabel v-model="item.type" code="notice_type" size="small" />
|
||||
<el-text
|
||||
size="small"
|
||||
class="w-200px cursor-pointer !ml-2 !flex-1"
|
||||
truncated
|
||||
@click="handleReadNotice(item.id)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</el-text>
|
||||
<template #dropdown>
|
||||
<div class="p-5">
|
||||
<template v-if="noticeList.length > 0">
|
||||
<div v-for="(item, index) in noticeList" :key="index" class="w-500px py-3">
|
||||
<div class="flex-y-center">
|
||||
<DictLabel v-model="item.type" code="notice_type" size="small" />
|
||||
<el-text
|
||||
size="small"
|
||||
class="w-200px cursor-pointer !ml-2 !flex-1"
|
||||
truncated
|
||||
@click="handleReadNotice(item.id)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</el-text>
|
||||
|
||||
<div class="text-xs text-gray">
|
||||
{{ item.publishTime }}
|
||||
</div>
|
||||
<div class="text-xs text-gray">
|
||||
{{ item.publishTime }}
|
||||
</div>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="flex-x-between">
|
||||
<el-link type="primary" underline="never" @click="handleViewMoreNotice">
|
||||
<span class="text-xs">查看更多</span>
|
||||
<el-icon class="text-xs">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-link>
|
||||
<el-link
|
||||
v-if="noticeList.length > 0"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="handleMarkAllAsRead"
|
||||
>
|
||||
<span class="text-xs">全部已读</span>
|
||||
</el-link>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="flex-center h-150px w-350px">
|
||||
<el-empty :image-size="50" description="暂无消息" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
||||
<el-dialog
|
||||
v-model="noticeDialogVisible"
|
||||
:title="noticeDetail?.title ?? '通知详情'"
|
||||
width="800px"
|
||||
custom-class="notification-detail"
|
||||
>
|
||||
<div v-if="noticeDetail" class="p-x-20px">
|
||||
<div class="flex-y-center mb-16px text-13px text-color-secondary">
|
||||
<span class="flex-y-center">
|
||||
<el-icon><User /></el-icon>
|
||||
{{ noticeDetail.publisherName }}
|
||||
</span>
|
||||
<span class="ml-2 flex-y-center">
|
||||
<el-icon><Timer /></el-icon>
|
||||
{{ noticeDetail.publishTime }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="max-h-60vh pt-16px mb-24px overflow-y-auto border-t border-solid border-color">
|
||||
<div v-html="noticeDetail.content"></div>
|
||||
</div>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="flex-x-between">
|
||||
<el-link type="primary" underline="never" @click="handleViewMoreNotice">
|
||||
<span class="text-xs">查看更多</span>
|
||||
<el-icon class="text-xs">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-link>
|
||||
<el-link
|
||||
v-if="noticeList.length > 0"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="handleMarkAllAsRead"
|
||||
>
|
||||
<span class="text-xs">全部已读</span>
|
||||
</el-link>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="flex-center h-150px w-350px">
|
||||
<el-empty :image-size="50" description="暂无消息" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
||||
<el-dialog
|
||||
v-model="noticeDialogVisible"
|
||||
:title="noticeDetail?.title ?? '通知详情'"
|
||||
width="800px"
|
||||
custom-class="notification-detail"
|
||||
>
|
||||
<div v-if="noticeDetail" class="p-x-20px">
|
||||
<div class="flex-y-center mb-16px text-13px text-color-secondary">
|
||||
<span class="flex-y-center">
|
||||
<el-icon><User /></el-icon>
|
||||
{{ noticeDetail.publisherName }}
|
||||
</span>
|
||||
<span class="ml-2 flex-y-center">
|
||||
<el-icon><Timer /></el-icon>
|
||||
{{ noticeDetail.publishTime }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="max-h-60vh pt-16px mb-24px overflow-y-auto border-t border-solid border-color">
|
||||
<div v-html="noticeDetail.content"></div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -162,14 +160,4 @@ onBeforeUnmount(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notification {
|
||||
:deep(.el-badge) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
<!-- 布局大小 -->
|
||||
<el-tooltip :content="t('sizeSelect.tooltip')" effect="dark" placement="bottom">
|
||||
<el-dropdown trigger="click" @command="handleSizeChange">
|
||||
<div>
|
||||
<div class="i-svg:size" />
|
||||
</div>
|
||||
<div class="i-svg:size" />
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
|
||||
@@ -226,7 +226,7 @@ const queryParams = reactive<{
|
||||
[key: string]: any;
|
||||
}>({
|
||||
pageNum: 1,
|
||||
pageSize: pageSize,
|
||||
pageSize,
|
||||
});
|
||||
|
||||
// 计算popover的宽度
|
||||
@@ -284,7 +284,7 @@ const selectedItems = ref<IObject[]>([]);
|
||||
const confirmText = computed(() => {
|
||||
return selectedItems.value.length > 0 ? `已选(${selectedItems.value.length})` : "确 定";
|
||||
});
|
||||
function handleSelect(selection: any[], _row: any) {
|
||||
function handleSelect(selection: any[]) {
|
||||
if (isMultiple || selection.length === 0) {
|
||||
// 多选
|
||||
selectedItems.value = selection;
|
||||
|
||||
@@ -130,7 +130,7 @@ watch(
|
||||
fileList.value = value.map((item) => {
|
||||
const name = item.name ? item.name : item.url?.substring(item.url.lastIndexOf("/") + 1);
|
||||
return {
|
||||
name: name,
|
||||
name,
|
||||
url: item.url,
|
||||
status: "success",
|
||||
uid: getUid(),
|
||||
@@ -199,11 +199,11 @@ const handleSuccess = (response: any, uploadFile: UploadFile, files: UploadFiles
|
||||
return file.status === "success" || file.status === "fail";
|
||||
})
|
||||
) {
|
||||
let fileInfos = [] as FileInfo[];
|
||||
const fileInfos = [] as FileInfo[];
|
||||
files.map((file: UploadFile) => {
|
||||
if (file.status === "success") {
|
||||
//只取携带response的才是刚上传的
|
||||
let res = file.response as FileInfo;
|
||||
const res = file.response as FileInfo;
|
||||
if (res) {
|
||||
fileInfos.push({ name: res.name, url: res.url } as FileInfo);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user