修改bug

This commit is contained in:
Teo
2025-08-13 23:35:26 +08:00
parent 544cc07862
commit 606722f19e
7 changed files with 618 additions and 37 deletions

View File

@ -4,7 +4,11 @@
<el-table-column type="selection" width="55" align="center" />
<el-table-column align="center" prop="projectName" label="工程名称" />
<el-table-column align="center" prop="submitUnit" label="提出单位" />
<el-table-column align="center" prop="specialty" label="专业" />
<el-table-column align="center" prop="specialty" label="专业">
<template #default="{ row }">
<dict-tag :options="des_user_major" :value="row.specialty" />
</template>
</el-table-column>
<el-table-column align="center" prop="submitDate" label="提出日期">
<template #default="{ row }">
{{ formatDate(row.submitDate) }}
@ -41,14 +45,16 @@
<el-descriptions :column="2" border style="margin-top: 8px" label-width="160px" size="large">
<el-descriptions-item label-align="center" label="工程名称" class-name="zebra"> {{ tableDetail.projectName }} </el-descriptions-item>
<el-descriptions-item label-align="center" label="提出单位" class-name="zebra"> {{ tableDetail.submitUnit }} </el-descriptions-item>
<el-descriptions-item label-align="center" label="专业" label-class-name="white"> {{ tableDetail.specialty }} </el-descriptions-item>
<el-descriptions-item label-align="center" label="专业" label-class-name="white"
><dict-tag :options="des_user_major" :value="tableDetail.specialty" />
</el-descriptions-item>
<el-descriptions-item label-align="center" label="提出日期" label-class-name="white">
{{ dayjs(tableDetail.submitDate).format('YYYY-MM-DD') }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="卷册名称" class-name="zebra"> {{ tableDetail.volumeName }} </el-descriptions-item>
<el-descriptions-item label-align="center" label="卷册号" class-name="zebra"> {{ tableDetail.volumeNumber }} </el-descriptions-item>
<el-descriptions-item label-align="center" label="附图" :span="2" label-class-name="white">
<image-preview :src="item.url" v-for="item in tableDetail.attachments" width="200px" class="mr" />
<img :src="item.url" v-for="item in tableDetail.attachmentsImgList" alt="" style="width: 200px; height: auto" />
</el-descriptions-item>
<el-descriptions-item label-align="center" label="变更原因" :span="2" class-name="zebra">
<el-checkbox-group v-model="tableDetail.changeReasons">
@ -64,6 +70,11 @@
<el-descriptions-item label-align="center" label="内容" :span="2" label-class-name="white">
{{ tableDetail.content }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="附件" :span="2" label-class-name="white">
<el-link type="primary" :underline="false" :href="tableDetail.attachmentsList.url" target="_blank">{{
tableDetail.attachmentsList.originalName
}}</el-link>
</el-descriptions-item>
<el-descriptions-item label-align="center" label="变更费用估算" :span="2" class-name="zebra">
{{ tableDetail.costEstimation }}
</el-descriptions-item>
@ -163,6 +174,7 @@ const props = defineProps({
default: ''
}
});
const tableDetail = ref<any>({});
const exportRef = ref<HTMLElement>();
const radioList = ref([
@ -177,13 +189,24 @@ const radioList = ref([
]);
const detailVisible = ref(false);
const formatDate = (val: string | Date) => (val ? dayjs(val).format('YYYY-MM-DD') : '');
const { des_user_major } = toRefs<any>(proxy?.useDict('des_user_major'));
const handleDetail = async (row) => {
const res = await listByIds(row.id);
tableDetail.value = {
...row,
hasAttachmentList: res.data
};
tableDetail.value = { ...row };
if (row.attachmentsImg) {
const res = await listByIds(row.attachmentsImg);
tableDetail.value.attachmentsImgList = res.data;
}
if (row.attachments) {
const res = await listByIds(row.attachments);
tableDetail.value.attachmentsList = res.data[0];
}
// tableDetail.value = {
// ...row,
// hasAttachmentList: res.data
// };
detailVisible.value = true;
};
/** 多选框选中数据 */
@ -220,27 +243,62 @@ const handleViewInfo = (row) => {
}
});
};
const handleDownload = () => {
const handleDownload = async () => {
const style = `
<style>
.white { background: #fff !important; }
.none { display: none !important; }
.zebra { background: #f5f7fa !important; }
.el-descriptions__table { table-layout: fixed !important; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #333; padding: 6px; font-size: 14px; }
</style>
`;
<style>
.white { background: #fff !important; }
.none { display: none !important; }
.zebra { background: #f5f7fa !important; }
.el-descriptions__table { table-layout: fixed !important; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #333; padding: 6px; font-size: 14px; }
</style>
`;
const el = exportRef.value;
if (!el) return;
// 拷贝 DOM避免修改原内容
// 拷贝 DOM避免影响原内容
const clone = el.cloneNode(true) as HTMLElement;
// 删除 .dialog-footer
const footer = clone.querySelector('.dialog-footer');
if (footer) {
footer.remove();
}
// 工具函数:图片转成指定宽度的 base64
const resizeImageToBase64 = (img: HTMLImageElement, maxWidth = 500) => {
return new Promise<string>((resolve) => {
const image = new Image();
image.crossOrigin = 'anonymous';
image.src = img.src;
image.onload = () => {
const scale = Math.min(1, maxWidth / image.naturalWidth);
const canvas = document.createElement('canvas');
canvas.width = image.naturalWidth * scale;
canvas.height = image.naturalHeight * scale;
const ctx = canvas.getContext('2d');
ctx!.drawImage(image, 0, 0, canvas.width, canvas.height);
resolve(canvas.toDataURL('image/png'));
};
image.onerror = () => {
resolve(img.src); // 如果加载失败就用原地址
};
});
};
// 找到所有图片并替换成 base64顺序执行以避免并发问题
const imgs = Array.from(clone.querySelectorAll('img'));
for (let img of imgs) {
const base64 = await resizeImageToBase64(img, 200);
img.src = base64;
}
// 应用表格的内联样式
applyInlineTableStyles(clone);
// 包裹 HTML 内容
// 拼接 HTML
const html = `
<html>
<head>
@ -256,6 +314,7 @@ const handleDownload = () => {
const blob = (window as any).htmlDocx.asBlob(html);
saveAs(blob, '变更单.docx');
};
const applyInlineTableStyles = (rootEl: HTMLElement) => {
rootEl.querySelectorAll('table').forEach((table) => {
table.setAttribute('style', 'width:100%; border-collapse:collapse; table-layout:fixed; border:1px solid #333;');
@ -328,6 +387,9 @@ const applyInlineTableStyles = (rootEl: HTMLElement) => {
flex-direction: column;
justify-content: center;
cursor: pointer;
img {
transform: rotateZ(180deg);
}
}
}
</style>

View File

@ -50,7 +50,9 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="专业">
<el-input v-model="form.specialty" />
<el-select v-model="form.specialty" placeholder="">
<el-option v-for="item in des_user_major" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
@ -69,7 +71,7 @@
</el-col>
<el-col :span="12">
<el-form-item label="附图">
<file-Upload v-model="form.attachments">
<file-Upload v-model="form.attachmentsImg" :file-type="['pdf', 'png', 'jpg', 'jpeg', 'gif', 'bmp']">
<el-button type="primary">上传附件</el-button>
</file-Upload>
</el-form-item>
@ -98,7 +100,7 @@
<el-input v-model="form.content" type="textarea" :rows="6" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="附件" prop="attachments">
<file-upload v-model="form.attachments" :limit="1" :file-type="['pdf', 'png', 'jpg', 'jpeg', 'gif', 'bmp']"></file-upload>
<file-upload v-model="form.attachments" :limit="1" :file-type="['pdf']"></file-upload>
</el-form-item>
<el-form-item label="变更费用估算" prop="costEstimation">
<el-input v-model="form.costEstimation" :rows="6" placeholder="请输入变更费用估算" />
@ -174,6 +176,7 @@ const { proxy } = getCurrentInstance() as ComponentInternalInstance;
import { useUserStoreHook } from '@/store/modules/user';
import { listByIds } from '@/api/system/oss';
import { addContactnotice, getContactnotice, updateContactnotice } from '@/api/cory/contactnotice';
const { des_user_major } = toRefs(proxy?.useDict('des_user_major'));
// 获取用户 store
const userStore = useUserStoreHook();