Browse Source

客户发料

master
shenzhouyu 3 months ago
parent
commit
cd751f659c
  1. 1
      src/router/index.js
  2. 8
      src/views/main.vue
  3. 2
      src/views/modules/customerIssue/customerIssue.vue
  4. 55
      src/views/modules/customerIssue/customerIssuePDA.vue
  5. 647
      src/views/modules/customerIssue/customerIssuePDAIssueList.vue
  6. 6
      src/views/modules/customerIssue/customerIssuePDAList.vue
  7. 167
      src/views/modules/customerIssue/customerIssuePrintSelect.vue

1
src/router/index.js

@ -89,6 +89,7 @@ const globalRoutes = [
{ path: "/customerIssuePDA", name: "customerIssuePDA", component: resolve => require(["@/views/modules/customerIssue/customerIssuePDA.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: false } },
{ path: "/customerIssuePDAList", name: "customerIssuePDAList", component: resolve => require(["@/views/modules/customerIssue/customerIssuePDAList.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{ path: "/customerIssuePDAIssueList", name: "customerIssuePDAIssueList", component: resolve => require(["@/views/modules/customerIssue/customerIssuePDAIssueList.vue"], resolve), meta: { transition: 'instant', preload: true, keepAlive: true } },
{ path: "/customerIssuePrintSelect", name: "customerIssuePrintSelect", component: resolve => require(["@/views/modules/customerIssue/customerIssuePrintSelect.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}},

8
src/views/main.vue

@ -105,13 +105,7 @@
<div class="menu-text">委外发料</div>
</div>
<!-- <div class="menu-item disabled" @click="navigateWithWarehouseCheck('customerissue')"> -->
<div class="menu-item disabled" @click="handleDisabledFeature('customerissue')">
<div class="menu-icon customer-issue">
<van-icon name="send-gift-o" size="24" />
</div>
<div class="menu-text">客户发料</div>
</div>
<div class="menu-item disabled" @click="handleDisabledFeature('saleshipping')">
<div class="menu-item disabled" @click="handleDisabledFeature('customerissue')">
<div class="menu-icon sales-delivery">
<van-icon name="logistics" size="24" />
</div>

2
src/views/modules/customerIssue/customerIssue.vue

@ -35,7 +35,7 @@ export default {
{ icon: 'records', label: '申请单发料', iconClass: 'request', to: 'customerIssuePDA', disabled: false },
{ icon: 'logistics', label: '移库发料', iconClass: 'move', to: 'customerIssuePicking', disabled: true },
{ icon: 'revoke', label: '发料撤销', iconClass: 'cancel', to: 'customerIssuePicking', disabled: true }, */
{ icon: 'records', label: '申请单发料', iconClass: 'request', to: 'customerIssuePDA', disabled: false },
{ icon: 'records', label: '客户发料', iconClass: 'request', to: 'customerIssuePDA', disabled: false },
]
}
},

55
src/views/modules/customerIssue/customerIssuePDA.vue

@ -20,26 +20,26 @@
<div v-for="material in displayIssueRequestMaterials" :key="`${material.partNo}-${material.itemNo}`"
:class="['work-order-card', { selected: selectedRequestMaterial && isSameRequestMaterial(selectedRequestMaterial, material) }]" @click="selectRequestMaterial(material)">
<div class="card-title">
<span class="title-label">申请单号{{ material.notifyNo }} </span>
<span class="title-label">申请单号{{ material.SHIPMENT_ID }} </span>
</div>
<!-- 工单号单独一行 -->
<div class="part-desc-row">
<span class="desc-text">客户订单号{{ material.soorderNo }}</span>
<span class="desc-text">客户地址{{ material.RECEIVER_ADDRESS_NAME }}</span>
</div>
<div class="card-details">
<div class="detail-item">
<div class="detail-label">申请数量</div>
<div class="detail-value">{{ material.unissureQty }}</div>
<div class="detail-label">发料类型</div>
<div class="detail-value">{{ material.SHIPMENT_TYPE }}</div>
</div>
<div class="detail-item">
<div class="detail-label">状态</div>
<div class="detail-value">待发料</div>
<div class="detail-value">{{material.STATE}}</div>
</div>
<div class="detail-item">
<div class="detail-label">单位</div>
<div class="detail-value">{{ material.uom || "个" }}</div>
<div class="detail-label">计划发料日期</div>
<div class="detail-value">{{ material.PLANNED_SHIP_DATE }}</div>
</div>
</div>
</div>
@ -57,29 +57,29 @@
>
<div class="card-title">
<span class="title-label"
>物料编码{{ material.componentPartNo }} &nbsp;&nbsp; 行号{{
material.bomItemNo
>物料编码{{ material.INVENTORY_PART_NO }} &nbsp;&nbsp; 行号{{
material.SOURCE_REF2
}}</span
>
</div>
<!-- 物料描述单独一行 -->
<div class="part-desc-row">
<span class="desc-text">{{ material.componentPartDesc }}</span>
<span class="desc-text">客户单号{{ material.SOURCE_REF1 }}</span>
</div>
<div class="card-details">
<div class="detail-item">
<div class="detail-label">需求数量</div>
<div class="detail-value">{{ material.qtyToIssue }}</div>
<div class="detail-label">销售行号</div>
<div class="detail-value">{{ material.SHIPMENT_LINE_NO }}</div>
</div>
<div class="detail-item">
<div class="detail-label">已发数量</div>
<div class="detail-value">{{ material.qtyIssued || 0 }}</div>
<div class="detail-label">需求数量</div>
<div class="detail-value">{{ material.INVENTORY_QTY }}</div>
</div>
<div class="detail-item">
<div class="detail-label">单位</div>
<div class="detail-value">{{ material.uom || "个" }}</div>
<div class="detail-value">{{ material.INVENTORY_UOM }}</div>
</div>
</div>
</div>
@ -178,11 +178,9 @@ export default {
getCustomerIssueNotifyHeaderInfo({
site: localStorage.getItem('site'),
notifyNo: this.requestIssueForm.requestNo,
workOrderNo: this.requestIssueForm.requestNo,
}).then(({ data }) => {
if (data.code === 0) {
console.log(data)
this.issueRequestMaterials = data.data || []
if (this.issueRequestMaterials.length === 0) {
this.$message.warning('查询申请单不存在')
@ -207,8 +205,7 @@ export default {
selectRequestMaterial(material) {
if (
this.showOnlySelected &&
this.selectedRequestMaterial &&
this.isSameRequestMaterial(this.selectedRequestMaterial, material)
this.selectedRequestMaterial
) {
//
this.selectedRequestMaterial = null
@ -220,16 +217,14 @@ export default {
//
this.selectedRequestMaterial = material
this.selectedWorkOrder = material.notifyNo
this.selectedWorkOrder = material.SHIPMENT_ID
this.showOnlySelected = true
this.getCustomerIssueNotifyHeaderOrderMaterialList(material)
},
getCustomerIssueNotifyHeaderOrderMaterialList(material){
let params = {
site: localStorage.getItem('site'),
notifyNo: material.notifyNo,
itemNo: material.itemNo,
soorderNo: material.soorderNo,
workOrderNo: material.SHIPMENT_ID,
};
getCustomerIssueNotifyHeaderOrderMaterialList(params).then(({ data }) => {
if (data.code === 0) {
@ -251,13 +246,13 @@ export default {
// 仿 productionReturnPicking.vue openIssueList
openIssueDetail(material) {
this.$router.push({
name: 'customerIssuePDAList',
name: 'customerIssuePDAIssueList',
query: {
notifyNo: this.selectedRequestMaterial.notifyNo, //
itemNo: this.selectedRequestMaterial.itemNo, //
workOrderNo: this.selectedRequestMaterial.soorderNo, //
partNo: material.componentPartNo, //
unissureQty: material.qtyToIssue, //
itemNo: material.SHIPMENT_LINE_NO, //
workOrderNo: this.selectedRequestMaterial.SHIPMENT_ID, //
partNo: material.INVENTORY_PART_NO, //
issureQty: material.INVENTORY_QTY, //
assignedQty: material.QTY_ASSIGNED, //
}
})
},

647
src/views/modules/customerIssue/customerIssuePDAIssueList.vue

@ -22,22 +22,15 @@
</div>
<!-- 订单信息卡片对齐直接领料明细样式 -->
<div class="work-order-list" v-if="orderInfo.orderNo">
<div class="work-order-list" v-if="orderNo">
<div class="work-order-card">
<div class="card-title">
<span class="title-label">{{
orderInfo.type === "customerOrder" ? "客户订单号" : "发料申请单号"
}}{{ orderInfo.orderNo }}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;批次号{{ batchNo }}</span>
<span class="title-label">申请单号{{ orderInfo.orderNo }}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;行号{{ itemNo }}</span>
</div>
<!-- 关联信息单独一行 -->
<div class="part-desc-row">
<span class="desc-text">{{ orderInfo.type === "customerOrder" ? "关联单号" : "关联客户订单" }}{{
orderInfo.transactionId
}}&nbsp;&nbsp;申请单发量{{unissureQty}}</span>
</div>
<div class="part-desc-row">
<span class="desc-text">{{ orderInfo.partNo }}</span>
<span class="desc-text">物料号{{ orderInfo.partNo }}</span>
</div>
<div class="part-desc-row">
<span class="desc-text">{{ orderInfo.description }}</span>
@ -46,11 +39,11 @@
<div class="card-details">
<div class="detail-item">
<div class="detail-label">已发数量</div>
<div class="detail-value">{{ qtyIssued }}</div>
<div class="detail-value">{{ assignedQty }}</div>
</div>
<div class="detail-item">
<div class="detail-label">发料数量</div>
<div class="detail-value">{{ orderInfo.quantity }}</div>
<div class="detail-value">{{ qtyIssued }}</div>
</div>
<div class="detail-item">
<div class="detail-label">本次</div>
@ -98,6 +91,9 @@
<el-button class="action-btn primary" style="margin-left: 10px" @click="confirmIssue" :loading="loading">
确定发料
</el-button>
<button class="action-btn secondary" style="margin-left: 10px" @click="openPrintDialog">
打印
</button>
<button class="action-btn secondary" style="margin-left: 10px" @click="cancelIssue">
取消
@ -140,6 +136,101 @@
</div>
</div>
</div>
<!-- 打印选择弹框 -->
<div v-if="showPrintDialog" class="print-overlay">
<div class="print-modal">
<div class="modal-header">
<span class="modal-title">选择打印标签</span>
<i class="el-icon-close close-btn" @click="closePrintDialog"></i>
</div>
<div class="modal-body">
<div class="print-section-title">
<div class="title-left">
<i class="el-icon-tickets"></i>
<span>请选择需要打印的标签</span>
</div>
<div class="title-right">
<el-checkbox v-model="printAllChecked" @change="togglePrintAll">全选</el-checkbox>
</div>
</div>
<div class="print-label-list">
<div class="list-header">
<div class="col-no">NO.</div>
<div class="col-label">物料标签</div>
<div class="col-part">库位</div>
<div class="col-qty">发料数量</div>
<div class="col-check">选择</div>
</div>
<div v-for="(label, index) in printLabelList" :key="label.id" class="list-item">
<div class="col-no">{{ index + 1 }}</div>
<div class="col-label">{{ label.labelCode }}</div>
<div class="col-part">{{ label.locationId }}</div>
<div class="col-qty">{{ label.quantity }}</div>
<div class="col-check">
<el-checkbox v-model="label.__checked"></el-checkbox>
</div>
</div>
<div v-if="printLabelList.length === 0" class="empty-labels">
<p>暂无扫描标签</p>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn-secondary" @click="closePrintDialog">取消</button>
<button class="btn-secondary" @click="openQuantityDialog('QC')">打印QC</button>
<button class="btn-secondary" @click="openQuantityDialog('BOX')">打印BOX</button>
</div>
</div>
</div>
<!-- QC数量输入弹框 -->
<div v-if="showQCDialog" class="quantity-overlay">
<div class="quantity-modal">
<div class="modal-header">
<span class="modal-title">输入QC打印数量</span>
<i class="el-icon-close close-btn" @click="closeQuantityDialog"></i>
</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label">QC打印数量 <span class="required">*</span></label>
<el-input v-model="qcQuantity" type="number" :min="1" placeholder="请输入QC打印数量" class="form-input" />
</div>
</div>
<div class="modal-footer">
<button class="btn-cancel" @click="closeQuantityDialog">取消</button>
<button class="btn-confirm" @click="confirmQCPrint">确定打印</button>
</div>
</div>
</div>
<!-- BOX数量输入弹框 -->
<div v-if="showBOXDialog" class="quantity-overlay">
<div class="quantity-modal">
<div class="modal-header">
<span class="modal-title">输入BOX打印数量</span>
<i class="el-icon-close close-btn" @click="closeQuantityDialog"></i>
</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label">BOX打印数量 <span class="required">*</span></label>
<el-input v-model="boxQuantity" type="number" :min="1" placeholder="请输入BOX打印数量" class="form-input" />
</div>
</div>
<div class="modal-footer">
<button class="btn-cancel" @click="closeQuantityDialog">取消</button>
<button class="btn-confirm" @click="confirmBOXPrint">确定打印</button>
</div>
</div>
</div>
</div>
</template>
@ -178,6 +269,17 @@ export default {
unissureQty: 0, //
itemNo: '', // ID
loading: false,
//
showPrintDialog: false,
printLabelList: [],
printAllChecked: true,
assignedQty: 0, //
//
showQCDialog: false,
showBOXDialog: false,
qcQuantity: 1,
boxQuantity: 1,
currentPrintType: '', //
}
},
computed: {
@ -211,7 +313,6 @@ export default {
const params = {
scannedLabel: labelCode,
orderNo: this.orderNo,
orderType: this.orderType,
site: localStorage.getItem('site'),
batchNo: this.batchNo,
componentPartNo: this.partNo,
@ -327,7 +428,6 @@ export default {
const issueParams = {
site: localStorage.getItem('site'),
workOrderNo: this.orderNo,
orderType: this.orderType,
batchNo: this.batchNo,
componentPartNo: this.partNo,
transactionId: this.transactionId,
@ -352,9 +452,20 @@ export default {
.then(({ data }) => {
if (data.code === 0 && data) {
this.$message.success('客户发料成功')
this.$router.push({
name: 'customerIssuePDA',
})
//
try {
const payload = this.labelList.map((label) => ({
labelCode: label.labelCode,
issueQty: label.quantity,
batchNo: label.batchNo,
partNo: label.partNo,
locationId: label.locationId,
warehouseId: label.warehouseId,
wdrNo: label.wdrNo || '*',
}))
sessionStorage.setItem('customerIssueScannedLabels', JSON.stringify(payload))
} catch (e) {}
this.$router.push({ name: 'customerIssuePrintSelect' })
this.loading = false
} else {
this.$message.error(data.message || '操作失败')
@ -389,47 +500,153 @@ export default {
//
loadOrderDetails() {
const params = {
orderNo: this.orderNo,
orderType: this.orderType,
site: localStorage.getItem('site'),
partNo: this.partNo,
this.orderInfo.orderNo = this.orderNo
this.orderInfo.itemNo = this.itemNo
this.orderInfo.partNo = this.partNo
},
//
openPrintDialog() {
if (this.labelList.length === 0) {
this.$message.warning('请先扫描发料标签')
return
}
console.log('加载订单详情参数:', params)
//
this.printLabelList = this.labelList.map(label => ({
...label,
__checked: true
}))
this.printAllChecked = true
this.showPrintDialog = true
},
//
getInventoryPart(params)
.then(({ data }) => {
if (data && data.code === 0) {
this.orderInfo = data.inventoryPart[0]
this.orderInfo.type = this.orderType
this.orderInfo.orderNo = this.orderNo
this.orderInfo.transactionId = this.transactionId
this.orderInfo.quantity = this.quantity
} else {
this.$message.error(data.msg || '获取订单详情失败')
}
})
.catch(() => {
this.$message.error('获取订单详情失败')
})
//
closePrintDialog() {
this.showPrintDialog = false
this.printLabelList = []
this.printAllChecked = true
},
// /
togglePrintAll(checked) {
this.printLabelList.forEach(label => {
this.$set(label, '__checked', checked)
})
},
//
onPrint(type) {
const selected = this.printLabelList.filter(label => label.__checked)
if (selected.length === 0) {
this.$message.warning('请至少选择一条记录')
return
}
// 使
try {
const payload = selected.map(label => ({
labelCode: label.labelCode,
issueQty: label.quantity,
batchNo: label.batchNo,
partNo: label.partNo,
locationId: label.locationId,
warehouseId: label.warehouseId,
wdrNo: label.wdrNo || '*',
}))
sessionStorage.setItem('customerIssuePrintSelected', JSON.stringify(payload))
sessionStorage.setItem('customerIssuePrintType', type)
this.$message.success('已准备打印:' + type)
this.closePrintDialog()
//
// this.$router.push({ name: 'somePrintPage' })
} catch (e) {
this.$message.error('打印准备失败')
}
},
//
openQuantityDialog(type) {
const selected = this.printLabelList.filter(label => label.__checked)
if (selected.length === 0) {
this.$message.warning('请至少选择一条记录')
return
}
this.currentPrintType = type
if (type === 'QC') {
this.showQCDialog = true
} else if (type === 'BOX') {
this.showBOXDialog = true
}
},
//
closeQuantityDialog() {
this.showQCDialog = false
this.showBOXDialog = false
this.currentPrintType = ''
},
// QC
confirmQCPrint() {
if (!this.qcQuantity || this.qcQuantity <= 0) {
this.$message.warning('请输入有效的QC打印数量')
return
}
this.executePrint('QC', this.qcQuantity)
},
// BOX
confirmBOXPrint() {
if (!this.boxQuantity || this.boxQuantity <= 0) {
this.$message.warning('请输入有效的BOX打印数量')
return
}
this.executePrint('BOX', this.boxQuantity)
},
//
executePrint(type, quantity) {
const selected = this.printLabelList.filter(label => label.__checked)
try {
const payload = selected.map(label => ({
labelCode: label.labelCode,
issueQty: label.quantity,
batchNo: label.batchNo,
partNo: label.partNo,
locationId: label.locationId,
warehouseId: label.warehouseId,
wdrNo: label.wdrNo || '*',
}))
sessionStorage.setItem('customerIssuePrintSelected', JSON.stringify(payload))
sessionStorage.setItem('customerIssuePrintType', type)
sessionStorage.setItem('customerIssuePrintQuantity', quantity.toString())
this.$message.success(`已准备打印:${type},数量:${quantity}`)
this.closeQuantityDialog()
this.closePrintDialog()
//
// this.$router.push({ name: 'somePrintPage' })
} catch (e) {
this.$message.error('打印准备失败')
}
},
},
mounted() {
//
console.log('路由参数:', this.$route.query.material)
console.log('路由参数:', this.$route.query)
this.orderNo = this.$route.query.workOrderNo
this.orderType = this.$route.query.material.orderType || 'customerOrder'
this.partNo = this.$route.query.material.partNo
this.transactionId = this.$route.query.material.ifsTransactionID
this.accountingId = this.$route.query.material.ifsAccountingID
this.quantity = this.$route.query.material.quantity
this.batchNo = this.$route.query.material.batchNo
this.unissureQty = this.$route.query.material.unissureQty
this.itemNo = this.$route.query.material.itemNo
this.qtyIssued = this.$route.query.material.qtyIssued || 0
this.partNo = this.$route.query.partNo
this.itemNo = this.$route.query.itemNo
this.qtyIssued = this.$route.query.issureQty
this.assignedQty = this.$route.query.assignedQty
if (!this.orderNo) {
this.$message.error('参数错误')
@ -1029,6 +1246,205 @@ export default {
border-color: #13998c;
}
/* 打印弹框样式 */
.print-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
padding: 10px;
}
.print-modal {
background: white;
border-radius: 12px;
width: 100%;
max-width: 500px;
max-height: 80vh;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
overflow: hidden;
display: flex;
flex-direction: column;
}
.print-modal .modal-header {
background: #17b3a3;
color: white;
padding: 12px 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.print-modal .modal-title {
font-size: 16px;
font-weight: 500;
margin: 0;
}
.print-modal .close-btn {
font-size: 16px;
cursor: pointer;
color: white;
transition: color 0.2s ease;
padding: 4px;
display: flex;
align-items: center;
justify-content: center;
}
.print-modal .close-btn:hover {
color: #e0e0e0;
}
.print-modal .modal-body {
padding: 6px;
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.print-section-title {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 0;
margin-bottom: 12px;
border-bottom: 1px solid #e0e0e0;
}
.print-section-title .title-left {
display: flex;
align-items: center;
}
.print-section-title .title-left i {
color: #17b3a3;
font-size: 16px;
margin-right: 8px;
}
.print-section-title .title-left span {
color: #17b3a3;
font-size: 14px;
font-weight: 500;
}
.print-section-title .title-right {
display: flex;
align-items: center;
}
.print-label-list {
flex: 1;
/* 允许列表区域在弹框内上下滚动,避免只显示固定条数 */
max-height: 50vh;
overflow-y: auto;
overflow-x: hidden;
position: relative; /* 为粘性表头提供更高的层叠上下文控制 */
border: 1px solid #e0e0e0;
border-radius: 6px;
}
.print-label-list .list-header {
display: flex;
background: #f8f9fa;
padding: 10px 8px;
border-bottom: 1px solid #e0e0e0;
font-size: 12px;
color: #666;
font-weight: 500;
position: sticky;
top: 0;
z-index: 5; /* 保证表头覆盖列表项与复选框 */
}
.print-label-list .list-item {
display: flex;
padding: 10px 8px;
border-bottom: 1px solid #f0f0f0;
font-size: 12px;
color: #333;
align-items: center;
min-height: 36px;
}
.print-label-list .list-item:last-child {
border-bottom: none;
}
.print-label-list .col-no {
width: 30px;
text-align: center;
}
.print-label-list .col-label {
flex: 1.5;
text-align: center;
word-break: break-all;
white-space: normal;
line-height: 1.2;
}
.print-label-list .col-part {
flex: 1.2;
text-align: center;
}
.print-label-list .col-qty {
width: 70px;
text-align: center;
}
.print-label-list .col-check {
width: 50px;
text-align: center;
}
/* 放大复选框(仅作用于打印弹框列表区域) */
.print-label-list .col-check ::v-deep .el-checkbox {
transform: scale(1.2);
transform-origin: center center;
}
/* 调整放大后与行高的对齐 */
.print-label-list .col-check {
display: flex;
align-items: center;
justify-content: center;
}
.print-modal .modal-footer {
padding: 16px 20px;
display: flex;
gap: 12px;
justify-content: flex-end;
border-top: 1px solid #f0f0f0;
}
.print-modal .btn-secondary {
padding: 10px 20px;
border-radius: 6px;
font-size: 14px;
cursor: pointer;
transition: all 0.2s;
border: 1px solid #17b3a3;
background: white;
color: #17b3a3;
}
.print-modal .btn-secondary:hover {
background: #17b3a3;
color: white;
}
/* 响应式设计 */
@media (max-width: 360px) {
.header-bar {
@ -1075,4 +1491,137 @@ export default {
flex: 1.2;
}
}
/* 数量输入弹框样式 */
.quantity-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.quantity-modal {
background: white;
border-radius: 12px;
width: 100%;
max-width: 400px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
overflow: hidden;
display: flex;
flex-direction: column;
}
.quantity-modal .modal-header {
background: #17b3a3;
color: white;
padding: 12px 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.quantity-modal .modal-title {
font-size: 16px;
font-weight: 500;
margin: 0;
}
.quantity-modal .close-btn {
font-size: 16px;
cursor: pointer;
color: white;
transition: color 0.2s ease;
padding: 4px;
display: flex;
align-items: center;
justify-content: center;
}
.quantity-modal .close-btn:hover {
color: #e0e0e0;
}
.quantity-modal .modal-body {
padding: 20px;
}
.quantity-modal .form-group {
margin-bottom: 16px;
}
.quantity-modal .form-label {
display: block;
font-size: 14px;
color: #333;
margin-bottom: 6px;
font-weight: 500;
}
.quantity-modal .required {
color: #ff4949;
}
.quantity-modal .form-input {
width: 100%;
}
.quantity-modal .form-input ::v-deep .el-input__inner {
height: 40px;
border: 2px solid #dcdfe6;
border-radius: 6px;
font-size: 14px;
padding: 0 12px;
}
.quantity-modal .form-input ::v-deep .el-input__inner:focus {
border-color: #17b3a3;
outline: none;
}
.quantity-modal .modal-footer {
padding: 16px 20px;
display: flex;
gap: 12px;
justify-content: flex-end;
border-top: 1px solid #f0f0f0;
}
.quantity-modal .btn-cancel {
padding: 10px 20px;
border-radius: 6px;
font-size: 14px;
cursor: pointer;
transition: all 0.2s;
border: 1px solid #dcdfe6;
background: white;
color: #606266;
}
.quantity-modal .btn-cancel:hover {
background: #f5f7fa;
border-color: #c0c4cc;
}
.quantity-modal .btn-confirm {
padding: 10px 20px;
border-radius: 6px;
font-size: 14px;
cursor: pointer;
transition: all 0.2s;
border: 1px solid #17b3a3;
background: #17b3a3;
color: white;
}
.quantity-modal .btn-confirm:hover {
background: #13998c;
border-color: #13998c;
}
</style>

6
src/views/modules/customerIssue/customerIssuePDAList.vue

@ -95,7 +95,7 @@ export default {
.then(({ data }) => {
this.loading = false;
if (data && data.code === 0) {
this.issueList = data.issueForShopOrder || [];
this.issueList = data.data || [];
} else {
this.$message.error(data.msg || '获取发料记录失败');
this.issueList = [];
@ -127,6 +127,8 @@ export default {
},
},
mounted() {
console.log("路由星系",this.$route.query);
this.workOrderNo = this.$route.query.workOrderNo;
this.partNo = this.$route.query.partNo;
this.unissureQty = this.$route.query.unissureQty;
@ -143,7 +145,7 @@ export default {
.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; }
.work-order-list { overflow-y: auto; }
.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); }

167
src/views/modules/customerIssue/customerIssuePrintSelect.vue

@ -0,0 +1,167 @@
<template>
<div class="pda-container">
<div class="header-bar">
<div class="header-left" @click="toCustomerIssue()">
<i class="el-icon-arrow-left"></i>
<span>选择打印标签</span>
</div>
<div class="header-right" @click="toMain()">首页</div>
</div>
<div class="section-title">
<div class="title-left">
<i class="el-icon-tickets"></i>
<span>请选择需要打印的标签</span>
</div>
<div class="title-right">
<el-checkbox v-model="allChecked" @change="toggleAll">全选</el-checkbox>
</div>
</div>
<div class="label-list">
<div class="list-header">
<div class="col-no">NO.</div>
<div class="col-label">物料标签</div>
<div class="col-part">库位</div>
<div class="col-qty">发料数量</div>
<div class="col-check">选择</div>
</div>
<div v-for="(item, index) in items" :key="item.labelCode" class="list-item">
<div class="col-no">{{ index + 1 }}</div>
<div class="col-label">{{ item.labelCode }}</div>
<div class="col-part">{{ item.locationId }}</div>
<div class="col-qty">{{ item.issueQty || item.quantity }}</div>
<div class="col-check">
<el-checkbox v-model="item.__checked"></el-checkbox>
</div>
</div>
<div v-if="items.length === 0" class="empty-labels">
<p>暂无数据</p>
</div>
</div>
<div class="bottom-actions">
<button class="action-btn secondary" @click="onPrint('QC')">打印QC</button>
<button class="action-btn primary" @click="onPrint('BOX')">打印BOX</button>
</div>
</div>
</template>
<script>
export default {
name: 'CustomerIssuePrintSelect',
data() {
return {
items: [],
allChecked: true,
}
},
methods: {
toggleAll(checked) {
this.items.forEach(i => {
this.$set(i, '__checked', checked)
})
},
toCustomerIssue() {
this.$confirm('确认不打印就跳转?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
this.$router.push({
name: 'customerIssuePDA',
})
})
.catch(() => {
//
})
},
toMain() {
this.$confirm('确认不打印就跳转到首页?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
this.$router.push({ path: '/' })
})
.catch(() => {
//
})
},
onPrint(type) {
const selected = this.items.filter(i => i.__checked)
if (selected.length === 0) {
this.$message.warning('请至少选择一条记录')
return
}
// 使
sessionStorage.setItem('customerIssuePrintSelected', JSON.stringify(selected))
sessionStorage.setItem('customerIssuePrintType', type)
this.$message.success('已准备打印:' + type)
//
// this.$router.push({ name: 'somePrintPage' })
}
},
mounted() {
//
try {
const raw = sessionStorage.getItem('customerIssueScannedLabels')
const list = raw ? JSON.parse(raw) : []
//
this.items = (list || []).map(x => ({
...x,
issueQty: x.issueQty != null ? x.issueQty : x.quantity,
__checked: true,
}))
this.allChecked = this.items.length > 0 && this.items.every(i => i.__checked)
} catch (e) {
this.items = []
}
}
}
</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; }
.section-title { display: flex; align-items: center; justify-content: space-between; padding: 6px 8px; background: white; margin: 0 10px; margin-top: 4px; border-radius: 8px 8px 0 0; border-bottom: 2px solid #17b3a3; }
.title-left { display: flex; align-items: center; }
.title-left i { color: #17b3a3; font-size: 16px; margin-right: 8px; }
.title-left span { color: #17b3a3; font-size: 14px; font-weight: 500; }
.label-list { background: white; margin: 0 10px 12px; border-radius: 0 0 8px 8px; overflow: hidden; overflow-y: auto; position: relative; }
.list-header { display: flex; background: #f8f9fa; padding: 12px 8px; border-bottom: 1px solid #e0e0e0; font-size: 12px; color: #666; font-weight: 500; position: sticky; top: 0; z-index: 5; }
.list-item { display: flex; padding: 12px 8px; border-bottom: 1px solid #f0f0f0; font-size: 12px; color: #333; align-items: flex-start; min-height: 48px; }
.col-no { width: 30px; text-align: center; }
.col-label { flex: 1.5; text-align: center; word-break: break-all; white-space: normal; line-height: 1.2; }
.col-part { flex: 1.2; text-align: center; }
.col-qty { width: 80px; text-align: center; }
.col-check { width: 100px; text-align: center; display: flex; align-items: center; justify-content: center; }
/* 放大复选框(直接控制 ElementUI 内部方框尺寸,兼容 scoped) */
.col-check ::v-deep .el-checkbox__inner { width: 26px; height: 26px; }
.col-check ::v-deep .el-checkbox__inner::after { left: 8px; top: 2px; height: 14px; width: 7px; }
/* 顶部“全选”复选框同步放大 */
.section-title .title-right { display: flex; align-items: center; }
.section-title .title-right ::v-deep .el-checkbox__inner { width: 26px; height: 26px; }
.section-title .title-right ::v-deep .el-checkbox__inner::after { left: 8px; top: 2px; height: 14px; width: 7px; }
.empty-labels { padding: 40px 20px; text-align: center; color: #999; }
.bottom-actions { display: flex; padding: 16px; gap: 20px; background: white; }
.action-btn { flex: 1; padding: 12px; border-radius: 20px; font-size: 14px; cursor: pointer; transition: all 0.2s ease; }
.action-btn.primary { border: 1px solid #17b3a3; background: #17b3a3; color: white; }
.action-btn.secondary { border: 1px solid #17b3a3; background: white; color: #17b3a3; }
.action-btn.primary:hover { background: #13998c; border-color: #13998c; }
.action-btn.secondary:hover { background: #17b3a3; color: white; }
.action-btn:active { transform: scale(0.98); }
@media (max-width: 360px) {
.section-title { margin: 0 12px; margin-top: 4px; }
.label-list { margin: 0 12px 8px; }
.list-header, .list-item { font-size: 11px; }
}
</style>
Loading…
Cancel
Save