bonus-ui/src/views/business/businessHandlingRecord/index.vue

683 lines
23 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 v-show="showSearch" :model="queryParams" ref="queryForm" size="small" inline>
<el-form-item label="申请日期" prop="startTime">
<el-date-picker
v-model="queryParams.startTime"
value-format="yyyy-MM-dd"
type="date"
placeholder="开始日期"
@change="() => queryParams.endTime = ''"
style="width: 130px"
/>
</el-form-item>
<el-form-item>-</el-form-item>
<el-form-item prop="endTime">
<el-date-picker
v-model="queryParams.endTime"
value-format="yyyy-MM-dd"
type="date"
placeholder="结束日期"
:picker-options="{ disabledDate: (t) => t.getTime() < new Date(queryParams.startTime).getTime() - 86400000}"
style="width: 130px"
/>
</el-form-item>
<el-form-item label="关键字" prop="keyWord">
<el-input
v-model="queryParams.keyWord"
placeholder="请输入关键字"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="审核状态" prop="taskStatus">
<el-select v-model="queryParams.taskStatus" placeholder="请选择审核状态" clearable>
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</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="handleReset">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5" v-hasPermi="['business:info:add']">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">领料申请</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出数据</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table :data="tableList" fit highlight-current-row style="width: 100%" :max-height="650" v-loading="loading">
<!-- 多选 -->
<el-table-column type="selection" width="55" align="center" @selection-change="selectionChange" />
<el-table-column
type="index"
width="55"
label="序号"
align="center"
:index="indexContinuation(queryParams.pageNum, queryParams.pageSize)"
/>
<el-table-column
v-for="(column, index) in tableColumns"
:show-overflow-tooltip="column.showTooltip"
:key="column.prop"
:label="column.label"
:prop="column.prop"
:width="column.width"
align="center"
>
<!-- 插槽 -->
<template v-slot="{ row }" v-if="column.prop == 'taskStatus'">
<!-- <dict-tag :options="dict.type.lease_apply_task_status" :value="scope.row.taskStatus" /> -->
<el-tag v-if="row.taskStatus == 0">{{ row.taskStatusName }}</el-tag>
<el-tag v-else-if="row.taskStatus == 3" type="success">{{ row.taskStatusName }}</el-tag>
<el-tag v-else-if="row.taskStatus == 5" type="info">{{ row.taskStatusName }}</el-tag>
<el-tag v-else-if="row.taskStatus == 6" type="warning">{{ row.taskStatusName }}</el-tag>
<el-tag v-else-if="row.taskStatus == 2" type="danger">{{ row.taskStatusName }}</el-tag>
<el-tag v-else-if="row.taskStatus == 1" type="success">{{ row.taskStatusName }}</el-tag>
</template>
</el-table-column>
<!-- 操作 -->
<el-table-column label="操作" align="center" width="180">
<template slot-scope="scope">
<el-button type="text" size="mini" icon="el-icon-search" @click="handleEdit(scope.row, 1)">查看</el-button>
<el-button
v-show="scope.row.taskStatus == '0' || scope.row.taskStatus == '5'"
v-hasPermi="['business:info:edit']"
type="text"
size="mini"
icon="el-icon-edit"
@click="handleEdit(scope.row, 2)"
>
编辑
</el-button>
<el-button
type="text"
size="mini"
icon="el-icon-document"
@click="getDialogContent(scope.row)"
style="color: #e6a23c"
>
业务联系单
</el-button>
<el-button
v-show="scope.row.taskStatus == '0' || scope.row.taskStatus == '5'"
v-hasPermi="['business:info:delete']"
type="text"
size="mini"
icon="el-icon-delete"
style="color: #f56c6c"
@click="handleDelete(scope.row)"
>
删除
</el-button>
<el-button
v-show="scope.row.taskStatus != 5 && scope.row.publishNum == 0"
type="text"
size="mini"
icon="el-icon-refresh"
style="color: #f56c6c"
@click="handleRefresh(scope.row)"
>
撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 弹框 -->
<el-dialog title="业务联系单" :visible.sync="dialogVisible" width="46%">
<div id="print-content" style="padding: 0 30px">
<span>发:</span>
<!-- 标题 -->
<div style="text-align: center; font-size: 16px">
<h3 style="font-size: 25px">{{ dialogForm.impUnitName }}</h3>
<h2 style="font-size: 35px; margin: 0 20%; display: flex; justify-content: space-around; align-items: center">
<span>业</span>
<span>务</span>
<span>联</span>
<span>系</span>
<span>单</span>
</h2>
</div>
<div
style="display: flex; justify-content: space-between; align-items: center; line-height: 1.9; padding: 0 15px"
>
<span style="text-decoration: underline">{{ dialogForm.leaseProject }}</span>
<span>
<span style="text-decoration: underline">{{ dialogForm.code }}</span>
</span>
</div>
<!-- 内容 -->
<div style="border: 3px solid #000; min-height: 800px; line-height: 1.9; position: relative">
<div style="font-weight: 800; border-bottom: 1px solid #888; display: flex">
<div style="width: 50%; padding-left: 10px">主送单位:{{ '技术质量科' }}</div>
<div style="width: 50%; padding-left: 10px; border-left: 1px solid #888">
抄送单位:{{ '物资管理中心' }}
</div>
</div>
<!-- 内容 -->
<div style="padding-left: 10px; min-height: 300px">
<div>联系内容:</div>
<div style="text-indent: 2em">
因在
<span style="font-weight: 800">
{{ dialogForm.leaseProject }}
</span>
进行架线施工需要,现需领用以下工具器,详见附件一:
<!-- dialogForm.maTypeNames -->
<div>{{ dialogForm.maTypeNames }}</div>
</div>
</div>
<!-- 说明 -->
<div style="padding-left: 10px; min-height: 200px">
<div>说明:</div>
<div>领料单位:{{ dialogForm.leaseUnit }}</div>
<!-- <div>项目部材料站站长联系人:{{ '徐青松' }} {{ '15234213324' }}</div> -->
<div>项目部技术联系人:{{ dialogForm.createBy }}{{ dialogForm.phone }}</div>
<div>领取人员:{{ dialogForm.leasePerson }}{{ dialogForm.phone }}</div>
</div>
<div
style="
width: 100%;
display: flex;
border-top: 1px solid #888;
border-bottom: 1px solid #888;
position: absolute;
bottom: 90px;
right: 0;
"
>
<div style="width: 35%; padding-left: 10px">主管:{{ '' }}</div>
<div style="width: 43%; padding-left: 10px; border-left: 1px solid #888">
联系:{{ dialogForm.leasePerson }} {{ dialogForm.phone }}
</div>
<div style="width: 22%; padding-left: 10px; border-left: 1px solid #888">
{{ handleTimeFormat(dialogForm.supplierTime) }}
</div>
</div>
<div
style="
width: 100%;
display: flex;
border-top: 1px solid #888;
border-bottom: 1px solid #888;
position: absolute;
bottom: 0;
right: 0;
"
>
<div style="width: 50%; padding-left: 10px">签复:</div>
<div
style="
width: 50%;
padding-left: 100px;
border-left: 1px solid #888;
display: flex;
justify-content: space-around;
align-items: center;
"
>
<span>年</span>
<span>月</span>
<span>日</span>
</div>
</div>
</div>
<!-- 附件 -->
<div style="margin-top: 100px">
<div style="font-size: 20px; padding-left: 40px; line-height: 1.9">
附件一:{{ dialogForm.leaseProject }}
<span style="margin-left: 20px">{{ dialogForm.code }}</span>
号附件
</div>
<div></div>
</div>
<table border="1" style="width: 100%; border-collapse: collapse">
<thead>
<tr>
<th style="width: 55px; text-align: center">序号</th>
<th
v-for="(column, index) in dialogColumns"
:key="column.prop"
:style="{ width: column.width, textAlign: 'center' }"
>
{{ column.label }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, rowIndex) in dialogList" :key="rowIndex">
<td style="text-align: center">{{ rowIndex + 1 }}</td>
<td v-for="(column, colIndex) in dialogColumns" :key="colIndex" :style="{ textAlign: 'center' }">
{{ row[column.prop] }}
</td>
</tr>
</tbody>
</table>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="print">打 印</el-button>
<el-button type="success" icon="el-icon-download" @click="downloadPDF">下载PDF</el-button>
<el-button @click="dialogVisible = false"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import printJS from 'print-js'
import { getLeaseTaskList, deleteLeaseTask, getLeaseTask, getCodePDF, revokeApi } from '@/api/business/index'
import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
import request from '@/utils/request'
export default {
name: 'Index',
dicts: ['lease_apply_task_status'],
data() {
return {
loading: false,
showSearch: true,
queryParams: {
pageNum: 1,
pageSize: 10,
keyWord: '', // 关键字
taskStatus: '', // 审核状态
timeRange: [], // 日期范围
startTime: '', // 开始日期
endTime: '' // 结束日期
},
// 考勤状态
statusOptions: [
{ label: '待提交', value: '5' },
{ label: '待审核', value: '0' },
{ label: '审核中', value: '6' },
{ label: '已完成', value: '3' },
{ label: '已驳回', value: '2' }
],
total: 0, // 总条数
// 表头
tableColumns: [
{ label: '申请时间', prop: 'createTime', width: '100' },
{ label: '申请人', prop: 'createBy', width: '80' },
{ label: '分公司', prop: 'impUnitName', showTooltip: false },
{ label: '领用单位', prop: 'leaseUnit', width: '180' },
{ label: '领用工程', prop: 'leaseProject', width: '180' },
{ label: '领料物资类型', prop: 'maTypeNames', showTooltip: true },
{ label: '协议号', prop: 'agreementCode' },
{ label: '业务单号', prop: 'code' },
{ label: '领料人', prop: 'leasePerson', width: '80' },
{ label: '领料人电话', prop: 'phone' },
{ label: '状态', prop: 'taskStatus', width: '80' }
],
// 表格数据
tableList: [],
dialogTitle: '', // 弹框标题
dialogVisible: false, // 弹框显示
dialogForm: {
proName: '', // 项目名称
code: '' // 业务单号
},
dialogColumns: [
{ label: '名称', prop: 'maTypeName', width: '150px' },
{ label: '规格', prop: 'typeName', width: '150px' },
{ label: '单位', prop: 'unitName', width: '60px' },
{ label: '数量', prop: 'preNum', width: '60px' },
{ label: '备注', prop: 'remark', width: '' }
],
dialogList: []
}
},
created() {
this.getList()
},
methods: {
// 查询
handleQuery() {
this.getList()
},
// 重置
handleReset() {
this.queryParams.pageNum = 1
this.queryParams.pageSize = 10
this.$refs.queryForm.resetFields()
this.getList()
},
// 获取列表
async getList() {
console.log('列表-查询', this.queryParams)
try {
this.loading = true
const params = {
...this.queryParams,
// startTime: this.queryParams.timeRange[0] || '',
// endTime: this.queryParams.timeRange[1] || ''
}
const res = await getLeaseTaskList(params)
console.log('🚀 ~ 获取列表 ~ res:', res)
this.tableList = res.data.rows
this.total = res.data.total || 0
} catch (error) {
console.log('🚀 ~ 获取列表 ~ error:', error)
this.tableList = []
this.total = 0
} finally {
this.loading = false
}
},
// 多选
selectionChange(val) {
console.log('selectionChange', val)
},
handleAdd() {
console.log('领料申请')
this.$router.push({ path: '/business/businessHandling/index' })
},
// 编辑
handleEdit(row, type) {
console.log('编辑', row)
let params = {}
if (type === 1) {
params = { type: 'detail', id: row.id, taskId: row.taskId }
} else {
params = { type: 'edit', id: row.id }
}
this.$router.push({ path: '/business/businessHandling/index', query: params })
},
// 删除
handleDelete(row) {
console.log('删除', row)
this.$confirm('是否删除该数据?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const res = await deleteLeaseTask(row.id)
console.log('🚀 ~ 删除 ~ res:', res)
this.getList()
this.$message({
type: 'success',
message: '删除成功!'
})
})
},
// 撤回
handleRefresh(row) {
console.log('🚀 ~ 撤回 ~ row:', row)
// 二次确认
this.$confirm('是否确定撤回?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
this.loading = true
const res = await revokeApi({ taskId: row.taskId })
console.log('🚀 ~ 撤回 ~ res:', res)
this.$message({
type: 'success',
message: '撤回成功!'
})
this.getList()
} catch (error) {
console.log('🚀 ~ handleRefresh ~ error:', error)
} finally {
this.loading = false
}
})
},
// 导出数据
/*handleExport() {
try {
let fileName = `数据_${new Date().getTime()}.xLsx`
let url = ''
const params = { ...this.queryParams }
console.log('🚀 ~ 导出 ~ params:', params)
// this.derive(url, params, fileName)
} catch (error) {
console.log('导出数据失败', error)
}
},*/
handleExport() {
const formatTime = date => {
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
const seconds = String(date.getSeconds()).padStart(2, '0')
return `${year}${month}${day}_${hours}${minutes}${seconds}`
}
const currentTime = formatTime(new Date())
this.download(
'/material/leaseTask/exportLeaseRecord',
{ ...this.queryParams },
`领用记录数据_${currentTime}.xlsx`
)
},
// 打印
print() {
const element = document.getElementById('print-content')
// 确保元素存在
if (!element) {
this.$message.error('未找到要打印的元素')
return
}
this.$modal.loading('正在生成单据,请稍候...')
// 使用html2canvas将DOM元素转换为canvas
html2canvas(element, {
scale: 2, // 提高清晰度
useCORS: true, // 允许加载跨域图片
allowTaint: true,
backgroundColor: '#ffffff'
})
.then(canvas => {
// 创建PDF文档
const pdf = new jsPDF('p', 'mm', 'a4')
// 获取canvas的宽度和高度
const imgWidth = 210 // A4纸的宽度(mm)
const pageHeight = 297 // A4纸的高度(mm)
const imgHeight = (canvas.height * imgWidth) / canvas.width
// 将canvas转换为图片
const imgData = canvas.toDataURL('image/jpeg', 1.0)
// 添加图片到PDF
pdf.addImage(imgData, 'JPEG', 0, 0, imgWidth, imgHeight)
// 生成PDF文件名
const fileName = `业务联系单_${this.dialogForm.code || '未命名'}_${new Date().getTime()}.pdf`
// 将PDF转换为Blob对象
const pdfBlob = pdf.output('blob')
// 创建FormData对象用于上传
const formData = new FormData()
formData.append('file', pdfBlob, fileName)
formData.append('id', this.dialogForm.leaseProjectId)
// 上传到服务器
this.$modal.closeLoading()
// 调用上传API - 使用request
request
.post('/material/leaseTask/uploadPdf', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(response => {
if (response.code === 200) {
this.$modal.msgSuccess('单据文件已保存到服务器')
// 上传成功后执行打印
printJS({
printable: 'print-content',
type: 'html',
scanStyles: false,
maxWidth: '1400'
})
} else {
this.$modal.msgError('保存单据文件失败')
}
})
.catch(() => {
this.$modal.msgError('上传单据文件时发生错误')
// 即使上传失败也执行打印
printJS({
printable: 'print-content',
type: 'html',
scanStyles: false,
maxWidth: '1400'
})
})
})
.catch(error => {
this.$modal.closeLoading()
this.$modal.msgError('生成单据时发生错误')
console.error('生成单据错误:', error)
})
},
// 下载PDF
async downloadPDF() {
try {
this.$modal.loading('正在生成PDF请稍候...')
// 获取要转换的DOM元素
const element = document.getElementById('print-content')
if (!element) {
this.$modal.closeLoading()
this.$message.error('未找到要导出的内容')
return
}
// 使用html2canvas将DOM元素转换为canvas
const canvas = await html2canvas(element, {
scale: 2, // 提高清晰度
useCORS: true, // 允许加载跨域图片
allowTaint: true,
logging: false, // 关闭日志记录
backgroundColor: '#ffffff'
})
// 创建PDF文档
const pdf = new jsPDF('p', 'mm', 'a4')
// 获取canvas的宽度和高度
const imgWidth = 210 // A4纸的宽度(mm)
const pageHeight = 297 // A4纸的高度(mm)
const imgHeight = (canvas.height * imgWidth) / canvas.width
let heightLeft = imgHeight
let position = 0
// 将canvas转换为图片
const imgData = canvas.toDataURL('image/jpeg', 1.0)
// 如果内容超过一页,需要分页
if (heightLeft > pageHeight) {
// 第一页
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight)
heightLeft -= pageHeight
// 添加后续页面
while (heightLeft > 0) {
position = heightLeft - imgHeight
pdf.addPage()
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight)
heightLeft -= pageHeight
}
} else {
// 单页内容
pdf.addImage(imgData, 'JPEG', 0, 0, imgWidth, imgHeight)
}
// 生成PDF文件名
const fileName = `业务联系单_${this.dialogForm.code || '未命名'}_${new Date().getTime()}.pdf`
// 下载PDF
pdf.save(fileName)
this.$modal.closeLoading()
this.$message.success('PDF下载成功')
} catch (error) {
console.error('生成PDF失败:', error)
this.$modal.closeLoading()
this.$message.error('生成PDF失败请稍后重试')
}
},
// 获取弹框内容
async getDialogContent(row) {
console.log('🚀 ~ getDialogContent ~ row:', row.taskId)
const loading = this.$loading({
lock: true,
text: '加载中...'
})
try {
// 获取业务联系单
const res = await getLeaseTask(row.id)
console.log('🚀 ~ getDialogContent ~ res:', res)
// 获取PDF
const PDFres = await getCodePDF(row.taskId)
console.log('🚀 ~ getDialogContent ~ res:', PDFres)
this.dialogVisible = true
this.dialogForm = {
...res.data.leaseApplyInfo,
pdfUrl: PDFres.data.url
}
this.dialogList = res.data.leaseApplyDetailsList
loading.close()
} catch (error) {
console.log('🚀 ~ 获取弹框内容 ~ error:', error)
loading.close()
}
},
// 处理时间格式 2021-09-01 转换为 2021年09月01日
handleTimeFormat(time) {
if (time) {
return time.replace(/-/g, '年').replace(/-/g, '月') + '日'
}
return ''
}
}
}
</script>
<style lang="scss" scoped></style>