完善单元格合并逻辑
This commit is contained in:
@@ -142,6 +142,13 @@ public class ErpPurchasePlanController extends BaseController {
|
||||
return R.ok(iErpPurchasePlanService.queryDeliveryList(planId));
|
||||
}
|
||||
|
||||
/** 刷新到货:拿已上传卷号去 WMS 钢卷表实时复核,签收入库的自动翻为已到货(无需重传) */
|
||||
@PutMapping("/{planId}/refreshArrival")
|
||||
public R<Void> refreshArrival(@PathVariable Long planId) {
|
||||
iErpPurchasePlanService.refreshProgress(planId);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/** 某计划的到货上传批次(每次上传一条,可回看) */
|
||||
@GetMapping("/{planId}/deliveryBatches")
|
||||
public R<List<ErpPurchasePlanDeliveryBatchVo>> deliveryBatches(@PathVariable Long planId) {
|
||||
|
||||
@@ -46,6 +46,7 @@ import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -340,7 +341,31 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
if (valid.isEmpty()) {
|
||||
throw new ServiceException("未解析到有效到货数据,请检查文件内容或列名是否与模板一致");
|
||||
}
|
||||
// 2) kg→t 单位判定(文件级:单卷重量最大值超阈值视为 kg)
|
||||
// 2) 牌号校验:到货表里的牌号必须都在本计划「采购要求」的牌号范围内
|
||||
List<ErpPurchasePlanItem> planItems = itemMapper.selectList(Wrappers.lambdaQuery(ErpPurchasePlanItem.class)
|
||||
.eq(ErpPurchasePlanItem::getPlanId, planId));
|
||||
Set<String> reqGrades = planItems.stream()
|
||||
.map(it -> normCoil(it.getGrade()))
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.collect(Collectors.toSet());
|
||||
if (!reqGrades.isEmpty()) {
|
||||
Set<String> badGrades = new LinkedHashSet<>();
|
||||
for (ErpPurchasePlanDeliveryImportVo r : valid) {
|
||||
String g = normCoil(r.getGrade());
|
||||
if (StringUtils.isBlank(g)) {
|
||||
badGrades.add("(空牌号)");
|
||||
} else if (!reqGrades.contains(g)) {
|
||||
badGrades.add(r.getGrade().trim());
|
||||
}
|
||||
}
|
||||
if (!badGrades.isEmpty()) {
|
||||
String allow = planItems.stream().map(ErpPurchasePlanItem::getGrade)
|
||||
.filter(StringUtils::isNotBlank).map(String::trim).distinct().collect(Collectors.joining("、"));
|
||||
throw new ServiceException("到货表中的牌号 [" + String.join("、", badGrades)
|
||||
+ "] 不在本计划采购要求的牌号范围内(仅允许:" + allow + "),请核对后重新上传");
|
||||
}
|
||||
}
|
||||
// 3) kg→t 单位判定(文件级:单卷重量最大值超阈值视为 kg)
|
||||
BigDecimal maxCoil = valid.stream()
|
||||
.map(ErpPurchasePlanDeliveryImportVo::getCoilWeight)
|
||||
.filter(w -> w != null)
|
||||
@@ -348,7 +373,7 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
.orElse(BigDecimal.ZERO);
|
||||
boolean kgConverted = maxCoil.compareTo(KG_THRESHOLD) > 0;
|
||||
|
||||
// 3) 卷号去 WMS 钢卷表校验:存在且 data_type<>10 即视为已实际到货入库
|
||||
// 4) 卷号去 WMS 钢卷表校验:存在且 data_type<>10 即视为已实际到货入库
|
||||
List<String> uploadCoilNos = valid.stream()
|
||||
.map(ErpPurchasePlanDeliveryImportVo::getCoilNo)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
@@ -358,13 +383,13 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
: baseMapper.selectExistingSupplierCoilNos(uploadCoilNos).stream()
|
||||
.map(this::normCoil).collect(Collectors.toSet());
|
||||
|
||||
// 4) 先建批次(每次上传存档,可随时回看)
|
||||
// 5) 先建批次(每次上传存档,可随时回看)
|
||||
ErpPurchasePlanDeliveryBatch batch = new ErpPurchasePlanDeliveryBatch();
|
||||
batch.setPlanId(planId);
|
||||
batch.setFileName(StringUtils.isNotBlank(fileName) ? fileName : "到货表");
|
||||
deliveryBatchMapper.insert(batch);
|
||||
|
||||
// 5) 合并单元格向下填充 + 单位换算 + 落库 + WMS到货标记
|
||||
// 6) 合并单元格向下填充 + 单位换算 + 落库 + WMS到货标记
|
||||
String lastTruckNo = null;
|
||||
BigDecimal lastTruckWeight = null;
|
||||
Integer lastPieceCount = null;
|
||||
@@ -401,10 +426,10 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
matched++;
|
||||
}
|
||||
}
|
||||
// 6) 汇总刷新进度
|
||||
// 7) 汇总刷新进度
|
||||
refreshProgress(planId);
|
||||
|
||||
// 7) 回填批次统计(行数、WMS确认到货卷数、上传后进度快照)
|
||||
// 8) 回填批次统计(行数、WMS确认到货卷数、上传后进度快照)
|
||||
ErpPurchasePlan after = baseMapper.selectById(planId);
|
||||
batch.setRowCount(count);
|
||||
batch.setMatchedCount(matched);
|
||||
@@ -492,13 +517,29 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
if (plan == null) {
|
||||
return;
|
||||
}
|
||||
// 到货 = 累计所有上传批次中 WMS 已确认到货(arrived=1)的卷
|
||||
// 到货 = 累计所有上传批次中 WMS 已确认到货的卷。
|
||||
// 每次刷新都拿卷号去 WMS 钢卷表实时复核:之前未到、后来签收入库的,这里会自动翻成已到货,无需重新上传。
|
||||
List<ErpPurchasePlanDelivery> deliveries = deliveryMapper.selectList(Wrappers.lambdaQuery(ErpPurchasePlanDelivery.class)
|
||||
.eq(ErpPurchasePlanDelivery::getPlanId, planId));
|
||||
List<String> coilNos = deliveries.stream()
|
||||
.map(ErpPurchasePlanDelivery::getCoilNo)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toList());
|
||||
Set<String> wmsArrivedSet = coilNos.isEmpty() ? new HashSet<>()
|
||||
: baseMapper.selectExistingSupplierCoilNos(coilNos).stream()
|
||||
.map(this::normCoil).collect(Collectors.toSet());
|
||||
|
||||
int arrivedCount = 0;
|
||||
BigDecimal arrivedWeight = BigDecimal.ZERO;
|
||||
for (ErpPurchasePlanDelivery d : deliveries) {
|
||||
if (d.getArrived() != null && d.getArrived() == 1) {
|
||||
int nowArrived = StringUtils.isNotBlank(d.getCoilNo()) && wmsArrivedSet.contains(normCoil(d.getCoilNo())) ? 1 : 0;
|
||||
// 状态有变化才回写,减少无谓更新
|
||||
if (d.getArrived() == null || d.getArrived() != nowArrived) {
|
||||
d.setArrived(nowArrived);
|
||||
deliveryMapper.updateById(d);
|
||||
}
|
||||
if (nowArrived == 1) {
|
||||
arrivedCount++;
|
||||
arrivedWeight = arrivedWeight.add(d.getCoilWeight() == null ? BigDecimal.ZERO : d.getCoilWeight());
|
||||
}
|
||||
|
||||
@@ -124,6 +124,14 @@ export function listDeliveryPlans(query) {
|
||||
})
|
||||
}
|
||||
|
||||
// 刷新到货(拿已上传卷号去 WMS 实时复核,签收的自动翻为已到货)
|
||||
export function refreshArrival(planId) {
|
||||
return request({
|
||||
url: `/erp/purchasePlan/${planId}/refreshArrival`,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
// 某计划的到货上传批次(每次上传一条)
|
||||
export function listDeliveryBatches(planId) {
|
||||
return request({
|
||||
|
||||
@@ -59,16 +59,19 @@
|
||||
<span class="pd-d-title">{{ current.planNo }}</span>
|
||||
<span class="pd-badge" :class="current.planStatus === '1' ? 'p1' : 'p0'">{{ current.planStatus === '1' ? '已到齐' : '到货中' }}</span>
|
||||
</div>
|
||||
<el-upload
|
||||
:headers="upload.headers"
|
||||
:action="uploadUrl"
|
||||
:show-file-list="false"
|
||||
accept=".xlsx,.xls"
|
||||
:on-success="handleUploadSuccess"
|
||||
:on-error="handleUploadError"
|
||||
>
|
||||
<el-button type="primary" size="small" icon="el-icon-upload2">上传到货表格</el-button>
|
||||
</el-upload>
|
||||
<div class="pd-head-act">
|
||||
<el-button size="small" icon="el-icon-refresh" :loading="refreshing" @click="doRefreshArrival">刷新到货</el-button>
|
||||
<el-upload
|
||||
:headers="upload.headers"
|
||||
:action="uploadUrl"
|
||||
:show-file-list="false"
|
||||
accept=".xlsx,.xls"
|
||||
:on-success="handleUploadSuccess"
|
||||
:on-error="handleUploadError"
|
||||
>
|
||||
<el-button type="primary" size="small" icon="el-icon-upload2">上传到货表格</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pd-meta">
|
||||
@@ -169,7 +172,8 @@ import {
|
||||
getPurchasePlan,
|
||||
listDeliveryPlans,
|
||||
listDeliveryBatches,
|
||||
listDeliveryByBatch
|
||||
listDeliveryByBatch,
|
||||
refreshArrival
|
||||
} from '@/api/erp/purchasePlan'
|
||||
import { getToken } from '@/utils/auth'
|
||||
|
||||
@@ -188,6 +192,7 @@ export default {
|
||||
currentBatch: {},
|
||||
batchRows: [],
|
||||
batchRowsLoading: false,
|
||||
refreshing: false,
|
||||
upload: { headers: { Authorization: 'Bearer ' + getToken() } },
|
||||
progressColor: '#5b8db8'
|
||||
}
|
||||
@@ -222,7 +227,11 @@ export default {
|
||||
this.current = { ...p }
|
||||
this.currentBatch = {}
|
||||
this.batchRows = []
|
||||
this.refreshDetail()
|
||||
// 打开即静默复核一次 WMS 到货状态,保证看到的是最新
|
||||
const planId = p.planId
|
||||
refreshArrival(planId).catch(() => {}).finally(() => {
|
||||
if (this.current.planId === planId) this.refreshDetail()
|
||||
})
|
||||
},
|
||||
refreshDetail() {
|
||||
const planId = this.current.planId
|
||||
@@ -230,6 +239,16 @@ export default {
|
||||
getPurchasePlan(planId).then(res => { this.current = { ...this.current, ...(res.data || {}) } })
|
||||
this.loadBatches()
|
||||
},
|
||||
doRefreshArrival() {
|
||||
if (!this.current.planId) return
|
||||
this.refreshing = true
|
||||
refreshArrival(this.current.planId).then(() => {
|
||||
this.$modal.msgSuccess('已按钢卷表刷新到货状态')
|
||||
this.refreshDetail()
|
||||
if (this.currentBatch.batchId) this.viewBatch(this.currentBatch)
|
||||
this.getList(true)
|
||||
}).finally(() => { this.refreshing = false })
|
||||
},
|
||||
loadBatches() {
|
||||
this.batchLoading = true
|
||||
listDeliveryBatches(this.current.planId).then(res => {
|
||||
@@ -302,6 +321,7 @@ $sub: #909399;
|
||||
p { font-size: 13px; }
|
||||
}
|
||||
.pd-d-head { display: flex; justify-content: space-between; align-items: center; padding: 14px 18px; border-bottom: 1px solid $line; }
|
||||
.pd-head-act { display: flex; gap: 10px; align-items: center; ::v-deep .el-button { margin: 0; } }
|
||||
.pd-d-title { font-size: 15px; font-weight: 600; color: $ink; margin-right: 8px; }
|
||||
.pd-badge {
|
||||
font-size: 11px; line-height: 16px; padding: 0 6px; border-radius: 2px; border: 1px solid #dcdfe6; color: $sub; background: #fafafa;
|
||||
|
||||
Reference in New Issue
Block a user