601 lines
17 KiB
Vue
601 lines
17 KiB
Vue
<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="companyName">
|
||
<el-input
|
||
v-model="queryParams.companyName"
|
||
placeholder="请输入单位名称"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="状态" prop="status">
|
||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
|
||
<el-option label="启用" :value="true"></el-option>
|
||
<el-option label="禁用" :value="false"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<!-- 工具栏 -->
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="primary"
|
||
icon="el-icon-plus"
|
||
size="mini"
|
||
@click="handleAdd"
|
||
>新增
|
||
</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="danger"
|
||
icon="el-icon-delete"
|
||
size="mini"
|
||
:disabled="multiple"
|
||
@click="handleDelete"
|
||
>删除
|
||
</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 数据表格 -->
|
||
<el-table
|
||
v-loading="loading"
|
||
:data="chargeCompanyList"
|
||
@selection-change="handleSelectionChange"
|
||
style="width: 100%"
|
||
>
|
||
<el-table-column type="selection" width="55" align="center"></el-table-column>
|
||
<el-table-column label="单位名称" prop="companyName" min-width="180"></el-table-column>
|
||
<el-table-column label="联系人" prop="contactPerson" min-width="120"></el-table-column>
|
||
<el-table-column label="联系电话" prop="contactPhone" min-width="150"></el-table-column>
|
||
<el-table-column label="单位地址" prop="address" min-width="200"></el-table-column>
|
||
<el-table-column label="状态" prop="status" min-width="120">
|
||
<template slot-scope="scope">
|
||
<el-switch
|
||
v-model="scope.row.status"
|
||
active-text="启用"
|
||
inactive-text="禁用"
|
||
@change="handleStatusChange(scope.row)"
|
||
:disabled="!checkPermi(['chargeCompany:status:edit']),"
|
||
></el-switch>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="备注" prop="remark" min-width="180"></el-table-column>
|
||
<!-- 查看资料列 -->
|
||
<el-table-column label="查看资料" min-width="100" align="center">
|
||
<template slot-scope="scope">
|
||
<el-button
|
||
v-if="scope.row.file"
|
||
type="text"
|
||
icon="el-icon-document"
|
||
size="mini"
|
||
@click="handleViewFiles(scope.row.file)"
|
||
>查看资料</el-button>
|
||
<span v-else>无资料</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" min-width="120" fixed="right">
|
||
<template slot-scope="scope">
|
||
<el-button
|
||
type="text"
|
||
icon="el-icon-edit"
|
||
size="mini"
|
||
@click="handleUpdate(scope.row)"
|
||
>编辑</el-button>
|
||
<el-button
|
||
type="text"
|
||
icon="el-icon-delete"
|
||
size="mini"
|
||
@click="handleDelete(scope.row)"
|
||
>删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<!-- 分页组件 -->
|
||
<pagination
|
||
v-show="total > 0"
|
||
:total="total"
|
||
:page.sync="queryParams.pageNo"
|
||
:limit.sync="queryParams.pageSize"
|
||
@pagination="getList"
|
||
/>
|
||
|
||
<!-- 添加或修改挂账单位对话框 -->
|
||
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
|
||
<ChargeCompanyForm
|
||
ref="chargeCompanyForm"
|
||
v-model="formData"
|
||
:systemCode="queryParams.systemCode || systemCode || ''"
|
||
/>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||
<el-button @click="cancel">取 消</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<!-- 文件预览对话框 -->
|
||
<el-dialog :title="'文件预览(' + currentFileName + ')'" :visible.sync="fileDialogVisible" width="70%" append-to-body>
|
||
<!-- 全屏按钮 -->
|
||
<el-button
|
||
class="fullscreen-btn"
|
||
icon="el-icon-full-screen"
|
||
size="mini"
|
||
@click="toggleFullScreen"
|
||
style="position: absolute; top: 10px; right: 100px; z-index: 10;"
|
||
>
|
||
全屏
|
||
</el-button>
|
||
<div class="preview-container" ref="previewContainer">
|
||
<!-- 左侧预览区域 -->
|
||
<div class="preview-area">
|
||
<!-- 音频预览 -->
|
||
<audio v-if="isAudioType" class="preview-iframe" controls>
|
||
<source :src="currentFileUrl"/>
|
||
</audio>
|
||
<!-- 图片预览 -->
|
||
<img
|
||
v-if="isImageType"
|
||
:src="currentFileUrl"
|
||
class="preview-iframe"
|
||
style="max-width: 100%; max-height: 80vh; object-fit: contain;"
|
||
>
|
||
<!-- Office文档预览 -->
|
||
<iframe
|
||
v-if="!isAudioType && !isImageType && !isPdfType && !isTxtType"
|
||
:src="officePreviewUrl"
|
||
frameborder="0"
|
||
class="preview-iframe"
|
||
>
|
||
</iframe>
|
||
<!-- PDF和TXT预览 -->
|
||
<iframe
|
||
v-if="isPdfType || isTxtType"
|
||
:src="currentFileUrl"
|
||
frameborder="0"
|
||
class="preview-iframe"
|
||
>
|
||
</iframe>
|
||
</div>
|
||
|
||
<!-- 右侧文件列表 -->
|
||
<div class="file-list">
|
||
<el-table
|
||
:data="currentFileList"
|
||
height="100%"
|
||
@row-click="handleFileClick"
|
||
:row-class-name="getRowClassName">
|
||
<el-table-column
|
||
label="文件列表"
|
||
min-width="180">
|
||
<template #default="{ row }">
|
||
<div class="file-item">
|
||
<i :class="isImageFile(row) ? 'el-icon-picture' : 'el-icon-document'" class="file-icon"></i>
|
||
{{ getFileName(row) }}
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { getChargeCompanyList, getChargeCompany, addChargeCompany, updateChargeCompany, deleteChargeCompany ,reviewChargeCompany} from './api/chargeCompanyApi'
|
||
import Pagination from '@/components/Pagination'
|
||
import { getLastPathSegment } from '@/utils/ruoyi'
|
||
import ChargeCompanyForm from './form/ChargeCompanyForm'
|
||
|
||
export default {
|
||
name: 'ChargeCompany',
|
||
components: {
|
||
Pagination,
|
||
ChargeCompanyForm
|
||
},
|
||
props: {
|
||
// 接收systemCode参数,默认为null,将在created钩子中初始化
|
||
systemCode: {
|
||
type: String,
|
||
default: null
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
// 遮罩层
|
||
loading: true,
|
||
// 选中数组
|
||
ids: [],
|
||
// 非单个禁用
|
||
single: true,
|
||
// 非多个禁用
|
||
multiple: true,
|
||
// 显示搜索条件
|
||
showSearch: true,
|
||
// 总条数
|
||
total: 0,
|
||
// 挂账单位表格数据
|
||
chargeCompanyList: [],
|
||
// 弹出层标题
|
||
title: '',
|
||
// 是否显示弹出层
|
||
open: false,
|
||
// 查询参数
|
||
queryParams: {
|
||
pageNo: 1,
|
||
pageSize: 10,
|
||
companyName: null,
|
||
status: null,
|
||
systemCode: ''
|
||
},
|
||
// 表单数据
|
||
formData: {
|
||
id: null,
|
||
companyName: null,
|
||
contactPerson: null,
|
||
contactPhone: null,
|
||
address: null,
|
||
status: false,
|
||
systemCode: '',
|
||
remark: null,
|
||
file: ''
|
||
},
|
||
// 文件预览相关
|
||
fileDialogVisible: false,
|
||
currentFileList: [],
|
||
currentFileUrl: '',
|
||
currentFileName: '',
|
||
currentFileType: '',
|
||
officePreviewUrl: '',
|
||
// 文件预览地址
|
||
viewFileUrl: 'https://www.nuoyunr.com/minio/',
|
||
previewUrl: process.env.VUE_APP_PREVIEW_URL || process.env.VUE_APP_FILE_API
|
||
}
|
||
},
|
||
created() {
|
||
// 设置systemCode,如果未传入则从路由中获取,并确保是字符串类型
|
||
const currentSystemCode = String(this.systemCode || getLastPathSegment(this.$route.path))
|
||
this.queryParams.systemCode = currentSystemCode
|
||
this.formData.systemCode = currentSystemCode
|
||
this.getList()
|
||
},
|
||
watch: {
|
||
// 监听systemCode变化,确保传入字符串类型
|
||
systemCode: function(newVal) {
|
||
const systemCodeStr = String(newVal || '')
|
||
this.queryParams.systemCode = systemCodeStr
|
||
this.formData.systemCode = systemCodeStr
|
||
this.getList()
|
||
}
|
||
},
|
||
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.toLowerCase().endsWith(ext));
|
||
},
|
||
// 判断是否为PDF类型
|
||
isPdfType() {
|
||
return this.currentFileUrl.toLowerCase().endsWith('.pdf');
|
||
},
|
||
// 判断是否为TXT类型
|
||
isTxtType() {
|
||
return this.currentFileUrl.toLowerCase().endsWith('.txt');
|
||
}
|
||
},
|
||
methods: {
|
||
/** 查询挂账单位列表 */
|
||
getList() {
|
||
this.loading = true
|
||
getChargeCompanyList(this.queryParams).then(response => {
|
||
this.chargeCompanyList = response.data.records
|
||
this.total = response.data.total
|
||
this.loading = false
|
||
})
|
||
},
|
||
/** 搜索按钮操作 */
|
||
handleQuery() {
|
||
this.queryParams.pageNo = 1
|
||
this.getList()
|
||
},
|
||
/** 重置按钮操作 */
|
||
resetQuery() {
|
||
this.resetForm('queryForm')
|
||
this.handleQuery()
|
||
},
|
||
// 多选框选中数据
|
||
handleSelectionChange(selection) {
|
||
this.ids = selection.map(item => item.id)
|
||
this.single = selection.length !== 1
|
||
this.multiple = !selection.length
|
||
},
|
||
/** 新增按钮操作 */
|
||
handleAdd() {
|
||
this.reset()
|
||
// 确保新增时带入systemCode
|
||
this.formData.systemCode = this.queryParams.systemCode
|
||
this.open = true
|
||
this.title = '新增挂账单位'
|
||
},
|
||
/** 修改按钮操作 */
|
||
handleUpdate(row) {
|
||
this.reset()
|
||
const id = row.id || this.ids
|
||
getChargeCompany(id).then(response => {
|
||
this.formData = response.data
|
||
this.open = true
|
||
this.title = '修改挂账单位'
|
||
})
|
||
},
|
||
/** 状态变更 */
|
||
handleStatusChange(row) {
|
||
const statusMsg = row.status ? '启用' : '禁用'
|
||
this.$modal.confirm(`是否确认${statusMsg}该挂账单位?`).then(() => {
|
||
reviewChargeCompany(row).then(() => {
|
||
this.$modal.msgSuccess(`${statusMsg}成功`)
|
||
this.getList()
|
||
}).catch(() => {
|
||
row.status = !row.status // 回滚状态
|
||
this.$modal.msgError(`${statusMsg}失败`)
|
||
})
|
||
}).catch(() => {
|
||
row.status = !row.status // 回滚状态
|
||
})
|
||
},
|
||
/** 提交按钮 */
|
||
submitForm() {
|
||
this.$refs.chargeCompanyForm.validate(valid => {
|
||
if (valid) {
|
||
if (this.formData.id != null) {
|
||
updateChargeCompany(this.formData).then(() => {
|
||
this.$modal.msgSuccess('修改成功')
|
||
this.open = false
|
||
this.getList()
|
||
})
|
||
} else {
|
||
addChargeCompany(this.formData).then(() => {
|
||
this.$modal.msgSuccess('新增成功')
|
||
this.open = false
|
||
this.getList()
|
||
})
|
||
}
|
||
}
|
||
})
|
||
},
|
||
/** 取消按钮 */
|
||
cancel() {
|
||
this.open = false
|
||
this.reset()
|
||
},
|
||
/** 重置表单 */
|
||
reset() {
|
||
this.formData = {
|
||
id: null,
|
||
companyName: null,
|
||
contactPerson: null,
|
||
contactPhone: null,
|
||
address: null,
|
||
status: false,
|
||
systemCode: this.queryParams.systemCode,
|
||
remark: null
|
||
}
|
||
if (this.$refs.chargeCompanyForm) {
|
||
this.$refs.chargeCompanyForm.resetFields()
|
||
}
|
||
},
|
||
/** 删除按钮操作 */
|
||
handleDelete(row) {
|
||
const ids = row.id || this.ids
|
||
this.$modal.confirm('是否确认删除所选挂账单位?').then(() => {
|
||
return deleteChargeCompany(ids)
|
||
}).then(() => {
|
||
this.getList()
|
||
this.$modal.msgSuccess('删除成功')
|
||
}).catch(() => {})
|
||
},
|
||
|
||
// 打开附件对话框
|
||
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地址,参考file.vue的实现
|
||
return `${this.viewFileUrl.replace(/\/$/, '')}/${filePath.replace(/^\//, '')}`;
|
||
},
|
||
|
||
// 从路径中提取文件名
|
||
getFileName(filePath) {
|
||
if (!filePath) return '未命名文件';
|
||
return filePath.split('/').pop() || filePath.split('\\').pop() || '未命名文件';
|
||
},
|
||
|
||
// 判断是否为图片文件
|
||
isImageFile(filePath) {
|
||
if (!filePath) return false;
|
||
const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'];
|
||
const extension = filePath.split('.').pop().toLowerCase();
|
||
return imageExtensions.includes(extension);
|
||
},
|
||
|
||
// 预览指定文件
|
||
previewFile(filePath) {
|
||
// 获取完整的文件URL,处理图片访问地址前缀
|
||
this.currentFileUrl = this.getFullFileUrl(filePath);
|
||
console.log(this.currentFileUrl);
|
||
|
||
this.currentFileName = this.getFileName(filePath);
|
||
this.currentFileType = this.getFileExtension(filePath);
|
||
|
||
// 生成Office文档预览URL,参考file.vue的实现
|
||
this.officePreviewUrl = 'https://view.officeapps.live.com/op/view.aspx?src=' +
|
||
encodeURIComponent(this.currentFileUrl);
|
||
console.log(this.officePreviewUrl);
|
||
},
|
||
|
||
// 获取文件扩展名
|
||
getFileExtension(filePath) {
|
||
if (!filePath) return '';
|
||
return filePath.split('.').pop().toLowerCase();
|
||
},
|
||
|
||
// 处理文件列表项点击
|
||
handleFileClick(row) {
|
||
this.previewFile(row);
|
||
},
|
||
|
||
// 获取行样式,高亮当前选中的文件
|
||
getRowClassName({row}) {
|
||
return row === this.currentFileList.find(item => this.getFileName(item) === this.currentFileName) ? 'highlight-row' : '';
|
||
},
|
||
|
||
// 全屏切换
|
||
async toggleFullScreen() {
|
||
const container = this.$refs.previewContainer;
|
||
if (!container) return;
|
||
|
||
try {
|
||
if (!document.fullscreenElement) {
|
||
await container.requestFullscreen(); // 进入全屏
|
||
} else {
|
||
await document.exitFullscreen(); // 退出全屏
|
||
}
|
||
} catch (err) {
|
||
console.error(`全屏切换失败: ${err.message}`);
|
||
this.$message.warning('全屏切换失败');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.app-container {
|
||
padding: 20px;
|
||
}
|
||
|
||
.mb8 {
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
/* 预览容器样式 */
|
||
.preview-container {
|
||
width: 100%;
|
||
height: 70vh;
|
||
display: flex;
|
||
background-color: #f5f5f5;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 预览区域样式 */
|
||
.preview-area {
|
||
flex: 1;
|
||
height: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
overflow: auto;
|
||
}
|
||
|
||
/* 文件列表样式 */
|
||
.file-list {
|
||
width: 250px;
|
||
height: 100%;
|
||
background-color: #fff;
|
||
border-left: 1px solid #e0e0e0;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.preview-iframe {
|
||
width: 100%;
|
||
height: 100%;
|
||
max-height: 70vh;
|
||
}
|
||
|
||
/* 文件列表项样式 */
|
||
.file-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 10px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.file-icon {
|
||
margin-right: 8px;
|
||
font-size: 18px;
|
||
}
|
||
|
||
/* 高亮行样式 */
|
||
.highlight-row {
|
||
background-color: #e6f7ff !important;
|
||
}
|
||
|
||
/* 表格行悬停样式 */
|
||
:deep(.el-table__row:hover) {
|
||
background-color: #f5f7fa;
|
||
}
|
||
|
||
/* 全屏按钮样式 */
|
||
.fullscreen-btn {
|
||
position: absolute;
|
||
top: 10px;
|
||
right: 100px;
|
||
z-index: 10;
|
||
}
|
||
|
||
/* 修复预览对话框中的样式问题 */
|
||
:deep(.el-dialog__body) {
|
||
padding: 30px 20px 20px;
|
||
position: relative;
|
||
height: 80vh;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 确保表格高度自适应 */
|
||
:deep(.el-table) {
|
||
height: 100% !important;
|
||
}
|
||
|
||
:deep(.el-table__body-wrapper) {
|
||
overflow-y: auto;
|
||
}
|
||
|
||
/* 响应式调整 */
|
||
@media (max-width: 768px) {
|
||
.file-list {
|
||
width: 200px;
|
||
}
|
||
}
|
||
</style> |