smart-bid-web/src/views/enterpriseLibrary/rejectionItem/index.vue

452 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>
<!-- 废标项库页面 -->
<el-card class="rejection-item-container">
<!-- 返回按钮 -->
<div class="back-container">
<el-button type="default" size="small" @click="handleBack" class="back-btn">
返回
</el-button>
</div>
<!-- 数据列表完全依赖TableModel的内置搜索 -->
<div class="table-container">
<TableModel
:formLabel="formLabel"
:showOperation="true"
:showRightTools="false"
ref="rejectionItemTableRef"
:columnsList="columnsList"
:sendParams="{ enterpriseId: enterpriseId }"
:request-api="listRejectionItem"
>
<template slot="tableTitle">
<h3>数据列表</h3>
</template>
<template slot="tableActions">
<el-button
@click="handleAdd"
v-hasPermi="['enterpriseLibrary:rejectionItem:add']"
class="add-btn"
>
<i class="el-icon-plus"></i> 新增废标项
</el-button>
<el-button type="primary" class="import-btn" @click="handleImport">导入</el-button>
<el-button type="primary" class="export-btn" @click="handleExport">导出</el-button>
</template>
<template slot="itemState" slot-scope="{ data }">
<el-switch
v-model="data.itemState"
:active-value="'0'"
:inactive-value="'1'"
@change="handleStateChange(data)"
/>
</template>
<template slot="handle" slot-scope="{ data }">
<el-button
type="text"
v-hasPermi="['enterpriseLibrary:rejectionItem:edit']"
class="action-btn"
style="color: #EAA819;"
@click="handleUpdate(data)"
>
编辑
</el-button>
<el-button
type="text"
v-hasPermi="['enterpriseLibrary:rejectionItem:del']"
class="action-btn"
style="color: #DB3E29;"
@click="handleDelete(data)"
>
删除
</el-button>
</template>
</TableModel>
</div>
<!-- 新增/编辑废标项弹窗 -->
<RejectionItemForm
ref="rejectionItemForm"
v-if="dialogVisible"
:isAdd="isAdd"
:rowData="row"
@handleQuery="handleQuery"
@closeDialog="dialogVisible = false"
:title="dialogTitle"
:width="600"
/>
<!-- 导入弹窗 -->
<el-dialog
title="导入废标项"
:visible.sync="importDialogVisible"
width="500px"
:close-on-click-modal="false"
>
<el-upload
class="upload-excel"
ref="upload"
action
:http-request="handleFileUpload"
:on-success="onUploadSuccess"
:on-error="onUploadError"
:before-upload="beforeUpload"
:show-file-list="true"
accept=".xlsx, .xls"
:limit="1"
:file-list="fileList"
>
<el-button size="small" type="primary">选择Excel文件</el-button>
<div slot="tip" class="el-upload__tip">
仅支持.xlsx、.xls格式文件<el-button type="text" @click="downloadTemplate">下载导入模板</el-button>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button @click="importDialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitImport">确认导入</el-button>
</div>
</el-dialog>
</el-card>
</template>
<script>
import TableModel from '@/components/TableModel2'
import { columnsList, formLabel } from './config'
import RejectionItemForm from './components/RejectionItemForm.vue'
import {
importRejectionItem,
downloadImportTemplate,
listRejectionItem,
delRejectionItem,
updateRejectionItem,
checkItemNameUnique,
exportRejectionItem // 导入导出接口
} from '@/api/enterpriseLibrary/rejectionItem/rejectionItem'
import { encryptWithSM4, decryptWithSM4 } from '@/utils/sm'
export default {
name: 'RejectionItem',
components: {
TableModel,
RejectionItemForm
},
data() {
return {
formLabel,
columnsList,
listRejectionItem, // 列表查询接口
dialogVisible: false,
isAdd: '',
row: {},
dialogTitle: '',
enterpriseId: decryptWithSM4(this.$route.query.enterpriseId) || '0',
importDialogVisible: false, // 导入弹窗开关
fileList: [], // 上传的文件列表
uploadFile: null // 暂存上传的文件对象
}
},
created() {
// 初始化企业ID到TableModel的查询参数中
this.$nextTick(() => {
this.$refs.rejectionItemTableRef.queryParams.enterpriseId = this.enterpriseId
this.$refs.rejectionItemTableRef.getTableList()
})
},
methods: {
// 返回上一页
handleBack() {
const obj = {
path: "/enterpriseKnowledge/index",
query: {
enterpriseId: encryptWithSM4(this.$refs.rejectionItemTableRef.queryParams.enterpriseId || '0'),
}
}
this.$tab.closeOpenPage(obj)
},
// 新增废标项
handleAdd() {
this.dialogTitle = "新增废标项";
this.isAdd = 'add';
this.row = {
enterpriseId: this.$refs.rejectionItemTableRef.queryParams.enterpriseId
}; // 携带企业ID
this.dialogVisible = true;
},
// 修改废标项
handleUpdate(row) {
this.dialogTitle = "修改废标项";
this.isAdd = 'edit';
this.row = { ...row };
this.dialogVisible = true;
},
// 切换状态(启用/未启用)
handleStateChange(row) {
// 保存当前状态(用于更新失败时回滚)
const originalState = row.itemState;
// 调用更新接口
updateRejectionItem({
...row,
itemState: row.itemState
}).then(res => {
if (res.code === 200) {
this.$modal.msgSuccess("状态更新成功");
// 状态更新成功后,调用列表接口刷新数据
this.handleQuery();
} else {
this.$modal.msgError(res.msg);
// 更新失败时回滚开关状态
row.itemState = originalState;
}
}).catch(error => {
this.$modal.msgError("状态更新失败:" + error);
// 接口调用失败时回滚开关状态
row.itemState = originalState;
});
},
// 删除废标项
handleDelete(row) {
this.$modal.confirm(`是否确认删除“${row.itemName}”?`).then(() => {
this.$modal.loading("正在删除,请稍候...");
delRejectionItem({
itemId: row.itemId,
enterpriseId: this.$refs.rejectionItemTableRef.queryParams.enterpriseId
}).then(res => {
this.$modal.closeLoading();
if (res.code === 200) {
this.$modal.msgSuccess("删除成功");
this.handleQuery();
} else {
this.$modal.msgError(res.msg);
}
}).catch(error => {
this.$modal.closeLoading();
this.$modal.msgError(error);
});
});
},
// 查询列表调用TableModel的内置方法
handleQuery() {
this.$refs.rejectionItemTableRef.getTableList();
},
// 导出废标项(核心修改:实现导出逻辑)
handleExport() {
// 1. 获取表格的查询参数包含企业ID和用户输入的筛选条件
const queryParams = {
...this.$refs.rejectionItemTableRef.queryParams,
enterpriseId: this.enterpriseId // 确保携带企业ID
};
// 2. 显示加载中提示
this.$modal.loading("正在导出数据,请稍候...");
// 3. 调用导出接口
exportRejectionItem(queryParams)
.then(blob => {
this.$modal.closeLoading();
// 4. 处理文件流,生成下载链接
const url = window.URL.createObjectURL(new Blob([blob]));
const a = document.createElement('a');
a.href = url;
// 文件名格式废标项数据_时间戳.xlsx
a.download = `废标项数据_${new Date().getTime()}.xlsx`;
document.body.appendChild(a);
a.click();
// 5. 清理资源
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
// 6. 提示导出成功
this.$modal.msgSuccess("导出成功");
})
.catch(error => {
this.$modal.closeLoading();
// 错误处理
this.$modal.msgError(`导出失败:${error.message || error}`);
});
},
// 打开导入弹窗
handleImport() {
this.importDialogVisible = true;
this.fileList = []; // 清空文件列表
this.uploadFile = null;
},
// 上传前校验文件格式和大小
beforeUpload(file) {
const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|| file.type === 'application/vnd.ms-excel';
const isLt2M = file.size / 1024 / 1024 < 2; // 限制2MB以内
if (!isExcel) {
this.$message.error('只能上传Excel文件');
return false;
}
if (!isLt2M) {
this.$message.error('文件大小不能超过2MB');
return false;
}
// 暂存文件对象,用于后续手动提交
this.uploadFile = file;
return false; // 阻止自动上传,等待用户点击"确认导入"
},
// 自定义文件上传(实际调用后端导入接口)
handleFileUpload(options) {
const formData = new FormData();
// 必传企业ID确保数据归属
formData.append('enterpriseId', this.enterpriseId);
// 必传Excel文件
formData.append('file', options.file);
// 调用后端导入接口
importRejectionItem(formData)
.then(res => {
options.onSuccess(res); // 触发上传成功回调
})
.catch(err => {
options.onError(err); // 触发上传失败回调
});
},
// 点击"确认导入"按钮
submitImport() {
if (!this.uploadFile) {
this.$message.warning('请选择要导入的Excel文件');
return;
}
// 手动触发上传
this.$refs.upload.submit();
},
// 上传成功回调
onUploadSuccess(res) {
if (res.code === 200) {
this.$message.success(`导入成功!共${res.successCount}条,失败${res.failCount}条`);
// 关闭弹窗并刷新列表
this.importDialogVisible = false;
this.handleQuery(); // 刷新数据列表
} else {
this.$message.error(`导入失败:${res.msg || '服务器异常'}`);
// 若有失败数据,可展示失败原因
if (res.failData && res.failData.length > 0) {
console.log('导入失败详情:', res.failData);
// 可弹窗展示失败数据明细
}
}
},
// 上传失败回调
onUploadError(err) {
this.$message.error(`导入异常:${err.message || '网络错误'}`);
},
// 下载导入模板
downloadTemplate() {
downloadImportTemplate(this.enterpriseId)
.then(blob => {
// 处理模板文件流,触发下载
const url = window.URL.createObjectURL(new Blob([blob]));
const a = document.createElement('a');
a.href = url;
a.download = `废标项导入模板.xlsx`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
})
.catch(err => {
this.$message.error(`模板下载失败:${err.message}`);
});
}
}
}
</script>
<style scoped lang="scss">
/* 原有样式不变 */
.rejection-item-container {
height: calc(100vh - 84px);
overflow: hidden;
//background: linear-gradient(180deg, #F1F6FF 20%, #E5EFFF 100%);
}
.back-container {
display: flex;
justify-content: flex-end;
align-items: center;
margin-bottom: 20px;
padding: 0 20px;
.back-btn {
width: 98px;
height: 36px;
background: #FFFFFF;
box-shadow: 0px 4px 8px 0px rgba(76, 76, 76, 0.2);
border-radius: 4px;
border: none;
color: #666;
font-size: 14px;
transition: all 0.3s ease;
&:hover {
background: #f5f5f5;
color: #409EFF;
box-shadow: 0px 6px 12px 0px rgba(76, 76, 76, 0.3);
}
}
}
.add-btn {
width: 121px;
height: 36px;
background: #1F72EA;
box-shadow: 0px 4px 8px 0px rgba(51, 135, 255, 0.5);
border-radius: 4px;
border: none;
color: #fff;
font-size: 14px;
transition: all 0.3s;
margin-right: 10px;
&:hover {
background: #4A8BFF;
box-shadow: 0px 6px 12px 0px rgba(51, 135, 255, 0.6);
}
}
.import-btn, .export-btn {
width: 98px;
height: 36px;
background: #1F72EA;
box-shadow: 0px 4px 8px 0px rgba(51, 135, 255, 0.5);
border-radius: 4px;
border: none;
color: #fff;
font-size: 14px;
transition: all 0.3s;
margin-right: 10px;
&:hover {
background: #4A8BFF;
box-shadow: 0px 6px 12px 0px rgba(51, 135, 255, 0.6);
}
}
.action-btn {
margin-right: 8px;
&:last-child {
margin-right: 0;
}
}
.upload-excel {
margin: 20px 0;
}
</style>