Browse Source

修改委外和生产发料

master
shenzhouyu 6 months ago
parent
commit
7eb76f0e5d
  1. 2
      src/router/index.js
  2. 350
      src/views/modules/outsourcing-issue/DirectIssue.vue
  3. 50
      src/views/modules/outsourcing-issue/MoveIssue.vue
  4. 70
      src/views/modules/outsourcing-issue/PickingIssue.vue
  5. 58
      src/views/modules/outsourcing-issue/ReturnIssue.vue
  6. 345
      src/views/modules/outsourcing-issue/index.vue
  7. 36
      src/views/modules/production-issue/productionIssuePda.vue

2
src/router/index.js

@ -34,7 +34,7 @@ const globalRoutes = [
// handlingunit
{path: "/handlingunit",name: "handlingunit", component: resolve => require(["@/views/modules/handling-unit/handling-unit-management.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
// 生产发料
{path: "/productionissue",name: "productionissue", component: resolve => require(["@/views/modules/production-issue/production-issue-pda.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
{path: "/productionissue",name: "productionissue", component: resolve => require(["@/views/modules/production-issue/productionIssuePda.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
//生产退料
{path: "/productionreturn",name: "productionreturn", component: resolve => require(["@/views/modules/production-issue/productionReturnPDA.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
{path: '/production-issue/pick/:orderNo',

350
src/views/modules/outsourcing-issue/DirectIssue.vue

@ -0,0 +1,350 @@
<template>
<div class="input-section">
<!-- PO号输入 -->
<div class="input-group" v-if="!materialList.length">
<div class="input-group">
<label>PO号</label>
<div class="input-with-scan">
<input v-model="poNo" placeholder="请输入或扫描PO号" @keyup.enter="loadMaterials" />
</div>
</div>
<div class="input-group">
<button @click="loadMaterials" class="scan-btn">确认</button>
</div>
</div>
<!-- 物料列表 -->
<div class="materials-section" v-if="materialList.length">
<div class="section-header">
<h3>PO物料 ({{ poNo }})</h3>
<button @click="resetPO" class="reset-btn">重新选择</button>
</div>
<div class="material-list">
<div v-for="(material, index) in materialList" :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.desc }}</div>
<div class="qty-info">
需求: {{ material.qty }} | 已发: {{ material.recvQty }} | 剩余: {{ material.thisRecvQty }}
</div>
</div>
<div class="material-status">
<span v-if="material.thisRecvQty > 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="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.batchNo }}</span></div>
<div class="info-row"><span class="label">可用数量:</span><span class="value">{{ labelInfo.availableQty }}</span>
</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.thisRecvQty, labelInfo.availableQty)"
placeholder="请输入发料数量" />
</div>
<div class="input-group">
<label>备注</label>
<input v-model="remark" placeholder="可选" />
</div>
<button @click="confirmIssue" class="confirm-btn" :disabled="!issueQty">确认发料</button>
</div>
</div>
<!-- 消息提示 -->
<div class="message" v-if="message" :class="messageType">{{ message }}</div>
</div>
</template>
<script>
import { getPoList } from '@/api/po/po.js'
export default {
name: 'DirectIssue',
data() {
return {
poNo: '',
materialList: [],
selectedMaterial: null,
scannedLabel: '',
labelInfo: null,
issueQty: null,
remark: '',
message: '',
messageType: 'info',
}
},
methods: {
async loadMaterials() {
if (!this.poNo) {
this.showMessage('请输入PO号', 'error')
return
}
// APIPO
try {
const { data } = await getPoList({
poNumber: this.poNo,
site: localStorage.getItem('site'),
})
if (data.code === 0 && data.rows && data.rows.length > 0) {
this.materialList = data.rows
} else {
this.showMessage(data.msg || '未找到PO物料', 'warning')
}
} catch (e) {
this.showMessage('网络错误', 'error')
}
},
selectMaterial(material) {
if (material.thisRecvQty <= 0) {
this.showMessage('该物料已发料完成', 'warning')
return
}
this.selectedMaterial = material
this.scannedLabel = ''
this.labelInfo = null
this.issueQty = null
},
resetPO() {
this.poNo = ''
this.materialList = []
this.selectedMaterial = null
this.scannedLabel = ''
this.labelInfo = null
this.issueQty = null
},
parseMaterialLabel() {
// TODO: APIlabelInfo
this.labelInfo = {
partNo: this.selectedMaterial.partNo,
batchNo: 'BATCH001',
availableQty: 100,
}
this.issueQty = null
this.showMessage('标签解析成功', 'success')
},
confirmIssue() {
if (!this.issueQty || this.issueQty <= 0) {
this.showMessage('请输入有效的发料数量', 'error')
return
}
// TODO: API
this.showMessage('发料成功', 'success')
//
this.loadMaterials()
this.selectedMaterial = null
this.scannedLabel = ''
this.labelInfo = null
this.issueQty = null
},
showMessage(text, type = 'info') {
this.message = text
this.messageType = type
setTimeout(() => {
this.message = ''
}, 2000)
},
},
}
</script>
<style scoped>
.input-section {
background: white;
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.reset-btn {
background: #17b3a3;
color: white;
border: none;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
}
.input-group {
margin-bottom: 15px;
}
.input-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #333;
}
.input-with-scan {
display: flex;
gap: 10px;
}
.input-with-scan input {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
.scan-btn,
.confirm-btn {
background: #17b3a3;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
white-space: nowrap;
}
.scan-btn:hover,
.confirm-btn:hover {
background: #13998c;
}
.confirm-btn:disabled {
background: #6c757d;
cursor: not-allowed;
}
.material-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.material-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px;
border: 1px solid #ddd;
border-radius: 6px;
cursor: pointer;
transition: all 0.3s;
}
.material-item.selected {
border-color: #007bff;
background-color: #e3f2fd;
}
.material-info {
flex: 1;
}
.part-no {
font-weight: bold;
font-size: 16px;
color: #333;
margin-bottom: 4px;
}
.part-desc {
color: #666;
font-size: 14px;
margin-bottom: 4px;
}
.qty-info {
font-size: 12px;
color: #666;
}
.material-status {
text-align: right;
}
.status-pending {
background: #ffc107;
color: #212529;
padding: 4px 8px;
border-radius: 12px;
font-size: 12px;
}
.status-complete {
background: #28a745;
color: white;
padding: 4px 8px;
border-radius: 12px;
font-size: 12px;
}
.label-info {
background: #f8f9fa;
border-radius: 6px;
padding: 15px;
margin-bottom: 15px;
}
.info-row {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
padding: 5px 0;
border-bottom: 1px solid #eee;
}
.info-row:last-child {
border-bottom: none;
margin-bottom: 0;
}
.info-row .label {
font-weight: bold;
color: #666;
}
.info-row .value {
color: #333;
}
.qty-input {
margin-top: 15px;
}
.qty-input input[type='number'] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
.message {
margin-top: 10px;
padding: 8px 12px;
border-radius: 4px;
font-weight: bold;
}
.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;
}
.confirm-btn {
width: 100%;
}
.scan-btn {
width: 100%;
}
</style>

50
src/views/modules/outsourcing-issue/MoveIssue.vue

@ -0,0 +1,50 @@
<template>
<div class="input-section">
<!-- 申请单/PO号输入 -->
<div class="input-group">
<label>申请单/PO号</label>
<div class="input-with-scan">
<input v-model="orderNo" placeholder="请输入申请单号或PO号" />
<button class="scan-btn">确认</button>
</div>
</div>
<!-- 选择库位 -->
<div class="input-group">
<label>目标库位</label>
<div class="input-with-scan">
<input v-model="location" placeholder="请输入目标库位" />
<button class="scan-btn">选择</button>
</div>
</div>
<!-- 生成移库记录 -->
<div class="input-group">
<button class="confirm-btn">生成移库记录</button>
</div>
</div>
</template>
<script>
export default {
name: 'MoveIssue',
data() {
return {
orderNo: '',
location: ''
}
}
}
</script>
<style scoped>
.input-section { background: white; border-radius: 8px; padding: 15px; margin-bottom: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
.section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #eee; }
.reset-btn { background: #17b3a3; color: white; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; }
.input-group { margin-bottom: 15px; }
.input-group label { display: block; margin-bottom: 5px; font-weight: bold; color: #333; }
.input-with-scan { display: flex; gap: 10px; }
.input-with-scan input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; }
.scan-btn, .confirm-btn { background: #17b3a3; color: white; border: none; padding: 10px 15px; border-radius: 4px; cursor: pointer; font-size: 14px; white-space: nowrap; }
.scan-btn:hover, .confirm-btn:hover { background: #13998c; }
.confirm-btn:disabled { background: #6c757d; cursor: not-allowed; }
.confirm-btn {
width: 100%;
}
</style>

70
src/views/modules/outsourcing-issue/PickingIssue.vue

@ -0,0 +1,70 @@
<template>
<div class="input-section">
<!-- 申请单号输入 -->
<div class="input-group">
<label>申请单号</label>
<div class="input-with-scan">
<input v-model="notifyNo" placeholder="请输入申请单号" />
<button class="scan-btn">创建托盘</button>
</div>
</div>
<!-- 扫描箱卷绑定 -->
<div class="input-group">
<label>扫描箱/</label>
<div class="input-with-scan">
<input v-model="scannedUnit" placeholder="请扫描处理单元条码" />
<button class="scan-btn">绑定</button>
</div>
</div>
<!-- 已绑定单元列表 -->
<div class="bound-units">
<div class="section-header">
<h4>已绑定单元 (0)</h4>
</div>
<div class="unit-list">
<!-- TODO: 列表渲染绑定单元 -->
</div>
</div>
<!-- 打印托盘标签 -->
<div class="print-section">
<div class="input-group">
<label>打印机</label>
<select>
<option value="">请选择打印机</option>
<option value="PRINTER_01">打印机01</option>
<option value="PRINTER_02">打印机02</option>
</select>
</div>
<button class="print-btn">打印托盘标签</button>
</div>
</div>
</template>
<script>
export default {
name: 'PickingIssue',
data() {
return {
notifyNo: '',
scannedUnit: ''
}
}
}
</script>
<style scoped>
.input-section { background: white; border-radius: 8px; padding: 15px; margin-bottom: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
.section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #eee; }
.reset-btn { background: #17b3a3; color: white; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; }
.input-group { margin-bottom: 15px; }
.input-group label { display: block; margin-bottom: 5px; font-weight: bold; color: #333; }
.input-with-scan { display: flex; gap: 10px; }
.input-with-scan input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; }
.scan-btn, .print-btn { background: #17b3a3; color: white; border: none; padding: 10px 15px; border-radius: 4px; cursor: pointer; font-size: 14px; white-space: nowrap; }
.scan-btn:hover, .print-btn:hover { background: #13998c; }
.print-btn:disabled { background: #6c757d; cursor: not-allowed; }
.bound-units { margin-top: 20px; }
.unit-list { display: flex; flex-direction: column; gap: 8px; max-height: 200px; overflow-y: auto; }
.unit-item { background: #e9ecef; padding: 10px; border-radius: 4px; font-family: monospace; font-size: 14px; }
.print-btn {
width: 100%;
}
</style>

58
src/views/modules/outsourcing-issue/ReturnIssue.vue

@ -0,0 +1,58 @@
<template>
<div class="input-section">
<!-- 退料类型选择 -->
<div class="input-group">
<label>退料类型</label>
<select v-model="returnType">
<option value="">请选择退料类型</option>
<option value="over">多发退料</option>
<option value="quality">质量退料</option>
<option value="other">其他退料</option>
</select>
</div>
<!-- 退料数量 -->
<div class="input-group">
<label>退料数量</label>
<input v-model="returnQty" type="number" placeholder="请输入退料数量" />
<!-- 生成退料记录 -->
</div>
<button class="scan-btn">生成退料记录</button>
</div>
</template>
<script>
export default {
name: 'ReturnIssue',
data() {
return {
returnType: '',
returnQty: ''
}
}
}
</script>
<style scoped>
.input-section { background: white; border-radius: 8px; padding: 15px; margin-bottom: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
.section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #eee; }
.reset-btn { background: #17b3a3; color: white; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; }
.input-group { margin-bottom: 15px; }
.input-group label { display: block; margin-bottom: 5px; font-weight: bold; color: #333; }
.input-group select, .input-group input { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; }
.scan-btn, .confirm-btn, .print-btn {
background: #17b3a3;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
white-space: nowrap;
width: 100%;
}
.scan-btn:hover, .confirm-btn:hover, .print-btn:hover {
background: #13998c;
}
.confirm-btn:disabled { background: #6c757d; cursor: not-allowed; }
</style>

345
src/views/modules/outsourcing-issue/index.vue

@ -1,280 +1,141 @@
<template>
<div class="outsourcing-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 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="pda-container">
<div class="status-bar">
<div class="goBack" @click="goBack"><i class="el-icon-arrow-left"></i>上一页</div>
<div class="goBack">{{ functionTitle }}</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">输入工单/PO号扫描物料标签直接发料</div>
</div>
<div class="order-info">
<div class="info-row">
<span class="label">供应商</span>
<span class="value">{{ item.supplier }}</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.outsourcingQuantity }}</span>
</div>
<div class="info-row">
<span class="label">交货日期</span>
<span class="value">{{ item.deliveryDate }}</span>
</div>
<div class="info-row">
<span class="label">联系人</span>
<span class="value">{{ item.contactPerson }}</span>
</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="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 class="function-card" @click="selectFunction('move')">
<div class="function-icon">🚚</div>
<div class="function-title">移库发料</div>
<div class="function-desc">输入申请单/PO号选择库位生成移库记录</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 v-if="selectedFunction === 'direct'">
<direct-issue @back="resetAll" />
</div>
<!-- 拣选装托盘骨架 -->
<div v-if="selectedFunction === 'picking'">
<picking-issue @back="resetAll" />
</div>
</van-list>
</van-pull-refresh>
<!-- 移库发料骨架 -->
<div v-if="selectedFunction === 'move'">
<move-issue @back="resetAll" />
</div>
<!-- 退料骨架 -->
<div v-if="selectedFunction === 'return'">
<return-issue @back="resetAll" />
</div>
</div>
</div>
</div>
</template>
<script>
import DirectIssue from './DirectIssue.vue'
import PickingIssue from './PickingIssue.vue'
import MoveIssue from './MoveIssue.vue'
import ReturnIssue from './ReturnIssue.vue'
export default {
name: 'OutsourcingIssue',
name: 'OutsourcingIssuePDA',
components: {
DirectIssue,
PickingIssue,
MoveIssue,
ReturnIssue
},
data() {
return {
searchValue: '',
activeTab: 'all',
refreshing: false,
loading: false,
finished: false,
orderList: [
{
id: 1,
orderNo: 'OS202401001',
supplier: '委外供应商A',
productName: '委外产品A',
outsourcingQuantity: 500,
deliveryDate: '2024-01-25',
contactPerson: '张经理',
totalMaterialQuantity: 1000,
issuedQuantity: 0,
status: 0
},
{
id: 2,
orderNo: 'OS202401002',
supplier: '委外供应商B',
productName: '委外产品B',
outsourcingQuantity: 300,
deliveryDate: '2024-01-22',
contactPerson: '李经理',
totalMaterialQuantity: 600,
issuedQuantity: 400,
status: 1
},
{
id: 3,
orderNo: 'OS202401003',
supplier: '委外供应商C',
productName: '委外产品C',
outsourcingQuantity: 200,
deliveryDate: '2024-01-18',
contactPerson: '王经理',
totalMaterialQuantity: 400,
issuedQuantity: 400,
status: 2
}
]
selectedFunction: null
}
},
mounted() {
this.loadData()
computed: {
functionTitle() {
if (!this.selectedFunction) return '委外发料';
if (this.selectedFunction === 'direct') return '直接发料';
if (this.selectedFunction === 'picking') return '拣选装托盘';
if (this.selectedFunction === 'move') return '移库发料';
if (this.selectedFunction === 'return') return '退料';
return '委外发料';
}
},
methods: {
loadData() {
this.loading = true
setTimeout(() => {
this.loading = false
this.finished = true
}, 1000)
},
onRefresh() {
this.refreshing = true
setTimeout(() => {
this.refreshing = false
this.$toast.success('刷新成功')
}, 1000)
selectFunction(func) {
this.selectedFunction = func
},
onLoad() {
this.loadData()
resetAll() {
this.selectedFunction = null
},
handleSearch() {
this.loadData()
},
handleClear() {
this.searchValue = ''
this.loadData()
},
handleTabChange() {
this.loadData()
},
handleOrderClick(item) {
if (item.status === 0 || item.status === 1) {
this.$router.push(`/outsourcing-issue/pick/${item.orderNo}`)
goBack() {
if (!this.selectedFunction) {
this.$router.push('/')
} else {
this.$toast('该订单已完成发料')
}
},
getStatusText(status) {
const statusMap = {
0: '待发料',
1: '部分发料',
2: '已完成'
}
return statusMap[status] || '未知'
},
getStatusClass(status) {
const classMap = {
0: 'status-pending',
1: 'status-partial',
2: 'status-completed'
this.selectedFunction = null
}
return classMap[status] || ''
}
}
}
</script>
<style scoped>
.outsourcing-issue-container {
.outsourcing-issue {
padding: 10px;
font-family: Arial, sans-serif;
background-color: #f5f5f5;
min-height: 100vh;
background-color: #f7f8fa;
}
.search-section {
padding: 10px 16px;
background: white;
}
.filter-section {
background: white;
border-bottom: 1px solid #ebedf0;
.function-selector {
display: flex;
flex-direction: column;
gap: 15px;
padding: 20px 0;
}
.order-item {
.function-card {
background: white;
margin: 10px 16px;
border-radius: 8px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.order-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.order-no {
font-size: 16px;
font-weight: bold;
color: #323233;
}
.order-status {
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
color: white;
padding: 20px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
cursor: pointer;
transition: all 0.3s;
text-align: center;
}
.status-pending {
background-color: #ff976a;
.function-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
.status-partial {
background-color: #1989fa;
.function-icon {
font-size: 48px;
margin-bottom: 10px;
}
.status-completed {
background-color: #07c160;
.function-title {
font-size: 18px;
font-weight: bold;
margin-bottom: 8px;
color: #333;
}
.order-info {
.function-desc {
font-size: 14px;
margin-bottom: 12px;
}
.info-row {
display: flex;
margin-bottom: 6px;
}
.info-row:last-child {
margin-bottom: 0;
}
.label {
color: #969799;
width: 80px;
flex-shrink: 0;
}
.value {
color: #323233;
flex: 1;
}
.progress-section {
margin-top: 12px;
}
.progress-text {
font-size: 12px;
color: #646566;
margin-top: 4px;
text-align: center;
color: #666;
}
</style>

36
src/views/modules/production-issue/production-issue-pda.vue → src/views/modules/production-issue/productionIssuePda.vue

@ -454,7 +454,7 @@ export default {
//
async loadWorkOrderMaterials() {
if (!this.directIssueForm.workOrderNo) {
this.showMessage('请输入工单号', 'error')
this.$message.error('请输入工单号', 'error')
return
}
@ -523,7 +523,7 @@ export default {
const response = await directIssue(issueData)
if (response.code === 0) {
if (response.data.code === 0) {
this.showMessage('发料成功', 'success')
//
await this.loadWorkOrderMaterials()
@ -533,7 +533,7 @@ export default {
this.labelInfo = null
this.issueQty = null
} else {
this.showMessage(response.msg, 'error')
this.showMessage(response.data.msg, 'error')
}
} catch (error) {
this.showMessage('发料失败', 'error')
@ -558,13 +558,13 @@ export default {
notifyNo: this.requestIssueForm.notifyNo
})
if (response.code === 0) {
this.requestMaterials = response.materials || []
if (response.data.code === 0) {
this.requestMaterials = response.data.materials || []
if (this.requestMaterials.length === 0) {
this.showMessage('该申请单没有物料需求', 'warning')
}
} else {
this.showMessage(response.msg, 'error')
this.showMessage(response.data.msg, 'error')
}
} catch (error) {
this.showMessage('加载申请单物料失败', 'error')
@ -616,7 +616,7 @@ export default {
const response = await requestIssue(issueData)
if (response.code === 0) {
if (response.data.code === 0) {
this.showMessage('发料成功,已同步到IFS', 'success')
//
await this.loadRequestMaterials()
@ -626,7 +626,7 @@ export default {
this.labelInfo = null
this.issueQty = null
} else {
this.showMessage(response.msg, 'error')
this.showMessage(response.data.msg, 'error')
}
} catch (error) {
this.showMessage('发料失败', 'error')
@ -651,16 +651,16 @@ export default {
palletType: 'PALLET'
})
if (response.code === 0) {
if (response.data.code === 0) {
this.currentPallet = {
palletId: response.palletId,
palletId: response.data.palletId,
notifyNo: this.palletForm.notifyNo,
scannedUnits: [],
unitCount: 0
}
this.showMessage('托盘创建成功: ' + response.palletId, 'success')
this.showMessage('托盘创建成功: ' + response.data.palletId, 'success')
} else {
this.showMessage(response.msg, 'error')
this.showMessage(response.data.msg, 'error')
}
} catch (error) {
this.showMessage('创建托盘失败', 'error')
@ -691,13 +691,13 @@ export default {
scannedUnits: [this.scannedUnit]
})
if (response.code === 0) {
if (response.data.code === 0) {
this.currentPallet.scannedUnits.push(this.scannedUnit)
this.currentPallet.unitCount = this.currentPallet.scannedUnits.length
this.showMessage('绑定成功', 'success')
this.scannedUnit = ''
} else {
this.showMessage(response.msg, 'error')
this.showMessage(response.data.msg, 'error')
}
} catch (error) {
this.showMessage('绑定失败', 'error')
@ -722,10 +722,10 @@ export default {
printerName: this.palletForm.printerName
})
if (response.code === 0) {
if (response.data.code === 0) {
this.showMessage('标签打印成功', 'success')
} else {
this.showMessage(response.msg, 'error')
this.showMessage(response.data.msg, 'error')
}
} catch (error) {
this.showMessage('打印失败', 'error')
@ -750,8 +750,8 @@ export default {
scannedLabel: this.scannedLabel
})
if (response.code === 0 && response.labelInfo) {
this.labelInfo = response.labelInfo
if (response.data.code === 0 && response.data.labelInfo) {
this.labelInfo = response.data.labelInfo
this.issueQty = null //
this.showMessage('标签解析成功', 'success')
} else {
Loading…
Cancel
Save