heli-mes/mes-ui/mes-ui-admin-vue3/src/views/heli/storagein/detail.vue
2025-08-04 15:43:45 +08:00

504 lines
15 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="hl-card" style="position: relative">
<template #header>
<span>详情页</span>
</template>
<el-form ref="formRef" :model="formData" label-width="160px" v-loading="formLoading">
<!-- 基础信息 -->
<el-card class="hl-card-info">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">基础信息</span>
</template>
<el-row>
<el-col :span="24">
<el-row>
<el-col :span="6">
<el-row>
<el-col :span="24">
<el-form-item label="入库单号" prop="purchaseNo">
<el-input class="!w-300px" placeholder="系统自动生成" v-model="formData.storageNo" disabled />
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="6">
<el-row>
<el-form-item label="入库日期" prop="ordDate">
<el-date-picker
v-model="formData.ordDate"
type="date"
value-format="x"
placeholder="入库日期"
disabled
/>
</el-form-item>
</el-row>
</el-col>
</el-row>
</el-col>
</el-row>
</el-card>
<!-- 采购单信息 -->
<el-card class="hl-card-info">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">入库单信息</span>
</template>
<el-row>
<el-col>
<el-card class="hl-incard">
<el-form ref="multipleTable" :model="formData.list" v-loading="loading" label-width="0">
<el-table :data="formData.list" class="hl-table" >
<el-table-column prop="projectSubCode" min-width="150" label="子项目编码" align="center"/>
<el-table-column prop="boomName" min-width="150" label="物料名称" align="center"/>
<el-table-column prop="materialCode" min-width="150" label="物料编码" align="center"/>
<el-table-column prop="boomSpec" min-width="100" label="规格型号" align="center"/>
<el-table-column prop="purchaseAmount" min-width="100" label="采购数量" align="center" />
<el-table-column prop="storageAmount" min-width="100" label="入库数量" align="center"/>
<el-table-column prop="supplierName" min-width="150" label="供应商" align="center" />
<el-table-column prop="estimatedPrice" min-width="100" label="预估总价" align="center"/>
</el-table>
</el-form>
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
@pagination="getList" />
</el-card>
</el-col>
</el-row>
</el-card>
</el-form>
<div class="hl-footer text-center">
<el-button @click="cancel" size="large">取 消</el-button>
<el-button @click="isPrint()" type="primary" size="large" :loading="printLoading" v-if="formData.goodsType==1">打印</el-button>
<el-button @click="deleteForm()" type="danger" size="large" >删除</el-button>
</div>
</el-card>
<el-dialog v-model="printDialogVisible" width="80%" title="入库单打印" :close-on-click-modal="false">
<div id="printArea" class="print-content">
<div class="print-header">
<div class="order-info">
<div style="display: flex;">
<span style="width: 210px;">编号:{{ printData.storageNo}}</span>
<span style="margin-left:20px; width: 170px;">入库日期:{{ formatDate(printData.ordDate) }}</span>
<span style="margin-left:20px;width: 250px">供应商:{{ printData.supplierName }}</span>
</div>
</div>
</div>
<table class="print-table">
<colgroup>
<col style="width: 8%;" /> <!-- 序号 -->
<col style="width: 18%;" /> <!-- 零件名称 -->
<col style="width: 10%;" /> <!-- 规格 -->
<col style="width: 8%;" /> <!-- 单位 -->
<col style="width: 10%;" /> <!-- 入库数量 -->
<col style="width: 10%;" /> <!-- 单价 -->
<col style="width: 10%;" /> <!-- 小计 -->
<col style="width: 12%;" /> <!-- 项目名称 -->
<col style="width: 14%;" /> <!-- 备注 - 给更多空间 -->
</colgroup>
<thead>
<tr>
<th>序号</th>
<th>零件名称</th>
<th>规格</th>
<th>单位</th>
<th>入库数量</th>
<th>单价(元)</th>
<th>小计(元)</th>
<th>项目名称</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in 17" :key="index">
<td>{{ index + 1 }}</td>
<td style="word-wrap: break-word; word-break: break-all; max-width: 150px;">
{{ printData.storageInDetailDOList[index]?.boomName ? limitTo20Chars(printData.storageInDetailDOList[index].boomName) : '' }}
</td>
<td style="word-wrap: break-word; word-break: break-all;">{{ printData.storageInDetailDOList[index]?.boomSpec || '' }}</td>
<td>{{ printData.storageInDetailDOList[index]?.unit || '' }}</td>
<td>{{ printData.storageInDetailDOList[index]?.storageAmount || '' }}</td>
<td>{{ printData.storageInDetailDOList[index]?.price || '' }}</td>
<td>{{ printData.storageInDetailDOList[index]?.estimatedPrice || '' }}</td>
<td style="word-wrap: break-word; word-break: break-all; max-width: 120px;">
{{ printData.storageInDetailDOList[index]?.projectName || '' }}
</td>
<td style="word-wrap: break-word; word-break: break-all; white-space: normal; padding: 4px; max-width: 100px; min-height: 30px;">
{{ printData.storageInDetailDOList[index]?.description || '' }}
</td>
</tr>
</tbody>
</table>
<div class="order-info" style="margin-top: 10px;border-bottom: 1px solid #ccc;padding-bottom: 10px;">
<div style="display: flex;width: 40%;">
<span >经手人:{{ printData.userName }}</span>
</div>
<div style="display: flex;width: 20%;justify-content: center;">
</div>
<div style="display: flex; width: 40%;justify-content: right;">
<span style="margin-left:20px;width: 150px">仓库签字:{{ printData.signature }}</span>
<span style="margin-left:20px;width: 150px">日期:{{ printData.date }}</span>
</div>
</div>
</div>
<template #footer>
<el-button @click="printDialogVisible = false">关闭</el-button>
<el-button type="primary" @click="doPrint">打印</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {ElTable} from 'element-plus'
import * as UserApi from '@/api/system/user'
import { useTagsViewStore } from '@/store/modules/tagsView'
const reload: any = inject('reload')
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const { query } = useRoute()
const router = useRouter()
const tagsViewStore = useTagsViewStore()
import * as StorageinApi from '@/api/heli/storagein'
import * as StorageinDetailApi from '@/api/heli/storageindetail'
import {ref} from "vue";
const dialogVisible = ref(false) // 弹窗的是否展示
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formData = ref({
id: undefined,
storageNo: undefined,
ordDate: undefined,
projectId: undefined,
projectPlanId: undefined,
projectPlanNo: undefined,
projectCode: undefined,
auditor: undefined,
createTime: new Date(),
status: undefined,
description: undefined,
boomItemDOList: [],
boomItemRemoveList: [],
matBoomDOList: [],
matItemRemoveList: [],
attachments: [],
supplierName:undefined,
list:[]
})
const formRef = ref() // 表单 Ref
const subFormRef = ref() // 表单 Ref
const loading = ref(true) // 列表的加载中
const total = ref(0) // 列表的总页数
const subBoomFormLoading = ref(false)
const subBoomFormRef = ref()
const userList = ref<UserApi.UserVO[]>([]) // 用户列表
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
storageNoId: query.id
})
// 页面数据加载初始化
onMounted(async () => {
// 获取物料需求计划信息
formData.value = await StorageinApi.getStorageIn(query.id)
getList();
})
const cancel = async () => {
router.push({ path: '/purchase/storagein' })
tagsViewStore.delVisitedView(router.currentRoute.value)
}
function formatDate(val) {
if (!val) return ''
const date = new Date(val)
return date.toLocaleDateString()
}
const printLoading = ref(false)
// 打印弹窗内容
const printDialogVisible = ref(false)
const printData = ref({})
function openPrintDialog(data) {
printData.value = data
printDialogVisible.value = true
}
const isPrint = async () => {
printLoading.value = true
printLoading.value = true
try {
var newVar = await StorageinApi.isPrint(query.id);
console.log(newVar)
openPrintDialog(newVar)
} finally {
printLoading.value = false
}
}
function doPrint() {
// 创建新的打印窗口
const printContent = document.getElementById('printArea')
if (!printContent) return
const iframe = document.createElement('iframe')
iframe.style.position = 'absolute'
iframe.style.width = '0'
iframe.style.height = '0'
iframe.style.border = 'none'
document.body.appendChild(iframe)
const doc = iframe.contentWindow?.document
doc?.open()
doc?.write(`
<!DOCTYPE html>
<html>
<head>
<title >入库单</title>
<style>
@page {
size: 241mm 140mm;
margin: 5mm;
}
body {
font-family: Arial, sans-serif;
margin: 10px;
font-size: 12px;
}
.print-content {
width: 100%;
padding-top: 15px;
}
.order-info {
justify-content: space-between;
display: flex;
flex-wrap: wrap;
align-items: center;
padding-left:8px
}
.stamp-info {
margin-top: 10px;
}
.stamp-info span{
font-size: 15px !important;
}
.order-info span{
font-size: 15px !important;
}
.print-table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
table-layout: fixed;
border: 2px solid #000 !important; /* 加粗外边框 */
}
.print-table th, .print-table td {
border: 1px solid #000 !important; /* 使用黑色边框,更清晰 */
padding: 2px 0px;
text-align: center;
height: 11px;
/*min-height: 26px;*/
/*line-height: 1.2;*/
word-wrap: break-word;
word-break: break-all;
vertical-align: top;
}
.print-table th {
background-color: #f5f5f5;
font-weight: bold;
border: 1px solid #000 !important;
}
/* 特别加强最后一列(备注列)的右边框 */
.print-table th:last-child,
.print-table td:last-child {
border-right: 2px solid #000 !important;
white-space: normal !important;
word-wrap: break-word !important;
word-break: break-all !important;
overflow-wrap: break-word !important;
padding: 4px 2px;
}
</style>
</head>
<body>
${printContent.innerHTML}
</body>
</html>
`)
doc?.close()
iframe.onload = () => {
iframe.contentWindow?.focus()
iframe.contentWindow?.print()
setTimeout(() => document.body.removeChild(iframe), 1000)
}
StorageinApi.updateIsPrint(query.id);
}
function limitTo20Chars(input) {
if (typeof input !== 'string') return '';
return input.length > 20 ? input.slice(0, 20) : input;
}
const deleteForm = async () => {
// 删除的二次确认
await message.delConfirm()
// 发起删除
await StorageinApi.deleteStorageIn(query.id)
message.success(t('common.delSuccess'))
router.push({ path: '/purchase/storagein' })
tagsViewStore.delVisitedView(router.currentRoute.value)
}
const getList = async () => {
loading.value = true
try {
const data = await StorageinDetailApi.getByStorageId(queryParams)
formData.value.list = data.list
total.value = data.total
} finally {
loading.value = false
}
}
</script>
<style scoped>
/* 打印样式 */
@media print {
/* 隐藏所有非打印内容 */
body * {
visibility: hidden;
}
/* 只显示打印区域 */
#printArea, #printArea * {
visibility: visible;
}
/* 打印区域定位 */
#printArea {
position: absolute;
left: 0;
top: 0;
width: 100%;
}
/* 隐藏弹窗相关元素 */
.el-dialog, .el-dialog__wrapper, .el-dialog__header, .el-dialog__footer {
display: none !important;
}
}
.order-info {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
}
.order-info span {
font-size: 15px !important;
margin-right: 10px !important;
}
.stamp-info {
margin-top: 10px;
}
.stamp-info span{
font-size: 15px !important;
}
.print-table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
border: 1px solid #ccc;
table-layout: fixed;
}
.print-table th,
.print-table td {
border: 1px solid #000 !important; /* 使用黑色边框 */
padding: 6px 4px;
text-align: center;
font-size: 13px !important;
height: auto;
min-height: 30px;
line-height: 1.4;
word-wrap: break-word;
word-break: break-all;
vertical-align: top;
}
.print-table th {
background-color: #f5f7fa;
color: #303133;
font-weight: 600;
font-size: 13px !important;
border: 1px solid #000 !important;
}
/* 备注列特殊样式 - 加强右边框 */
.print-table th:last-child,
.print-table td:last-child {
border-right: 2px solid #000 !important;
white-space: normal !important;
word-wrap: break-word !important;
word-break: break-all !important;
overflow-wrap: break-word !important;
text-align: center;
padding: 4px 2px;
}
/* 打印专用样式 */
@media print {
.print-table {
width: 98% !important; /* 稍微减小宽度避免边框被裁剪 */
margin: 0 auto;
border: 2px solid #000 !important;
}
.print-table th,
.print-table td {
border: 1px solid #000 !important;
-webkit-print-color-adjust: exact !important;
color-adjust: exact !important;
}
.print-table th:last-child,
.print-table td:last-child {
border-right: 2px solid #000 !important;
}
}
</style>