订单增加状态搜索
This commit is contained in:
@@ -38,6 +38,11 @@ public class TabOrderMonitorQuery implements Serializable
|
||||
private List<String> orderIdentifiers;
|
||||
/** 上游产品代码 LINE_CODE(产品比对点进订单号时使用) */
|
||||
private String productCode;
|
||||
/**
|
||||
* 订单状态 ORDER_STATUS 多选。
|
||||
* 空则服务端回落默认 3,4,5,6,7,8,11(与历史硬编码一致)。
|
||||
*/
|
||||
private List<Integer> orderStatuses;
|
||||
/** 分批同步计费每批条数 */
|
||||
private Integer batchSize;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.bms.price.enums;
|
||||
|
||||
/**
|
||||
* Snapshot of prc_order_bill.order_status (aligned with upstream TAB_ORDER).
|
||||
* Fee refund sets {@link #REFUNDED} (9 / 已退件).
|
||||
*/
|
||||
public enum BillOrderStatus
|
||||
{
|
||||
/** Upstream: returned package; also set after billing-list fee refund. */
|
||||
REFUNDED(9);
|
||||
|
||||
private final int code;
|
||||
|
||||
BillOrderStatus(int code)
|
||||
{
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public Integer getCodeBoxed()
|
||||
{
|
||||
return Integer.valueOf(code);
|
||||
}
|
||||
|
||||
public boolean matches(Integer status)
|
||||
{
|
||||
return status != null && status.intValue() == code;
|
||||
}
|
||||
|
||||
public static BillOrderStatus of(Integer status)
|
||||
{
|
||||
if (status == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
for (BillOrderStatus value : values())
|
||||
{
|
||||
if (value.code == status.intValue())
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.bms.price.oracle;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
@@ -71,6 +72,12 @@ public class TabOrderMonitorService
|
||||
/** 单批 Oracle 查询最长等待(从库 socketTimeout 为 120s,留同样余量)。 */
|
||||
private static final long COLLECT_BATCH_TIMEOUT_SECONDS = 120L;
|
||||
|
||||
/** Same default as historical hardcoded ORDER_STATUS IN (...). */
|
||||
private static final List<Integer> DEFAULT_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
|
||||
private OracleUpstreamOrderMapper oracleUpstreamOrderMapper;
|
||||
|
||||
@@ -994,7 +1001,8 @@ public class TabOrderMonitorService
|
||||
appendSorted(sb, q.getCustomerCodes());
|
||||
sb.append('|').append(safe(q.getBeginTime())).append('|').append(safe(q.getEndTime()))
|
||||
.append('|').append(safe(q.getOrderId())).append('|').append(safe(q.getOrgOrderId()))
|
||||
.append('|').append(safe(q.getTransferOrderId()));
|
||||
.append('|').append(safe(q.getTransferOrderId())).append('|');
|
||||
appendSortedInts(sb, q.getOrderStatuses());
|
||||
return Integer.toHexString(sb.toString().hashCode());
|
||||
}
|
||||
|
||||
@@ -1012,6 +1020,20 @@ public class TabOrderMonitorService
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendSortedInts(StringBuilder sb, List<Integer> values)
|
||||
{
|
||||
if (values == null || values.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<Integer> copy = new ArrayList<Integer>(values);
|
||||
Collections.sort(copy);
|
||||
for (Integer v : copy)
|
||||
{
|
||||
sb.append(v).append(',');
|
||||
}
|
||||
}
|
||||
|
||||
private static String safe(String s)
|
||||
{
|
||||
return s == null ? "" : s;
|
||||
@@ -1152,6 +1174,25 @@ public class TabOrderMonitorService
|
||||
query.setOrderId(trimToNull(query.getOrderId()));
|
||||
query.setOrgOrderId(trimToNull(query.getOrgOrderId()));
|
||||
query.setTransferOrderId(trimToNull(query.getTransferOrderId()));
|
||||
normalizeOrderStatuses(query);
|
||||
}
|
||||
|
||||
/** Empty/missing -> default 3,4,5,6,7,8,11 so SQL always has a status IN list. */
|
||||
private static void normalizeOrderStatuses(TabOrderMonitorQuery query)
|
||||
{
|
||||
List<Integer> statuses = query.getOrderStatuses();
|
||||
List<Integer> cleaned = new ArrayList<Integer>();
|
||||
if (statuses != null)
|
||||
{
|
||||
for (Integer s : statuses)
|
||||
{
|
||||
if (s != null)
|
||||
{
|
||||
cleaned.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
query.setOrderStatuses(cleaned.isEmpty() ? new ArrayList<Integer>(DEFAULT_ORDER_STATUSES) : cleaned);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+21
-1
@@ -77,6 +77,7 @@ import com.bms.price.domain.vo.TmsPriceQuoteFeeLine;
|
||||
import com.bms.price.domain.vo.TmsPriceQuoteResult;
|
||||
import com.bms.price.enums.BillCreditArrearsStatus;
|
||||
import com.bms.price.enums.BillCustomerActiveStatus;
|
||||
import com.bms.price.enums.BillOrderStatus;
|
||||
import com.bms.price.enums.BillRefundStatus;
|
||||
import com.bms.price.enums.BillBillingFailStatus;
|
||||
import com.bms.price.enums.TmsOrderBillMatchType;
|
||||
@@ -300,6 +301,8 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService
|
||||
refundFee.setManualFlag("0");
|
||||
incomeBillFeeMapper.insertPrcIncomeBillFee(refundFee);
|
||||
bill.setRefundStatus(BillRefundStatus.REFUNDED.getCode());
|
||||
// Align with upstream 已退件 after fee refund.
|
||||
bill.setOrderStatus(BillOrderStatus.REFUNDED.getCodeBoxed());
|
||||
if (incomeBill != null)
|
||||
{
|
||||
incomeBill.setRefundStatus(BillRefundStatus.REFUNDED.getCode());
|
||||
@@ -315,6 +318,7 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService
|
||||
req.put("refundAmount", feeSum.negate());
|
||||
req.put("feeId", refundFee.getFeeId());
|
||||
req.put("refundStatus", bill.getRefundStatus());
|
||||
req.put("orderStatus", bill.getOrderStatus());
|
||||
if (billSearchStore != null)
|
||||
{
|
||||
billSearchStore.save(EsLogType.BILL,
|
||||
@@ -762,6 +766,7 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.bizDateRequired"));
|
||||
}
|
||||
assertOrderBillNotRefunded(bill);
|
||||
TmsPriceBillRequest req = buildBillRequestFromBill(bill);
|
||||
return billLocalWithDbRetry(billId.trim(), req);
|
||||
}
|
||||
@@ -1631,6 +1636,7 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService
|
||||
String billKey = Md5Utils.hash(orderNo);
|
||||
PrcOrderBill existed = orderBillMapper.selectPrcOrderBillByOrderNo(orderNo);
|
||||
assertOrderBillEditable(existed);
|
||||
assertOrderBillNotRefunded(existed);
|
||||
BigDecimal previousIncome = existed == null ? BigDecimal.ZERO : nz(existed.getIncomeTotal());
|
||||
PrcOrderBill bill = existed == null ? new PrcOrderBill() : existed;
|
||||
if (existed == null)
|
||||
@@ -2087,6 +2093,15 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService
|
||||
}
|
||||
}
|
||||
|
||||
/** Block rebill when refundStatus=REFUNDED (order_status=9 alone is logistics return, not fee refund). */
|
||||
private void assertOrderBillNotRefunded(PrcOrderBill bill)
|
||||
{
|
||||
if (bill != null && BillRefundStatus.REFUNDED.getCode().equalsIgnoreCase(bill.getRefundStatus()))
|
||||
{
|
||||
throw new ServiceException("\u8ba2\u5355\u5df2\u9000\u8d39\uff0c\u4e0d\u53ef\u91cd\u65b0\u8ba1\u8d39");
|
||||
}
|
||||
}
|
||||
|
||||
private static BigDecimal nz(BigDecimal v)
|
||||
{
|
||||
return v == null ? BigDecimal.ZERO : v;
|
||||
@@ -2931,7 +2946,12 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (request.getOrderStatus() != null)
|
||||
// Fee refund marks order_status=9 (已退件); do not let Oracle sync overwrite it.
|
||||
if (BillRefundStatus.REFUNDED.getCode().equalsIgnoreCase(bill.getRefundStatus()))
|
||||
{
|
||||
bill.setOrderStatus(BillOrderStatus.REFUNDED.getCodeBoxed());
|
||||
}
|
||||
else if (request.getOrderStatus() != null)
|
||||
{
|
||||
bill.setOrderStatus(request.getOrderStatus());
|
||||
}
|
||||
|
||||
@@ -67,7 +67,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
AND o.PICKUP_DATE <= TO_DATE(#{query.endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||
</if>
|
||||
AND o.BL_PICKUP = 1
|
||||
AND o.ORDER_STATUS IN (3, 4, 5, 6, 7, 8, 11)
|
||||
<if test="query.orderStatuses != null and query.orderStatuses.size() > 0">
|
||||
AND o.ORDER_STATUS IN
|
||||
<foreach collection="query.orderStatuses" item="st" open="(" separator="," close=")">
|
||||
#{st}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="query.orderStatuses == null or query.orderStatuses.size() == 0">
|
||||
AND o.ORDER_STATUS IN (3, 4, 5, 6, 7, 8, 11)
|
||||
</if>
|
||||
<if test="query.orderId != null and query.orderId != ''">
|
||||
AND o.ORDER_ID = #{query.orderId}
|
||||
</if>
|
||||
|
||||
@@ -213,6 +213,7 @@ function submit(skipConfirm) {
|
||||
orderId: q.orderId || undefined,
|
||||
orgOrderId: q.orgOrderId || undefined,
|
||||
transferOrderId: q.transferOrderId || undefined,
|
||||
orderStatuses: Array.isArray(q.orderStatuses) && q.orderStatuses.length ? q.orderStatuses : undefined,
|
||||
batchSize: 100
|
||||
}).then(res => {
|
||||
const asyncTaskId = res.data?.asyncTaskId || res.data
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:search-columns="searchColumns"
|
||||
:default-params="defaultParams"
|
||||
:query="queryList"
|
||||
row-key="orderId"
|
||||
:auto-load="false"
|
||||
selection
|
||||
search-action-align="center"
|
||||
:search-per-row="4"
|
||||
:page-sizes="[100, 200, 300, 400]"
|
||||
:page-size="100"
|
||||
@@ -83,6 +83,31 @@
|
||||
<template #col-country="{ row }">
|
||||
{{ row.countryName || '-' }} ({{ row.country || '-' }})
|
||||
</template>
|
||||
<template #search-orderStatuses="{ model }">
|
||||
<el-select
|
||||
v-model="model.orderStatuses"
|
||||
multiple
|
||||
clearable
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="请选择"
|
||||
style="width: 100%"
|
||||
>
|
||||
<template #header>
|
||||
<el-checkbox
|
||||
:model-value="isAllOrderStatusSelected(model)"
|
||||
:indeterminate="isOrderStatusIndeterminate(model)"
|
||||
@change="(checked) => toggleAllOrderStatus(model, checked)"
|
||||
>全选</el-checkbox>
|
||||
</template>
|
||||
<el-option
|
||||
v-for="opt in orderStatusOptions"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
<template #col-orderStatus="{ row }">
|
||||
{{ orderStatusLabel(row.orderStatus) }}
|
||||
</template>
|
||||
@@ -130,6 +155,27 @@ const syncFloat = ref(null)
|
||||
/** 比对回填搜索模式:走专用转单号接口,不影响普通列表 */
|
||||
const transferFillMode = ref(false)
|
||||
|
||||
const orderStatusMap = {
|
||||
0: '预报订单',
|
||||
1: '确认订单',
|
||||
2: '已中转',
|
||||
3: '已收货',
|
||||
4: '已装箱',
|
||||
5: '已出库',
|
||||
6: '转运中',
|
||||
7: '已上网',
|
||||
8: '已签收',
|
||||
9: '已退件',
|
||||
10: '已删除',
|
||||
11: '已复核'
|
||||
}
|
||||
|
||||
const orderStatusOptions = Object.keys(orderStatusMap).map(k => ({ label: orderStatusMap[k], value: Number(k) }))
|
||||
|
||||
const defaultParams = {
|
||||
orderStatuses: [3, 4, 5, 6, 7, 8, 11]
|
||||
}
|
||||
|
||||
const searchColumns = [
|
||||
{
|
||||
// 客户名称或客户代码混合录入,一行一个
|
||||
@@ -164,7 +210,20 @@ const searchColumns = [
|
||||
clearable: true,
|
||||
defaultTime: [new Date(2000, 0, 1, 0, 0, 0), new Date(2000, 0, 1, 23, 59, 59)]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '订单状态',
|
||||
prop: 'orderStatuses',
|
||||
component: 'select',
|
||||
options: orderStatusOptions,
|
||||
placeholder: '请选择',
|
||||
props: {
|
||||
multiple: true,
|
||||
clearable: true,
|
||||
collapseTags: true,
|
||||
collapseTagsTooltip: true
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
const columns = [
|
||||
@@ -186,21 +245,6 @@ const columns = [
|
||||
// { label: '操作', prop: 'action', align: 'center', width: 120, fixed: 'right', slot: 'action', showInToolbar: false }
|
||||
]
|
||||
|
||||
const orderStatusMap = {
|
||||
0: '预报订单',
|
||||
1: '确认订单',
|
||||
2: '已中转',
|
||||
3: '已收货',
|
||||
4: '已装箱',
|
||||
5: '已出库',
|
||||
6: '转运中',
|
||||
7: '已上网',
|
||||
8: '已签收',
|
||||
9: '已退件',
|
||||
10: '已删除',
|
||||
11: '已复核'
|
||||
}
|
||||
|
||||
const syncFloatVisible = computed(() => {
|
||||
const p = syncFloat.value
|
||||
return !!(p && (p.loading || p.finished))
|
||||
@@ -220,6 +264,30 @@ const syncFloatSummary = computed(() => {
|
||||
})
|
||||
const syncFloatTooltip = computed(() => syncFloat.value?.message || '点击查看详情')
|
||||
|
||||
|
||||
const orderStatusAllValues = computed(() => orderStatusOptions.map(o => o.value))
|
||||
|
||||
function selectedOrderStatuses(model) {
|
||||
return Array.isArray(model?.orderStatuses) ? model.orderStatuses : []
|
||||
}
|
||||
|
||||
function isAllOrderStatusSelected(model) {
|
||||
const selected = selectedOrderStatuses(model)
|
||||
const all = orderStatusAllValues.value
|
||||
return all.length > 0 && selected.length === all.length
|
||||
}
|
||||
|
||||
function isOrderStatusIndeterminate(model) {
|
||||
const selected = selectedOrderStatuses(model)
|
||||
const all = orderStatusAllValues.value
|
||||
return selected.length > 0 && selected.length < all.length
|
||||
}
|
||||
|
||||
function toggleAllOrderStatus(model, checked) {
|
||||
if (!model) return
|
||||
model.orderStatuses = checked ? [...orderStatusAllValues.value] : []
|
||||
}
|
||||
|
||||
function orderStatusLabel(status) {
|
||||
if (status === null || status === undefined || status === '') return '-'
|
||||
const key = Number(status)
|
||||
|
||||
Reference in New Issue
Block a user