<template>
|
<el-dialog
|
v-model="dialogVisible"
|
title="杂收杂发平账"
|
width="1000px"
|
:close-on-click-modal="false"
|
:destroy-on-close="true"
|
@closed="handleDialogClosed"
|
>
|
<div class="reconciliation-container">
|
<!-- 单据基本信息 -->
|
<div class="order-info">
|
<div class="info-row">
|
<span class="label">单据ID:</span>
|
<span class="value">{{ currentRow.id || "-" }}</span>
|
</div>
|
<div class="info-row" v-if="selectedItem">
|
<span class="label">已选订单:</span>
|
<span class="value selected-order">{{ selectedItem.id }}</span>
|
</div>
|
</div>
|
|
<!-- 数据列表展示 -->
|
<el-scrollbar height="400px" class="custom-scrollbar">
|
<transition-group name="data-item-transition">
|
<div
|
class="data-item"
|
v-for="(item, index) in displayData"
|
:key="`${item.orderId}-${index}`"
|
>
|
<div class="radio-container">
|
<el-radio
|
v-model="selectedItem"
|
:label="item"
|
:value="item"
|
@change="handleRadioChange(item)"
|
></el-radio>
|
</div>
|
<div class="data-detail">
|
<div class="detail-row">
|
<span class="label">订单ID:</span>
|
<span class="value">{{ item.id || "-" }}</span>
|
</div>
|
<div class="detail-row">
|
<span class="label">物料编码:</span>
|
<span class="value">{{ item.materielCode || "-" }}</span>
|
</div>
|
<div class="detail-row">
|
<span class="label">物料名称:</span>
|
<span class="value">{{ item.materielName || "-" }}</span>
|
</div>
|
<div class="detail-row">
|
<span class="label">批次号:</span>
|
<span class="value">{{ item.batchNo || "-" }}</span>
|
</div>
|
<div class="detail-row">
|
<span class="label">订单数量:</span>
|
<span class="value">{{ item.orderQuantity || 0 }}</span>
|
</div>
|
<div class="detail-row">
|
<span class="label">单位:</span>
|
<span class="value">{{ item.unit || "-" }}</span>
|
</div>
|
<div class="detail-row">
|
<span class="label">供应商编码:</span>
|
<span class="value">{{ item.supplyCode || "-" }}</span>
|
</div>
|
<div class="detail-row">
|
<span class="label">仓库编码:</span>
|
<span class="value">{{ item.warehouseCode || "-" }}</span>
|
</div>
|
</div>
|
</div>
|
</transition-group>
|
<div class="empty-tip" v-if="displayData.length === 0">
|
<span>暂无相关数据</span>
|
</div>
|
</el-scrollbar>
|
</div>
|
|
<template #footer>
|
<el-button @click="dialogVisible = false">关闭</el-button>
|
<el-button
|
type="primary"
|
@click="handleConfirm"
|
:disabled="!selectedItem"
|
:loading="loading"
|
>
|
{{ loading ? "平账中..." : "确认平账" }}
|
</el-button>
|
</template>
|
</el-dialog>
|
|
<!-- 打印组件(必须在模板中声明,才能通过ref获取) -->
|
<printView ref="printViewRef" @parentcall="parentcall"></printView>
|
</template>
|
|
<script setup>
|
import { ref } from "vue";
|
import printView from "@/extension/outbound/extend/printView.vue";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
import axios from "axios";
|
|
// 弹窗显示状态
|
const dialogVisible = ref(false);
|
// 当前选中的行数据
|
const currentRow = ref({});
|
// 要展示的数据列表
|
const displayData = ref([]);
|
// 选中的数据项
|
const selectedItem = ref(null);
|
// 加载状态
|
const loading = ref(false);
|
// 声明打印组件的ref引用(关键:替代this.$refs.printView)
|
const printViewRef = ref(null);
|
|
// 打开弹窗方法(供父组件调用)
|
const open = (row, data) => {
|
currentRow.value = row;
|
displayData.value = data;
|
selectedItem.value = null; // 重置选择
|
dialogVisible.value = true;
|
};
|
|
// 处理单选按钮变化
|
const handleRadioChange = (item) => {
|
selectedItem.value = item;
|
};
|
|
// 弹窗关闭时的处理
|
const handleDialogClosed = () => {
|
selectedItem.value = null;
|
loading.value = false;
|
};
|
|
// 父组件调用的回调(如果printView需要)
|
const parentcall = (params) => {
|
console.log("printView回调参数:", params);
|
};
|
|
// 确认平账操作
|
const handleConfirm = async () => {
|
if (!selectedItem.value) {
|
ElMessage.warning("请选择一条数据进行平账处理");
|
return;
|
}
|
|
try {
|
// 确认提示
|
await ElMessageBox.confirm(
|
`确定要对订单 ${selectedItem.value.id} 进行平账处理吗?`,
|
"平账确认",
|
{
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
}
|
);
|
|
loading.value = true;
|
|
// 调用平账接口
|
const params = {
|
id: currentRow.value.id, // 行ID
|
orderId: selectedItem.value.id, // 选择的单据orderId
|
};
|
|
const response = await axios.get(
|
"/api/TakeStockOrder/DocumentReconciliation",
|
{
|
params: params,
|
}
|
);
|
|
console.log("接口完整返回值:", response); // 调试用:打印完整返回
|
|
// 第一步:校验最外层状态
|
if (response.data?.status) {
|
ElMessage.success("平账操作成功");
|
|
// 第二步:解析正确的scannedDetail层级(三层data)
|
const thirdLayerData = response.data.data?.data; // 关键修复:取第三层data
|
const scannedDetail = thirdLayerData?.scannedDetail;
|
|
console.log("解析后的scannedDetail:", scannedDetail); // 调试用:打印目标数据
|
|
// 第三步:判断打印条件
|
if (scannedDetail?.isUnpacked && scannedDetail?.materialCodes?.length > 0) {
|
// 确保打印组件实例存在
|
if (printViewRef.value) {
|
console.log("触发打印方法,参数:", scannedDetail.materialCodes);
|
printViewRef.value.open(scannedDetail.materialCodes);
|
} else {
|
ElMessage.warning("打印组件未加载完成,请检查组件引用");
|
}
|
} else {
|
ElMessage.info("无需打印:未满足拆包条件或无物料编码数据");
|
}
|
|
dialogVisible.value = false;
|
} else {
|
ElMessage.error(response.data?.message || "平账操作失败");
|
}
|
} catch (error) {
|
// 完善错误处理:区分用户取消和真实错误
|
if (error === "cancel" || error === "close") {
|
ElMessage.info("已取消平账操作");
|
return;
|
}
|
// 打印错误日志,方便排查
|
console.error("平账接口调用失败:", error);
|
ElMessage.error(`平账操作失败:${error.message || "网络异常"}`);
|
} finally {
|
loading.value = false;
|
}
|
};
|
|
// 暴露方法给父组件
|
defineExpose({
|
open,
|
});
|
</script>
|
|
<style scoped>
|
/* 样式部分不变,省略重复代码 */
|
.reconciliation-container {
|
padding: 10px 0;
|
}
|
|
.order-info {
|
margin-bottom: 20px;
|
padding: 10px;
|
background: #f5f7fa;
|
border-radius: 4px;
|
display: flex;
|
flex-wrap: wrap;
|
gap: 20px;
|
}
|
|
.info-row {
|
display: flex;
|
align-items: center;
|
}
|
|
.label {
|
font-weight: 600;
|
color: #606266;
|
margin-right: 5px;
|
min-width: 80px;
|
text-align: right;
|
}
|
|
.value {
|
color: #303133;
|
}
|
|
.selected-order {
|
color: #409eff;
|
font-weight: 600;
|
}
|
|
.custom-scrollbar {
|
border: 1px solid #e4e7ed;
|
border-radius: 4px;
|
}
|
|
.data-item {
|
display: flex;
|
align-items: flex-start;
|
padding: 15px;
|
margin: 10px;
|
background: #fff;
|
border: 1px solid #e4e7ed;
|
border-radius: 4px;
|
transition: all 0.3s;
|
}
|
|
.data-item:hover {
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
}
|
|
.data-item.selected {
|
border-color: #409eff;
|
background-color: #f0f7ff;
|
}
|
|
.radio-container {
|
margin-right: 12px;
|
margin-top: 4px;
|
}
|
|
.data-detail {
|
display: grid;
|
grid-template-columns: repeat(2, 1fr);
|
gap: 10px;
|
flex: 1;
|
}
|
|
.detail-row {
|
display: flex;
|
align-items: center;
|
}
|
|
.empty-tip {
|
text-align: center;
|
padding: 50px 0;
|
color: #909399;
|
}
|
|
.data-item-transition-enter-from,
|
.data-item-transition-leave-to {
|
opacity: 0;
|
transform: translateY(10px);
|
}
|
|
.data-item-transition-enter-active,
|
.data-item-transition-leave-active {
|
transition: all 0.3s ease;
|
}
|
|
:deep(.el-radio__label) {
|
display: none;
|
}
|
</style>
|