Browse Source

委外和MR修改

master
shenzhouyu 9 months ago
parent
commit
68976c8af6
  1. 8
      src/api/mr/mr.js
  2. 16
      src/api/outsourcing/outsourcing-return.js
  3. 7
      src/router/index.js
  4. 8
      src/views/modules/mr-issue/mrPicking.vue
  5. 4
      src/views/modules/mr-issue/mrPickingDetail.vue
  6. 5
      src/views/modules/mr-issue/mrPickingReturn.vue
  7. 9
      src/views/modules/mr-issue/mrReturnIssueList.vue
  8. 431
      src/views/modules/mr-issue/mrReturnPickingDetail.vue
  9. 6
      src/views/modules/outsourcing-issue/index.vue
  10. 399
      src/views/modules/outsourcing-return/index.vue
  11. 1444
      src/views/modules/outsourcing-return/outsourcingReturnPDAIssueList.vue
  12. 162
      src/views/modules/outsourcing-return/outsourcingReturnPDAList.vue

8
src/api/mr/mr.js

@ -16,4 +16,10 @@ export const getReturnMrInfo = data => createAPI(`/pda/mr/getReturnMrInfo`, 'pos
export const getMrMaterials = data => createAPI(`/pda/mr/getMrMaterials`, 'post', data)
export const getIssueForMaterialRequisition = data => createAPI(`/pda/mr/getIssueForMaterialRequisition`, 'post', data)
export const getIssueForMaterialRequisition = data => createAPI(`/pda/mr/getIssueForMaterialRequisition`, 'post', data)
export const scanMaterialLabelNotInStock = data => createAPI(`/pda/mr/scanMaterialLabelNotInStock`, 'post', data)
export const getInventoryPart = data => createAPI(`/pda/mr/getInventoryPart`, 'post', data)
export const confirmMrUnIssue = data => createAPI(`/pda/mr/confirmMrUnIssue`, 'post', data)

16
src/api/outsourcing/outsourcing-return.js

@ -0,0 +1,16 @@
import { createAPI } from "@/utils/httpRequest.js";
// 搜索委外订单(用于退料)
export const searchOutsourcingOrdersForReturn = data => createAPI(`/pda/outsourcing/return/searchOutsourcingOrdersForReturn`,'post',data)
// 获取委外订单发料记录
export const getUnissueMatericalForOutsourcingOrder = data => createAPI(`/pda/outsourcing/return/getUnissueMatericalForOutsourcingOrder`,'post',data)
// 获取委外订单物料详情
export const getInventoryPartForOutsourcing = data => createAPI(`/pda/outsourcing/return/getInventoryPartForOutsourcing`,'post',data)
// 扫描委外退料标签
export const scanMaterialLabelForOutsourcing = data => createAPI(`/pda/outsourcing/return/scanMaterialLabelForOutsourcing`,'post',data)
// 确认委外退料
export const outsourcingReturnUnissueConfirm = data => createAPI(`/pda/outsourcing/return/outsourcingReturnUnissueConfirm`,'post',data)

7
src/router/index.js

@ -76,6 +76,11 @@ const globalRoutes = [
{ path: "/outsourcingPicking", name: "outsourcingPicking", component: resolve => require(["@/views/modules/outsourcing-issue/outsourcingPicking.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{ path: "/outsourcingPickingDetail/:outsourcingNo", name: "outsourcingPickingDetail", component: resolve => require(["@/views/modules/outsourcing-issue/outsourcingPickingDetail.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
// 委外退料
{ path: "/outsourcingReturn", name: "outsourcingReturn", component: resolve => require(["@/views/modules/outsourcing-return/index.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{ path: "/outsourcingReturnPDAList/:outsourcingOrderNo/:partNo/:unissureQty/:itemNo", name: "outsourcingReturnPDAList", component: resolve => require(["@/views/modules/outsourcing-return/outsourcingReturnPDAList.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{ path: "/outsourcingReturnPDAIssueList/:outsourcingOrderNo/:material", name: "outsourcingReturnPDAIssueList", component: resolve => require(["@/views/modules/outsourcing-return/outsourcingReturnPDAIssueList.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
// 客户订单发货
{path: "/saleshipping",name: "saleshipping", component: resolve => require(["@/views/modules/sales-delivery/index.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
@ -99,7 +104,7 @@ const globalRoutes = [
// MR退料
{path: "/mrPickingReturn", name: "mrPickingReturn", component: resolve => require(["@/views/modules/mr-issue/mrPickingReturn.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{path: "/mrReturnIssueList", name: "mrReturnIssueList", component: resolve => require(["@/views/modules/mr-issue/mrReturnIssueList.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{path: "/mrReturnPickingDetail/:orderNo/:orderType/:partNo/:transactionId/:quantity/:batchNo", name: "mrReturnPickingDetail", component: resolve => require(["@/views/modules/mr-issue/mrReturnPickingDetail.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{path: "/mrReturnPickingDetail/:orderNo/:orderType/:partNo/:transactionId/:quantity/:batchNo/:issueInfo", name: "mrReturnPickingDetail", component: resolve => require(["@/views/modules/mr-issue/mrReturnPickingDetail.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
// 盘点
{path: "/stocktaking",name: "stocktaking", component: resolve => require(["@/views/modules/inventory/index.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},

8
src/views/modules/mr-issue/mrPicking.vue

@ -28,7 +28,7 @@
<!-- 物料描述单独一行 -->
<div class="part-desc-row">
<span class="desc-text">目的地:{{ item.intDestDesc }}</span>
<span class="desc-text">描述:{{ item.intDestDesc }}</span>
</div>
<div class="part-desc-row">
<span class="desc-text">状态:{{ item.statusCode }}</span>
@ -66,12 +66,12 @@
<div class="card-details">
<div class="detail-item">
<div class="detail-label">需求数量</div>
<div class="detail-label">已发数量</div>
<div class="detail-value">{{ material.qtyIssued }}</div>
</div>
<div class="detail-item">
<div class="detail-label">到期数量</div>
<div class="detail-value">{{ material.qtyDue || 0 }}</div>
<div class="detail-label">发料数量</div>
<div class="detail-value">{{ material.qtyDue }}</div>
</div>
<div class="detail-item">
<div class="detail-label">单位</div>

4
src/views/modules/mr-issue/mrPickingDetail.vue

@ -40,11 +40,11 @@
<div class="card-details">
<div class="detail-item">
<div class="detail-label">需求数量</div>
<div class="detail-label">已发数量</div>
<div class="detail-value">{{ mrInfo.qtyIssued }}</div>
</div>
<div class="detail-item">
<div class="detail-label">到期数量</div>
<div class="detail-label">发料数量</div>
<div class="detail-value">{{ mrInfo.qtyDue || 0 }}</div>
</div>
<div class="detail-item">

5
src/views/modules/mr-issue/mrPickingReturn.vue

@ -38,7 +38,7 @@
<!-- 物料描述单独一行 -->
<div class="part-desc-row">
<span class="desc-text">目的地:{{ mr.intDestDesc }}</span>
<span class="desc-text">描述:{{ mr.intDestDesc }}</span>
</div>
<div class="part-desc-row">
<span class="desc-text">状态:{{ mr.statusCode }}</span>
@ -87,7 +87,7 @@
<div class="card-details">
<div class="detail-item">
<div class="detail-label">退回数量</div>
<div class="detail-value">{{ material.qtyReturned }}</div>
<div class="detail-value">{{ material.qtyDue }}</div>
</div>
<div class="detail-item">
<div class="detail-label">已发数量</div>
@ -248,6 +248,7 @@ export default {
params: {
orderNo: this.selectedMr.orderNo,
partNo: material.partNo,
partDesc: material.partDesc
},
});
},

9
src/views/modules/mr-issue/mrReturnIssueList.vue

@ -63,6 +63,7 @@ export default {
return {
orderNo: '',
partNo: '',
partDesc:'',
loading: false,
issueList: [],
};
@ -76,7 +77,8 @@ export default {
}
this.loading = true;
const params = {
orderNo: '8715',
//orderNo: this.orderNo.trim(),
orderNo: '10520',
site: this.$store.state.user.site,
partNo: this.partNo,
};
@ -105,6 +107,10 @@ export default {
transactionId: item.TRANSACTION_ID,
quantity: item.QUANTITY,
batchNo: item.LOT_BATCH_NO,
issueInfo:{
accountingId: item.ACCOUNTING_ID,
partDesc: this.partDesc
}
},
});
},
@ -112,6 +118,7 @@ export default {
mounted() {
this.orderNo = this.$route.params.orderNo;
this.partNo = this.$route.params.partNo;
this.partDesc = this.$route.params.partDesc
this.loadIssueList();
},
};

431
src/views/modules/mr-issue/mrReturnPickingDetail.vue

@ -4,29 +4,17 @@
<div class="header-bar">
<div class="header-left" @click="$router.back()">
<i class="el-icon-arrow-left"></i>
<span>MR退料</span>
<span>生产退仓</span>
</div>
<div class="header-right" @click="$router.push({ path: '/' })">首页</div>
</div>
<!-- 搜索框 -->
<div class="search-container">
<el-input
clearable
class="compact-input"
v-model="scanCode"
placeholder="请扫描物料标签或批次号"
prefix-icon="el-icon-search"
@keyup.enter.native="handleScan"
ref="scanInput"
/>
<el-input clearable class="compact-input" v-model="scanCode" placeholder="请扫描物料标签或批次号"
prefix-icon="el-icon-search" @keyup.enter.native="handleScan" ref="scanInput" />
<div class="mode-switch">
<el-switch
class="custom-switch"
v-model="isRemoveMode"
active-color="#ff4949"
inactive-color="#13ce66"
>
<el-switch class="custom-switch" v-model="isRemoveMode" active-color="#ff4949" inactive-color="#13ce66">
</el-switch>
<span v-if="isRemoveMode" class="switch-text">{{ "移除" }}</span>
<span v-else class="switch-text2">{{ "添加" }}</span>
@ -34,21 +22,19 @@
</div>
<!-- 订单信息卡片 -->
<div class="work-order-list" v-if="orderInfo.orderNo">
<div class="work-order-list">
<div class="work-order-card">
<div class="card-title">
<span class="title-label"
>MR号{{ orderInfo.orderNo }}</span
>
<span class="title-label">{{
orderInfo.type === "workOrder" ? "工单号" : "退料申请单号"
}}{{ orderInfo.orderNo }}</span>
</div>
<!-- 关联信息单独一行 -->
<div class="part-desc-row">
<span class="desc-text"
>发料号{{
<span class="desc-text">{{ orderInfo.type === "workOrder" ? "关联单号" : "关联工单" }}{{
orderInfo.transactionId
}}</span
>
}}</span>
</div>
<div class="part-desc-row">
<span class="desc-text">{{ orderInfo.partNo }}</span>
@ -59,7 +45,7 @@
<div class="card-details">
<div class="detail-item">
<div class="detail-label">数量</div>
<div class="detail-label">退数量</div>
<div class="detail-value">{{ orderInfo.quantity }}</div>
</div>
<div class="detail-item">
@ -77,9 +63,7 @@
<span>退料信息确认</span>
</div>
<div class="title-right">
<span class="material-list-link" @click="showMaterialListDialog"
>物料清单</span
>
<span class="material-list-link" @click="showMaterialListDialog">物料清单</span>
</div>
</div>
@ -88,19 +72,13 @@
<div class="list-header">
<div class="col-no">NO.</div>
<div class="col-label">物料标签</div>
<div class="col-part">物料编码</div>
<div class="col-batch">批次号</div>
<div class="col-qty">退料数量</div>
</div>
<div
v-for="(label, index) in labelList"
:key="label.id"
class="list-item"
>
<div v-for="(label, index) in labelList" :key="label.id" class="list-item">
<div class="col-no">{{ labelList.length - index }}</div>
<div class="col-label">{{ label.labelCode }}</div>
<div class="col-part">{{ label.partNo }}</div>
<div class="col-batch">{{ label.batchNo }}</div>
<div class="col-qty">{{ label.quantity }}</div>
</div>
@ -112,7 +90,7 @@
</div>
<!-- 退料原因选择 -->
<div class="return-reason-section">
<!-- <div class="return-reason-section">
<div class="reason-title">退料原因</div>
<el-select
v-model="returnReason"
@ -125,24 +103,16 @@
<el-option label="生产变更" value="PRODUCTION_CHANGE"></el-option>
<el-option label="其他原因" value="OTHER"></el-option>
</el-select>
</div>
</div> -->
<!-- 底部操作按钮 -->
<div class="bottom-actions">
<button class="action-btn primary" @click="printLabels">打印</button>
<button
class="action-btn primary"
style="margin-left: 10px"
@click="confirmReturn"
>
<!-- <button class="action-btn primary" @click="printLabels">打印</button> -->
<button class="action-btn primary" style="margin-left: 10px" @click="confirmReturn">
确定退料
</button>
<button
class="action-btn secondary"
style="margin-left: 10px"
@click="cancelReturn"
>
<button class="action-btn secondary" style="margin-left: 10px" @click="cancelReturn">
取消
</button>
</div>
@ -172,11 +142,7 @@
</div>
<div class="table-body">
<div
v-for="(item, index) in materialList"
:key="index"
class="table-row"
>
<div v-for="(item, index) in materialList" :key="index" class="table-row">
<div class="col-no">{{ index + 1 }}</div>
<div class="col-material-code">
{{ item.materialCode || item.partNo }}
@ -210,21 +176,12 @@
<div class="form-row">
<div class="form-group">
<label class="form-label">物料编码</label>
<el-input
v-model="printData.materialCode1"
placeholder="请输入物料编码"
@input="handleMaterialCodeInput"
disabled
class="form-input"
/>
<el-input v-model="printData.materialCode1" placeholder="请输入物料编码" @input="handleMaterialCodeInput"
disabled class="form-input" />
</div>
<div class="form-group">
<label class="form-label">物料数量</label>
<el-input
v-model="printData.materialCode2"
placeholder="物料数量"
class="form-input"
/>
<el-input v-model="printData.materialCode2" placeholder="物料数量" class="form-input" />
</div>
<div class="add-btn">
<i class="el-icon-plus" @click="addWmsLabel"></i>
@ -235,13 +192,17 @@
<div class="form-row">
<div class="form-group">
<label class="form-label">物料名称</label>
<el-input v-model="printData.materialName" placeholder="物料名称自动带出" disabled
class="form-input disabled-input" />
</div>
<!-- <div class="form-group">
<label class="form-label">单位</label>
<el-input
v-model="printData.materialName"
placeholder="物料名称自动带出"
v-model="printData.unit"
disabled
class="form-input disabled-input"
/>
</div>
</div> -->
</div>
<!-- 入库信息确认标题 -->
@ -255,19 +216,13 @@
<div class="print-list-header">
<div class="print-col-no">NO.</div>
<div class="print-col-label">标签条码</div>
<div class="print-col-material">物料编码</div>
<div class="print-col-qty">标签数量</div>
</div>
<div class="print-list-body">
<div
v-for="(item, index) in printLabelList"
:key="index"
class="print-list-item"
>
<div v-for="(item, index) in printLabelList" :key="index" class="print-list-item">
<div class="print-col-no">{{ index+1 }}</div>
<div class="print-col-label">{{ item.labelCode }}</div>
<div class="print-col-material">{{ item.partNo }}</div>
<div class="print-col-qty">{{ item.quantity }}</div>
</div>
</div>
@ -289,187 +244,162 @@
</template>
<script>
import moment from "moment";
import {
// getWorkOrderMaterials,
// parseMaterialLabel,
// directReturn,
getInventoryPart,
scanMaterialLabelNotInStock,
} from '@/api/mr/mr'
import moment from 'moment'
export default {
data() {
return {
scanCode: "",
scanCode: '',
orderInfo: {},
labelList: [],
orderNo: "",
orderType: "",
orderNo: '',
orderType: '',
showMaterialDialog: false,
materialList: [],
materialListLoading: false,
isRemoveMode: false, //
returnReason: "",
returnReason: '',
showPrintDialog: false,
printData: {},
partNo:"", //
transactionId:"", //
quantity:"", // 退
batchNo:"", //
partNo: '', //
transactionId: '', //
accountingId: '',
quantity: '', // 退
batchNo: '', //
printLabelList: [],
};
partDesc:''
}
},
computed: {
totalScannedQty() {
return this.labelList.reduce(
(sum, l) => sum + (Number(l.quantity) || 0),
0
);
)
},
},
methods: {
formatDate(date) {
return date ? moment(date).format("YYYY-MM-DD") : "";
return date ? moment(date).format('YYYY-MM-DD') : ''
},
//
handleScan() {
if (!this.scanCode.trim()) {
return;
return
}
if (this.isRemoveMode) {
this.removeLabelByCode(this.scanCode.trim());
this.removeLabelByCode(this.scanCode.trim())
} else {
this.validateAndAddLabel(this.scanCode.trim());
this.validateAndAddLabel(this.scanCode.trim())
}
this.scanCode = "";
this.scanCode = ''
},
//
// 退
validateAndAddLabel(labelCode) {
console.log(this.partNo)
const params = {
labelCode: labelCode,
orderNo: this.orderNo,
orderType: this.orderType,
site: this.$store.state.user.site,
};
partNo: this.partNo,
}
// MR退
this.simulateReturnLabelScan(params)
.then((result) => {
if (result.success) {
scanMaterialLabelNotInStock(params)
.then(({ data }) => {
if (data.code == 0 && data) {
//
const exists = this.labelList.find(
(item) => item.labelCode === labelCode
);
)
if (exists) {
this.$message.warning("该标签已扫描,请勿重复扫描");
return;
this.$message.warning('该标签已扫描,请勿重复扫描')
return
}
//
this.labelList.push({
id: Date.now(),
labelCode: labelCode,
partNo: result.data.partNo,
quantity: result.data.quantity,
batchNo: result.data.batchNo,
returnReason: result.data.returnReason,
});
partNo: data.labelInfo.partNo,
quantity: data.labelInfo.availableQty,
batchNo: data.labelInfo.batchNo,
returnReason: data.labelInfo.returnReason,
})
this.$message.success("操作成功");
this.$message.success('操作成功')
} else {
this.$message.error(
result.message || "该标签不符合退料要求,请检查"
);
result.message || '该标签不符合退料要求,请检查'
)
}
})
.catch(() => {
this.$message.error("操作失败");
});
},
// MR退API
simulateReturnLabelScan() {
return new Promise((resolve) => {
setTimeout(() => {
//
resolve({
success: true,
data: {
partNo: "MAT" + Math.floor(Math.random() * 1000),
quantity: Math.floor(Math.random() * 50) + 1,
batchNo: "BATCH" + Math.floor(Math.random() * 100),
returnReason: "QUALITY_ISSUE",
},
});
}, 500);
});
this.$message.error('操作失败')
})
},
//
removeLabelByCode(labelCode) {
const index = this.labelList.findIndex(
(item) => item.labelCode === labelCode
);
)
if (index !== -1) {
this.labelList.splice(index, 1);
this.$message.success("操作成功");
this.labelList.splice(index, 1)
this.$message.success('操作成功')
} else {
this.$message.warning("未找到该标签");
this.$message.warning('未找到该标签')
}
},
// MR退
// 退
confirmReturn() {
if (this.labelList.length === 0) {
this.$message.warning("请先扫描退料标签");
return;
}
if (!this.returnReason) {
this.$message.warning("请选择退料原因");
return;
this.$message.warning('请先扫描退料标签')
return
}
const returnParams = {
site: this.orderInfo.site,
site: this.$store.state.user.site,
orderNo: this.orderNo,
orderType: this.orderType,
returnReason: this.returnReason,
labels: this.labelList.map((label) => ({
selectedMaterials: this.labelList.map((label) => ({
labelCode: label.labelCode,
quantity: label.quantity,
batchNo: label.batchNo,
partNo: label.partNo,
})),
};
}
// MR退API
this.simulateReturnConfirm(returnParams)
// 退API
confirmMrUnIssue(returnParams)
.then((result) => {
if (result.success) {
this.$message.success("MR退料成功");
this.$router.back();
this.$message.success('生产退料成功')
this.$router.back()
} else {
this.$message.error(result.message || "操作失败");
this.$message.error(result.message || '操作失败')
}
})
.catch(() => {
this.$message.error("操作失败");
});
},
// MR退API
simulateReturnConfirm() {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
success: true,
message: "MR退料成功",
});
}, 1000);
});
this.$message.error('操作失败')
})
},
//
printLabels() {
this.showPrintDialog = true;
this.initPrintData();
this.showPrintDialog = true
this.initPrintData()
},
//
@ -478,104 +408,104 @@ export default {
materialCode1: this.partNo,
materialCode2: 0,
materialName: this.orderInfo.description,
unit: "",
inboundQty: "",
};
this.printLabelList = [];
unit: '',
inboundQty: '',
}
this.printLabelList = []
},
//
closePrintDialog() {
this.showPrintDialog = false;
this.printData = {};
this.showPrintDialog = false
this.printData = {}
},
//
confirmPrint() {
if (!this.printData.materialCode1.trim()) {
this.$message.warning("请输入物料编码");
return;
this.$message.warning('请输入物料编码')
return
}
if (!this.printData.inboundQty || this.printData.inboundQty <= 0) {
this.$message.warning("请输入有效的入库数量");
return;
this.$message.warning('请输入有效的入库数量')
return
}
//
this.$message.success("打印成功");
this.closePrintDialog();
this.$message.success('打印成功')
this.closePrintDialog()
},
//
handleMaterialCodeInput() {
if (this.printData.materialCode1.trim()) {
//
this.printData.materialName = "物料名称自动带出";
this.printData.unit = "PCS";
this.printData.materialName = '物料名称自动带出'
this.printData.unit = 'PCS'
} else {
this.printData.materialName = "";
this.printData.unit = "";
this.printData.materialName = ''
this.printData.unit = ''
}
},
// 退
cancelReturn() {
if (this.labelList.length > 0) {
this.$confirm("取消后将清空已扫描的标签,确定取消吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "继续操作",
type: "warning",
this.$confirm('取消后将清空已扫描的标签,确定取消吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '继续操作',
type: 'warning',
})
.then(() => {
this.$router.back();
this.$router.back()
})
.catch(() => {
//
});
})
} else {
this.$router.back();
this.$router.back()
}
},
//
showMaterialListDialog() {
this.showMaterialDialog = true;
this.loadMaterialList();
this.showMaterialDialog = true
this.loadMaterialList()
},
//
loadMaterialList() {
console.log("加载退料物料清单", this.orderInfo, this.orderNo);
console.log('加载退料物料清单', this.orderInfo, this.orderNo)
if (!this.$store.state.user.site || !this.orderNo) {
this.$message.error("缺少必要参数,无法获取物料清单");
return;
this.$message.error('缺少必要参数,无法获取物料清单')
return
}
this.materialListLoading = true;
this.materialListLoading = true
const params = {
site: this.$store.state.user.site,
orderNo: this.orderNo,
orderType: this.orderType,
};
}
//
this.simulateMaterialList(params)
.then((data) => {
this.materialListLoading = false;
this.materialListLoading = false
if (data && data.code === 0) {
this.materialList = data.materials || [];
this.materialList = data.materials || []
} else {
this.$message.error(data.msg || "获取物料清单失败");
this.materialList = [];
this.$message.error(data.msg || '获取物料清单失败')
this.materialList = []
}
})
.catch(() => {
this.materialListLoading = false;
this.$message.error("获取物料清单失败");
this.materialList = [];
});
this.materialListLoading = false
this.$message.error('获取物料清单失败')
this.materialList = []
})
},
// API
@ -584,41 +514,48 @@ export default {
setTimeout(() => {
const mockMaterials = [
{
materialCode: "MAT001",
partNo: "MAT001",
materialCode: 'MAT001',
partNo: 'MAT001',
returnableQty: 100,
returnedQty: 20,
},
{
materialCode: "MAT002",
partNo: "MAT002",
materialCode: 'MAT002',
partNo: 'MAT002',
returnableQty: 200,
returnedQty: 50,
},
{
materialCode: "MAT003",
partNo: "MAT003",
materialCode: 'MAT003',
partNo: 'MAT003',
returnableQty: 150,
returnedQty: 0,
},
];
]
resolve({
code: 0,
materials: mockMaterials,
});
}, 500);
});
})
}, 500)
})
},
//
closeMaterialDialog() {
this.showMaterialDialog = false;
this.showMaterialDialog = false
},
//
loadOrderDetails() {
const params = {
this.orderInfo = JSON.parse(JSON.stringify({}))
this.orderInfo.type = this.orderType
this.orderInfo.orderNo = this.orderNo
this.orderInfo.transactionId = this.transactionId
this.orderInfo.quantity = this.quantity
this.orderInfo.partNo = this.partNo
this.orderInfo.partDesc = this.partDesc
/* const params = {
orderNo: this.orderNo,
orderType: this.orderType,
site: this.$store.state.user.site,
@ -639,63 +576,73 @@ export default {
}
}).catch(() => {
this.$message.error("获取订单详情失败");
});
}); */
},
addWmsLabel(){
if(!this.printData.materialCode1.trim()){
this.$message.warning("请输入物料编码");
return;
addWmsLabel() {
if (!this.printData.materialCode1.trim()) {
this.$message.warning('请输入物料编码')
return
}
if(!this.printData.materialCode2 || this.printData.materialCode2<=0){
this.$message.warning("请输入有效的物料数量");
return;
if (!this.printData.materialCode2 || this.printData.materialCode2 <= 0) {
this.$message.warning('请输入有效的物料数量')
return
}
let newLabel = {
site: this.$store.state.user.site,
partNo: this.printData.materialCode1,
quantity: this.printData.materialCode2,
batchNo: this.batchNo,
warehouseId:"",
locationId:"",
warehouseId: '',
locationId: '',
}
console.log("添加标签:",newLabel);
console.log('添加标签:', newLabel)
//
this.printLabelList.push(newLabel);
this.$message.success("操作成功");
this.printLabelList.push(newLabel)
this.$message.success('操作成功')
//
this.printData.materialCode2 = 0;
this.printData.unit = "";
}
this.printData.materialCode2 = 0
this.printData.unit = ''
},
},
mounted() {
//
this.orderNo = this.$route.params.orderNo;
this.orderType = this.$route.params.orderType || "mr";
this.orderNo = this.$route.params.orderNo
this.orderType = this.$route.params.orderType || 'workOrder'
this.partNo = this.$route.params.partNo
this.partDesc = this.$route.params.issueInfo.partDesc
this.transactionId = this.$route.params.transactionId
this.accountingId = this.$route.params.issueInfo.accountingId
this.quantity = this.$route.params.quantity
this.batchNo = this.$route.params.batchNo
console.log("订单号:", this.orderNo, "订单类型:", this.orderType,"物料编码:",this.partNo);
console.log(
'订单号:',
this.orderNo,
'订单类型:',
this.orderType,
'物料编码:',
this.partNo,
this.transactionId
)
if (!this.orderNo) {
this.$message.error("参数错误");
this.$router.back();
return;
this.$message.error('参数错误')
this.$router.back()
return
}
//
this.$nextTick(() => {
if (this.$refs.scanInput) {
this.$refs.scanInput.focus();
this.$refs.scanInput.focus()
}
});
})
//
this.loadOrderDetails();
this.loadOrderDetails()
},
};
}
</script>
<style scoped>
@ -900,7 +847,7 @@ export default {
}
.detail-value .total::before {
content: "/";
content: '/';
color: #333;
}

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

@ -43,7 +43,7 @@ export default {
label: "申请单发料",
iconClass: "picking",
to: "outsourcingPicking",
disabled: false,
disabled: true,
},
{
icon: "logistics",
@ -56,8 +56,8 @@ export default {
icon: "revoke",
label: "退料",
iconClass: "return",
to: "outsourcingPicking",
disabled: true,
to: "outsourcingReturn",
disabled: false,
},
],
};

399
src/views/modules/outsourcing-return/index.vue

@ -0,0 +1,399 @@
<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">
<el-input
clearable
class="compact-input"
v-model="searchValue"
placeholder="请扫描委外订单号或物料编码"
prefix-icon="el-icon-search"
@keyup.enter.native="handleSearch"
ref="searchInput"
/>
</div>
<!-- 搜索结果列表 -->
<div class="content-area">
<div class="work-order-list" v-if="searchResults.length > 0">
<div
v-for="(item, index) in searchResults"
:key="index"
class="material-card"
@click="goToDetail(item)"
>
<div class="card-title">
<span class="title-label">委外订单号{{ item.outsourcingOrderNo }}</span>
</div>
<div class="part-desc-row">
<span class="desc-text">物料编码{{ item.partNo }}</span>
</div>
<div class="part-desc-row">
<span class="desc-text">{{ item.description }}</span>
</div>
<div class="card-details">
<div class="detail-item">
<div class="detail-label">发料数量</div>
<div class="detail-value">{{ item.issuedQty }}</div>
</div>
<div class="detail-item">
<div class="detail-label">已退数量</div>
<div class="detail-value">{{ item.returnedQty || 0 }}</div>
</div>
<div class="detail-item">
<div class="detail-label">可退数量</div>
<div class="detail-value">{{ item.returnableQty }}</div>
</div>
</div>
</div>
</div>
<div v-if="!loading && searchResults.length === 0 && hasSearched" 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 v-if="!hasSearched" class="welcome-state">
<i class="el-icon-search"></i>
<p>请输入委外订单号或物料编码进行搜索</p>
</div>
</div>
</div>
</template>
<script>
import { searchOutsourcingOrdersForReturn } from '@/api/outsourcing/outsourcing-return';
export default {
data() {
return {
searchValue: '',
searchResults: [],
loading: false,
hasSearched: false,
};
},
methods: {
handleSearch() {
if (!this.searchValue.trim()) {
this.$message.warning('请输入搜索内容');
return;
}
this.loading = true;
this.hasSearched = true;
const params = {
searchValue: this.searchValue.trim(),
site: this.$store.state.user.site,
};
searchOutsourcingOrdersForReturn(params)
.then(({ data }) => {
this.loading = false;
if (data && data.code === 0) {
this.searchResults = data.orders || [];
if (this.searchResults.length === 0) {
this.$message.info('未找到相关委外订单');
}
} else {
this.$message.error(data.msg || '搜索失败');
this.searchResults = [];
}
})
.catch(() => {
this.loading = false;
this.$message.error('搜索失败');
this.searchResults = [];
});
},
goToDetail(item) {
if (item.returnableQty <= 0) {
this.$message.warning('该物料已无可退数量');
return;
}
this.$router.push({
name: 'outsourcingReturnPDAList',
params: {
outsourcingOrderNo: item.outsourcingOrderNo,
partNo: item.partNo,
unissureQty: item.returnableQty,
itemNo: item.itemNo,
},
});
},
},
mounted() {
//
this.$nextTick(() => {
if (this.$refs.searchInput) {
this.$refs.searchInput.focus();
}
});
},
};
</script>
<style scoped>
.pda-container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
background: #f5f5f5;
}
/* 头部栏 */
.header-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 16px;
background: #17b3a3;
color: white;
height: 40px;
min-height: 40px;
}
.header-left {
display: flex;
align-items: center;
cursor: pointer;
font-size: 16px;
font-weight: 500;
}
.header-left i {
margin-right: 8px;
font-size: 18px;
}
.header-right {
cursor: pointer;
font-size: 16px;
font-weight: 500;
}
/* 搜索容器 */
.search-container {
padding: 12px 16px;
background: white;
}
.search-container .el-input {
width: 100%;
}
/* 紧凑型输入框样式 */
.compact-input ::v-deep .el-input__inner {
height: 40px;
padding: 0 12px 0 35px;
font-size: 14px;
}
.compact-input ::v-deep .el-input__prefix {
left: 10px;
}
.compact-input ::v-deep .el-input__suffix {
right: 30px;
}
/* 内容区域 */
.content-area {
flex: 1;
overflow-y: auto;
}
/* 工单列表 */
.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;
}
.empty-state p {
margin: 0;
font-size: 14px;
}
/* 加载状态 */
.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;
}
.loading-state p {
margin: 0;
font-size: 14px;
}
/* 欢迎状态 */
.welcome-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
color: #999;
}
.welcome-state i {
font-size: 48px;
margin-bottom: 16px;
color: #17b3a3;
}
.welcome-state p {
margin: 0;
font-size: 14px;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* 响应式设计 */
@media (max-width: 360px) {
.header-bar {
padding: 8px 12px;
}
.search-container {
padding: 8px 12px;
}
.work-order-list {
padding: 8px 12px;
}
.card-details {
flex-wrap: wrap;
gap: 6px;
}
.detail-item {
flex: 0 0 48%;
margin-bottom: 6px;
min-width: 50px;
}
}
</style>

1444
src/views/modules/outsourcing-return/outsourcingReturnPDAIssueList.vue
File diff suppressed because it is too large
View File

162
src/views/modules/outsourcing-return/outsourcingReturnPDAList.vue

@ -0,0 +1,162 @@
<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">委外订单号:{{ outsourcingOrderNo }}</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 { getUnissueMatericalForOutsourcingOrder } from '@/api/outsourcing/outsourcing-return';
export default {
data() {
return {
outsourcingOrderNo: '',
partNo: '',
loading: false,
issueList: [],
unissureQty: 0,
itemNo: '',
};
},
methods: {
loadIssueList() {
if (!this.outsourcingOrderNo || !this.partNo) {
return;
}
this.loading = true;
const params = {
outsourcingOrderNo: this.outsourcingOrderNo,
site: this.$store.state.user.site,
partNo: this.partNo,
};
getUnissueMatericalForOutsourcingOrder(params)
.then(({ data }) => {
this.loading = false;
if (data && data.code === 0) {
this.issueList = data.issueForOutsourcingOrder || [];
} else {
this.$message.error(data.msg || '获取发料记录失败');
this.issueList = [];
}
})
.catch(() => {
this.loading = false;
this.$message.error('获取发料记录失败');
});
},
goDetail(item) {
this.$router.push({
name: 'outsourcingReturnPDAIssueList',
params: {
outsourcingOrderNo: this.outsourcingOrderNo,
material:{
itemNo: this.itemNo,
partNo: this.partNo,
orderType: 'outsourcingOrder',
ifsTransactionID: item.TRANSACTION_ID,
quantity: item.QUANTITY,
batchNo: item.LOT_BATCH_NO,
unissureQty: this.unissureQty,
ifsAccountingID:item.ACCOUNTING_ID,
qtyReversed:item.QTY_REVERSED || 0,
}
},
});
},
},
mounted() {
this.outsourcingOrderNo = this.$route.params.outsourcingOrderNo;
this.partNo = this.$route.params.partNo;
this.unissureQty = this.$route.params.unissureQty;
this.itemNo = this.$route.params.itemNo;
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; }
.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>
Loading…
Cancel
Save