修改同步落库

This commit is contained in:
wuweihua
2026-10-27 00:04:21 +08:00
parent 2bae431e74
commit 7924450b89
7 changed files with 90 additions and 249 deletions
@@ -170,7 +170,7 @@ public class TabOrderMonitorController extends BaseController
customerKeywordResolver.resolve(query); customerKeywordResolver.resolve(query);
String asyncTaskId = UUID.randomUUID().toString().replace("-", ""); String asyncTaskId = UUID.randomUUID().toString().replace("-", "");
tabOrderCompareAsyncRunner.put(asyncTaskId, TabOrderCompareTask.STATUS_PENDING, 0, "queued", tabOrderCompareAsyncRunner.put(asyncTaskId, TabOrderCompareTask.STATUS_PENDING, 0, "queued",
0, 0, 0, 0, null, null, null); 0, 0, 0, null, null);
tabOrderCompareAsyncRunner.run(asyncTaskId, query); tabOrderCompareAsyncRunner.run(asyncTaskId, query);
Map<String, Object> data = new HashMap<String, Object>(); Map<String, Object> data = new HashMap<String, Object>();
data.put("asyncTaskId", asyncTaskId); data.put("asyncTaskId", asyncTaskId);
@@ -7,8 +7,8 @@ import java.util.Map;
/** /**
* 订单比对异步任务进度(Redis)。 * 订单比对异步任务进度(Redis)。
* missing = 上游有转单号、本地无; * missing = 上游有转单号、本地在指定状态集合中无对应单;
* statusMismatch = 本地有转单号但 order_status 与上游不一致。 * statusMismatch 已废弃(恒为 0,不再比对状态)。
*/ */
public class TabOrderCompareTask implements Serializable public class TabOrderCompareTask implements Serializable
{ {
@@ -39,14 +39,16 @@ public interface PrcOrderBillMapper
List<String> selectExistingOrderIdentifiers(@Param("identifiers") List<String> identifiers, List<String> selectExistingOrderIdentifiers(@Param("identifiers") List<String> identifiers,
@Param("customerCodes") List<String> customerCodes); @Param("customerCodes") List<String> customerCodes);
/** 订单比对:仅按转单号批量查本地已存在。 */ /** 订单比对:仅按转单号批量查本地已存在(可选 order_status 过滤)。 */
List<String> selectExistingTransferNos(@Param("transferNos") List<String> transferNos, List<String> selectExistingTransferNos(@Param("transferNos") List<String> transferNos,
@Param("customerCodes") List<String> customerCodes); @Param("customerCodes") List<String> customerCodes,
@Param("orderStatuses") List<Integer> orderStatuses);
/** 订单比对:按转单号批量查本地 transfer_no + order_status。 */ /** 订单比对:按转单号批量查本地 transfer_no + order_status。 */
List<java.util.Map<String, Object>> selectTransferOrderStatuses( List<java.util.Map<String, Object>> selectTransferOrderStatuses(
@Param("transferNos") List<String> transferNos, @Param("transferNos") List<String> transferNos,
@Param("customerCodes") List<String> customerCodes); @Param("customerCodes") List<String> customerCodes,
@Param("orderStatuses") List<Integer> orderStatuses);
/** 订单号下拉搜索(带数据权限) */ /** 订单号下拉搜索(带数据权限) */
public List<String> selectOrderNoOptions(@Param("query") PrcOrderBill query, @Param("limit") int limit); public List<String> selectOrderNoOptions(@Param("query") PrcOrderBill query, @Param("limit") int limit);
@@ -1,11 +1,14 @@
package com.bms.price.task; package com.bms.price.task;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -22,7 +25,8 @@ import com.bms.price.search.IBillSearchStore;
import com.bms.price.search.TabOrderSyncEsLog; import com.bms.price.search.TabOrderSyncEsLog;
/** /**
* 订单比对异步任务:分页拉上游转单号+状态,与本地 transfer_no / order_status 比对。 * 订单比对异步任务:分页拉上游转单号,与本地 transfer_no 比对是否缺失。
* 上游扫描与本地匹配均使用列表「订单状态」筛选;不再比对/列出状态不一致。
*/ */
@Component @Component
public class TabOrderCompareAsyncRunner public class TabOrderCompareAsyncRunner
@@ -36,8 +40,12 @@ public class TabOrderCompareAsyncRunner
public static final int SCAN_HARD_LIMIT = 50000; public static final int SCAN_HARD_LIMIT = 50000;
/** 进度/抽屉中保留的缺失转单号上限 */ /** 进度/抽屉中保留的缺失转单号上限 */
public static final int MISSING_SAMPLE_LIMIT = 5000; public static final int MISSING_SAMPLE_LIMIT = 5000;
/** 状态不一致样本上限 */
public static final int STATUS_MISMATCH_SAMPLE_LIMIT = 5000; /** Fallback when search orderStatuses empty (same as order-source list default). */
public static final List<Integer> COMPARE_LOCAL_ORDER_STATUSES =
Collections.unmodifiableList(Arrays.asList(
Integer.valueOf(3), Integer.valueOf(4), Integer.valueOf(5), Integer.valueOf(6),
Integer.valueOf(7), Integer.valueOf(8), Integer.valueOf(11)));
@Autowired @Autowired
private TabOrderMonitorService tabOrderMonitorService; private TabOrderMonitorService tabOrderMonitorService;
@@ -63,14 +71,18 @@ public class TabOrderCompareAsyncRunner
query.setOrgOrderId(null); query.setOrgOrderId(null);
query.setTransferOrderId(null); query.setTransferOrderId(null);
} }
// Use list filter orderStatuses for both upstream scan and local match (no hardcode).
List<Integer> compareStatuses = resolveCompareStatuses(query);
if (query != null)
{
query.setOrderStatuses(new ArrayList<Integer>(compareStatuses));
}
put(asyncTaskId, TabOrderCompareTask.STATUS_RUNNING, 0, "starting", put(asyncTaskId, TabOrderCompareTask.STATUS_RUNNING, 0, "starting",
0, 0, 0, 0, null, null, null); 0, 0, 0, null, null);
int scanned = 0; int scanned = 0;
int matched = 0; int matched = 0;
int missing = 0; int missing = 0;
int statusMismatch = 0;
List<String> missingSample = new ArrayList<String>(); List<String> missingSample = new ArrayList<String>();
List<Map<String, Object>> statusMismatchSample = new ArrayList<Map<String, Object>>();
int pageNum = 1; int pageNum = 1;
while (true) while (true)
{ {
@@ -96,8 +108,8 @@ public class TabOrderCompareAsyncRunner
transferNos.add(String.valueOf(tn).trim()); transferNos.add(String.valueOf(tn).trim());
} }
} }
Map<String, Integer> localStatusByTn = Set<String> localTns = findLocalTransferNos(
findLocalStatuses(transferNos, query == null ? null : query.getCustomerCodes()); transferNos, query == null ? null : query.getCustomerCodes(), compareStatuses);
for (Map<String, Object> row : pageRows) for (Map<String, Object> row : pageRows)
{ {
if (row == null) if (row == null)
@@ -112,8 +124,7 @@ public class TabOrderCompareAsyncRunner
String tn = String.valueOf(tnObj).trim(); String tn = String.valueOf(tnObj).trim();
scanned++; scanned++;
String key = tn.toUpperCase(Locale.ROOT); String key = tn.toUpperCase(Locale.ROOT);
Integer upstreamStatus = toInteger(row.get("orderStatus")); if (!localTns.contains(key))
if (!localStatusByTn.containsKey(key))
{ {
missing++; missing++;
if (missingSample.size() < MISSING_SAMPLE_LIMIT) if (missingSample.size() < MISSING_SAMPLE_LIMIT)
@@ -123,19 +134,6 @@ public class TabOrderCompareAsyncRunner
continue; continue;
} }
matched++; matched++;
Integer localStatus = localStatusByTn.get(key);
if (!statusEquals(upstreamStatus, localStatus))
{
statusMismatch++;
if (statusMismatchSample.size() < STATUS_MISMATCH_SAMPLE_LIMIT)
{
Map<String, Object> one = new LinkedHashMap<String, Object>();
one.put("transferNo", tn);
one.put("upstreamStatus", upstreamStatus);
one.put("localStatus", localStatus);
statusMismatchSample.add(one);
}
}
} }
int percent = Math.min(99, (int) ((scanned * 100L) / Math.max(scanned + pageSize, 1))); int percent = Math.min(99, (int) ((scanned * 100L) / Math.max(scanned + pageSize, 1)));
if (pageRows.size() < pageSize) if (pageRows.size() < pageSize)
@@ -143,9 +141,8 @@ public class TabOrderCompareAsyncRunner
percent = 99; percent = 99;
} }
put(asyncTaskId, TabOrderCompareTask.STATUS_RUNNING, percent, put(asyncTaskId, TabOrderCompareTask.STATUS_RUNNING, percent,
"scanning page=" + pageNum + " scanned=" + scanned "scanning page=" + pageNum + " scanned=" + scanned + " missing=" + missing,
+ " missing=" + missing + " statusMismatch=" + statusMismatch, scanned, matched, missing, null, missingSample);
scanned, matched, missing, statusMismatch, null, missingSample, statusMismatchSample);
if (pageRows.size() < pageSize) if (pageRows.size() < pageSize)
{ {
break; break;
@@ -157,30 +154,19 @@ public class TabOrderCompareAsyncRunner
resp.put("scanned", Integer.valueOf(scanned)); resp.put("scanned", Integer.valueOf(scanned));
resp.put("matched", Integer.valueOf(matched)); resp.put("matched", Integer.valueOf(matched));
resp.put("missing", Integer.valueOf(missing)); resp.put("missing", Integer.valueOf(missing));
resp.put("statusMismatch", Integer.valueOf(statusMismatch)); resp.put("statusMismatch", Integer.valueOf(0));
resp.put("missingTransferNos", missingSample); resp.put("missingTransferNos", missingSample);
resp.put("statusMismatchSamples", statusMismatchSample); resp.put("statusMismatchSamples", Collections.emptyList());
List<String> mismatchTns = new ArrayList<String>(); resp.put("statusMismatchTransferNos", Collections.emptyList());
for (Map<String, Object> one : statusMismatchSample)
{
if (one == null) { continue; }
Object tn = one.get("transferNo");
if (tn != null && StringUtils.isNotEmpty(String.valueOf(tn).trim()))
{
mismatchTns.add(String.valueOf(tn).trim());
}
}
resp.put("statusMismatchTransferNos", mismatchTns);
resp.put("missingTruncated", Boolean.valueOf(missing > missingSample.size())); resp.put("missingTruncated", Boolean.valueOf(missing > missingSample.size()));
resp.put("statusMismatchTruncated", resp.put("statusMismatchTruncated", Boolean.FALSE);
Boolean.valueOf(statusMismatch > statusMismatchSample.size()));
put(asyncTaskId, TabOrderCompareTask.STATUS_SUCCESS, 100, put(asyncTaskId, TabOrderCompareTask.STATUS_SUCCESS, 100,
"done scanned=" + scanned + " missing=" + missing + " statusMismatch=" + statusMismatch, "done scanned=" + scanned + " missing=" + missing,
scanned, matched, missing, statusMismatch, null, missingSample, statusMismatchSample); scanned, matched, missing, null, missingSample);
TabOrderSyncEsLog.save(billSearchStore, asyncTaskId, "COMPARE_DONE", query, resp, "SUCCESS", null); TabOrderSyncEsLog.save(billSearchStore, asyncTaskId, "COMPARE_DONE", query, resp, "SUCCESS", null);
log.info("orderSource compare done asyncTaskId={} scanned={} matched={} missing={} statusMismatch={}", log.info("orderSource compare done asyncTaskId={} scanned={} matched={} missing={}",
asyncTaskId, Integer.valueOf(scanned), Integer.valueOf(matched), asyncTaskId, Integer.valueOf(scanned), Integer.valueOf(matched),
Integer.valueOf(missing), Integer.valueOf(statusMismatch)); Integer.valueOf(missing));
} }
catch (Exception e) catch (Exception e)
{ {
@@ -191,100 +177,56 @@ public class TabOrderCompareAsyncRunner
msg = e.getClass().getSimpleName(); msg = e.getClass().getSimpleName();
} }
put(asyncTaskId, TabOrderCompareTask.STATUS_FAIL, 100, "failed", put(asyncTaskId, TabOrderCompareTask.STATUS_FAIL, 100, "failed",
0, 0, 0, 0, msg, null, null); 0, 0, 0, msg, null);
TabOrderSyncEsLog.save(billSearchStore, asyncTaskId, "COMPARE_DONE", query, null, "FAIL", msg); TabOrderSyncEsLog.save(billSearchStore, asyncTaskId, "COMPARE_DONE", query, null, "FAIL", msg);
} }
} }
/** transferNo(upper) -> local order_status (null value means local row exists with null status). */ /**
private Map<String, Integer> findLocalStatuses(List<String> transferNos, List<String> customerCodes) * Prefer search filter orderStatuses; if empty, same default as order-source list
* (3/4/5/6/7/8/11) so SQL still has an IN list.
*/
private static List<Integer> resolveCompareStatuses(TabOrderMonitorQuery query)
{ {
Map<String, Integer> found = new HashMap<String, Integer>(); List<Integer> cleaned = new ArrayList<Integer>();
if (query != null && query.getOrderStatuses() != null)
{
for (Integer s : query.getOrderStatuses())
{
if (s != null)
{
cleaned.add(s);
}
}
}
return cleaned.isEmpty() ? new ArrayList<Integer>(COMPARE_LOCAL_ORDER_STATUSES) : cleaned;
}
/** transferNo(upper) present locally with the given order_status filter. */
private Set<String> findLocalTransferNos(List<String> transferNos, List<String> customerCodes,
List<Integer> orderStatuses)
{
Set<String> found = new HashSet<String>();
if (transferNos == null || transferNos.isEmpty()) if (transferNos == null || transferNos.isEmpty())
{ {
return found; return found;
} }
List<Map<String, Object>> rows = List<String> rows = prcOrderBillMapper.selectExistingTransferNos(
prcOrderBillMapper.selectTransferOrderStatuses(transferNos, cleanCodes(customerCodes)); transferNos, cleanCodes(customerCodes), orderStatuses);
if (rows == null) if (rows == null)
{ {
return found; return found;
} }
for (Map<String, Object> row : rows) for (String tn : rows)
{ {
if (row == null) if (StringUtils.isNotEmpty(tn))
{ {
continue; found.add(tn.trim().toUpperCase(Locale.ROOT));
}
Object tn = first(row, "transferNo", "TRANSFERNO", "transfer_no");
if (tn == null || StringUtils.isEmpty(String.valueOf(tn).trim()))
{
continue;
}
String key = String.valueOf(tn).trim().toUpperCase(Locale.ROOT);
Integer st = toInteger(first(row, "orderStatus", "ORDERSTATUS", "order_status"));
// Keep first hit; duplicate transfer_no rare.
if (!found.containsKey(key))
{
found.put(key, st);
} }
} }
return found; return found;
} }
private static Object first(Map<String, Object> row, String... keys)
{
if (row == null || keys == null)
{
return null;
}
for (String k : keys)
{
if (row.containsKey(k) && row.get(k) != null)
{
return row.get(k);
}
}
return null;
}
private static Integer toInteger(Object v)
{
if (v == null || "".equals(String.valueOf(v).trim()))
{
return null;
}
if (v instanceof Integer)
{
return (Integer) v;
}
if (v instanceof Number)
{
return Integer.valueOf(((Number) v).intValue());
}
try
{
return Integer.valueOf(String.valueOf(v).trim());
}
catch (Exception e)
{
return null;
}
}
private static boolean statusEquals(Integer a, Integer b)
{
if (a == null && b == null)
{
return true;
}
if (a == null || b == null)
{
return false;
}
return a.intValue() == b.intValue();
}
private static List<String> cleanCodes(List<String> codes) private static List<String> cleanCodes(List<String> codes)
{ {
if (codes == null || codes.isEmpty()) if (codes == null || codes.isEmpty())
@@ -303,8 +245,7 @@ public class TabOrderCompareAsyncRunner
} }
public void put(String taskId, String status, int percent, String message, public void put(String taskId, String status, int percent, String message,
int scanned, int matched, int missing, int statusMismatch, String error, int scanned, int matched, int missing, String error, List<String> missingSample)
List<String> missingSample, List<Map<String, Object>> statusMismatchSample)
{ {
TabOrderCompareTask task = new TabOrderCompareTask(); TabOrderCompareTask task = new TabOrderCompareTask();
task.setTaskId(taskId); task.setTaskId(taskId);
@@ -314,27 +255,14 @@ public class TabOrderCompareAsyncRunner
task.setScanned(scanned); task.setScanned(scanned);
task.setMatched(matched); task.setMatched(matched);
task.setMissing(missing); task.setMissing(missing);
task.setStatusMismatch(statusMismatch); task.setStatusMismatch(0);
task.setError(error); task.setError(error);
if (missingSample != null) if (missingSample != null)
{ {
task.setMissingTransferNos(new ArrayList<String>(missingSample)); task.setMissingTransferNos(new ArrayList<String>(missingSample));
} }
if (statusMismatchSample != null) task.setStatusMismatchSamples(new ArrayList<Map<String, Object>>());
{ task.setStatusMismatchTransferNos(new ArrayList<String>());
task.setStatusMismatchSamples(new ArrayList<Map<String, Object>>(statusMismatchSample));
List<String> tnList = new ArrayList<String>();
for (Map<String, Object> one : statusMismatchSample)
{
if (one == null) { continue; }
Object tn = one.get("transferNo");
if (tn != null && StringUtils.isNotEmpty(String.valueOf(tn).trim()))
{
tnList.add(String.valueOf(tn).trim());
}
}
task.setStatusMismatchTransferNos(tnList);
}
redisCache.setCacheObject(CACHE_KEY_PREFIX + taskId, task, TTL_MINUTES, TimeUnit.MINUTES); redisCache.setCacheObject(CACHE_KEY_PREFIX + taskId, task, TTL_MINUTES, TimeUnit.MINUTES);
} }
@@ -216,11 +216,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<foreach collection="customerCodes" item="ccode" open="(" separator="," close=")"> <foreach collection="customerCodes" item="ccode" open="(" separator="," close=")">
#{ccode} #{ccode}
</foreach> </foreach>
</if>
<if test="orderStatuses != null and orderStatuses.size() > 0">
AND p.order_status IN
<foreach collection="orderStatuses" item="st" open="(" separator="," close=")">
#{st}
</foreach>
</if> </if>
AND p.transfer_no IS NOT NULL AND p.transfer_no != '' AND p.transfer_no IS NOT NULL AND p.transfer_no != ''
</select> </select>
<!-- 订单比对:本地转单号 + 订单状态(用于状态一致性比对) --> <!-- 订单比对:本地转单号 + 订单状态 -->
<select id="selectTransferOrderStatuses" resultType="java.util.HashMap"> <select id="selectTransferOrderStatuses" resultType="java.util.HashMap">
SELECT p.transfer_no AS transferNo, p.order_status AS orderStatus SELECT p.transfer_no AS transferNo, p.order_status AS orderStatus
FROM prc_order_bill p FROM prc_order_bill p
@@ -233,6 +239,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<foreach collection="customerCodes" item="ccode" open="(" separator="," close=")"> <foreach collection="customerCodes" item="ccode" open="(" separator="," close=")">
#{ccode} #{ccode}
</foreach> </foreach>
</if>
<if test="orderStatuses != null and orderStatuses.size() > 0">
AND p.order_status IN
<foreach collection="orderStatuses" item="st" open="(" separator="," close=")">
#{st}
</foreach>
</if> </if>
AND p.transfer_no IS NOT NULL AND p.transfer_no != '' AND p.transfer_no IS NOT NULL AND p.transfer_no != ''
</select> </select>
@@ -31,7 +31,6 @@
已扫描 {{ progress.scanned || 0 }} 已扫描 {{ progress.scanned || 0 }}
/ 本地已有 {{ progress.matched || 0 }} / 本地已有 {{ progress.matched || 0 }}
/ 本地缺失 {{ progress.missing || 0 }} / 本地缺失 {{ progress.missing || 0 }}
/ 状态不一致 {{ progress.statusMismatch || 0 }}
</div> </div>
<div v-if="progress.message" class="msg-line">{{ progress.message }}</div> <div v-if="progress.message" class="msg-line">{{ progress.message }}</div>
<div v-if="progress.error" class="err-line">{{ progress.error }}</div> <div v-if="progress.error" class="err-line">{{ progress.error }}</div>
@@ -41,34 +40,7 @@
type="info" type="info"
:closable="false" :closable="false"
show-icon show-icon
title="比对转单号 + 订单状态:1) 上游有转单号、本地没有;2) 两端都有但 order_status 不一致。异步分页扫描,结果已写入操作记录。" title="仅比对转单号是否已落库:上游有、本地在当前「订单状态」筛选范围内没有。不再比对状态一致性。"
/>
<div class="json-panel__head">
<span>状态不一致(样本 {{ statusMismatchCount }})</span>
<el-button
type="primary"
link
:disabled="!canFillMismatch"
@click="fillMismatchToSearch"
>回填到单号搜索</el-button>
</div>
<el-table
v-if="statusMismatchRows.length"
:data="statusMismatchRows"
border
size="small"
max-height="320"
class="mb12"
>
<el-table-column type="index" width="55" label="#" />
<el-table-column prop="transferNo" label="转单号" min-width="180" show-overflow-tooltip />
<el-table-column prop="upstreamStatusLabel" label="上游状态" width="110" />
<el-table-column prop="localStatusLabel" label="本地状态" width="110" />
</el-table>
<el-empty
v-else-if="!running"
description="暂无状态不一致"
/> />
<div class="json-panel__head"> <div class="json-panel__head">
@@ -159,65 +131,6 @@ const progressStatus = computed(() => {
return undefined return undefined
}) })
const orderStatusMap = {
'0': '待提货',
'1': '已提货',
'2': '已收货',
'3': '运输中',
'4': '派送中',
'5': '已签收',
'6': '已完成',
'7': '已取消',
'8': '异常',
'9': '退件中',
'10': '已退件'
}
function labelStatus(v) {
const k = v == null ? '' : String(v).trim()
if (!k) return '-'
return orderStatusMap[k] || k
}
function normalizeMismatchList(raw) {
if (!Array.isArray(raw)) return []
return raw.map(row => {
if (row == null) return null
if (typeof row === 'string') {
return { transferNo: row, upstreamStatus: null, localStatus: null }
}
return {
transferNo: row.transferNo || row.transfer_no || '',
upstreamStatus: row.upstreamStatus ?? row.upstream_status ?? null,
localStatus: row.localStatus ?? row.local_status ?? null
}
}).filter(Boolean)
}
const statusMismatchRows = computed(() => {
const samples = normalizeMismatchList(progress.value?.statusMismatchSamples)
if (samples.length) {
return samples.map(row => ({
transferNo: row.transferNo,
upstreamStatusLabel: labelStatus(row.upstreamStatus),
localStatusLabel: labelStatus(row.localStatus)
}))
}
// fallback: flat transfer_no list when map samples missing
const flat = progress.value?.statusMismatchTransferNos || []
return (Array.isArray(flat) ? flat : []).map(tn => ({
transferNo: tn,
upstreamStatusLabel: '-',
localStatusLabel: '-'
}))
})
const statusMismatchCount = computed(() => {
const n = Number(progress.value?.statusMismatch)
if (!Number.isNaN(n) && n > 0) return n
return statusMismatchRows.value.length
})
const missingRows = computed(() => { const missingRows = computed(() => {
const list = progress.value?.missingTransferNos || [] const list = progress.value?.missingTransferNos || []
return (Array.isArray(list) ? list : []).map(tn => ({ transferNo: tn })) return (Array.isArray(list) ? list : []).map(tn => ({ transferNo: tn }))
@@ -233,9 +146,6 @@ const canFillSearch = computed(() => {
return !running.value && missingRows.value.length > 0 return !running.value && missingRows.value.length > 0
}) })
const canFillMismatch = computed(() => {
return !running.value && statusMismatchRows.value.length > 0
})
function fillToSearch() { function fillToSearch() {
const list = missingRows.value.map(r => String(r.transferNo || '').trim()).filter(Boolean) const list = missingRows.value.map(r => String(r.transferNo || '').trim()).filter(Boolean)
@@ -248,17 +158,6 @@ function fillToSearch() {
visible.value = false visible.value = false
} }
function fillMismatchToSearch() {
const list = statusMismatchRows.value.map(r => String(r.transferNo || '').trim()).filter(Boolean)
if (!list.length) {
ElMessage.warning('暂无可回填的状态不一致转单号')
return
}
const truncated = !!(progress.value?.statusMismatchTruncated)
|| (Number(progress.value?.statusMismatch || 0) > list.length)
emit('fill-search', { transferNos: list, truncated })
visible.value = false
}
function clearTimer() { function clearTimer() {
if (timer) { if (timer) {
@@ -291,7 +190,7 @@ function open(q) {
ElMessage.error('启动比对任务失败') ElMessage.error('启动比对任务失败')
return return
} }
progress.value = { status: 'PENDING', percent: 0, message: 'queued', scanned: 0, matched: 0, missing: 0, statusMismatch: 0 } progress.value = { status: 'PENDING', percent: 0, message: 'queued', scanned: 0, matched: 0, missing: 0 }
poll() poll()
timer = setInterval(poll, 1500) timer = setInterval(poll, 1500)
}).catch(() => { }).catch(() => {
@@ -421,7 +421,7 @@ function openOrderCompare() {
return return
} }
proxy.$modal.confirm( proxy.$modal.confirm(
'将按当前客户与提货时间,异步分页比对上游转单号与订单状态(缺失转单号 + 状态不一致),确认继续?', '将按当前客户、提货时间与订单状态筛选,异步分页比对上游转单号是否已落库,确认继续?',
'二次确认' '二次确认'
).then(() => { ).then(() => {
// 比对只按客户+时间;不带单号框内容(回填后可能有数千转单号,带上会把比对拖死) // 比对只按客户+时间;不带单号框内容(回填后可能有数千转单号,带上会把比对拖死)