You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

657 lines
14 KiB

<template>
<div class="pda-container">
<!-- 头部栏 -->
<div class="header-bar">
<div class="header-left" @click="goBack">
<i class="el-icon-arrow-left"></i>
<span>{{ functionTitle }}</span>
</div>
<div class="header-right" @click="$router.push({ path: '/' })">首页</div>
</div>
<!-- 申请单输入 -->
<div class="search-container">
<el-input clearable v-model="requestIssueForm.requestNo" placeholder="请输入SHIPMENTID" prefix-icon="el-icon-search"
@keyup.enter.native="loadIssueRequestMaterials" ref="requestNoInput" />
</div>
<!-- 申请单物料列表 -->
<div class="work-order-list" v-if="issueRequestMaterials.length > 0 ">
<div v-for="material in displayIssueRequestMaterials" :key="`${material.partNo}-${material.itemNo}`"
class="work-order-card" @click="openIssueDetail(material)">
<div class="card-title">
<span class="title-label">shipmentId:{{ material.SHIPMENT_ID }} </span>
</div>
<!-- 工单号单独一行 -->
<div class="part-desc-row">
<span class="desc-text">客户名称:{{ material.RECEIVER_ADDRESS_NAME }}</span>
</div>
<div class="card-details">
<div class="detail-item">
<div class="detail-label">发料类型</div>
<div class="detail-value">{{ material.SHIPMENT_TYPE }}</div>
</div>
<div class="detail-item">
<div class="detail-label">状态</div>
<div class="detail-value">{{material.STATE}}</div>
</div>
<div class="detail-item">
<div class="detail-label">计划发料日期</div>
<div class="detail-value">{{ material.PLANNED_SHIP_DATE }}</div>
</div>
</div>
</div>
</div>
<!-- 材料列表(新增,仿 directIssue.vue) -->
<div
class="content-area"
v-if="selectedWorkOrder && materialList.length > 0"
>
<div
v-for="(material, index) in materialList"
:key="index"
class="material-card"
@click="openIssueDetail(material)"
>
<div class="card-title">
<span class="title-label"
>物料编码:{{ material.INVENTORY_PART_NO }} &nbsp;&nbsp; 行号:{{
material.SOURCE_REF2
}}</span
>
</div>
<!-- 物料描述单独一行 -->
<div class="part-desc-row">
<span class="desc-text">客户单号:{{ material.SOURCE_REF1 }}</span>
</div>
<div class="card-details">
<div class="detail-item">
<div class="detail-label">销售行号</div>
<div class="detail-value">{{ material.SHIPMENT_LINE_NO }}</div>
</div>
<div class="detail-item">
<div class="detail-label">需求数量</div>
<div class="detail-value">{{ material.INVENTORY_QTY }}</div>
</div>
<div class="detail-item">
<div class="detail-label">单位</div>
<div class="detail-value">{{ material.INVENTORY_UOM }}</div>
</div>
</div>
</div>
</div>
<!-- 空状态 -->
<div
v-if="selectedWorkOrder && materialList.length === 0"
class="empty-state"
>
<i class="el-icon-box"></i>
<p>该申请单暂无材料清单</p>
</div>
<!-- 加载状态 -->
<div v-if="loading" class="loading-state">
<i class="el-icon-loading"></i>
<p>加载中...</p>
</div>
</div>
</template>
<script>
import {
getCustomerIssueNotifyHeaderInfo,
getCustomerIssueNotifyHeaderOrderMaterialList,
} from '@/api/customerIssue/customer-issue'
import { getWorkOrderMaterials } from '@/api/production/production-issue'
export default {
name: 'customerIssuePDA',
data() {
return {
loading: false,
loadingText: '',
message: '',
messageType: 'info',
// 基于申请单发料
requestIssueForm: {
site: localStorage.getItem('site'),
requestNo: '',
operatorName: 'PDA_USER',
issueReason: '',
targetLocation: '',
remark: '',
createLabel: false,
printerName: '',
},
issueRequestMaterials: [],
selectedRequestMaterial: null,
selectedWorkOrder:'',
materialList: [], // 新增:材料清单
showOnlySelected: false,
}
},
computed: {
functionTitle() {
return '客户单发料'
},
displayIssueRequestMaterials() {
if (this.showOnlySelected && this.selectedRequestMaterial) {
return [this.selectedRequestMaterial]
}
return this.issueRequestMaterials
}
},
methods: {
goBack() {
this.$router.back()
},
goBackToMaterials() {
this.selectedRequestMaterial = null
},
resetAll() {
this.issueRequestMaterials = []
this.selectedRequestMaterial = null
this.message = ''
},
// 基于申请单发料相关方法
async loadIssueRequestMaterials() {
if (this.loading) {
console.log("正在加载中,防重复提交");
return;
}
if (!this.requestIssueForm.requestNo) {
this.showMessage('请输入发料申请单号', 'error')
return
}
this.loading = true
this.loadingText = '加载申请单物料...'
this.issueRequestMaterials = []
this.materialList = []
this.selectedRequestMaterial = null
this.showOnlySelected = false
getCustomerIssueNotifyHeaderInfo({
site: localStorage.getItem('site'),
workOrderNo: this.requestIssueForm.requestNo,
}).then(({ data }) => {
if (data.code === 0) {
this.issueRequestMaterials = data.data || []
if (this.issueRequestMaterials.length === 0) {
this.$message.warning('查询申请单不存在')
}
} else {
this.$message.error(data.msg, 'error')
}
})
.finally(() => {
this.loading = false
})
},
isSameRequestMaterial(a, b) {
if (!a || !b) return false
return (
a.notifyNo === b.notifyNo &&
a.itemNo === b.itemNo &&
a.soorderNo === b.soorderNo
)
},
selectRequestMaterial(material) {
if (
this.showOnlySelected &&
this.selectedRequestMaterial
) {
// 再次点击同一条,恢复显示所有主数据
this.selectedRequestMaterial = null
this.selectedWorkOrder = ''
this.materialList = []
this.showOnlySelected = false
return
}
// 选择并仅显示当前申请单物料
this.selectedRequestMaterial = material
this.selectedWorkOrder = material.SHIPMENT_ID
this.showOnlySelected = true
this.getCustomerIssueNotifyHeaderOrderMaterialList(material)
},
getCustomerIssueNotifyHeaderOrderMaterialList(material){
let params = {
site: localStorage.getItem('site'),
workOrderNo: material.SHIPMENT_ID,
};
getCustomerIssueNotifyHeaderOrderMaterialList(params).then(({ data }) => {
if (data.code === 0) {
console.log(data)
this.materialList = data.data || []
if (this.materialList.length === 0) {
this.$message.warning('该申请单行号暂无材料清单')
}
} else {
this.$message.error(data.msg, 'error')
}
}).catch((error) => {
this.$message.error('获取材料清单失败: ' + error.message, 'error')
});
},
// 打开材料列表页面(仿照 productionReturnPicking.vue 的 openIssueList)
openIssueDetail(material) {
this.$router.push({
name: 'customerIssuePDAIssueList',
query: {
state: material.STATE, // 申请单行号
shipmentId: material.SHIPMENT_ID, // 客户订单号
orderType: material.SHIPMENT_TYPE, // 订单类型
}
})
},
resetRequest() {
this.requestIssueForm.requestNo = ''
this.issueRequestMaterials = []
this.selectedRequestMaterial = null
},
showMessage(text, type = 'info') {
this.message = text
this.messageType = type
setTimeout(() => {
this.message = ''
}, 3000)
},
},
created () {
this.resetRequest()
},
mounted() {
// 聚焦申请单号输入框
this.$nextTick(() => {
if (this.$refs.requestNoInput) {
this.$refs.requestNoInput.focus()
}
})
},
}
</script>
<style scoped>
.pda-container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
background: #f5f5f5;
}
/* 头部栏 */
.header-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 16px;
background: #17b3a3;
color: white;
height: 40px;
min-height: 40px;
}
.header-left {
display: flex;
align-items: center;
cursor: pointer;
font-size: 16px;
font-weight: 500;
}
.header-left i {
margin-right: 8px;
font-size: 18px;
}
.header-right {
cursor: pointer;
font-size: 16px;
font-weight: 500;
}
/* 搜索容器 */
.search-container {
padding: 12px 16px;
background: white;
display: flex;
align-items: center;
gap: 12px;
}
.search-container .el-input {
flex: 1;
}
/* 工单列表 */
.work-order-list {
overflow-y: auto;
padding: 12px 16px;
}
/* 工单卡片 */
.work-order-card {
background: white;
border-radius: 8px;
margin-bottom: 12px;
padding: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
cursor: pointer;
transition: all 0.2s ease;
border: 2px solid transparent;
}
.work-order-card:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
transform: translateY(-1px);
}
.work-order-card.selected {
border-color: #17b3a3;
background: #f0fffe;
}
.work-order-card:active {
transform: translateY(0);
}
/* 内容区域 */
.content-area {
flex: 1;
overflow-y: auto;
padding: 12px 16px;
}
/* 材料卡片 */
.material-card {
background: white;
border-radius: 8px;
margin-bottom: 12px;
padding: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
cursor: pointer;
transition: all 0.2s ease;
border: 2px solid transparent;
}
.material-card:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
transform: translateY(-1px);
}
.material-card.selected {
border-color: #17b3a3;
background: #f0fffe;
}
.material-card:active {
transform: translateY(0);
}
/* 卡片标题 */
.card-title {
margin-bottom: 12px;
}
.title-label {
font-size: 12px;
color: #666;
display: block;
margin-bottom: 4px;
}
.title-value {
font-size: 16px;
font-weight: bold;
color: #333;
margin-left: 16px;
}
/* 物料描述行 */
.part-desc-row {
margin-bottom: 12px;
padding: 0 4px;
}
.desc-text {
font-size: 12px;
color: #666;
line-height: 1.3;
word-break: break-all;
}
/* 卡片详情 */
.card-details {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 4px;
}
.detail-item {
flex: 1;
text-align: center;
min-width: 50px;
max-width: 70px;
}
.detail-label {
font-size: 11px;
color: #666;
margin-bottom: 4px;
line-height: 1.2;
margin-left: -12px;
}
.detail-value {
font-size: 13px;
color: #333;
line-height: 1.2;
margin-left: -12px;
}
/* 区域头部 */
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
padding: 12px 16px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.section-header span {
font-size: 14px;
font-weight: 500;
color: #333;
}
.reset-btn {
background: #17b3a3;
color: white;
border: none;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
}
.reset-btn:hover {
background: #13998c;
}
/* 输入组 */
.input-group {
margin-bottom: 12px;
}
.input-with-scan {
display: flex;
gap: 8px;
align-items: center;
}
.input-with-scan .el-input {
flex: 1;
}
/* 复选框组 */
.checkbox-group {
margin-bottom: 12px;
}
/* 确认区域 */
.confirm-section {
padding: 16px;
background: white;
border-radius: 8px;
margin-top: 12px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
/* 空状态 */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
color: #999;
}
.empty-state i {
font-size: 48px;
margin-bottom: 16px;
}
.empty-state p {
font-size: 14px;
margin: 0;
}
/* 加载状态 */
.loading-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
color: #17b3a3;
}
.loading-state i {
font-size: 24px;
margin-bottom: 12px;
animation: spin 1s linear infinite;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.loading-state p {
font-size: 14px;
margin: 0;
}
/* 消息提示 */
.message {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
padding: 12px 20px;
border-radius: 6px;
font-weight: bold;
z-index: 1001;
max-width: 90%;
text-align: center;
}
.message.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.message.error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.message.warning {
background: #fff3cd;
color: #856404;
border: 1px solid #ffeaa7;
}
.message.info {
background: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
/* 响应式设计 */
@media (max-width: 360px) {
.header-bar {
padding: 8px 12px;
}
.search-container {
padding: 8px 12px;
}
.work-order-list {
padding: 8px 12px;
}
.work-order-card {
padding: 12px;
}
.content-area {
padding: 8px 12px;
}
.material-card {
padding: 12px;
}
.card-details {
flex-wrap: wrap;
gap: 6px;
}
.detail-item {
flex: 0 0 48%;
margin-bottom: 6px;
min-width: 50px;
}
}
</style>