| | |
| | | <div |
| | | @click.stop="handleClick(1)" |
| | | class="absolute h100 flex a-center c-fff fs--14 SHS pointer-events-none" |
| | | style="left: 20px; right: 60px; z-index: 1;" |
| | | style="left: 20px; right: 60px; z-index: 1" |
| | | v-if="startTimeTxt" |
| | | > |
| | | {{ startTimeTxt }} |
| | |
| | | @click.stop="handleClick(1)" |
| | | v-else |
| | | class="absolute h100 flex a-center c-fff fs--14 SHSR pointer-events-none" |
| | | style="left: 20px; right: 60px; z-index: 1;" |
| | | style="left: 20px; right: 60px; z-index: 1" |
| | | > |
| | | 请选择开始日期 |
| | | </div> |
| | | <div class="flex a-center gap--5" style="position: relative; z-index: 2;"> |
| | | <div |
| | | class="flex a-center gap--5" |
| | | style="position: relative; z-index: 2" |
| | | > |
| | | <i |
| | | @click.stop="clearStartTime" |
| | | class="el-icon-circle-close c-fff cursor-pointer" |
| | |
| | | <div |
| | | @click="handleClick(2)" |
| | | class="absolute h100 flex a-center c-fff fs--14 SHS pointer-events-none" |
| | | style="left: 20px; right: 60px; z-index: 1;" |
| | | style="left: 20px; right: 60px; z-index: 1" |
| | | v-if="endTimeTxt" |
| | | > |
| | | {{ endTimeTxt }} |
| | |
| | | @click="handleClick(2)" |
| | | v-else |
| | | class="absolute h100 flex a-center c-fff fs--14 SHSR pointer-events-none" |
| | | style="left: 20px; right: 60px; z-index: 1;" |
| | | style="left: 20px; right: 60px; z-index: 1" |
| | | > |
| | | 请选择结束日期 |
| | | </div> |
| | | <div class="flex a-center gap--5" style="position: relative; z-index: 2;"> |
| | | <div |
| | | class="flex a-center gap--5" |
| | | style="position: relative; z-index: 2" |
| | | > |
| | | <i |
| | | @click.stop="clearEndTime" |
| | | class="el-icon-circle-close c-fff cursor-pointer" |
| | |
| | | {{ formatAddress(row.addressInfo) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="本月检查情况" prop="checkResult" min-width="120"> |
| | | <el-table-column |
| | | label="本月检查情况" |
| | | prop="checkResult" |
| | | min-width="120" |
| | | > |
| | | <template #default="{ row }"> |
| | | <div class="flex a-center j-center"> |
| | | <div class="ripple" v-if="row.checkResult"> |
| | |
| | | ></div> |
| | | </div> |
| | | <div :class="row.checkResult ? 'ml--6' : ''" class="SHSR"> |
| | | {{ row.checkResult || '-' }} |
| | | {{ row.checkResult || "-" }} |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | </el-table-column> |
| | | <el-table-column label="本月检查风险" prop="risk" min-width="120"> |
| | | <template #default="{ row }"> |
| | | <div class="SHSR">{{ row.risk || '-' }}</div> |
| | | <div class="SHSR">{{ row.risk || "-" }}</div> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | |
| | | </div> |
| | | <!-- 项目列表弹窗 --> |
| | | <CustomDialog title="项目" :visible.sync="projectVisible" width="1420px"> |
| | | <CustomTable |
| | | :data="checkList" |
| | | height="630" |
| | | v-loading="checkLoading" |
| | | > |
| | | <CustomTable :data="checkList" height="630" v-loading="checkLoading"> |
| | | <el-table-column label="检查计划" prop="planName" min-width="150" /> |
| | | <el-table-column label="计划类型" min-width="120"> |
| | | <template #default="{ row }"> |
| | |
| | | </el-table-column> |
| | | <el-table-column label="分数" prop="score" min-width="100"> |
| | | <template #default="{ row }"> |
| | | {{ row.score || '-' }} |
| | | {{ commentType === "1" ? row.fuzzyScore : row.score }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column v-if="shouldShowRiskLevel" label="风险类型" min-width="120"> |
| | | <el-table-column |
| | | v-if="shouldShowRiskLevel" |
| | | label="风险类型" |
| | | min-width="120" |
| | | > |
| | | <template #default="{ row }"> |
| | | {{ formatRiskLevel(row.riskLevel) }} |
| | | </template> |
| | |
| | | class="py--12 w100 txt-center br--10 bgcolor6 report-btn" |
| | | :class="{ |
| | | 'report-disabled': row.containSystemRes !== 1, |
| | | 'report-enabled': row.containSystemRes === 1 |
| | | 'report-enabled': row.containSystemRes === 1, |
| | | }" |
| | | > |
| | | <span>安全报告</span> |
| | | <span v-if="row.containSystemRes !== 1" class="no-report-tag">(暂无)</span> |
| | | <span v-if="row.containSystemRes !== 1" class="no-report-tag" |
| | | >(暂无)</span |
| | | > |
| | | </div> |
| | | <div |
| | | @click="openReport('device', row)" |
| | | class="py--12 w100 txt-center br--10 bgcolor7 report-btn" |
| | | :class="{ |
| | | 'report-disabled': row.containDeviceRes !== 1, |
| | | 'report-enabled': row.containDeviceRes === 1 |
| | | 'report-enabled': row.containDeviceRes === 1, |
| | | }" |
| | | > |
| | | <span>设备报告</span> |
| | | <span v-if="row.containDeviceRes !== 1" class="no-report-tag">(暂无)</span> |
| | | <span v-if="row.containDeviceRes !== 1" class="no-report-tag" |
| | | >(暂无)</span |
| | | > |
| | | </div> |
| | | </div> |
| | | </el-popover> |
| | |
| | | > |
| | | <el-descriptions :column="3"> |
| | | <el-descriptions-item label="施工单位"> |
| | | {{ companyInfo.construction?.name || '-' }} |
| | | {{ companyInfo.construction?.name || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="项目经理"> |
| | | {{ companyInfo.construction?.leader || '-' }} |
| | | {{ companyInfo.construction?.leader || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="联系方式"> |
| | | {{ companyInfo.construction?.phone || '-' }} |
| | | {{ companyInfo.construction?.phone || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="监理单位"> |
| | | {{ companyInfo.supervisor?.name || '-' }} |
| | | {{ companyInfo.supervisor?.name || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="总监"> |
| | | {{ companyInfo.supervisor?.leader || '-' }} |
| | | {{ companyInfo.supervisor?.leader || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="联系方式"> |
| | | {{ companyInfo.supervisor?.phone || '-' }} |
| | | {{ companyInfo.supervisor?.phone || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="建设单位"> |
| | | {{ companyInfo.development?.name || '-' }} |
| | | {{ companyInfo.development?.name || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="项目负责人"> |
| | | {{ companyInfo.development?.leader || '-' }} |
| | | {{ companyInfo.development?.leader || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="联系方式"> |
| | | {{ companyInfo.development?.phone || '-' }} |
| | | {{ companyInfo.development?.phone || "-" }} |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | </CustomDialog> |
| | |
| | | width="1420px" |
| | | @close="closeReportDialog" |
| | | > |
| | | <div style="height: 691px;" class="flex flex-column" v-loading="reportLoading"> |
| | | <div |
| | | style="height: 691px" |
| | | class="flex flex-column" |
| | | v-loading="reportLoading" |
| | | > |
| | | <!-- PDF预览容器 --> |
| | | <div |
| | | v-if="showPreview && pdfUrl" |
| | | style="width: 100%; height: 100%; overflow: auto; background: #525659;" |
| | | style="width: 100%; height: 100%; overflow: auto; background: #525659" |
| | | > |
| | | <iframe |
| | | :src="pdfUrl" |
| | | style="width: 100%; height: 100%; border: none;" |
| | | style="width: 100%; height: 100%; border: none" |
| | | frameborder="0" |
| | | ></iframe> |
| | | </div> |
| | |
| | | </div> |
| | | <!-- 底部操作按钮 --> |
| | | <div class="flex j-center gap--20 mt--20"> |
| | | <el-button type="primary" @click="downloadReport" :disabled="!reportBlobUrl">下载报告</el-button> |
| | | <el-button |
| | | type="primary" |
| | | @click="downloadReport" |
| | | :disabled="!reportBlobUrl" |
| | | >下载报告</el-button |
| | | > |
| | | <el-button @click="closeReportDialog">关闭</el-button> |
| | | </div> |
| | | </div> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import HeaderBox from '../header/index.vue' |
| | | import moment from 'moment' |
| | | import HeaderBox from "../header/index.vue"; |
| | | import moment from "moment"; |
| | | import { |
| | | getProjectList, |
| | | projectList, |
| | |
| | | getFuzzyReportWord, |
| | | getScoreReportWord, |
| | | getFuzzyReportPdfUrl, |
| | | getScoreReportPdfUrl |
| | | } from './service' |
| | | getScoreReportPdfUrl, |
| | | } from "./service"; |
| | | export default { |
| | | components: { HeaderBox }, |
| | | props: {}, |
| | |
| | | riskLevel: null, // 项目风险 |
| | | startTime: null, // 开始时间 |
| | | endTime: null, // 结束时间 |
| | | startTimeTxt: '', // 开始时间显示文本 |
| | | endTimeTxt: '', // 结束时间显示文本 |
| | | projectName: '', // 项目名称搜索 |
| | | startTimeTxt: "", // 开始时间显示文本 |
| | | endTimeTxt: "", // 结束时间显示文本 |
| | | projectName: "", // 项目名称搜索 |
| | | |
| | | // 下拉选项 |
| | | projectOptions: [], // 项目下拉列表 |
| | | projectTypeOptions: [ |
| | | { label: '房建', value: 0 }, |
| | | { label: '市政', value: 1 }, |
| | | { label: '固定资产', value: 2 } |
| | | { label: "房建", value: 0 }, |
| | | { label: "市政", value: 1 }, |
| | | { label: "固定资产", value: 2 }, |
| | | ], // 项目类型下拉列表 |
| | | riskLevelOptions: [ |
| | | { label: '拒绝接受风险', value: 0 }, |
| | | { label: '不可接受风险', value: 1 }, |
| | | { label: '可接受风险', value: 2 }, |
| | | { label: '可容忍风险', value: 3 }, |
| | | { label: '可忽略风险', value: 4 } |
| | | { label: "拒绝接受风险", value: 0 }, |
| | | { label: "不可接受风险", value: 1 }, |
| | | { label: "可接受风险", value: 2 }, |
| | | { label: "可容忍风险", value: 3 }, |
| | | { label: "可忽略风险", value: 4 }, |
| | | ], |
| | | |
| | | // 表格数据 |
| | |
| | | |
| | | // 用户信息 |
| | | userInfo: {}, |
| | | clientId: localStorage.getItem('clientId'), |
| | | clientId: localStorage.getItem("clientId"), |
| | | isClientMode: false, // 是否是委托方模式 |
| | | |
| | | // 报告相关 |
| | | reportUrl: '', // 已废弃,保留兼容性 |
| | | reportBlobUrl: '', // Blob URL用于下载 |
| | | pdfUrl: '', // PDF预览URL |
| | | reportUrl: "", // 已废弃,保留兼容性 |
| | | reportBlobUrl: "", // Blob URL用于下载 |
| | | pdfUrl: "", // PDF预览URL |
| | | reportLoading: false, |
| | | showPreview: false, // 是否显示预览 |
| | | currentRow: null, // 当前选中的行数据 |
| | | |
| | | // 评价类型 |
| | | commentType: localStorage.getItem('commentType') || null, |
| | | projectCategory: null |
| | | } |
| | | commentType: localStorage.getItem("commentType") || null, |
| | | projectCategory: null, |
| | | }; |
| | | }, |
| | | computed: { |
| | | // 是否显示风险类型列(commentType 不为 2 时显示) |
| | | shouldShowRiskLevel () { |
| | | return this.commentType != '2' |
| | | } |
| | | return this.commentType != "2"; |
| | | }, |
| | | }, |
| | | watch: { |
| | | startTime: { |
| | | handler (newVal) { |
| | | if (newVal) { |
| | | this.startTimeTxt = moment(newVal).format('YYYY年MM月DD日 HH:mm:ss') |
| | | this.startTimeTxt = moment(newVal).format("YYYY年MM月DD日 HH:mm:ss"); |
| | | } else { |
| | | this.startTimeTxt = '' |
| | | this.startTimeTxt = ""; |
| | | } |
| | | }, |
| | | immediate: true |
| | | immediate: true, |
| | | }, |
| | | endTime: { |
| | | handler (newVal) { |
| | | if (newVal) { |
| | | this.endTimeTxt = moment(newVal).format('YYYY年MM月DD日 HH:mm:ss') |
| | | this.endTimeTxt = moment(newVal).format("YYYY年MM月DD日 HH:mm:ss"); |
| | | } else { |
| | | this.endTimeTxt = '' |
| | | this.endTimeTxt = ""; |
| | | } |
| | | }, |
| | | immediate: true |
| | | } |
| | | immediate: true, |
| | | }, |
| | | }, |
| | | created () { |
| | | if (this.$route.query.projectCategory) { |
| | | this.projectCategory = this.$route.query.projectCategory |
| | | this.projectCategory = this.$route.query.projectCategory; |
| | | } |
| | | |
| | | // 接收从 home 页面传递过来的时间参数并回填 |
| | | if (this.$route.query.startTime) { |
| | | this.startTime = new Date(this.$route.query.startTime) |
| | | this.startTime = new Date(this.$route.query.startTime); |
| | | } |
| | | if (this.$route.query.endTime) { |
| | | this.endTime = new Date(this.$route.query.endTime) |
| | | this.endTime = new Date(this.$route.query.endTime); |
| | | } |
| | | |
| | | this.initUserInfo() |
| | | this.initData() |
| | | this.initUserInfo(); |
| | | this.initData(); |
| | | }, |
| | | mounted () {}, |
| | | methods: { |
| | | // 初始化用户信息 |
| | | initUserInfo () { |
| | | const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}') |
| | | this.userInfo = userInfo |
| | | const userInfo = JSON.parse(localStorage.getItem("userInfo") || "{}"); |
| | | this.userInfo = userInfo; |
| | | // 判断是否是委托方(type为1表示委托方) |
| | | this.isClientMode = userInfo.type === 1 |
| | | this.isClientMode = userInfo.type === 1; |
| | | }, |
| | | |
| | | // 初始化数据 |
| | | async initData () { |
| | | await this.loadProjectOptions() |
| | | await this.loadTableData() |
| | | await this.loadProjectOptions(); |
| | | await this.loadTableData(); |
| | | }, |
| | | |
| | | // 加载项目下拉列表(仅委托方需要) |
| | | async loadProjectOptions () { |
| | | if (!this.isClientMode) return |
| | | if (!this.isClientMode) return; |
| | | |
| | | try { |
| | | const res = await getProjectList({ |
| | | clientId: this.clientId, |
| | | projectCategory: ['ongoing', 'fixed'][localStorage.getItem('activeTab') - 1] |
| | | }) |
| | | projectCategory: ["ongoing", "fixed"][ |
| | | localStorage.getItem("activeTab") - 1 |
| | | ], |
| | | }); |
| | | if (res) { |
| | | this.projectOptions = res.map((item) => ({ |
| | | label: item.name, |
| | | value: item.id |
| | | })) |
| | | value: item.id, |
| | | })); |
| | | } |
| | | } catch (error) { |
| | | console.error('加载项目列表失败:', error) |
| | | console.error("加载项目列表失败:", error); |
| | | } |
| | | }, |
| | | |
| | | // 加载表格数据 |
| | | async loadTableData () { |
| | | this.loading = true |
| | | this.loading = true; |
| | | try { |
| | | const params = { |
| | | pageNum: this.currentPage, |
| | | pageSize: this.pageSize, |
| | | clientId: this.clientId |
| | | } |
| | | clientId: this.clientId, |
| | | }; |
| | | |
| | | // 添加搜索条件 |
| | | if (this.searchProjectId) params.projectId = this.searchProjectId |
| | | if (this.projectType) params.type = this.projectType |
| | | if (this.riskLevel !== null && this.riskLevel !== '') { params.riskLevel = this.riskLevel } |
| | | if (this.searchProjectId) params.projectId = this.searchProjectId; |
| | | if (this.projectType) params.type = this.projectType; |
| | | if (this.riskLevel !== null && this.riskLevel !== "") { |
| | | params.riskLevel = this.riskLevel; |
| | | } |
| | | if (this.startTime) { |
| | | params.startTime = moment(this.startTime).format( |
| | | 'YYYY-MM-DD HH:mm:ss' |
| | | ) |
| | | "YYYY-MM-DD HH:mm:ss" |
| | | ); |
| | | } |
| | | if (this.endTime) { params.endTime = moment(this.endTime).format('YYYY-MM-DD HH:mm:ss') } |
| | | if (this.projectName) params.name = this.projectName |
| | | if (this.endTime) { |
| | | params.endTime = moment(this.endTime).format("YYYY-MM-DD HH:mm:ss"); |
| | | } |
| | | if (this.projectName) params.name = this.projectName; |
| | | if (this.projectCategory) { |
| | | params.category = localStorage.getItem('activeTab') |
| | | params.category = localStorage.getItem("activeTab"); |
| | | } |
| | | |
| | | const res = await projectList(params) |
| | | const res = await projectList(params); |
| | | if (res) { |
| | | this.tableData = res.records || [] |
| | | this.total = res.total || 0 |
| | | this.tableData = res.records || []; |
| | | this.total = res.total || 0; |
| | | } |
| | | } catch (error) { |
| | | console.error('加载项目列表失败:', error) |
| | | this.$message.error('加载项目列表失败') |
| | | console.error("加载项目列表失败:", error); |
| | | this.$message.error("加载项目列表失败"); |
| | | } finally { |
| | | this.loading = false |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | |
| | | // 搜索 |
| | | handleSearch () { |
| | | this.currentPage = 1 |
| | | this.loadTableData() |
| | | this.currentPage = 1; |
| | | this.loadTableData(); |
| | | }, |
| | | |
| | | // 清除项目选择 |
| | | clearSearchProjectId () { |
| | | this.searchProjectId = null |
| | | this.handleSearch() |
| | | this.searchProjectId = null; |
| | | this.handleSearch(); |
| | | }, |
| | | |
| | | // 清除项目类型 |
| | | clearProjectType () { |
| | | this.projectType = null |
| | | this.handleSearch() |
| | | this.projectType = null; |
| | | this.handleSearch(); |
| | | }, |
| | | |
| | | // 清除风险等级 |
| | | clearRiskLevel () { |
| | | this.riskLevel = null |
| | | this.handleSearch() |
| | | this.riskLevel = null; |
| | | this.handleSearch(); |
| | | }, |
| | | |
| | | // 清除开始时间 |
| | | clearStartTime () { |
| | | this.startTime = null |
| | | this.handleSearch() |
| | | this.startTime = null; |
| | | this.handleSearch(); |
| | | }, |
| | | |
| | | // 清除结束时间 |
| | | clearEndTime () { |
| | | this.endTime = null |
| | | this.handleSearch() |
| | | this.endTime = null; |
| | | this.handleSearch(); |
| | | }, |
| | | |
| | | // 分页大小改变 |
| | | handleSizeChange (val) { |
| | | this.pageSize = val |
| | | this.currentPage = 1 |
| | | this.loadTableData() |
| | | this.pageSize = val; |
| | | this.currentPage = 1; |
| | | this.loadTableData(); |
| | | }, |
| | | |
| | | // 当前页改变 |
| | | handleCurrentChange (val) { |
| | | this.currentPage = val |
| | | this.loadTableData() |
| | | this.currentPage = val; |
| | | this.loadTableData(); |
| | | }, |
| | | |
| | | // 点击日期选择器 |
| | | handleClick (type) { |
| | | this.$refs[`datetime${type}`].focus() |
| | | this.$refs[`datetime${type}`].focus(); |
| | | }, |
| | | |
| | | // 返回 |
| | | backFun () { |
| | | this.$router.go(-1) |
| | | this.$router.go(-1); |
| | | }, |
| | | |
| | | // 跳转到项目详情 |
| | | toProjectDetail (row) { |
| | | this.$router.push({ |
| | | path: '/projectHome', |
| | | path: "/projectHome", |
| | | query: { |
| | | projectId: row.id, |
| | | projectName: row.name |
| | | } |
| | | }) |
| | | projectName: row.name, |
| | | }, |
| | | }); |
| | | }, |
| | | |
| | | // 跳转到隐患页面 |
| | | toHiddenDanger (row, type) { |
| | | this.$router.push({ |
| | | path: '/hiddenDanger', |
| | | path: "/hiddenDanger", |
| | | query: { |
| | | projectId: row.id, |
| | | activeTab: type, |
| | | projectCategory: ['ongoing', 'fixed'][localStorage.getItem('activeTab') - 1] |
| | | } |
| | | }) |
| | | projectCategory: ["ongoing", "fixed"][ |
| | | localStorage.getItem("activeTab") - 1 |
| | | ], |
| | | }, |
| | | }); |
| | | }, |
| | | |
| | | // 打开报告弹窗 |
| | | async openReportDialog (row) { |
| | | this.currentProjectId = row.id |
| | | this.projectVisible = true |
| | | await this.loadCheckList(row.id) |
| | | this.currentProjectId = row.id; |
| | | this.projectVisible = true; |
| | | await this.loadCheckList(row.id); |
| | | }, |
| | | |
| | | // 加载检查列表 |
| | | async loadCheckList (projectId) { |
| | | this.checkLoading = true |
| | | this.checkLoading = true; |
| | | try { |
| | | const res = await getDeviceDetailCheckList({ |
| | | projectId: projectId |
| | | }) |
| | | projectId: projectId, |
| | | }); |
| | | if (res) { |
| | | this.checkList = res.records || [] |
| | | this.checkList = res.records || []; |
| | | } |
| | | } catch (error) { |
| | | console.error('加载检查列表失败:', error) |
| | | this.$message.error('加载检查列表失败') |
| | | console.error("加载检查列表失败:", error); |
| | | this.$message.error("加载检查列表失败"); |
| | | } finally { |
| | | this.checkLoading = false |
| | | this.checkLoading = false; |
| | | } |
| | | }, |
| | | |
| | |
| | | this.companyInfo = { |
| | | construction: this.parseCompanyInfo(row.constructionCompanyInfo), |
| | | supervisor: this.parseCompanyInfo(row.supervisorCompanyInfo), |
| | | development: this.parseCompanyInfo(row.developmentCompanyInfo) |
| | | } |
| | | this.companyVisible = true |
| | | development: this.parseCompanyInfo(row.developmentCompanyInfo), |
| | | }; |
| | | this.companyVisible = true; |
| | | }, |
| | | |
| | | // 解析单位信息字符串 |
| | | parseCompanyInfo (infoStr) { |
| | | if (!infoStr) return {} |
| | | if (!infoStr) return {}; |
| | | try { |
| | | return JSON.parse(infoStr) |
| | | return JSON.parse(infoStr); |
| | | } catch (error) { |
| | | return {} |
| | | return {}; |
| | | } |
| | | }, |
| | | |
| | | // 检查是否有任何报告 |
| | | hasAnyReport (row) { |
| | | return row.containSystemRes === 1 || row.containDeviceRes === 1 |
| | | return row.containSystemRes === 1 || row.containDeviceRes === 1; |
| | | }, |
| | | |
| | | // 检查报告可用性(当按钮被禁用时点击) |
| | | checkReportAvailability (row) { |
| | | if (!this.hasAnyReport(row)) { |
| | | this.$message.warning('该计划暂无可查看的报告') |
| | | this.$message.warning("该计划暂无可查看的报告"); |
| | | } |
| | | }, |
| | | |
| | | // 打开报告 |
| | | async openReport (type, row) { |
| | | // 根据类型检查是否有对应报告 |
| | | const hasReport = type === 'safe' |
| | | const hasReport = |
| | | type === "safe" |
| | | ? row.containSystemRes === 1 |
| | | : row.containDeviceRes === 1 |
| | | : row.containDeviceRes === 1; |
| | | |
| | | if (!hasReport) { |
| | | this.$message.warning(`暂无${type === 'safe' ? '安全' : '设备'}报告`) |
| | | return |
| | | this.$message.warning(`暂无${type === "safe" ? "安全" : "设备"}报告`); |
| | | return; |
| | | } |
| | | |
| | | this.currentRow = row |
| | | this.reportVisible = true |
| | | this.showPreview = false |
| | | this.reportLoading = true |
| | | this.currentRow = row; |
| | | this.reportVisible = true; |
| | | this.showPreview = false; |
| | | this.reportLoading = true; |
| | | |
| | | try { |
| | | // 从 localStorage 获取模板 ID |
| | | const deviceTemplateId = localStorage.getItem('deviceTemplateId') |
| | | const safetyId = localStorage.getItem('safetyId') |
| | | const safetyName = localStorage.getItem('safetyName') |
| | | const deviceTemplateName = localStorage.getItem('deviceTemplateName') |
| | | const deviceTemplateId = localStorage.getItem("deviceTemplateId"); |
| | | const safetyId = localStorage.getItem("safetyId"); |
| | | const safetyName = localStorage.getItem("safetyName"); |
| | | const deviceTemplateName = localStorage.getItem("deviceTemplateName"); |
| | | |
| | | // 检查任务 ID |
| | | const checkTaskId = row.id |
| | | const checkTaskId = row.id; |
| | | if (!checkTaskId) { |
| | | this.$message.error('缺少检查任务ID') |
| | | this.reportLoading = false |
| | | this.reportVisible = false |
| | | return |
| | | this.$message.error("缺少检查任务ID"); |
| | | this.reportLoading = false; |
| | | this.reportVisible = false; |
| | | return; |
| | | } |
| | | |
| | | // 使用当前时间戳作为 uuid |
| | | const uuid = Date.now().toString() |
| | | const uuid = Date.now().toString(); |
| | | |
| | | // 第一步:调用接口生成Word文档(返回Word文档流) |
| | | let wordBlob |
| | | let wordBlob; |
| | | try { |
| | | if (type === 'safe') { |
| | | if (type === "safe") { |
| | | // 安全报告(模糊评价) |
| | | if (!safetyId) { |
| | | this.$message.error('缺少安全报告模板ID') |
| | | this.reportLoading = false |
| | | this.reportVisible = false |
| | | return |
| | | this.$message.error("缺少安全报告模板ID"); |
| | | this.reportLoading = false; |
| | | this.reportVisible = false; |
| | | return; |
| | | } |
| | | const safeCommentType = parseInt( |
| | | localStorage.getItem("commentType") || "1" |
| | | ); |
| | | if (safeCommentType === 1) { |
| | | wordBlob = await getFuzzyReportWord({ |
| | | checkTaskId: checkTaskId, |
| | | templateId: safetyId, |
| | | uuid: safetyName |
| | | }) |
| | | uuid: safetyName, |
| | | }); |
| | | } else { |
| | | wordBlob = await getScoreReportWord({ |
| | | checkTaskId: checkTaskId, |
| | | templateId: safetyId, |
| | | uuid: safetyName, |
| | | }); |
| | | } |
| | | } else { |
| | | // 设备报告(打分评价) |
| | | if (!deviceTemplateId) { |
| | | this.$message.error('缺少设备报告模板ID') |
| | | this.reportLoading = false |
| | | this.reportVisible = false |
| | | return |
| | | this.$message.error("缺少设备报告模板ID"); |
| | | this.reportLoading = false; |
| | | this.reportVisible = false; |
| | | return; |
| | | } |
| | | const safeCommentType = parseInt( |
| | | localStorage.getItem("commentType") || "1" |
| | | ); |
| | | if (safeCommentType === 1) { |
| | | wordBlob = await getFuzzyReportWord({ |
| | | checkTaskId: checkTaskId, |
| | | templateId: deviceTemplateId, |
| | | uuid: deviceTemplateName, |
| | | }); |
| | | } else { |
| | | wordBlob = await getScoreReportWord({ |
| | | checkTaskId: checkTaskId, |
| | | templateId: deviceTemplateId, |
| | | uuid: deviceTemplateName |
| | | }) |
| | | uuid: deviceTemplateName, |
| | | }); |
| | | } |
| | | } |
| | | } catch (error) { |
| | | // 捕获生成Word文档时的错误 |
| | | console.error('生成Word文档失败:', error) |
| | | this.$message.error(error.message || '生成报告失败') |
| | | this.reportLoading = false |
| | | this.reportVisible = false |
| | | return |
| | | console.error("生成Word文档失败:", error); |
| | | this.$message.error(error.message || "生成报告失败"); |
| | | this.reportLoading = false; |
| | | this.reportVisible = false; |
| | | return; |
| | | } |
| | | |
| | | // 检查 Word 文档是否生成成功 |
| | | |
| | | if (!wordBlob || wordBlob.size === 0) { |
| | | this.$message.error('报告生成失败') |
| | | this.reportLoading = false |
| | | this.reportVisible = false |
| | | return |
| | | this.$message.error("报告生成失败"); |
| | | this.reportLoading = false; |
| | | this.reportVisible = false; |
| | | return; |
| | | } |
| | | |
| | | // 第二步:使用uuid获取PDF链接 |
| | | let pdfUrlResponse |
| | | let pdfUrlResponse; |
| | | try { |
| | | if (type === 'safe') { |
| | | pdfUrlResponse = await getFuzzyReportPdfUrl({ uuid: safetyName }) |
| | | if (type === "safe") { |
| | | pdfUrlResponse = await getFuzzyReportPdfUrl({ uuid: safetyName }); |
| | | } else { |
| | | pdfUrlResponse = await getScoreReportPdfUrl({ uuid: deviceTemplateName }) |
| | | pdfUrlResponse = await getFuzzyReportPdfUrl({ |
| | | uuid: deviceTemplateName, |
| | | }); |
| | | } |
| | | } catch (error) { |
| | | // 捕获获取PDF链接时的错误 |
| | | console.error('获取PDF链接失败:', error) |
| | | this.$message.error(error.message || '获取PDF链接失败') |
| | | this.reportLoading = false |
| | | this.reportVisible = false |
| | | return |
| | | console.error("获取PDF链接失败:", error); |
| | | this.$message.error(error.message || "获取PDF链接失败"); |
| | | this.reportLoading = false; |
| | | this.reportVisible = false; |
| | | return; |
| | | } |
| | | |
| | | // 根据后端返回的数据结构获取PDF链接 |
| | | // 假设后端返回格式为 { data: "http://xxx.pdf" } 或直接返回字符串 |
| | | const pdfUrl = pdfUrlResponse.data || pdfUrlResponse |
| | | const pdfUrl = pdfUrlResponse.data || pdfUrlResponse; |
| | | |
| | | if (!pdfUrl) { |
| | | this.$message.error('获取PDF链接失败') |
| | | this.reportLoading = false |
| | | this.reportVisible = false |
| | | return |
| | | this.$message.error("获取PDF链接失败"); |
| | | this.reportLoading = false; |
| | | this.reportVisible = false; |
| | | return; |
| | | } |
| | | |
| | | // 保存PDF链接用于预览和下载 |
| | | this.pdfUrl = pdfUrl |
| | | this.reportBlobUrl = pdfUrl // 用于下载 |
| | | this.showPreview = true |
| | | this.pdfUrl = pdfUrl; |
| | | this.reportBlobUrl = pdfUrl; // 用于下载 |
| | | this.showPreview = true; |
| | | |
| | | this.$message.success('报告加载成功') |
| | | this.$message.success("报告加载成功"); |
| | | } catch (error) { |
| | | console.error('获取报告失败:', error) |
| | | console.error("获取报告失败:", error); |
| | | // 优先显示错误对象中的 message |
| | | if (error.message) { |
| | | this.$message.error(error.message) |
| | | this.$message.error(error.message); |
| | | } else if (error.response) { |
| | | const status = error.response.status |
| | | const status = error.response.status; |
| | | if (status === 404) { |
| | | this.$message.error('报告不存在') |
| | | this.$message.error("报告不存在"); |
| | | } else if (status === 500) { |
| | | this.$message.error('服务器错误,请稍后重试') |
| | | this.$message.error("服务器错误,请稍后重试"); |
| | | } else { |
| | | this.$message.error(`获取报告失败: ${error.response.statusText || '未知错误'}`) |
| | | this.$message.error( |
| | | `获取报告失败: ${error.response.statusText || "未知错误"}` |
| | | ); |
| | | } |
| | | } else { |
| | | this.$message.error('获取报告失败,请检查网络连接') |
| | | this.$message.error("获取报告失败,请检查网络连接"); |
| | | } |
| | | this.showPreview = false |
| | | this.reportVisible = false |
| | | this.showPreview = false; |
| | | this.reportVisible = false; |
| | | } finally { |
| | | this.reportLoading = false |
| | | this.reportLoading = false; |
| | | } |
| | | }, |
| | | |
| | | // 下载报告 |
| | | downloadReport () { |
| | | if (!this.reportBlobUrl) { |
| | | this.$message.warning('报告未加载') |
| | | return |
| | | this.$message.warning("报告未加载"); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | // 直接打开PDF链接进行下载 |
| | | window.open(this.reportBlobUrl, '_blank') |
| | | this.$message.success('报告下载成功') |
| | | window.open(this.reportBlobUrl, "_blank"); |
| | | this.$message.success("报告下载成功"); |
| | | } catch (error) { |
| | | console.error('下载报告失败:', error) |
| | | this.$message.error('下载报告失败') |
| | | console.error("下载报告失败:", error); |
| | | this.$message.error("下载报告失败"); |
| | | } |
| | | }, |
| | | |
| | | // 关闭报告弹窗 |
| | | closeReportDialog () { |
| | | this.reportVisible = false |
| | | this.showPreview = false |
| | | this.reportVisible = false; |
| | | this.showPreview = false; |
| | | |
| | | // 清空PDF链接(不需要释放URL,因为是服务器链接) |
| | | this.reportBlobUrl = '' |
| | | this.pdfUrl = '' |
| | | this.reportUrl = '' // 保留兼容性 |
| | | this.reportBlobUrl = ""; |
| | | this.pdfUrl = ""; |
| | | this.reportUrl = ""; // 保留兼容性 |
| | | }, |
| | | |
| | | // 格式化项目类型 |
| | | formatProjectType (type) { |
| | | const typeMap = { |
| | | 0: '房建', |
| | | 1: '市政', |
| | | 2: '建筑工程' |
| | | } |
| | | return typeMap[type] || '-' |
| | | 0: "房建", |
| | | 1: "市政", |
| | | 2: "建筑工程", |
| | | }; |
| | | return typeMap[type] || "-"; |
| | | }, |
| | | |
| | | // 格式化风险等级 |
| | | formatRiskLevel (level) { |
| | | const levelMap = { |
| | | 0: '拒绝接受风险', |
| | | 1: '不可接受风险', |
| | | 2: '可接受风险', |
| | | 3: '可容忍风险', |
| | | 4: '可忽略风险' |
| | | } |
| | | return levelMap[level] || '-' |
| | | 0: "拒绝接受风险", |
| | | 1: "不可接受风险", |
| | | 2: "可接受风险", |
| | | 3: "可容忍风险", |
| | | 4: "可忽略风险", |
| | | }; |
| | | return levelMap[level] || "-"; |
| | | }, |
| | | |
| | | // 格式化时间 |
| | | formatTime (time) { |
| | | return time ? moment(time).format('YYYY-MM-DD HH:mm:ss') : '-' |
| | | return time ? moment(time).format("YYYY-MM-DD HH:mm:ss") : "-"; |
| | | }, |
| | | |
| | | // 格式化计划类型 |
| | | formatPlanType (type) { |
| | | const typeMap = { |
| | | 1: '日常检查', |
| | | 2: '专项检查', |
| | | 3: '综合检查' |
| | | } |
| | | return typeMap[type] || '-' |
| | | 1: "日常检查", |
| | | 2: "专项检查", |
| | | 3: "综合检查", |
| | | }; |
| | | return typeMap[type] || "-"; |
| | | }, |
| | | |
| | | // 判断检查情况是否良好(用于控制图标颜色) |
| | | isCheckResultGood (checkResult) { |
| | | // 检查情况只有"已检查"和"未检查"两种状态 |
| | | // 已检查显示绿色,未检查显示红色 |
| | | if (!checkResult) return false |
| | | if (!checkResult) return false; |
| | | |
| | | return checkResult.includes('已检查') |
| | | return checkResult.includes("已检查"); |
| | | }, |
| | | |
| | | // 格式化地址信息 |
| | | formatAddress (addressInfo) { |
| | | if (!addressInfo) return '-' |
| | | if (!addressInfo) return "-"; |
| | | try { |
| | | const addressObj = JSON.parse(addressInfo) |
| | | const addressObj = JSON.parse(addressInfo); |
| | | // 拼接完整地址:省 + 市 + 区 + 详细地址 |
| | | const { province, city, district, detail } = addressObj |
| | | const parts = [] |
| | | if (province) parts.push(province) |
| | | if (city) parts.push(city) |
| | | if (district && district !== '其它区') parts.push(district) |
| | | if (detail) parts.push(detail) |
| | | return parts.join('') || '-' |
| | | const { province, city, district, detail } = addressObj; |
| | | const parts = []; |
| | | if (province) parts.push(province); |
| | | if (city) parts.push(city); |
| | | if (district && district !== "其它区") parts.push(district); |
| | | if (detail) parts.push(detail); |
| | | return parts.join("") || "-"; |
| | | } catch (error) { |
| | | // 如果解析失败,直接返回原始字符串 |
| | | return addressInfo || '-' |
| | | return addressInfo || "-"; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | <style lang="less"> |
| | | .custom-popper { |