增加订单复选搜索
This commit is contained in:
+50
-7
@@ -3415,7 +3415,7 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
||||
}
|
||||
PrcPriceSetVersion effect = null;
|
||||
PrcPriceSetVersion pending = null;
|
||||
PrcPriceSetVersion best = null;
|
||||
List<PrcPriceSetVersion> ranked = new ArrayList<PrcPriceSetVersion>();
|
||||
for (PrcPriceSetVersion v : list)
|
||||
{
|
||||
if (v == null || v.getPsvId() == null)
|
||||
@@ -3434,15 +3434,58 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
||||
{
|
||||
pending = v;
|
||||
}
|
||||
if (best == null || (v.getVersionSeq() != null && best.getVersionSeq() != null
|
||||
&& v.getVersionSeq().intValue() > best.getVersionSeq().intValue())
|
||||
|| (best.getVersionSeq() == null && v.getVersionSeq() != null))
|
||||
}
|
||||
if (effect != null)
|
||||
{
|
||||
ranked.add(effect);
|
||||
}
|
||||
if (pending != null && (effect == null || !pending.getPsvId().equals(effect.getPsvId())))
|
||||
{
|
||||
ranked.add(pending);
|
||||
}
|
||||
list.stream()
|
||||
.filter(v -> v != null && v.getPsvId() != null)
|
||||
.filter(v -> excludePsvId == null || !excludePsvId.equals(v.getPsvId()))
|
||||
.sorted((a, b) -> {
|
||||
int sa = a.getVersionSeq() == null ? 0 : a.getVersionSeq().intValue();
|
||||
int sb = b.getVersionSeq() == null ? 0 : b.getVersionSeq().intValue();
|
||||
return Integer.compare(sb, sa);
|
||||
})
|
||||
.forEach(v -> {
|
||||
boolean exists = false;
|
||||
for (PrcPriceSetVersion r : ranked)
|
||||
{
|
||||
if (r.getPsvId().equals(v.getPsvId()))
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!exists)
|
||||
{
|
||||
ranked.add(v);
|
||||
}
|
||||
});
|
||||
for (PrcPriceSetVersion cand : ranked)
|
||||
{
|
||||
if (versionHasSetProducts(cand.getPsvId()))
|
||||
{
|
||||
best = v;
|
||||
return cand.getPsvId();
|
||||
}
|
||||
}
|
||||
PrcPriceSetVersion pick = effect != null ? effect : (pending != null ? pending : best);
|
||||
return pick == null ? null : pick.getPsvId();
|
||||
return ranked.isEmpty() ? null : ranked.get(0).getPsvId();
|
||||
}
|
||||
|
||||
private boolean versionHasSetProducts(Long psvId)
|
||||
{
|
||||
if (psvId == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
PrcPriceSetProduct pq = new PrcPriceSetProduct();
|
||||
pq.setPsvId(psvId);
|
||||
List<PrcPriceSetProduct> products = setProductMapper.selectPrcPriceSetProductList(pq);
|
||||
return products != null && !products.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -79,6 +79,32 @@
|
||||
remote-search
|
||||
/>
|
||||
</template>
|
||||
<template #search-billingFailStatuses="{ model }">
|
||||
<el-select
|
||||
v-model="model.billingFailStatuses"
|
||||
multiple
|
||||
filterable
|
||||
clearable
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="请选择"
|
||||
style="width: 100%"
|
||||
>
|
||||
<template #header>
|
||||
<el-checkbox
|
||||
:model-value="isAllBillingFailSelected(model)"
|
||||
:indeterminate="isBillingFailIndeterminate(model)"
|
||||
@change="(checked) => toggleAllBillingFail(model, checked)"
|
||||
>全选</el-checkbox>
|
||||
</template>
|
||||
<el-option
|
||||
v-for="opt in billingFailStatusOptions"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
<template #col-product="{ row }">
|
||||
{{ row.productName || '-' }} ({{ row.productCode || '-' }})
|
||||
</template>
|
||||
@@ -158,7 +184,8 @@ const tableHeight = ref(480)
|
||||
let tableResizeObserver = null
|
||||
|
||||
const defaultParams = {
|
||||
orderStatuses: [3, 4, 5, 6, 7, 8, 11]
|
||||
orderStatuses: [3, 4, 5, 6, 7, 8, 11],
|
||||
billingFailStatuses: []
|
||||
}
|
||||
|
||||
const columns = [
|
||||
@@ -227,6 +254,29 @@ const billingFailStatusOptions = [
|
||||
{ label: '未知失败', value: 22 }
|
||||
]
|
||||
|
||||
const billingFailAllValues = computed(() => billingFailStatusOptions.map(o => o.value))
|
||||
|
||||
function selectedBillingFailStatuses(model) {
|
||||
return Array.isArray(model?.billingFailStatuses) ? model.billingFailStatuses : []
|
||||
}
|
||||
|
||||
function isAllBillingFailSelected(model) {
|
||||
const selected = selectedBillingFailStatuses(model)
|
||||
const all = billingFailAllValues.value
|
||||
return all.length > 0 && selected.length === all.length
|
||||
}
|
||||
|
||||
function isBillingFailIndeterminate(model) {
|
||||
const selected = selectedBillingFailStatuses(model)
|
||||
const all = billingFailAllValues.value
|
||||
return selected.length > 0 && selected.length < all.length
|
||||
}
|
||||
|
||||
function toggleAllBillingFail(model, checked) {
|
||||
if (!model) return
|
||||
model.billingFailStatuses = checked ? [...billingFailAllValues.value] : []
|
||||
}
|
||||
|
||||
const searchColumns = [
|
||||
{ label: '单号', prop: 'orderIdentifiers', placeholder: '订单号/运单号/转单号' },
|
||||
{ label: '客户', prop: 'customerCodes', placeholder: '客户名称/客户代码/对外代码' },
|
||||
@@ -268,7 +318,14 @@ const searchColumns = [
|
||||
prop: 'billingFailStatuses',
|
||||
component: 'select',
|
||||
options: billingFailStatusOptions,
|
||||
placeholder: '请选择'
|
||||
placeholder: '请选择',
|
||||
props: {
|
||||
multiple: true,
|
||||
filterable: true,
|
||||
clearable: true,
|
||||
collapseTags: true,
|
||||
collapseTagsTooltip: true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -391,7 +391,9 @@ async function loadLatestPriorVersionDraft() {
|
||||
const res = await getPriceSet(props.priceSetId)
|
||||
const data = res.data || {}
|
||||
const versions = data.versions || []
|
||||
const prior = pickLatestPriorVersion(versions, props.psvId || resolvedPsvId.value)
|
||||
// Only exclude the draft being edited. Do NOT use resolvedPsvId — it may
|
||||
// point at EFFECT after resolvePsvId() and wrongly skip the real prior.
|
||||
const prior = pickLatestPriorVersion(versions, props.psvId)
|
||||
if (!prior || prior.psvId == null) return false
|
||||
const products = (prior.products || [])
|
||||
.filter(p => p && p.productCode)
|
||||
|
||||
@@ -377,19 +377,31 @@ function onPriceBuildModeUpdate(mode) {
|
||||
}).catch(() => {})
|
||||
})
|
||||
} else if (mode === 'IMPORT') {
|
||||
nextTick(() => {
|
||||
nextTick(async () => {
|
||||
// newVersion/copy: wait until loadExisting fills priceSetId
|
||||
const qid = route.query.priceSetId
|
||||
if (!form.priceSetId && qid) {
|
||||
for (let i = 0; i < 50 && !form.priceSetId; i++) {
|
||||
await new Promise(r => setTimeout(r, 100))
|
||||
}
|
||||
}
|
||||
const loader = detailsRef.value && detailsRef.value.loadLatestPriorVersionDraft
|
||||
if (!loader) {
|
||||
proxy.$modal.msgSuccess("请导入 Excel 建价")
|
||||
return
|
||||
}
|
||||
loader().then(ok => {
|
||||
if (!form.priceSetId) {
|
||||
proxy.$modal.msgSuccess("新建套餐无历史版本可带出,请直接导入 Excel 建价")
|
||||
return
|
||||
}
|
||||
try {
|
||||
const ok = await loader()
|
||||
proxy.$modal.msgSuccess(ok
|
||||
? "已带出上一版全部产品,导入 Excel 按产品+国家覆盖或新增"
|
||||
: "暂无上一版产品,请导入 Excel 建价")
|
||||
}).catch(() => {
|
||||
: "未找到含产品的上一版,请导入 Excel 建价")
|
||||
} catch (e) {
|
||||
proxy.$modal.msgSuccess("请导入 Excel 建价")
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,9 +108,14 @@ export function nextVersionNo(versions) {
|
||||
return 'V' + (max + 1)
|
||||
}
|
||||
|
||||
function versionHasProducts(v) {
|
||||
return !!(v && (v.products || []).some(p => p && p.productCode))
|
||||
}
|
||||
|
||||
/**
|
||||
* Latest prior version for Excel build-price preload (exclude current draft).
|
||||
* Prefer EFFECT, then PENDING, then highest versionSeq.
|
||||
* Prefer EFFECT / PENDING / highest versionSeq that actually has products,
|
||||
* so an empty EFFECT does not hide an older version that still has data.
|
||||
*/
|
||||
export function pickLatestPriorVersion(versions, excludePsvId) {
|
||||
const list = (versions || []).filter(v => {
|
||||
@@ -119,11 +124,17 @@ export function pickLatestPriorVersion(versions, excludePsvId) {
|
||||
return true
|
||||
})
|
||||
if (!list.length) return null
|
||||
const ranked = []
|
||||
const effect = list.find(v => String(v.status) === VER_STATUS.EFFECT)
|
||||
if (effect) return effect
|
||||
if (effect) ranked.push(effect)
|
||||
const pending = list.find(v => String(v.status) === VER_STATUS.PENDING)
|
||||
if (pending) return pending
|
||||
return list.slice().sort((a, b) => (Number(b.versionSeq) || 0) - (Number(a.versionSeq) || 0))[0]
|
||||
if (pending && (!effect || String(pending.psvId) !== String(effect.psvId))) ranked.push(pending)
|
||||
const bySeq = list.slice().sort((a, b) => (Number(b.versionSeq) || 0) - (Number(a.versionSeq) || 0))
|
||||
bySeq.forEach(v => {
|
||||
if (!ranked.some(x => String(x.psvId) === String(v.psvId))) ranked.push(v)
|
||||
})
|
||||
const withProducts = ranked.find(versionHasProducts)
|
||||
return withProducts || ranked[0] || null
|
||||
}
|
||||
|
||||
/** Package status label */
|
||||
|
||||
Reference in New Issue
Block a user