Browse Source

样式修改

master
shenzhouyu 6 months ago
parent
commit
5333ddbed0
  1. 697
      src/views/modules/production-inbound/index.vue
  2. 153
      src/views/modules/production-issue/index.vue
  3. 604
      src/views/modules/production-issue/production-issue-pda.vue
  4. 613
      src/views/modules/production-issue/productionReturnPDA.vue

697
src/views/modules/production-inbound/index.vue

@ -1,412 +1,419 @@
<template>
<div class="production-inbound-pda">
<van-nav-bar title="生产入库" left-arrow @click-left="$router.back()" />
<!-- 功能选择 -->
<div class="function-selector" v-if="!selectedFunction">
<div class="function-card" @click="selectFunction('package')">
<div class="function-icon">📦</div>
<div class="function-title">包装创建</div>
<div class="function-desc">扫描通知单创建生产入库包装</div>
</div>
<div class="function-card" @click="selectFunction('pallet')">
<div class="function-icon">🏗</div>
<div class="function-title">装托盘</div>
<div class="function-desc">扫描包装装载到托盘</div>
</div>
<div class="function-card" @click="selectFunction('register')">
<div class="function-icon">📋</div>
<div class="function-title">入库登记</div>
<div class="function-desc">扫描包装完成入库登记</div>
<div>
<div class="pda-container">
<div class="status-bar">
<div class="goBack" @click="$router.back()"><i class="el-icon-arrow-left"></i>上一页</div>
<div class="goBack">生产入库</div>
<div class="network" style="color: #fff" @click="$router.push({ path: '/' })">🏠首页</div>
</div>
<div style="overflow-y: auto">
<!-- 功能选择 -->
<div class="function-selector" v-if="!selectedFunction">
<div class="function-card" @click="selectFunction('package')">
<div class="function-icon">📦</div>
<div class="function-title">包装创建</div>
<div class="function-desc">扫描通知单创建生产入库包装</div>
</div>
<div class="function-card" @click="selectFunction('return')">
<div class="function-icon"></div>
<div class="function-title">退库操作</div>
<div class="function-desc">扫描单元执行退库操作</div>
</div>
</div>
<div class="function-card" @click="selectFunction('pallet')">
<div class="function-icon">🏗</div>
<div class="function-title">装托盘</div>
<div class="function-desc">扫描包装装载到托盘</div>
</div>
<!-- 包装创建 -->
<div class="package-create" v-if="selectedFunction === 'package'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>包装创建</h2>
</div>
<div class="function-card" @click="selectFunction('register')">
<div class="function-icon">📋</div>
<div class="function-title">入库登记</div>
<div class="function-desc">扫描包装完成入库登记</div>
</div>
<!-- 通知单输入 -->
<div class="input-section" v-if="!notifyInfo.notifyNo">
<div class="input-group">
<label>通知单号</label>
<div class="input-with-scan">
<input
v-model="packageForm.notifyNo"
placeholder="请输入或扫描通知单号"
@keyup.enter="loadNotifyInfo"
/>
<button @click="loadNotifyInfo" class="scan-btn">确认</button>
<div class="function-card" @click="selectFunction('return')">
<div class="function-icon"></div>
<div class="function-title">退库操作</div>
<div class="function-desc">扫描单元执行退库操作</div>
</div>
</div>
</div>
<!-- 通知单信息 -->
<div class="notify-info" v-if="notifyInfo.notifyNo">
<div class="section-header">
<h3>通知单信息</h3>
<button @click="resetNotify" class="reset-btn">重新选择</button>
</div>
<div class="info-card">
<div class="info-row">
<span class="label">通知单号:</span>
<span class="value">{{ notifyInfo.notifyNo }}</span>
<!-- 包装创建 -->
<div class="package-create" v-if="selectedFunction === 'package'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>包装创建</h2>
</div>
<div class="info-row">
<span class="label">站点:</span>
<span class="value">{{ notifyInfo.site }}</span>
</div>
<div class="info-row">
<span class="label">申请人:</span>
<span class="value">{{ notifyInfo.userName }}</span>
</div>
<div class="info-row">
<span class="label">状态:</span>
<span class="value">{{ notifyInfo.status }}</span>
</div>
</div>
<!-- 物料清单 -->
<div class="materials-section" v-if="materialList.length">
<div class="section-header">
<h4>物料清单</h4>
<!-- 通知单输入 -->
<div class="input-section" v-if="!notifyInfo.notifyNo">
<div class="input-group">
<label>通知单号</label>
<div class="input-with-scan">
<input
v-model="packageForm.notifyNo"
placeholder="请输入或扫描通知单号"
@keyup.enter="loadNotifyInfo"
/>
<button @click="loadNotifyInfo" class="scan-btn">确认</button>
</div>
</div>
</div>
<div class="material-list">
<div v-for="material in materialList" :key="material.partNo" class="material-item">
<div class="material-info">
<div class="part-no">{{ material.partNo }}</div>
<div class="part-desc">{{ material.partDesc }}</div>
<div class="qty-info">
需求: {{ material.requireQty }} |
已入库: {{ material.inboundQty }} |
待入库: {{ material.pendingQty }}
<!-- 通知单信息 -->
<div class="notify-info" v-if="notifyInfo.notifyNo">
<div class="section-header">
<h3>通知单信息</h3>
<button @click="resetNotify" class="reset-btn">重新选择</button>
</div>
<div class="info-card">
<div class="info-row">
<span class="label">通知单号:</span>
<span class="value">{{ notifyInfo.notifyNo }}</span>
</div>
<div class="info-row">
<span class="label">站点:</span>
<span class="value">{{ notifyInfo.site }}</span>
</div>
<div class="info-row">
<span class="label">申请人:</span>
<span class="value">{{ notifyInfo.userName }}</span>
</div>
<div class="info-row">
<span class="label">状态:</span>
<span class="value">{{ notifyInfo.status }}</span>
</div>
</div>
<!-- 物料清单 -->
<div class="materials-section" v-if="materialList.length">
<div class="section-header">
<h4>物料清单</h4>
</div>
<div class="material-list">
<div v-for="material in materialList" :key="material.partNo" class="material-item">
<div class="material-info">
<div class="part-no">{{ material.partNo }}</div>
<div class="part-desc">{{ material.partDesc }}</div>
<div class="qty-info">
需求: {{ material.requireQty }} |
已入库: {{ material.inboundQty }} |
待入库: {{ material.pendingQty }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 包装创建表单 -->
<div class="create-form">
<div class="section-header">
<h4>创建包装</h4>
</div>
<div class="input-group">
<label>物料编码</label>
<input v-model="packageForm.partNo" placeholder="请输入物料编码" />
</div>
<div class="input-group">
<label>包装数量</label>
<input v-model="packageForm.qty" type="number" placeholder="请输入包装数量" />
</div>
<div class="input-group">
<label>批次号</label>
<input v-model="packageForm.batchNo" placeholder="请输入批次号(可选)" />
</div>
<button @click="createPackage" class="confirm-btn" :disabled="!packageForm.partNo || !packageForm.qty">
创建包装
</button>
</div>
<!-- 包装创建表单 -->
<div class="create-form">
<div class="section-header">
<h4>创建包装</h4>
</div>
<div class="input-group">
<label>物料编码</label>
<input v-model="packageForm.partNo" placeholder="请输入物料编码" />
</div>
<div class="input-group">
<label>包装数量</label>
<input v-model="packageForm.qty" type="number" placeholder="请输入包装数量" />
</div>
<div class="input-group">
<label>批次号</label>
<input v-model="packageForm.batchNo" placeholder="请输入批次号(可选)" />
</div>
<button @click="createPackage" class="confirm-btn" :disabled="!packageForm.partNo || !packageForm.qty">
创建包装
</button>
</div>
<!-- 已创建包装列表 -->
<div class="created-packages" v-if="createdPackages.length">
<div class="section-header">
<h4>已创建包装 ({{ createdPackages.length }})</h4>
</div>
<div class="package-list">
<div v-for="pkg in createdPackages" :key="pkg.unitId" class="package-item">
<div class="package-info">
<div class="unit-id">{{ pkg.unitId }}</div>
<div class="part-info">{{ pkg.partNo }} - {{ pkg.partDesc }}</div>
<div class="qty-info">数量: {{ pkg.qty }}</div>
<!-- 已创建包装列表 -->
<div class="created-packages" v-if="createdPackages.length">
<div class="section-header">
<h4>已创建包装 ({{ createdPackages.length }})</h4>
</div>
<div class="package-actions">
<button @click="printLabel(pkg)" class="print-btn">打印</button>
<div class="package-list">
<div v-for="pkg in createdPackages" :key="pkg.unitId" class="package-item">
<div class="package-info">
<div class="unit-id">{{ pkg.unitId }}</div>
<div class="part-info">{{ pkg.partNo }} - {{ pkg.partDesc }}</div>
<div class="qty-info">数量: {{ pkg.qty }}</div>
</div>
<div class="package-actions">
<button @click="printLabel(pkg)" class="print-btn">打印</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 装托盘 -->
<div class="pallet-pack" v-if="selectedFunction === 'pallet'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>装托盘</h2>
</div>
<!-- 托盘输入 -->
<div class="input-section">
<div class="input-group">
<label>托盘编码</label>
<div class="input-with-scan">
<input
v-model="palletForm.palletUnitId"
placeholder="请扫描托盘编码"
/>
<button @click="scanPallet" class="scan-btn">扫描</button>
<!-- 装托盘 -->
<div class="pallet-pack" v-if="selectedFunction === 'pallet'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>装托盘</h2>
</div>
</div>
</div>
<!-- 包装扫描 -->
<div class="scan-section">
<div class="section-header">
<h3>扫描包装</h3>
</div>
<div class="input-group">
<label>包装编码</label>
<div class="input-with-scan">
<input
v-model="scannedPackageId"
placeholder="请扫描包装编码"
@keyup.enter="scanPackageForPallet"
/>
<button @click="scanPackageForPallet" class="scan-btn">扫描</button>
<!-- 托盘输入 -->
<div class="input-section">
<div class="input-group">
<label>托盘编码</label>
<div class="input-with-scan">
<input
v-model="palletForm.palletUnitId"
placeholder="请扫描托盘编码"
/>
<button @click="scanPallet" class="scan-btn">扫描</button>
</div>
</div>
</div>
</div>
</div>
<!-- 已扫描包装列表 -->
<div class="scanned-packages" v-if="scannedPackages.length">
<div class="section-header">
<h4>已扫描包装 ({{ scannedPackages.length }})</h4>
</div>
<div class="package-list">
<div v-for="(pkg, index) in scannedPackages" :key="pkg.unitId" class="package-item">
<div class="package-info">
<div class="unit-id">{{ pkg.unitId }}</div>
<div class="part-info">{{ pkg.partNo }} - {{ pkg.partDesc }}</div>
<div class="qty-info">数量: {{ pkg.qty }}</div>
<!-- 包装扫描 -->
<div class="scan-section">
<div class="section-header">
<h3>扫描包装</h3>
</div>
<div class="package-actions">
<button @click="removePackage(index)" class="remove-btn">移除</button>
<div class="input-group">
<label>包装编码</label>
<div class="input-with-scan">
<input
v-model="scannedPackageId"
placeholder="请扫描包装编码"
@keyup.enter="scanPackageForPallet"
/>
<button @click="scanPackageForPallet" class="scan-btn">扫描</button>
</div>
</div>
</div>
</div>
<button @click="confirmPackToPallet" class="confirm-btn" :disabled="!palletForm.palletUnitId">
确认装托盘
</button>
</div>
</div>
<!-- 入库登记 -->
<div class="inbound-register" v-if="selectedFunction === 'register'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>入库登记</h2>
</div>
<!-- 已扫描包装列表 -->
<div class="scanned-packages" v-if="scannedPackages.length">
<div class="section-header">
<h4>已扫描包装 ({{ scannedPackages.length }})</h4>
</div>
<div class="package-list">
<div v-for="(pkg, index) in scannedPackages" :key="pkg.unitId" class="package-item">
<div class="package-info">
<div class="unit-id">{{ pkg.unitId }}</div>
<div class="part-info">{{ pkg.partNo }} - {{ pkg.partDesc }}</div>
<div class="qty-info">数量: {{ pkg.qty }}</div>
</div>
<div class="package-actions">
<button @click="removePackage(index)" class="remove-btn">移除</button>
</div>
</div>
</div>
<!-- 通知单输入 -->
<div class="input-section" v-if="!registerForm.notifyNo">
<div class="input-group">
<label>通知单号</label>
<div class="input-with-scan">
<input
v-model="tempNotifyNo"
placeholder="请输入通知单号"
@keyup.enter="setNotifyForRegister"
/>
<button @click="setNotifyForRegister" class="scan-btn">确认</button>
<button @click="confirmPackToPallet" class="confirm-btn" :disabled="!palletForm.palletUnitId">
确认装托盘
</button>
</div>
</div>
</div>
<!-- 库位输入 -->
<div class="input-section" v-if="registerForm.notifyNo">
<div class="input-group">
<label>库位</label>
<input v-model="registerForm.locationId" placeholder="请输入库位" />
</div>
</div>
<!-- 包装扫描 -->
<div class="scan-section" v-if="registerForm.notifyNo">
<div class="section-header">
<h3>扫描包装</h3>
</div>
<div class="input-group">
<label>包装编码</label>
<div class="input-with-scan">
<input
v-model="scannedPackageId"
placeholder="请扫描包装编码"
@keyup.enter="scanPackageForRegister"
/>
<button @click="scanPackageForRegister" class="scan-btn">扫描</button>
<!-- 入库登记 -->
<div class="inbound-register" v-if="selectedFunction === 'register'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>入库登记</h2>
</div>
</div>
</div>
<!-- 已扫描包装列表 -->
<div class="scanned-packages" v-if="scannedPackages.length">
<div class="section-header">
<h4>待入库包装 ({{ scannedPackages.length }})</h4>
</div>
<div class="package-list">
<div v-for="(pkg, index) in scannedPackages" :key="pkg.unitId" class="package-item">
<div class="package-info">
<div class="unit-id">{{ pkg.unitId }}</div>
<div class="part-info">{{ pkg.partNo }} - {{ pkg.partDesc }}</div>
<div class="qty-info">数量: {{ pkg.qty }}</div>
<!-- 通知单输入 -->
<div class="input-section" v-if="!registerForm.notifyNo">
<div class="input-group">
<label>通知单号</label>
<div class="input-with-scan">
<input
v-model="tempNotifyNo"
placeholder="请输入通知单号"
@keyup.enter="setNotifyForRegister"
/>
<button @click="setNotifyForRegister" class="scan-btn">确认</button>
</div>
</div>
<div class="package-actions">
<button @click="removePackage(index)" class="remove-btn">移除</button>
</div>
<!-- 库位输入 -->
<div class="input-section" v-if="registerForm.notifyNo">
<div class="input-group">
<label>库位</label>
<input v-model="registerForm.locationId" placeholder="请输入库位" />
</div>
</div>
</div>
<button @click="confirmInboundRegister" class="confirm-btn" :disabled="!registerForm.locationId">
确认入库
</button>
</div>
</div>
<!-- 包装扫描 -->
<div class="scan-section" v-if="registerForm.notifyNo">
<div class="section-header">
<h3>扫描包装</h3>
</div>
<div class="input-group">
<label>包装编码</label>
<div class="input-with-scan">
<input
v-model="scannedPackageId"
placeholder="请扫描包装编码"
@keyup.enter="scanPackageForRegister"
/>
<button @click="scanPackageForRegister" class="scan-btn">扫描</button>
</div>
</div>
</div>
<!-- 退库操作 -->
<div class="return-operation" v-if="selectedFunction === 'return'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>退库操作</h2>
</div>
<!-- 已扫描包装列表 -->
<div class="scanned-packages" v-if="scannedPackages.length">
<div class="section-header">
<h4>待入库包装 ({{ scannedPackages.length }})</h4>
</div>
<div class="package-list">
<div v-for="(pkg, index) in scannedPackages" :key="pkg.unitId" class="package-item">
<div class="package-info">
<div class="unit-id">{{ pkg.unitId }}</div>
<div class="part-info">{{ pkg.partNo }} - {{ pkg.partDesc }}</div>
<div class="qty-info">数量: {{ pkg.qty }}</div>
</div>
<div class="package-actions">
<button @click="removePackage(index)" class="remove-btn">移除</button>
</div>
</div>
</div>
<!-- 通知单输入 -->
<div class="input-section" v-if="!returnForm.notifyNo">
<div class="input-group">
<label>通知单号</label>
<div class="input-with-scan">
<input
v-model="tempNotifyNo"
placeholder="请输入通知单号"
@keyup.enter="loadInboundRecords"
/>
<button @click="loadInboundRecords" class="scan-btn">查询</button>
<button @click="confirmInboundRegister" class="confirm-btn" :disabled="!registerForm.locationId">
确认入库
</button>
</div>
</div>
</div>
<!-- 入库记录选择 -->
<div class="records-section" v-if="inboundRecords.length">
<div class="section-header">
<h3>选择入库记录</h3>
</div>
<div class="record-list">
<div v-for="record in inboundRecords" :key="record.transNo"
class="record-item"
:class="{ selected: selectedRecord === record.transNo }"
@click="selectRecord(record)">
<div class="record-info">
<div class="trans-no">{{ record.transNo }}</div>
<div class="trans-date">{{ record.transDate | formatDate }}</div>
<div class="qty-info">
入库: {{ record.inboundQty }} |
已退: {{ record.returnedQty }} |
可退: {{ record.availableReturnQty }}
<!-- 退库操作 -->
<div class="return-operation" v-if="selectedFunction === 'return'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>退库操作</h2>
</div>
<!-- 通知单输入 -->
<div class="input-section" v-if="!returnForm.notifyNo">
<div class="input-group">
<label>通知单号</label>
<div class="input-with-scan">
<input
v-model="tempNotifyNo"
placeholder="请输入通知单号"
@keyup.enter="loadInboundRecords"
/>
<button @click="loadInboundRecords" class="scan-btn">查询</button>
</div>
</div>
</div>
</div>
</div>
<!-- 退库方式选择 -->
<div class="return-type-section" v-if="selectedRecord">
<div class="section-header">
<h4>退库方式</h4>
</div>
<div class="radio-group">
<label class="radio-item">
<input type="radio" v-model="returnType" value="quantity" />
<span>按数量退库</span>
</label>
<label class="radio-item">
<input type="radio" v-model="returnType" value="unit" />
<span>按单元退库</span>
</label>
</div>
</div>
<!-- 按数量退库 -->
<div class="quantity-return" v-if="returnType === 'quantity'">
<div class="input-group">
<label>退库数量</label>
<input v-model="returnForm.returnQty" type="number" placeholder="请输入退库数量" />
</div>
<div class="input-group">
<label>退库原因</label>
<input v-model="returnForm.returnReason" placeholder="请输入退库原因" />
</div>
<button @click="confirmReturn" class="confirm-btn" :disabled="!returnForm.returnQty || !returnForm.returnReason">
确认退库
</button>
</div>
<!-- 入库记录选择 -->
<div class="records-section" v-if="inboundRecords.length">
<div class="section-header">
<h3>选择入库记录</h3>
</div>
<div class="record-list">
<div v-for="record in inboundRecords" :key="record.transNo"
class="record-item"
:class="{ selected: selectedRecord === record.transNo }"
@click="selectRecord(record)">
<div class="record-info">
<div class="trans-no">{{ record.transNo }}</div>
<div class="trans-date">{{ record.transDate | formatDate }}</div>
<div class="qty-info">
入库: {{ record.inboundQty }} |
已退: {{ record.returnedQty }} |
可退: {{ record.availableReturnQty }}
</div>
</div>
</div>
</div>
</div>
<!-- 按单元退库 -->
<div class="unit-return" v-if="returnType === 'unit'">
<div class="scan-section">
<div class="input-group">
<label>单元编码</label>
<div class="input-with-scan">
<input
v-model="scannedUnitId"
placeholder="请扫描单元编码"
@keyup.enter="scanUnitForReturn"
/>
<button @click="scanUnitForReturn" class="scan-btn">扫描</button>
<!-- 退库方式选择 -->
<div class="return-type-section" v-if="selectedRecord">
<div class="section-header">
<h4>退库方式</h4>
</div>
<div class="radio-group">
<label class="radio-item">
<input type="radio" v-model="returnType" value="quantity" />
<span>按数量退库</span>
</label>
<label class="radio-item">
<input type="radio" v-model="returnType" value="unit" />
<span>按单元退库</span>
</label>
</div>
</div>
</div>
<!-- 已扫描单元列表 -->
<div class="scanned-units" v-if="scannedUnits.length">
<div class="section-header">
<h4>已扫描单元 ({{ scannedUnits.length }})</h4>
<!-- 按数量退库 -->
<div class="quantity-return" v-if="returnType === 'quantity'">
<div class="input-group">
<label>退库数量</label>
<input v-model="returnForm.returnQty" type="number" placeholder="请输入退库数量" />
</div>
<div class="input-group">
<label>退库原因</label>
<input v-model="returnForm.returnReason" placeholder="请输入退库原因" />
</div>
<button @click="confirmReturn" class="confirm-btn" :disabled="!returnForm.returnQty || !returnForm.returnReason">
确认退库
</button>
</div>
<div class="unit-list">
<div v-for="(unit, index) in scannedUnits" :key="unit.unitId" class="unit-item">
<div class="unit-info">
<div class="unit-id">{{ unit.unitId }}</div>
<div class="part-info">{{ unit.partNo }} - {{ unit.partDesc }}</div>
<div class="qty-info">数量: {{ unit.qty }}</div>
<!-- 按单元退库 -->
<div class="unit-return" v-if="returnType === 'unit'">
<div class="scan-section">
<div class="input-group">
<label>单元编码</label>
<div class="input-with-scan">
<input
v-model="scannedUnitId"
placeholder="请扫描单元编码"
@keyup.enter="scanUnitForReturn"
/>
<button @click="scanUnitForReturn" class="scan-btn">扫描</button>
</div>
</div>
</div>
<!-- 已扫描单元列表 -->
<div class="scanned-units" v-if="scannedUnits.length">
<div class="section-header">
<h4>已扫描单元 ({{ scannedUnits.length }})</h4>
</div>
<div class="unit-actions">
<button @click="removeUnit(index)" class="remove-btn">移除</button>
<div class="unit-list">
<div v-for="(unit, index) in scannedUnits" :key="unit.unitId" class="unit-item">
<div class="unit-info">
<div class="unit-id">{{ unit.unitId }}</div>
<div class="part-info">{{ unit.partNo }} - {{ unit.partDesc }}</div>
<div class="qty-info">数量: {{ unit.qty }}</div>
</div>
<div class="unit-actions">
<button @click="removeUnit(index)" class="remove-btn">移除</button>
</div>
</div>
</div>
</div>
<div class="input-group">
<label>退库原因</label>
<input v-model="returnForm.returnReason" placeholder="请输入退库原因" />
</div>
<button @click="confirmReturn" class="confirm-btn" :disabled="!scannedUnits.length || !returnForm.returnReason">
确认退库
</button>
</div>
</div>
<div class="input-group">
<label>退库原因</label>
<input v-model="returnForm.returnReason" placeholder="请输入退库原因" />
<!-- 加载提示 -->
<div class="loading" v-if="loading">
<div class="loading-spinner"></div>
<div class="loading-text">{{ loadingText }}</div>
</div>
<button @click="confirmReturn" class="confirm-btn" :disabled="!scannedUnits.length || !returnForm.returnReason">
确认退库
</button>
<!-- 消息提示 -->
<div class="message" v-if="message" :class="messageType">
{{ message }}
</div>
</div>
</div>
<!-- 加载提示 -->
<div class="loading" v-if="loading">
<div class="loading-spinner"></div>
<div class="loading-text">{{ loadingText }}</div>
</div>
<!-- 消息提示 -->
<div class="message" v-if="message" :class="messageType">
{{ message }}
</div>
</div>
</template>

153
src/views/modules/production-issue/index.vue

@ -1,80 +1,87 @@
<template>
<div class="production-issue-container">
<van-nav-bar title="生产发料" left-arrow @click-left="$router.back()" />
<!-- 搜索栏 -->
<div class="search-section">
<van-search
v-model="searchValue"
placeholder="请输入生产订单号"
@search="handleSearch"
@clear="handleClear"
/>
</div>
<div>
<div class="pda-container">
<div class="status-bar">
<div class="goBack" @click="$router.back()"><i class="el-icon-arrow-left"></i>上一页</div>
<div class="goBack">生产发料</div>
<div class="network" style="color: #fff" @click="$router.push({ path: '/' })">🏠首页</div>
</div>
<div style="overflow-y: auto">
<!-- 搜索栏 -->
<div class="search-section">
<van-search
v-model="searchValue"
placeholder="请输入生产订单号"
@search="handleSearch"
@clear="handleClear"
/>
</div>
<!-- 状态筛选 -->
<div class="filter-section">
<van-tabs v-model="activeTab" @change="handleTabChange">
<van-tab title="全部" name="all" />
<van-tab title="待发料" name="0" />
<van-tab title="部分发料" name="1" />
<van-tab title="已完成" name="2" />
</van-tabs>
</div>
<!-- 状态筛选 -->
<div class="filter-section">
<van-tabs v-model="activeTab" @change="handleTabChange">
<van-tab title="全部" name="all" />
<van-tab title="待发料" name="0" />
<van-tab title="部分发料" name="1" />
<van-tab title="已完成" name="2" />
</van-tabs>
</div>
<!-- 生产订单列表 -->
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<div
v-for="item in orderList"
:key="item.id"
class="order-item"
@click="handleOrderClick(item)"
>
<div class="order-header">
<div class="order-no">{{ item.orderNo }}</div>
<div class="order-status" :class="getStatusClass(item.status)">
{{ getStatusText(item.status) }}
</div>
</div>
<div class="order-info">
<div class="info-row">
<span class="label">产品编码</span>
<span class="value">{{ item.productCode }}</span>
</div>
<div class="info-row">
<span class="label">产品名称</span>
<span class="value">{{ item.productName }}</span>
<!-- 生产订单列表 -->
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<div
v-for="item in orderList"
:key="item.id"
class="order-item"
@click="handleOrderClick(item)"
>
<div class="order-header">
<div class="order-no">{{ item.orderNo }}</div>
<div class="order-status" :class="getStatusClass(item.status)">
{{ getStatusText(item.status) }}
</div>
</div>
<div class="order-info">
<div class="info-row">
<span class="label">产品编码</span>
<span class="value">{{ item.productCode }}</span>
</div>
<div class="info-row">
<span class="label">产品名称</span>
<span class="value">{{ item.productName }}</span>
</div>
<div class="info-row">
<span class="label">生产数量</span>
<span class="value">{{ item.planQuantity }}</span>
</div>
<div class="info-row">
<span class="label">工作中心</span>
<span class="value">{{ item.workCenter }}</span>
</div>
<div class="info-row">
<span class="label">计划开始</span>
<span class="value">{{ item.planStartDate }}</span>
</div>
</div>
<div class="progress-section">
<van-progress
:percentage="Math.round((item.issuedQuantity / item.totalMaterialQuantity) * 100)"
:stroke-width="6"
color="#1989fa"
/>
<div class="progress-text">发料进度{{ item.issuedQuantity }}/{{ item.totalMaterialQuantity }}</div>
</div>
</div>
<div class="info-row">
<span class="label">生产数量</span>
<span class="value">{{ item.planQuantity }}</span>
</div>
<div class="info-row">
<span class="label">工作中心</span>
<span class="value">{{ item.workCenter }}</span>
</div>
<div class="info-row">
<span class="label">计划开始</span>
<span class="value">{{ item.planStartDate }}</span>
</div>
</div>
<div class="progress-section">
<van-progress
:percentage="Math.round((item.issuedQuantity / item.totalMaterialQuantity) * 100)"
:stroke-width="6"
color="#1989fa"
/>
<div class="progress-text">发料进度{{ item.issuedQuantity }}/{{ item.totalMaterialQuantity }}</div>
</div>
</div>
</van-list>
</van-pull-refresh>
</van-list>
</van-pull-refresh>
</div>
</div>
</div>
</template>

604
src/views/modules/production-issue/production-issue-pda.vue

@ -1,354 +1,362 @@
<template>
<div class="production-issue-pda">
<van-nav-bar title="生产发料" left-arrow @click-left="$router.back()" />
<!-- 功能选择 -->
<div class="function-selector" v-if="!selectedFunction">
<div class="function-card" @click="selectFunction('direct')">
<div class="function-icon">📦</div>
<div class="function-title">直接发料</div>
<div class="function-desc">输入工单号扫描物料标签直接发料</div>
<div>
<div class="pda-container">
<div class="status-bar">
<div class="goBack" @click="$router.back()"><i class="el-icon-arrow-left"></i>上一页</div>
<div class="goBack">生产发料</div>
<div class="network" style="color: #fff" @click="$router.push({ path: '/' })">🏠首页</div>
</div>
<div style="overflow-y: auto">
<!-- 功能选择 -->
<div class="function-selector" v-if="!selectedFunction">
<div class="function-card" @click="selectFunction('direct')">
<div class="function-icon">📦</div>
<div class="function-title">直接发料</div>
<div class="function-desc">输入工单号扫描物料标签直接发料</div>
</div>
<div class="function-card" @click="selectFunction('picking')">
<div class="function-icon">🏗</div>
<div class="function-title">拣选装托盘</div>
<div class="function-desc">基于申请单创建托盘扫描箱卷绑定</div>
</div>
<div class="function-card" @click="selectFunction('request')">
<div class="function-icon">📋</div>
<div class="function-title">申请单发料</div>
<div class="function-desc">基于申请单扫描物料标签发料</div>
</div>
</div>
<!-- 直接发料 -->
<div class="direct-issue" v-if="selectedFunction === 'direct'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>直接发料</h2>
</div>
<div class="function-card" @click="selectFunction('picking')">
<div class="function-icon">🏗</div>
<div class="function-title">拣选装托盘</div>
<div class="function-desc">基于申请单创建托盘扫描箱卷绑定</div>
</div>
<!-- 工单输入 -->
<div class="input-section" v-if="!workOrderMaterials.length">
<div class="input-group">
<label>工单号</label>
<div class="input-with-scan">
<input
v-model="directIssueForm.workOrderNo"
placeholder="请输入或扫描工单号"
@keyup.enter="loadWorkOrderMaterials"
/>
<button @click="loadWorkOrderMaterials" class="scan-btn">确认</button>
<div class="function-card" @click="selectFunction('request')">
<div class="function-icon">📋</div>
<div class="function-title">申请单发料</div>
<div class="function-desc">基于申请单扫描物料标签发料</div>
</div>
</div>
</div>
<!-- 物料列表 -->
<div class="materials-section" v-if="workOrderMaterials.length">
<div class="section-header">
<h3>工单物料 ({{ directIssueForm.workOrderNo }})</h3>
<button @click="resetWorkOrder" class="reset-btn">重新选择</button>
</div>
<!-- 直接发料 -->
<div class="direct-issue" v-if="selectedFunction === 'direct'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>直接发料</h2>
</div>
<div class="material-list">
<div v-for="(material, index) in workOrderMaterials" :key="index"
class="material-item"
:class="{ selected: (selectedMaterial?selectedMaterial.partNo:'') === (material&&material.partNo?material.partNo:'') }"
@click="selectMaterial(material)"
>
<div class="material-info">
<div class="part-no">{{ material.partNo }}</div>
<div class="part-desc">{{ material.partDesc }}</div>
<div class="qty-info">
需求: {{ material.requiredQty }} |
已发: {{ material.issuedQty }} |
剩余: {{ material.remainQty }}
<!-- 工单输入 -->
<div class="input-section" v-if="!workOrderMaterials.length">
<div class="input-group">
<label>工单号</label>
<div class="input-with-scan">
<input
v-model="directIssueForm.workOrderNo"
placeholder="请输入或扫描工单号"
@keyup.enter="loadWorkOrderMaterials"
/>
<button @click="loadWorkOrderMaterials" class="scan-btn">确认</button>
</div>
</div>
<div class="material-status">
<span v-if="material.remainQty > 0" class="status-pending">待发料</span>
<span v-else class="status-complete">已完成</span>
</div>
</div>
</div>
</div>
<!-- 扫描标签 -->
<div class="scan-section" v-if="selectedMaterial">
<div class="section-header">
<h3>扫描物料标签</h3>
</div>
<!-- 物料列表 -->
<div class="materials-section" v-if="workOrderMaterials.length">
<div class="section-header">
<h3>工单物料 ({{ directIssueForm.workOrderNo }})</h3>
<button @click="resetWorkOrder" class="reset-btn">重新选择</button>
</div>
<div class="input-group">
<label>物料标签</label>
<div class="input-with-scan">
<input
v-model="scannedLabel"
placeholder="请扫描物料标签"
@keyup.enter="parseMaterialLabel"
/>
<button @click="parseMaterialLabel" class="scan-btn">解析</button>
<div class="material-list">
<div v-for="(material, index) in workOrderMaterials" :key="index"
class="material-item"
:class="{ selected: (selectedMaterial?selectedMaterial.partNo:'') === (material&&material.partNo?material.partNo:'') }"
@click="selectMaterial(material)"
>
<div class="material-info">
<div class="part-no">{{ material.partNo }}</div>
<div class="part-desc">{{ material.partDesc }}</div>
<div class="qty-info">
需求: {{ material.requiredQty }} |
已发: {{ material.issuedQty }} |
剩余: {{ material.remainQty }}
</div>
</div>
<div class="material-status">
<span v-if="material.remainQty > 0" class="status-pending">待发料</span>
<span v-else class="status-complete">已完成</span>
</div>
</div>
</div>
</div>
</div>
<!-- 标签信息 -->
<div class="label-info" v-if="labelInfo">
<div class="info-row">
<span class="label">物料编码:</span>
<span class="value">{{ labelInfo.partNo }}</span>
</div>
<div class="info-row">
<span class="label">物料描述:</span>
<span class="value">{{ labelInfo.partDesc }}</span>
</div>
<div class="info-row">
<span class="label">批次号:</span>
<span class="value">{{ labelInfo.batchNo }}</span>
</div>
<div class="info-row">
<span class="label">库位:</span>
<span class="value">{{ labelInfo.locationId }}</span>
</div>
<div class="info-row">
<span class="label">可用数量:</span>
<span class="value">{{ labelInfo.availableQty }}</span>
</div>
</div>
<!-- 扫描标签 -->
<div class="scan-section" v-if="selectedMaterial">
<div class="section-header">
<h3>扫描物料标签</h3>
</div>
<!-- 发料数量 -->
<div class="qty-input" v-if="labelInfo">
<div class="input-group">
<label>发料数量</label>
<input
v-model="issueQty"
type="number"
:max="Math.min(selectedMaterial.remainQty, labelInfo.availableQty)"
placeholder="请输入发料数量"
/>
</div>
<div class="input-group">
<label>物料标签</label>
<div class="input-with-scan">
<input
v-model="scannedLabel"
placeholder="请扫描物料标签"
@keyup.enter="parseMaterialLabel"
/>
<button @click="parseMaterialLabel" class="scan-btn">解析</button>
</div>
</div>
<div class="input-group">
<label>备注</label>
<input v-model="directIssueForm.remark" placeholder="可选" />
</div>
<!-- 标签信息 -->
<div class="label-info" v-if="labelInfo">
<div class="info-row">
<span class="label">物料编码:</span>
<span class="value">{{ labelInfo.partNo }}</span>
</div>
<div class="info-row">
<span class="label">物料描述:</span>
<span class="value">{{ labelInfo.partDesc }}</span>
</div>
<div class="info-row">
<span class="label">批次号:</span>
<span class="value">{{ labelInfo.batchNo }}</span>
</div>
<div class="info-row">
<span class="label">库位:</span>
<span class="value">{{ labelInfo.locationId }}</span>
</div>
<div class="info-row">
<span class="label">可用数量:</span>
<span class="value">{{ labelInfo.availableQty }}</span>
</div>
</div>
<button @click="confirmDirectIssue" class="confirm-btn" :disabled="!issueQty">
确认发料
</button>
</div>
</div>
</div>
<!-- 发料数量 -->
<div class="qty-input" v-if="labelInfo">
<div class="input-group">
<label>发料数量</label>
<input
v-model="issueQty"
type="number"
:max="Math.min(selectedMaterial.remainQty, labelInfo.availableQty)"
placeholder="请输入发料数量"
/>
</div>
<!-- 拣选装托盘 -->
<div class="picking-pallet" v-if="selectedFunction === 'picking'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>拣选装托盘</h2>
</div>
<div class="input-group">
<label>备注</label>
<input v-model="directIssueForm.remark" placeholder="可选" />
</div>
<!-- 申请单输入 -->
<div class="input-section" v-if="!currentPallet.palletId">
<div class="input-group">
<label>申请单号</label>
<div class="input-with-scan">
<input
v-model="palletForm.notifyNo"
placeholder="请输入申请单号"
@keyup.enter="createPallet"
/>
<button @click="createPallet" class="scan-btn">创建托盘</button>
<button @click="confirmDirectIssue" class="confirm-btn" :disabled="!issueQty">
确认发料
</button>
</div>
</div>
</div>
</div>
<!-- 托盘信息 -->
<div class="pallet-info" v-if="currentPallet.palletId">
<div class="section-header">
<h3>托盘信息</h3>
</div>
<div class="info-card">
<div class="info-row">
<span class="label">托盘ID:</span>
<span class="value">{{ currentPallet.palletId }}</span>
</div>
<div class="info-row">
<span class="label">申请单号:</span>
<span class="value">{{ currentPallet.notifyNo }}</span>
<!-- 拣选装托盘 -->
<div class="picking-pallet" v-if="selectedFunction === 'picking'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>拣选装托盘</h2>
</div>
<div class="info-row">
<span class="label">已绑定单元:</span>
<span class="value">{{ currentPallet.unitCount || 0 }}</span>
</div>
</div>
<!-- 扫描绑定 -->
<div class="scan-bind-section">
<div class="input-group">
<label>扫描箱/</label>
<div class="input-with-scan">
<input
v-model="scannedUnit"
placeholder="请扫描处理单元条码"
@keyup.enter="bindUnit"
/>
<button @click="bindUnit" class="scan-btn">绑定</button>
<!-- 申请单输入 -->
<div class="input-section" v-if="!currentPallet.palletId">
<div class="input-group">
<label>申请单号</label>
<div class="input-with-scan">
<input
v-model="palletForm.notifyNo"
placeholder="请输入申请单号"
@keyup.enter="createPallet"
/>
<button @click="createPallet" class="scan-btn">创建托盘</button>
</div>
</div>
</div>
</div>
<!-- 已绑定单元列表 -->
<div class="bound-units" v-if="currentPallet.scannedUnits.length">
<div class="section-header">
<h4>已绑定单元 ({{ currentPallet.scannedUnits.length }})</h4>
</div>
<div class="unit-list">
<div v-for="unit in currentPallet.scannedUnits" :key="unit" class="unit-item">
{{ unit }}
<!-- 托盘信息 -->
<div class="pallet-info" v-if="currentPallet.palletId">
<div class="section-header">
<h3>托盘信息</h3>
</div>
</div>
</div>
<!-- 打印标签 -->
<div class="print-section">
<div class="input-group">
<label>打印机</label>
<select v-model="palletForm.printerName">
<option value="">请选择打印机</option>
<option value="PRINTER_01">打印机01</option>
<option value="PRINTER_02">打印机02</option>
</select>
</div>
<div class="info-card">
<div class="info-row">
<span class="label">托盘ID:</span>
<span class="value">{{ currentPallet.palletId }}</span>
</div>
<div class="info-row">
<span class="label">申请单号:</span>
<span class="value">{{ currentPallet.notifyNo }}</span>
</div>
<div class="info-row">
<span class="label">已绑定单元:</span>
<span class="value">{{ currentPallet.unitCount || 0 }}</span>
</div>
</div>
<button @click="printPalletLabel" class="print-btn" :disabled="!palletForm.printerName">
打印托盘标签
</button>
</div>
</div>
</div>
<!-- 扫描绑定 -->
<div class="scan-bind-section">
<div class="input-group">
<label>扫描箱/</label>
<div class="input-with-scan">
<input
v-model="scannedUnit"
placeholder="请扫描处理单元条码"
@keyup.enter="bindUnit"
/>
<button @click="bindUnit" class="scan-btn">绑定</button>
</div>
</div>
</div>
<!-- 申请单发料 -->
<div class="request-issue" v-if="selectedFunction === 'request'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>申请单发料</h2>
</div>
<!-- 已绑定单元列表 -->
<div class="bound-units" v-if="currentPallet.scannedUnits.length">
<div class="section-header">
<h4>已绑定单元 ({{ currentPallet.scannedUnits.length }})</h4>
</div>
<div class="unit-list">
<div v-for="unit in currentPallet.scannedUnits" :key="unit" class="unit-item">
{{ unit }}
</div>
</div>
</div>
<!-- 申请单输入 -->
<div class="input-section" v-if="!requestMaterials.length">
<div class="input-group">
<label>申请单号</label>
<div class="input-with-scan">
<input
v-model="requestIssueForm.notifyNo"
placeholder="请输入申请单号"
@keyup.enter="loadRequestMaterials"
/>
<button @click="loadRequestMaterials" class="scan-btn">确认</button>
<!-- 打印标签 -->
<div class="print-section">
<div class="input-group">
<label>打印机</label>
<select v-model="palletForm.printerName">
<option value="">请选择打印机</option>
<option value="PRINTER_01">打印机01</option>
<option value="PRINTER_02">打印机02</option>
</select>
</div>
<button @click="printPalletLabel" class="print-btn" :disabled="!palletForm.printerName">
打印托盘标签
</button>
</div>
</div>
</div>
</div>
<!-- 申请单物料列表 -->
<div class="materials-section" v-if="requestMaterials.length">
<div class="section-header">
<h3>申请单物料 ({{ requestIssueForm.notifyNo }})</h3>
<button @click="resetRequest" class="reset-btn">重新选择</button>
</div>
<!-- 申请单发料 -->
<div class="request-issue" v-if="selectedFunction === 'request'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>申请单发料</h2>
</div>
<div class="material-list">
<div
v-for="material in requestMaterials"
:key="`${material.partNo}-${material.itemNo}`"
class="material-item"
:class="{ selected: selectedRequestMaterial.itemNo === material.itemNo }"
@click="selectRequestMaterial(material)"
>
<div class="material-info">
<div class="part-no">{{ material.partNo }}</div>
<div class="part-desc">{{ material.partDesc }}</div>
<div class="work-order">工单: {{ material.workOrderNo }}</div>
<div class="qty-info">
申请: {{ material.requestQty }} |
已发: {{ material.issuedQty }} |
剩余: {{ material.remainQty }}
<!-- 申请单输入 -->
<div class="input-section" v-if="!requestMaterials.length">
<div class="input-group">
<label>申请单号</label>
<div class="input-with-scan">
<input
v-model="requestIssueForm.notifyNo"
placeholder="请输入申请单号"
@keyup.enter="loadRequestMaterials"
/>
<button @click="loadRequestMaterials" class="scan-btn">确认</button>
</div>
</div>
<div class="material-status">
<span v-if="material.remainQty > 0" class="status-pending">待发料</span>
<span v-else class="status-complete">已完成</span>
</div>
</div>
</div>
</div>
<!-- 扫描标签和发料 -->
<div class="scan-section" v-if="selectedRequestMaterial">
<div class="section-header">
<h3>扫描物料标签</h3>
</div>
<div class="input-group">
<label>物料标签</label>
<div class="input-with-scan">
<input
v-model="scannedLabel"
placeholder="请扫描物料标签"
@keyup.enter="parseMaterialLabel"
/>
<button @click="parseMaterialLabel" class="scan-btn">解析</button>
</div>
</div>
<!-- 申请单物料列表 -->
<div class="materials-section" v-if="requestMaterials.length">
<div class="section-header">
<h3>申请单物料 ({{ requestIssueForm.notifyNo }})</h3>
<button @click="resetRequest" class="reset-btn">重新选择</button>
</div>
<!-- 标签信息和发料确认 -->
<div class="label-info" v-if="labelInfo">
<div class="info-row">
<span class="label">物料编码:</span>
<span class="value">{{ labelInfo.partNo }}</span>
</div>
<div class="info-row">
<span class="label">批次号:</span>
<span class="value">{{ labelInfo.batchNo }}</span>
</div>
<div class="info-row">
<span class="label">可用数量:</span>
<span class="value">{{ labelInfo.availableQty }}</span>
<div class="material-list">
<div
v-for="material in requestMaterials"
:key="`${material.partNo}-${material.itemNo}`"
class="material-item"
:class="{ selected: selectedRequestMaterial.itemNo === material.itemNo }"
@click="selectRequestMaterial(material)"
>
<div class="material-info">
<div class="part-no">{{ material.partNo }}</div>
<div class="part-desc">{{ material.partDesc }}</div>
<div class="work-order">工单: {{ material.workOrderNo }}</div>
<div class="qty-info">
申请: {{ material.requestQty }} |
已发: {{ material.issuedQty }} |
剩余: {{ material.remainQty }}
</div>
</div>
<div class="material-status">
<span v-if="material.remainQty > 0" class="status-pending">待发料</span>
<span v-else class="status-complete">已完成</span>
</div>
</div>
</div>
</div>
<div class="qty-input">
<div class="input-group">
<label>发料数量</label>
<input
v-model="issueQty"
type="number"
:max="Math.min(selectedRequestMaterial.remainQty, labelInfo.availableQty)"
placeholder="请输入发料数量"
/>
<!-- 扫描标签和发料 -->
<div class="scan-section" v-if="selectedRequestMaterial">
<div class="section-header">
<h3>扫描物料标签</h3>
</div>
<div class="input-group">
<label>备注</label>
<input v-model="requestIssueForm.remark" placeholder="可选" />
<label>物料标签</label>
<div class="input-with-scan">
<input
v-model="scannedLabel"
placeholder="请扫描物料标签"
@keyup.enter="parseMaterialLabel"
/>
<button @click="parseMaterialLabel" class="scan-btn">解析</button>
</div>
</div>
<button @click="confirmRequestIssue" class="confirm-btn" :disabled="!issueQty">
确认发料 (同步IFS)
</button>
<!-- 标签信息和发料确认 -->
<div class="label-info" v-if="labelInfo">
<div class="info-row">
<span class="label">物料编码:</span>
<span class="value">{{ labelInfo.partNo }}</span>
</div>
<div class="info-row">
<span class="label">批次号:</span>
<span class="value">{{ labelInfo.batchNo }}</span>
</div>
<div class="info-row">
<span class="label">可用数量:</span>
<span class="value">{{ labelInfo.availableQty }}</span>
</div>
<div class="qty-input">
<div class="input-group">
<label>发料数量</label>
<input
v-model="issueQty"
type="number"
:max="Math.min(selectedRequestMaterial.remainQty, labelInfo.availableQty)"
placeholder="请输入发料数量"
/>
</div>
<div class="input-group">
<label>备注</label>
<input v-model="requestIssueForm.remark" placeholder="可选" />
</div>
<button @click="confirmRequestIssue" class="confirm-btn" :disabled="!issueQty">
确认发料 (同步IFS)
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 加载提示 -->
<div class="loading" v-if="loading">
<div class="loading-spinner"></div>
<div class="loading-text">{{ loadingText }}</div>
</div>
<!-- 加载提示 -->
<div class="loading" v-if="loading">
<div class="loading-spinner"></div>
<div class="loading-text">{{ loadingText }}</div>
</div>
<!-- 消息提示 -->
<div class="message" v-if="message" :class="messageType">
{{ message }}
<!-- 消息提示 -->
<div class="message" v-if="message" :class="messageType">
{{ message }}
</div>
</div>
</div>
</div>
</template>

613
src/views/modules/production-issue/productionReturnPDA.vue

@ -1,359 +1,366 @@
<template>
<div class="production-return-pda">
<van-nav-bar title="生产订单退料" left-arrow @click-left="$router.back()" />
<!-- 功能选择 -->
<div class="function-selector" v-if="!selectedFunction">
<div class="function-card" @click="selectFunction('direct')">
<div class="function-icon">📦</div>
<div class="function-title">直接退料</div>
<div class="function-desc">输入工单号选择材料行扫描物料标签直接退料</div>
<div>
<div class="pda-container">
<div class="status-bar">
<div class="goBack" @click="$router.back()"><i class="el-icon-arrow-left"></i>上一页</div>
<div class="goBack">生产订单退料</div>
<div class="network" style="color: #fff" @click="$router.push({ path: '/' })">🏠首页</div>
</div>
<div class="function-card" @click="selectFunction('request')">
<div class="function-icon">📋</div>
<div class="function-title">基于申请单退料</div>
<div class="function-desc">选择退料申请单选择发料记录录入退料数量</div>
</div>
</div>
<!-- 直接退料 -->
<div class="direct-return" v-if="selectedFunction === 'direct'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>直接退料</h2>
</div>
<!-- 工单输入 -->
<div class="input-section" v-if="!workOrderMaterials.length">
<div class="input-group">
<label>工单号</label>
<div class="input-with-scan">
<input
v-model="directReturnForm.workOrderNo"
placeholder="请输入或扫描工单号"
@keyup.enter="loadWorkOrderMaterials"
/>
<button @click="loadWorkOrderMaterials" class="scan-btn">确认</button>
<div style="overflow-y: auto">
<!-- 功能选择 -->
<div class="function-selector" v-if="!selectedFunction">
<div class="function-card" @click="selectFunction('direct')">
<div class="function-icon">📦</div>
<div class="function-title">直接退料</div>
<div class="function-desc">输入工单号选择材料行扫描物料标签直接退料</div>
</div>
</div>
</div>
<!-- 物料列表 -->
<div class="materials-section" v-if="workOrderMaterials.length">
<div class="section-header">
<h3>工单物料 ({{ directReturnForm.workOrderNo }})</h3>
<button @click="resetWorkOrder" class="reset-btn">重新选择</button>
</div>
<div class="material-list">
<div v-for="(material, index) in workOrderMaterials" :key="index"
class="material-item"
:class="{ selected: selectedMaterial && selectedMaterial.partNo === material.partNo }"
@click="selectMaterial(material)"
>
<div class="material-info">
<div class="part-no">{{ material.partNo }}</div>
<div class="part-desc">{{ material.partDesc }}</div>
<div class="qty-info">
已发: {{ material.issuedQty }} |
可退: {{ material.returnableQty }} |
已退: {{ material.returnedQty }}
</div>
</div>
<div class="material-status">
<span v-if="material.returnableQty > 0" class="status-returnable">可退料</span>
<span v-else class="status-complete">无可退</span>
</div>
<div class="function-card" @click="selectFunction('request')">
<div class="function-icon">📋</div>
<div class="function-title">基于申请单退料</div>
<div class="function-desc">选择退料申请单选择发料记录录入退料数量</div>
</div>
</div>
</div>
<!-- 扫描标签或输入数量 -->
<div class="scan-section" v-if="selectedMaterial">
<div class="section-header">
<h3>退料方式</h3>
</div>
<div class="return-method">
<div class="method-tabs">
<button
:class="['tab-btn', { active: returnMethod === 'scan' }]"
@click="returnMethod = 'scan'"
>
扫描标签
</button>
<button
:class="['tab-btn', { active: returnMethod === 'manual' }]"
@click="returnMethod = 'manual'"
>
手工输入
</button>
<!-- 直接退料 -->
<div class="direct-return" v-if="selectedFunction === 'direct'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>直接退料</h2>
</div>
<!-- 扫描标签方式 -->
<div v-if="returnMethod === 'scan'">
<!-- 工单输入 -->
<div class="input-section" v-if="!workOrderMaterials.length">
<div class="input-group">
<label>物料标签</label>
<label>工单号</label>
<div class="input-with-scan">
<input
v-model="scannedLabel"
placeholder="请扫描物料标签"
@keyup.enter="parseMaterialLabel"
v-model="directReturnForm.workOrderNo"
placeholder="请输入或扫描工单号"
@keyup.enter="loadWorkOrderMaterials"
/>
<button @click="parseMaterialLabel" class="scan-btn">解析</button>
<button @click="loadWorkOrderMaterials" class="scan-btn">确认</button>
</div>
</div>
</div>
<!-- 标签信息 -->
<div class="label-info" v-if="labelInfo">
<div class="info-row">
<span class="label">物料编码:</span>
<span class="value">{{ labelInfo.partNo }}</span>
</div>
<div class="info-row">
<span class="label">物料描述:</span>
<span class="value">{{ labelInfo.partDesc }}</span>
</div>
<div class="info-row">
<span class="label">批次号:</span>
<span class="value">{{ labelInfo.batchNo }}</span>
</div>
<div class="info-row">
<span class="label">当前数量:</span>
<span class="value">{{ labelInfo.currentQty }}</span>
</div>
<!-- 物料列表 -->
<div class="materials-section" v-if="workOrderMaterials.length">
<div class="section-header">
<h3>工单物料 ({{ directReturnForm.workOrderNo }})</h3>
<button @click="resetWorkOrder" class="reset-btn">重新选择</button>
</div>
</div>
<!-- 手工输入方式 -->
<div v-if="returnMethod === 'manual'">
<div class="input-group">
<label>批次号</label>
<input v-model="manualInput.batchNo" placeholder="请输入批次号" />
<div class="material-list">
<div v-for="(material, index) in workOrderMaterials" :key="index"
class="material-item"
:class="{ selected: selectedMaterial && selectedMaterial.partNo === material.partNo }"
@click="selectMaterial(material)"
>
<div class="material-info">
<div class="part-no">{{ material.partNo }}</div>
<div class="part-desc">{{ material.partDesc }}</div>
<div class="qty-info">
已发: {{ material.issuedQty }} |
可退: {{ material.returnableQty }} |
已退: {{ material.returnedQty }}
</div>
</div>
<div class="material-status">
<span v-if="material.returnableQty > 0" class="status-returnable">可退料</span>
<span v-else class="status-complete">无可退</span>
</div>
</div>
</div>
</div>
</div>
<!-- 退料数量和信息 -->
<div class="return-info" v-if="(returnMethod === 'scan' && labelInfo) || returnMethod === 'manual'">
<div class="input-group">
<label>退料数量</label>
<input
v-model="returnQty"
type="number"
:max="selectedMaterial.returnableQty"
placeholder="请输入退料数量"
/>
</div>
<!-- 扫描标签或输入数量 -->
<div class="scan-section" v-if="selectedMaterial">
<div class="section-header">
<h3>退料方式</h3>
</div>
<div class="input-group">
<label>退料原因</label>
<select v-model="directReturnForm.returnReason">
<option value="">请选择退料原因</option>
<option value="QUALITY_ISSUE">质量问题</option>
<option value="OVER_ISSUE">超发</option>
<option value="WRONG_MATERIAL">错误物料</option>
<option value="PRODUCTION_CHANGE">生产变更</option>
<option value="OTHER">其他</option>
</select>
</div>
<div class="return-method">
<div class="method-tabs">
<button
:class="['tab-btn', { active: returnMethod === 'scan' }]"
@click="returnMethod = 'scan'"
>
扫描标签
</button>
<button
:class="['tab-btn', { active: returnMethod === 'manual' }]"
@click="returnMethod = 'manual'"
>
手工输入
</button>
</div>
<div class="input-group">
<label>备注</label>
<input v-model="directReturnForm.remark" placeholder="可选" />
</div>
<!-- 扫描标签方式 -->
<div v-if="returnMethod === 'scan'">
<div class="input-group">
<label>物料标签</label>
<div class="input-with-scan">
<input
v-model="scannedLabel"
placeholder="请扫描物料标签"
@keyup.enter="parseMaterialLabel"
/>
<button @click="parseMaterialLabel" class="scan-btn">解析</button>
</div>
</div>
<!-- 标签信息 -->
<div class="label-info" v-if="labelInfo">
<div class="info-row">
<span class="label">物料编码:</span>
<span class="value">{{ labelInfo.partNo }}</span>
</div>
<div class="info-row">
<span class="label">物料描述:</span>
<span class="value">{{ labelInfo.partDesc }}</span>
</div>
<div class="info-row">
<span class="label">批次号:</span>
<span class="value">{{ labelInfo.batchNo }}</span>
</div>
<div class="info-row">
<span class="label">当前数量:</span>
<span class="value">{{ labelInfo.currentQty }}</span>
</div>
</div>
</div>
<!-- 打印标签选项 -->
<div class="print-options">
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" v-model="directReturnForm.createLabel" />
创建卷/箱记录并打印标签
</label>
<!-- 手工输入方式 -->
<div v-if="returnMethod === 'manual'">
<div class="input-group">
<label>批次号</label>
<input v-model="manualInput.batchNo" placeholder="请输入批次号" />
</div>
</div>
</div>
<div class="input-group" v-if="directReturnForm.createLabel">
<label>打印机</label>
<select v-model="directReturnForm.printerName">
<option value="">请选择打印机</option>
<option value="PRINTER_01">打印机01</option>
<option value="PRINTER_02">打印机02</option>
</select>
</div>
</div>
<!-- 退料数量和信息 -->
<div class="return-info" v-if="(returnMethod === 'scan' && labelInfo) || returnMethod === 'manual'">
<div class="input-group">
<label>退料数量</label>
<input
v-model="returnQty"
type="number"
:max="selectedMaterial.returnableQty"
placeholder="请输入退料数量"
/>
</div>
<button @click="confirmDirectReturn" class="confirm-btn" :disabled="!returnQty || !directReturnForm.returnReason">
确认退料 (同步IFS)
</button>
</div>
</div>
</div>
<div class="input-group">
<label>退料原因</label>
<select v-model="directReturnForm.returnReason">
<option value="">请选择退料原因</option>
<option value="QUALITY_ISSUE">质量问题</option>
<option value="OVER_ISSUE">超发</option>
<option value="WRONG_MATERIAL">错误物料</option>
<option value="PRODUCTION_CHANGE">生产变更</option>
<option value="OTHER">其他</option>
</select>
</div>
<!-- 基于申请单退料 -->
<div class="request-return" v-if="selectedFunction === 'request'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>基于申请单退料</h2>
</div>
<div class="input-group">
<label>备注</label>
<input v-model="directReturnForm.remark" placeholder="可选" />
</div>
<!-- 打印标签选项 -->
<div class="print-options">
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" v-model="directReturnForm.createLabel" />
创建卷/箱记录并打印标签
</label>
</div>
<div class="input-group" v-if="directReturnForm.createLabel">
<label>打印机</label>
<select v-model="directReturnForm.printerName">
<option value="">请选择打印机</option>
<option value="PRINTER_01">打印机01</option>
<option value="PRINTER_02">打印机02</option>
</select>
</div>
</div>
<!-- 申请单输入 -->
<div class="input-section" v-if="!returnRequestMaterials.length">
<div class="input-group">
<label>退料申请单号</label>
<div class="input-with-scan">
<input
v-model="requestReturnForm.requestNo"
placeholder="请输入退料申请单号"
@keyup.enter="loadReturnRequestMaterials"
/>
<button @click="loadReturnRequestMaterials" class="scan-btn">确认</button>
<button @click="confirmDirectReturn" class="confirm-btn" :disabled="!returnQty || !directReturnForm.returnReason">
确认退料 (同步IFS)
</button>
</div>
</div>
</div>
</div>
<!-- 申请单物料列表 -->
<div class="materials-section" v-if="returnRequestMaterials.length">
<div class="section-header">
<h3>申请单物料 ({{ requestReturnForm.requestNo }})</h3>
<button @click="resetRequest" class="reset-btn">重新选择</button>
</div>
<!-- 基于申请单退料 -->
<div class="request-return" v-if="selectedFunction === 'request'">
<div class="pda-header">
<button class="back-btn" @click="goBack"> 返回</button>
<h2>基于申请单退料</h2>
</div>
<div class="material-list">
<div
v-for="material in returnRequestMaterials"
:key="`${material.partNo}-${material.itemNo}`"
class="material-item"
:class="{ selected: selectedRequestMaterial && selectedRequestMaterial.itemNo === material.itemNo }"
@click="selectRequestMaterial(material)"
>
<div class="material-info">
<div class="part-no">{{ material.partNo }}</div>
<div class="part-desc">{{ material.partDesc }}</div>
<div class="work-order">工单: {{ material.workOrderNo }}</div>
<div class="qty-info">
申请: {{ material.requestQty }} |
已退: {{ material.returnedQty }} |
剩余: {{ material.remainQty }}
<!-- 申请单输入 -->
<div class="input-section" v-if="!returnRequestMaterials.length">
<div class="input-group">
<label>退料申请单号</label>
<div class="input-with-scan">
<input
v-model="requestReturnForm.requestNo"
placeholder="请输入退料申请单号"
@keyup.enter="loadReturnRequestMaterials"
/>
<button @click="loadReturnRequestMaterials" class="scan-btn">确认</button>
</div>
</div>
<div class="material-status">
<span v-if="material.remainQty > 0" class="status-pending">待退料</span>
<span v-else class="status-complete">已完成</span>
</div>
</div>
</div>
</div>
<!-- 选择发料记录 -->
<div class="issue-records-section" v-if="selectedRequestMaterial">
<div class="section-header">
<h3>发料记录</h3>
</div>
<div class="issue-records">
<div
v-for="record in issueRecords"
:key="record.issueId"
class="issue-record-item"
:class="{ selected: selectedIssueRecord && selectedIssueRecord.issueId === record.issueId }"
@click="selectIssueRecord(record)"
>
<div class="record-info">
<div class="issue-id">发料ID: {{ record.issueId }}</div>
<div class="issue-date">发料日期: {{ record.issueDate }}</div>
<div class="batch-info">批次: {{ record.batchNo }} | 数量: {{ record.issueQty }}</div>
<div class="return-info">可退: {{ record.returnableQty }}</div>
<!-- 申请单物料列表 -->
<div class="materials-section" v-if="returnRequestMaterials.length">
<div class="section-header">
<h3>申请单物料 ({{ requestReturnForm.requestNo }})</h3>
<button @click="resetRequest" class="reset-btn">重新选择</button>
</div>
<div class="record-status">
<span v-if="record.returnableQty > 0" class="status-returnable">可退料</span>
<span v-else class="status-complete">已退完</span>
<div class="material-list">
<div
v-for="material in returnRequestMaterials"
:key="`${material.partNo}-${material.itemNo}`"
class="material-item"
:class="{ selected: selectedRequestMaterial && selectedRequestMaterial.itemNo === material.itemNo }"
@click="selectRequestMaterial(material)"
>
<div class="material-info">
<div class="part-no">{{ material.partNo }}</div>
<div class="part-desc">{{ material.partDesc }}</div>
<div class="work-order">工单: {{ material.workOrderNo }}</div>
<div class="qty-info">
申请: {{ material.requestQty }} |
已退: {{ material.returnedQty }} |
剩余: {{ material.remainQty }}
</div>
</div>
<div class="material-status">
<span v-if="material.remainQty > 0" class="status-pending">待退料</span>
<span v-else class="status-complete">已完成</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 退料信息录入 -->
<div class="return-input-section" v-if="selectedIssueRecord">
<div class="section-header">
<h3>退料信息</h3>
</div>
<div class="return-details">
<div class="input-group">
<label>退料数量</label>
<input
v-model="returnQty"
type="number"
:max="selectedIssueRecord.returnableQty"
placeholder="请输入退料数量"
/>
</div>
<!-- 选择发料记录 -->
<div class="issue-records-section" v-if="selectedRequestMaterial">
<div class="section-header">
<h3>发料记录</h3>
</div>
<div class="input-group">
<label>退料原因</label>
<select v-model="requestReturnForm.returnReason">
<option value="">请选择退料原因</option>
<option value="QUALITY_ISSUE">质量问题</option>
<option value="OVER_ISSUE">超发</option>
<option value="WRONG_MATERIAL">错误物料</option>
<option value="PRODUCTION_CHANGE">生产变更</option>
<option value="OTHER">其他</option>
</select>
<div class="issue-records">
<div
v-for="record in issueRecords"
:key="record.issueId"
class="issue-record-item"
:class="{ selected: selectedIssueRecord && selectedIssueRecord.issueId === record.issueId }"
@click="selectIssueRecord(record)"
>
<div class="record-info">
<div class="issue-id">发料ID: {{ record.issueId }}</div>
<div class="issue-date">发料日期: {{ record.issueDate }}</div>
<div class="batch-info">批次: {{ record.batchNo }} | 数量: {{ record.issueQty }}</div>
<div class="return-info">可退: {{ record.returnableQty }}</div>
</div>
<div class="record-status">
<span v-if="record.returnableQty > 0" class="status-returnable">可退料</span>
<span v-else class="status-complete">已退完</span>
</div>
</div>
</div>
</div>
<div class="input-group">
<label>目标库位</label>
<div class="input-with-scan">
<input
v-model="requestReturnForm.targetLocation"
placeholder="请输入或扫描目标库位"
/>
<button @click="validateLocation" class="scan-btn">验证</button>
<!-- 退料信息录入 -->
<div class="return-input-section" v-if="selectedIssueRecord">
<div class="section-header">
<h3>退料信息</h3>
</div>
</div>
<div class="input-group">
<label>备注</label>
<input v-model="requestReturnForm.remark" placeholder="可选" />
</div>
<div class="return-details">
<div class="input-group">
<label>退料数量</label>
<input
v-model="returnQty"
type="number"
:max="selectedIssueRecord.returnableQty"
placeholder="请输入退料数量"
/>
</div>
<!-- 打印标签选项 -->
<div class="print-options">
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" v-model="requestReturnForm.createLabel" />
创建箱/卷记录并打印纸质标签
</label>
</div>
<div class="input-group">
<label>退料原因</label>
<select v-model="requestReturnForm.returnReason">
<option value="">请选择退料原因</option>
<option value="QUALITY_ISSUE">质量问题</option>
<option value="OVER_ISSUE">超发</option>
<option value="WRONG_MATERIAL">错误物料</option>
<option value="PRODUCTION_CHANGE">生产变更</option>
<option value="OTHER">其他</option>
</select>
</div>
<div class="input-group">
<label>目标库位</label>
<div class="input-with-scan">
<input
v-model="requestReturnForm.targetLocation"
placeholder="请输入或扫描目标库位"
/>
<button @click="validateLocation" class="scan-btn">验证</button>
</div>
</div>
<div class="input-group" v-if="requestReturnForm.createLabel">
<label>打印机</label>
<select v-model="requestReturnForm.printerName">
<option value="">请选择打印机</option>
<option value="PRINTER_01">打印机01</option>
<option value="PRINTER_02">打印机02</option>
</select>
<div class="input-group">
<label>备注</label>
<input v-model="requestReturnForm.remark" placeholder="可选" />
</div>
<!-- 打印标签选项 -->
<div class="print-options">
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" v-model="requestReturnForm.createLabel" />
创建箱/卷记录并打印纸质标签
</label>
</div>
<div class="input-group" v-if="requestReturnForm.createLabel">
<label>打印机</label>
<select v-model="requestReturnForm.printerName">
<option value="">请选择打印机</option>
<option value="PRINTER_01">打印机01</option>
<option value="PRINTER_02">打印机02</option>
</select>
</div>
</div>
<button @click="confirmRequestReturn" class="confirm-btn"
:disabled="!returnQty || !requestReturnForm.returnReason || !requestReturnForm.targetLocation">
确认退料并入库 (同步IFS)
</button>
</div>
</div>
<button @click="confirmRequestReturn" class="confirm-btn"
:disabled="!returnQty || !requestReturnForm.returnReason || !requestReturnForm.targetLocation">
确认退料并入库 (同步IFS)
</button>
</div>
</div>
</div>
<!-- 加载提示 -->
<div class="loading" v-if="loading">
<div class="loading-spinner"></div>
<div class="loading-text">{{ loadingText }}</div>
</div>
<!-- 加载提示 -->
<div class="loading" v-if="loading">
<div class="loading-spinner"></div>
<div class="loading-text">{{ loadingText }}</div>
</div>
<!-- 消息提示 -->
<div class="message" v-if="message" :class="messageType">
{{ message }}
<!-- 消息提示 -->
<div class="message" v-if="message" :class="messageType">
{{ message }}
</div>
</div>
</div>
</div>
</template>

Loading…
Cancel
Save