lanan-system-vue/src/views/base/chargeCompany/index.vue

601 lines
17 KiB
Vue
Raw Normal View History

2025-10-21 18:37:28 +08:00
<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)"
2025-10-22 14:10:47 +08:00
:disabled="!checkPermi(['chargeCompany:status:edit']),"
2025-10-21 18:37:28 +08:00
></el-switch>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" min-width="180"></el-table-column>
2025-10-22 14:10:47 +08:00
<!-- 查看资料列 -->
<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>
2025-10-21 18:37:28 +08:00
<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>
2025-10-22 14:10:47 +08:00
<!-- 文件预览对话框 -->
<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>
2025-10-21 18:37:28 +08:00
</div>
</template>
<script>
2025-10-23 14:58:19 +08:00
import { getChargeCompanyList, getChargeCompany, addChargeCompany, updateChargeCompany, deleteChargeCompany ,reviewChargeCompany} from './api/chargeCompanyApi'
2025-10-22 14:10:47 +08:00
import Pagination from '@/components/Pagination'
import { getLastPathSegment } from '@/utils/ruoyi'
import ChargeCompanyForm from './form/ChargeCompanyForm'
2025-10-21 18:37:28 +08:00
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: '',
2025-10-22 14:10:47 +08:00
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
2025-10-21 18:37:28 +08:00
}
},
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()
}
},
2025-10-22 14:10:47 +08:00
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');
}
},
2025-10-21 18:37:28 +08:00
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(() => {
2025-10-23 14:58:19 +08:00
reviewChargeCompany(row).then(() => {
2025-10-21 18:37:28 +08:00
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(() => {})
2025-10-22 14:10:47 +08:00
},
// 打开附件对话框
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('全屏切换失败');
}
2025-10-21 18:37:28 +08:00
}
}
}
</script>
<style scoped>
.app-container {
padding: 20px;
}
.mb8 {
margin-bottom: 8px;
}
2025-10-22 14:10:47 +08:00
/* 预览容器样式 */
.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;
}
}
2025-10-21 18:37:28 +08:00
</style>