Browse Source

申请单退料

master
shenzhouyu 4 months ago
parent
commit
d3ed238f86
  1. 6
      src/api/production/production-return.js
  2. 2
      src/router/index.js
  3. 1362
      src/views/modules/production-return/productionReturnPDA.vue
  4. 1908
      src/views/modules/production-return/productionReturnPDAIssueList.vue
  5. 156
      src/views/modules/production-return/productionReturnPDAList.vue
  6. 40
      src/views/modules/production-return/productionReturnPicking.vue

6
src/api/production/production-return.js

@ -1,6 +1,6 @@
import { createAPI } from "@/utils/httpRequest.js"; import { createAPI } from "@/utils/httpRequest.js";
//直接退料接口
// 获取工单信息 // 获取工单信息
export const getReturnWorkOrderInfo = data => createAPI(`/pda/production/return/getReturnWorkOrderInfo`,'post',data) export const getReturnWorkOrderInfo = data => createAPI(`/pda/production/return/getReturnWorkOrderInfo`,'post',data)
@ -17,3 +17,7 @@ export const createReturnLabel = data => createAPI(`/pda/production/issue/creat
export const printReturnLabel = data => createAPI(`/pda/production/issue/printReturnLabel`,'post',data) export const printReturnLabel = data => createAPI(`/pda/production/issue/printReturnLabel`,'post',data)
//申请单退料接口
export const getUnissueNotifyHeaderInfo = data => createAPI(`/pda/production/return/getUnissueNotifyHeaderInfo`,'post',data)
export const getUnissueNotifyHeaderOrderMaterialList = data => createAPI(`/pda/production/return/getUnissueNotifyHeaderOrderMaterialList`,'post',data)
export const getUnissueMatericalForShopOrder = data => createAPI(`/pda/production/return/getUnissueMatericalForShopOrder`,'post',data)

2
src/router/index.js

@ -54,6 +54,8 @@ const globalRoutes = [
{path: "/productionReturnIssueList", name: "productionReturnIssueList", component: resolve => require(["@/views/modules/production-return/productionReturnIssueList.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } }, {path: "/productionReturnIssueList", name: "productionReturnIssueList", component: resolve => require(["@/views/modules/production-return/productionReturnIssueList.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{path: "/productionReturnPickingDetail/:orderNo/:orderType/:partNo/:transactionId/:quantity/:batchNo", name: "productionReturnPickingDetail", component: resolve => require(["@/views/modules/production-return/productionReturnPickingDetail.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } }, {path: "/productionReturnPickingDetail/:orderNo/:orderType/:partNo/:transactionId/:quantity/:batchNo", name: "productionReturnPickingDetail", component: resolve => require(["@/views/modules/production-return/productionReturnPickingDetail.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{path: "/productionReturnPDA", name: "productionReturnPDA", component: resolve => require(["@/views/modules/production-return/productionReturnPDA.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } }, {path: "/productionReturnPDA", name: "productionReturnPDA", component: resolve => require(["@/views/modules/production-return/productionReturnPDA.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{path: "/productionReturnPDAList/:workOrderNo/:partNo/:unissureQty", name: "productionReturnPDAList", component: resolve => require(["@/views/modules/production-return/productionReturnPDAList.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{path: "/productionReturnPDAIssueList/:notifyNo/:itemNo/:workOrderNo", name: "productionReturnPDAIssueList", component: resolve => require(["@/views/modules/production-return/productionReturnPDAIssueList.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{path: '/production-return/pick/:orderNo', {path: '/production-return/pick/:orderNo',
name: 'ProductionIssuePick',component: resolve => require(["@/views/modules/production-return/pick.vue"], resolve), name: 'ProductionIssuePick',component: resolve => require(["@/views/modules/production-return/pick.vue"], resolve),
meta: { transition: 'instant' ,preload: true,keepAlive: true}}, meta: { transition: 'instant' ,preload: true,keepAlive: true}},

1362
src/views/modules/production-return/productionReturnPDA.vue
File diff suppressed because it is too large
View File

1908
src/views/modules/production-return/productionReturnPDAIssueList.vue
File diff suppressed because it is too large
View File

156
src/views/modules/production-return/productionReturnPDAList.vue

@ -0,0 +1,156 @@
<template>
<div class="pda-container">
<!-- 头部栏 -->
<div class="header-bar">
<div class="header-left" @click="$router.back()">
<i class="el-icon-arrow-left"></i>
<span>退仓 - 领料记录</span>
</div>
<div class="header-right" @click="$router.push({ path: '/' })">首页</div>
</div>
<div class="search-container">
<div class="card-title">
<label class="title-label">工单号:{{ workOrderNo }}</label>
</div>
<div class="card-title">
<label class="title-label">物料编码:{{ partNo }}</label>
</div>
<div class="card-title">
<label class="title-label">退料数量:{{ unissureQty }}</label>
</div>
</div>
<div class="content-area">
<div class="work-order-list" v-if="issueList.length > 0">
<div
v-for="(item, index) in issueList"
:key="index"
class="material-card"
@click="goDetail(item)"
>
<div class="card-title">
<span class="title-label">
物料编码{{ partNo }} &nbsp;&nbsp; 领料号{{ item.TRANSACTION_ID }}
</span>
</div>
<div class="part-desc-row">
<span class="desc-text">批次号{{ item.LOT_BATCH_NO || '-' }}</span>
</div>
<div class="card-details">
<div class="detail-item">
<div class="detail-label">领料数量</div>
<div class="detail-value">{{ item.QUANTITY }}</div>
</div>
<div class="detail-item">
<div class="detail-label">撤销数量</div>
<div class="detail-value">{{ item.QTY_REVERSED || 0 }}</div>
</div>
<div class="detail-item">
<div class="detail-label">单位</div>
<div class="detail-value">{{ item.uom || '个' }}</div>
</div>
</div>
</div>
</div>
<div v-if="!loading && issueList.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>
</div>
</template>
<script>
import { getUnissueMatericalForShopOrder } from '@/api/production/production-return';
export default {
data() {
return {
workOrderNo: '',
partNo: '',
loading: false,
issueList: [],
unissureQty: 0,
};
},
methods: {
loadIssueList() {
if (!this.workOrderNo || !this.partNo) {
return;
}
this.loading = true;
const params = {
workOrderNo: this.workOrderNo,
site: this.$store.state.user.site,
partNo: this.partNo,
};
getUnissueMatericalForShopOrder(params)
.then(({ data }) => {
this.loading = false;
if (data && data.code === 0) {
this.issueList = data.issueForShopOrder || [];
} else {
this.$message.error(data.msg || '获取领料记录失败');
this.issueList = [];
}
})
.catch(() => {
this.loading = false;
this.$message.error('获取领料记录失败');
});
},
goDetail(item) {
this.$router.push({
name: 'productionReturnPDAIssueList',
params: {
orderNo: this.workOrderNo,
orderType: 'workOrder',
partNo: this.partNo,
transactionId: item.TRANSACTION_ID,
quantity: item.QUANTITY,
batchNo: item.LOT_BATCH_NO,
},
});
},
},
mounted() {
this.workOrderNo = this.$route.params.workOrderNo;
this.partNo = this.$route.params.partNo;
this.unissureQty = this.$route.params.unissureQty;
this.loadIssueList();
},
};
</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; }
.content-area { flex: 1; overflow-y: auto; padding: 12px 16px; }
.work-order-list { 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:active { transform: translateY(0); }
.card-title { margin-bottom: 12px; }
.title-label { font-size: 12px; color: #666; display: block; margin-bottom: 4px; }
.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; }
.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; }
.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); } }
</style>

40
src/views/modules/production-return/productionReturnPicking.vue

@ -6,9 +6,7 @@
<i class="el-icon-arrow-left"></i> <i class="el-icon-arrow-left"></i>
<span>生产退仓</span> <span>生产退仓</span>
</div> </div>
<div class="header-right" @click="$router.push({ path: '/' })">
首页
</div>
<div class="header-right" @click="$router.push({ path: '/' })">首页</div>
</div> </div>
<!-- 工单号输入 --> <!-- 工单号输入 -->
@ -33,7 +31,6 @@
> >
<div class="card-title"> <div class="card-title">
<span class="title-label">工单号{{ workOrder.orderNo }}</span> <span class="title-label">工单号{{ workOrder.orderNo }}</span>
</div> </div>
<div class="part-desc-row"> <div class="part-desc-row">
<span class="title-value">{{ workOrder.partNo }}</span> <span class="title-value">{{ workOrder.partNo }}</span>
@ -120,9 +117,12 @@
</template> </template>
<script> <script>
import { getWorkOrderMaterials } from '@/api/production/production-issue';
import { getReturnWorkOrderInfo,getIssueForShopOrder } from '@/api/production/production-return';
import moment from 'moment';
import { getWorkOrderMaterials } from "@/api/production/production-issue";
import {
getReturnWorkOrderInfo,
getIssueForShopOrder,
} from "@/api/production/production-return";
import moment from "moment";
export default { export default {
data() { data() {
@ -137,7 +137,7 @@ export default {
}, },
methods: { methods: {
formatDate(date) { formatDate(date) {
return date ? moment(date).format('YYYY-MM-DD') : '';
return date ? moment(date).format("YYYY-MM-DD") : "";
}, },
// //
handleSearchWorkOrder() { handleSearchWorkOrder() {
@ -152,7 +152,8 @@ export default {
site: this.$store.state.user.site, site: this.$store.state.user.site,
}; };
getReturnWorkOrderInfo(params).then(({ data }) => {
getReturnWorkOrderInfo(params)
.then(({ data }) => {
this.loading = false; this.loading = false;
console.log("工单信息", data); console.log("工单信息", data);
@ -204,27 +205,26 @@ export default {
id: index + 1, id: index + 1,
})); }));
} else { } else {
this.$message.error(data.msg || '获取材料清单失败');
this.$message.error(data.msg || "获取材料清单失败");
this.materialList = []; this.materialList = [];
} }
}) })
.catch((error) => { .catch((error) => {
console.error('获取材料清单失败:', error);
this.$message.error('获取材料清单失败');
console.error("获取材料清单失败:", error);
this.$message.error("获取材料清单失败");
}); });
}, },
// //
openIssueList(material) { openIssueList(material) {
this.$router.push({ this.$router.push({
name: 'productionReturnIssueList',
name: "productionReturnIssueList",
params: { params: {
workOrderNo: this.selectedWorkOrder.orderNo, workOrderNo: this.selectedWorkOrder.orderNo,
partNo: material.componentPartNo, partNo: material.componentPartNo,
}, },
}); });
}, },
}, },
mounted() { mounted() {
@ -253,7 +253,7 @@ export default {
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 8px 16px; padding: 8px 16px;
background: #17B3A3;
background: #17b3a3;
color: white; color: white;
height: 40px; height: 40px;
min-height: 40px; min-height: 40px;
@ -445,7 +445,7 @@ export default {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 60px 20px; padding: 60px 20px;
color: #17B3A3;
color: #17b3a3;
} }
.loading-state i { .loading-state i {
@ -455,8 +455,12 @@ export default {
} }
@keyframes spin { @keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
} }
.loading-state p { .loading-state p {

Loading…
Cancel
Save