update:报告模板优化

This commit is contained in:
2026-01-30 14:23:18 +08:00
parent ad3f21d885
commit 9e5e32d6eb
4 changed files with 84 additions and 17 deletions

View File

@@ -1,8 +1,9 @@
<template> <template>
<div class="img-content"> <div class="img-content">
<div v-if="mode === 'edit'" class="pic"> <div v-if="mode === 'edit'" class="pic">
<div class="title-item">{{ titleKey || '请输入图片key' }}</div>
<el-icon :size="100"><Picture /></el-icon> <el-icon :size="100"><Picture /></el-icon>
<div class="key-name">{{ titleKey || '请输入图片key' }}</div> <div class="title-item">{{ paramsData.title }}</div>
</div> </div>
<div <div
v-else v-else
@@ -31,17 +32,24 @@
</div> </div>
</div> </div>
</template> </template>
<div v-else class="no-data">单击此处粘贴图片...</div> <div v-else class="preview">
<div class="no-data">单击此处粘贴图片...</div>
<div class="placeholder">{{ paramsData.title }}</div>
</div>
</div> </div>
<div v-if="mode === 'edit'" class="setting-btn" @click="diaShow = true"> <div v-if="mode === 'edit'" class="setting-btn" @click="diaShow = true">
<el-icon :size="22"><Setting /></el-icon> <el-icon :size="22"><Setting /></el-icon>
</div> </div>
<Dialog v-model="diaShow" diaTitle="图片设置" :width="400" @close="closeFun"> <Dialog v-model="diaShow" diaTitle="图片设置" :width="400" @close="closeFun">
<div class="content"> <div class="content">
<div class="title-key"> <div class="option-item">
<div class="label">图片key</div> <div class="label">图片key</div>
<el-input v-model="titleKey" placeholder="请输入" clearable /> <el-input v-model="titleKey" placeholder="请输入" clearable />
</div> </div>
<div class="option-item">
<div class="label">默认名称</div>
<el-input v-model="paramsData.title" placeholder="请输入" clearable />
</div>
</div> </div>
<template #footer> <template #footer>
<div> <div>
@@ -58,11 +66,12 @@ import { Picture, DeleteFilled } from '@element-plus/icons-vue';
import Dialog from '@/components/common/dialog/index.vue'; import Dialog from '@/components/common/dialog/index.vue';
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
const emit = defineEmits(['update:keyValue', 'update:value']); const emit = defineEmits(['update:keyValue', 'update:value', 'update:params']);
interface Props { interface Props {
keyValue: any; keyValue: any;
value: any; value: any;
params: any;
mode: string; mode: string;
disabled?: boolean; disabled?: boolean;
} }
@@ -70,6 +79,7 @@ interface Props {
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
keyValue: '', keyValue: '',
value: [], value: [],
params: {},
mode: '', mode: '',
disabled: false, disabled: false,
}); });
@@ -80,6 +90,7 @@ const fileList = ref<any>([]);
const isFocus = ref(false); const isFocus = ref(false);
const PasteContentRef = ref(); const PasteContentRef = ref();
const contenteditable = ref(false); const contenteditable = ref(false);
const paramsData = ref(cloneDeep(props.params));
watch( watch(
() => titleKey.value, () => titleKey.value,
@@ -89,6 +100,16 @@ watch(
{ deep: true } { deep: true }
); );
watch(
() => paramsData.value,
(val: any) => {
emit('update:params', val);
},
{
deep: true,
}
);
watch( watch(
() => props.value, () => props.value,
(val: any) => { (val: any) => {
@@ -150,6 +171,7 @@ const pasteFun = (event: any) => {
const base64 = reader.result; const base64 = reader.result;
fileList.value.push({ fileList.value.push({
src: base64, src: base64,
title: props.params.title,
}); });
emit('update:value', fileList.value); emit('update:value', fileList.value);
}; };
@@ -191,7 +213,7 @@ const closeFun = () => {
justify-content: center; justify-content: center;
align-content: center; align-content: center;
flex-wrap: wrap; flex-wrap: wrap;
.key-name { .title-item {
width: 100%; width: 100%;
text-align: center; text-align: center;
} }
@@ -241,8 +263,20 @@ const closeFun = () => {
cursor: pointer; cursor: pointer;
} }
} }
.no-data { .preview {
color: var(--el-text-color-placeholder); width: 100%;
height: 148px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-content: space-between;
.no-data {
color: var(--el-text-color-placeholder);
}
.placeholder {
text-align: center;
color: var(--el-text-color-primary);
}
} }
} }
.setting-btn { .setting-btn {
@@ -266,7 +300,7 @@ const closeFun = () => {
} }
.content { .content {
.title-key { .option-item {
display: flex; display: flex;
align-items: center; align-items: center;
width: 300px; width: 300px;

View File

@@ -79,6 +79,7 @@
<Img <Img
v-model:keyValue="unit.key" v-model:keyValue="unit.key"
v-model:value="unit.value" v-model:value="unit.value"
v-model:params="unit.params"
:mode="modeType" :mode="modeType"
:disabled="preview" :disabled="preview"
/> />
@@ -165,6 +166,7 @@ import Table from './table.vue';
import Img from './img.vue'; import Img from './img.vue';
import KkfileView from '@/components/common/filePreview/kkfileView.vue'; import KkfileView from '@/components/common/filePreview/kkfileView.vue';
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import { ElMessage } from 'element-plus';
interface Props { interface Props {
data: any; data: any;
@@ -283,10 +285,11 @@ const delFun = (paragraphIndex: any, gridIndex?: any, unitIndex?: any) => {
const createDataFun = (type: string) => { const createDataFun = (type: string) => {
return { return {
type, type, // 类型
key: '', key: '', // 报告生成对应key
value: '', value: '', // 内容
children: [], params: {}, // 其他参数
children: [], // 子节点
}; };
}; };
@@ -301,12 +304,14 @@ const getFormatDataFun = () => {
type: paragraph.type, type: paragraph.type,
key: paragraph.key, key: paragraph.key,
value: paragraph.value, value: paragraph.value,
params: paragraph.params,
}); });
paragraph.children.forEach((grid: any) => { paragraph.children.forEach((grid: any) => {
build.push({ build.push({
type: grid.type, type: grid.type,
key: grid.key, key: grid.key,
value: grid.value, value: grid.value,
params: grid.params,
}); });
grid.children.forEach((unit: any) => { grid.children.forEach((unit: any) => {
if (unit.type === 'form') { if (unit.type === 'form') {
@@ -315,6 +320,7 @@ const getFormatDataFun = () => {
type: 'text', type: 'text',
key: item.key, key: item.key,
value: item.value, value: item.value,
params: item.params,
}); });
}); });
} else { } else {
@@ -322,6 +328,7 @@ const getFormatDataFun = () => {
type: unit.type, type: unit.type,
key: unit.key, key: unit.key,
value: unit.value, value: unit.value,
params: unit.params,
}; };
if (unit.type === 'table') { if (unit.type === 'table') {
unitData.head = unit.head.map((i: any) => i.title); unitData.head = unit.head.map((i: any) => i.title);
@@ -334,8 +341,31 @@ const getFormatDataFun = () => {
return build; return build;
}; };
const checkKeysFun = () => {
const dataList = getFormatDataFun();
const keys: any = [];
let repeatKey = '';
dataList.some((item: any) => {
if (item.key) {
if (keys.includes(item.key)) {
repeatKey = item.key;
return true;
} else {
keys.push(item.key);
}
}
});
if (repeatKey) {
ElMessage.warning(`${repeatKey}重复,请更改后再提交`);
return false;
} else {
return true;
}
};
defineExpose({ defineExpose({
getFormatDataFun, getFormatDataFun,
checkKeysFun,
}); });
</script> </script>

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="table-content"> <div class="table-content">
<div v-if="mode === 'edit'" class="key-name">{{ titleKey || '请输入表格key ' }}</div> <div v-if="mode === 'edit'" class="title-item">{{ titleKey || '请输入表格key ' }}</div>
<el-table :data="tableData"> <el-table :data="tableData">
<el-table-column <el-table-column
v-for="(item, index) in head" v-for="(item, index) in head"
@@ -26,7 +26,7 @@
</div> </div>
<Dialog v-model="diaShow" diaTitle="表格设置" :width="500" @close="closeFun"> <Dialog v-model="diaShow" diaTitle="表格设置" :width="500" @close="closeFun">
<div class="content"> <div class="content">
<div class="title-key"> <div class="option-item">
<div class="label">表格key</div> <div class="label">表格key</div>
<el-input v-model="titleKey" placeholder="请输入" clearable /> <el-input v-model="titleKey" placeholder="请输入" clearable />
</div> </div>
@@ -156,7 +156,7 @@ const closeFun = () => {
opacity: 1; opacity: 1;
} }
} }
.key-name { .title-item {
background-color: var(--el-bg-color); background-color: var(--el-bg-color);
color: var(--el-text-color-placeholder); color: var(--el-text-color-placeholder);
text-align: center; text-align: center;
@@ -194,7 +194,7 @@ const closeFun = () => {
cursor: pointer; cursor: pointer;
} }
.content { .content {
.title-key { .option-item {
display: flex; display: flex;
align-items: center; align-items: center;
width: 300px; width: 300px;

View File

@@ -168,8 +168,11 @@ const saveDraftFun = async (callback?: () => void) => {
const showApproveDia = ref(false); const showApproveDia = ref(false);
const reportEditRef = ref<any>();
const openApproveDiaFun = () => { const openApproveDiaFun = () => {
showApproveDia.value = true; if (reportEditRef.value?.checkKeysFun()) {
showApproveDia.value = true;
}
}; };
onMounted(async () => { onMounted(async () => {