lanan-system-vue/src/views/base/workReport/index.vue
2025-08-08 15:44:08 +08:00

427 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="汇报主题" prop="reportTopic">
<el-input v-model="queryParams.reportTopic" placeholder="请输入汇报主题" clearable
@keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="汇报时间" prop="reportTime">
<el-date-picker v-model="queryParams.reportTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"/>
</el-form-item>
<el-form-item label="汇报人" prop="userId">
<el-input v-model="queryParams.userName" placeholder="请输入汇报人" clearable
@keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 操作工具栏 -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)">新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
:loading="exportLoading">导出
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="汇报主题" align="center" prop="reportTopic"/>
<el-table-column label="汇报时间" align="center" prop="reportTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.reportTime) }}</span>
</template>
</el-table-column>
<el-table-column label="汇报内容" align="center" prop="reportContent" show-overflow-tooltip/>
<el-table-column label="汇报人" align="center" prop="userName"/>
<el-table-column label="附件" align="center" width="100">
<template v-slot="scope">
<el-button
v-if="scope.row.filePath"
size="mini"
type="text"
@click="handleViewFiles(scope.row.filePath)"
>
查看附件
</el-button>
<span v-else>无附件</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="workReportView(scope.row.id)">查看<span style="font-weight: bold;font-size: 16px">|</span>打印
</el-button>
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.id)">修改
</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog :title="'文件预览(' + currentFileName + ''" :visible.sync="fileDialogVisible" width="70%"
append-to-body>
<div class="preview-container">
<!-- 左侧预览区域 -->
<!-- 音频文件 -->
<audio v-if="isAudioType" class="preview-iframe" controls>
<source :src="currentFileUrl"/>
</audio>
<!-- Office文档/文本/PDF -->
<iframe
v-else-if="!isImageType && currentFileType !== 'txt' && !isAudioType && currentFileType !== 'pdf'"
:src="officePreviewUrl"
frameborder="0"
class="preview-iframe"
></iframe>
<!-- 图片预览 -->
<image-preview
v-else-if="isImageType"
class="preview-iframe"
:src="currentFileUrl"
></image-preview>
<!-- PDF/文本 -->
<iframe
v-else-if="currentFileType === 'txt' || currentFileType === 'pdf'"
:src="currentFileUrl"
frameborder="0"
class="preview-iframe"
></iframe>
<!-- 右侧文件列表 -->
<div class="file-list" v-if="currentFileList.length > 1">
<el-table
:data="currentFileList"
height="100%"
@row-click="handleFileClick"
:row-class-name="getRowClassName">
<el-table-column
prop="fileName"
label="文件列表"
min-width="180">
<template #default="{ row }">
<div class="file-item">
<i :class="getFileIcon(row)"></i>
{{ getFileName(row) }}
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</el-dialog>
<!-- 打印 -->
<el-dialog :visible.sync="showView" width="50%" center>
<div v-html="htmText" id="printMe"></div>
<el-button type="primary" style="margin-left: 90%;margin-top:20px " v-print="'#printMe'" size="small">打印
</el-button>
</el-dialog>
<!-- 分页组件 -->
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getList"/>
<!-- 对话框(添加 / 修改) -->
<ReportForm ref="formRef" :servicePackageId="queryParams.servicePackageId" :dictType="reportToDictType"
@success="getList"/>
</div>
</template>
<script>
import * as ReportApi from '@/views/drivingSchool/workReport/api/index';
import ReportForm from './ReportForm.vue';
import print from 'vue-print-nb'
import {getLastPathSegment} from "@/utils/ruoyi";
export default {
name: "Report",
directives: {
print
},
components: {
ReportForm,
},
data() {
return {
// 遮罩层
loading: true,
showView: false,
// 导出遮罩层
exportLoading: false,
// 显示搜索条件
showSearch: true,
htmText: '',
// 总条数
total: 0,
// 工作汇报列表
list: [],
// 是否展开,默认全部展开
isExpandAll: true,
// 重新渲染表格状态
refreshTable: true,
// 选中行
currentRow: {},
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 10,
reportTopic: null,
reportTime: [],
createTime: [],
userId: null,
userName: null,
servicePackageId: this.$route.query.servicePackageId,
dictType: this.$route.query.dictType,
},
// 汇报对象的dictDtype
reportToDictType: '',
fileDialogVisible: false,
currentFileList: [],
activeFileTab: 0,
baseUrl: process.env.VUE_APP_BASE_API,
currentFileUrl: '',
currentFileName: '',
currentFileType: '',
officePreviewUrl: '',
};
},
computed: {
isImageType() {
return /\.(jpg|jpeg|png|gif|webp|bmp)$/i.test(this.currentFileUrl);
},
isAudioType() {
const audioExtensions = ['mp3', 'wav', 'ogg', 'aac', 'm4a', 'flac'];
return audioExtensions.some(ext => this.currentFileUrl.endsWith(ext));
}
},
created() {
const servicePackageId = getLastPathSegment(this.$route.path); // 默认为最后一段
console.log('服务套餐', servicePackageId)
this.queryParams.servicePackageId = servicePackageId;
switch (servicePackageId) {
case 'jiance':
this.queryParams.dictType = 'ins_high_rise';
this.reportToDictType = 'ins_report_role';
break;
case 'jiaxiao':
this.queryParams.dictType = 'drive_school_high_rise';
this.reportToDictType = 'drive_school_report_role';
break;
case 'weixiu':
this.queryParams.dictType = 'repair_high_rise';
this.reportToDictType = 'repair_report_role';
break;
case 'jiuyuan':
this.queryParams.dictType = 'recue_high_rise';
this.reportToDictType = 'rescue_report_role';
break;
}
console.log('服务套餐', this.reportToDictType)
this.getList();
},
methods: {
/** 查询列表 */
async getList() {
try {
this.loading = true;
const res = await ReportApi.getReportPage(this.queryParams);
this.list = res.data.records;
this.total = res.data.total;
} finally {
this.loading = false;
}
},
/** 搜索按钮操作 */
handleQuery() {
const reportTime = this.queryParams.reportTime;
this.queryParams = {
pageNo: 1,
pageSize: 10,
reportTopic: null,
reportTime: reportTime,
createTime: [],
userId: null,
userName: null,
servicePackageId: this.$route.query.servicePackageId,
dictType: this.$route.query.dictType,
}
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 添加/修改操作 */
openForm(id) {
this.$refs["formRef"].open(id);
},
workReportView(id) {
this.showView = true
ReportApi.workReportView(id).then(res => {
this.htmText = res.data
})
},
/** 删除按钮操作 */
async handleDelete(row) {
const id = row.id;
await this.$modal.confirm('是否确认删除工作汇报编号为"' + id + '"的数据项?')
try {
await ReportApi.deleteReport(id);
await this.getList();
this.$modal.msgSuccess("删除成功");
} catch {
}
},
/** 导出按钮操作 */
async handleExport() {
await this.$modal.confirm('是否确认导出所有工作汇报数据项?');
try {
this.exportLoading = true;
const data = await ReportApi.exportReportExcel(this.queryParams);
this.$download.excel(data, '工作汇报.xls');
} catch {
} finally {
this.exportLoading = false;
}
},
// 打开附件对话框
handleViewFiles(filePath) {
if (!filePath) {
this.$message.warning('没有附件');
return;
}
// 初始化数据
this.currentFileList = filePath.split(',').filter(item => item.trim());
this.fileDialogVisible = true;
// 默认显示第一个文件
if (this.currentFileList.length > 0) {
this.previewFile(this.currentFileList[0]);
}
},
// 获取完整文件URL拼接基础API地址
getFullFileUrl(filePath) {
if (!filePath) return '';
// 已经是完整URL或base64数据
if (filePath.startsWith('http') || filePath.startsWith('data:')) {
return filePath;
}
// 拼接基础API地址来自环境变量
const baseUrl = 'http://122.51.230.86:9000/' || '';
return `${baseUrl.replace(/\/$/, '')}/${filePath.replace(/^\//, '')}`;
},
// 从路径中提取文件名
getFileName(filePath) {
return filePath.split('/').pop() || '未命名文件';
},
// 判断是否为图片
isImage(filePath) {
return /\.(jpg|jpeg|png|gif|webp|bmp)$/i.test(filePath);
},
// 预览指定文件
previewFile(filePath) {
this.currentFileUrl = this.getFullFileUrl(filePath);
this.currentFileName = this.getFileName(filePath);
this.currentFileType = this.getFileExtension(filePath);
// 生成Office文档预览URL
this.officePreviewUrl = 'https://view.officeapps.live.com/op/view.aspx?src=' +
encodeURIComponent(this.currentFileUrl);
},
// 获取文件扩展名
getFileExtension(filePath) {
return filePath.split('.').pop().toLowerCase();
},
// 获取文件图标
getFileIcon(filePath) {
return this.isImage(filePath) ? 'el-icon-picture' : 'el-icon-document';
},
// 点击文件列表中的文件
handleFileClick(row) {
this.previewFile(row);
},
// 表格行类名
getRowClassName({row}) {
return row === this.currentFileUrl ? 'highlight-row' : '';
},
}
};
</script>
<style scoped>
.image-preview {
display: flex;
justify-content: center;
margin: 20px 0;
}
.image-preview img {
max-height: 500px;
max-width: 100%;
border: 1px solid #eee;
}
.preview-container {
display: flex;
height: 70vh;
}
.preview-iframe {
flex: 1;
width: 100%;
height: 100%;
border: none;
}
.file-list {
flex: 0 0 250px;
border-left: 1px solid #ebeef5;
padding-left: 10px;
margin-left: 10px;
}
.file-item {
cursor: pointer;
padding: 8px;
transition: background 0.3s;
}
.file-item:hover {
background: #f5f7fa;
}
.highlight-row {
background-color: #f0f7ff;
}
</style>