feat(pl): 证书齐备默认只看待安排前的跟进状态。
Web 列筛选和移动端跟进状态下拉默认勾选草稿中、等通知、待安排。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
da3ec62719
commit
421332cad4
5 files changed
+114
-1
No files matched your search
@@ -4,6 +4,7 @@ import test from 'node:test'
|
||||
import { effectScope } from 'vue'
|
||||
import { useServerColumnFilters } from '../src/composables/useServerColumnFilters'
|
||||
import { certReadyDefaultPlanDates } from '../src/utils/cert-ready-plan-date'
|
||||
import { PL_PLAN_CERT_READY_DEFAULT_FOLLOW_STATUSES } from '../src/utils/pl-display'
|
||||
|
||||
test('incomplete certificate filter is sent as quotaCertWaivedIn=0', () => {
|
||||
const scope = effectScope()
|
||||
@@ -39,6 +40,48 @@ test('web funnel and miniprogram status dropdown default to incomplete', () => {
|
||||
)
|
||||
assert.match(mobile, /certReadyDefaultPlanDates\(\)/)
|
||||
assert.match(mobile, /:plan-date-from="readyDateFrom"/)
|
||||
assert.match(
|
||||
web,
|
||||
/followStatus:\s*\{\s*text:\s*'',\s*selected:\s*\[\.\.\.PL_PLAN_CERT_READY_DEFAULT_FOLLOW_STATUSES\]\s*\}/
|
||||
)
|
||||
assert.match(
|
||||
mobile,
|
||||
/const readyFollow = ref<string\[\]>\(\[\.\.\.PL_PLAN_CERT_READY_DEFAULT_FOLLOW_STATUSES\]\)/
|
||||
)
|
||||
assert.match(mobile, /text:\s*'全部跟进状态'/)
|
||||
assert.match(mobile, /:follow-status="readyFollowQuery"/)
|
||||
const ready = readFileSync(
|
||||
new URL('../src/views/m/pl/plan-cert/ReadyTab.vue', import.meta.url),
|
||||
'utf8'
|
||||
)
|
||||
assert.match(ready, /followStatusIn: props\.followStatus/)
|
||||
})
|
||||
|
||||
test('certificate ready follow status defaults to drafting, waiting and pending', () => {
|
||||
assert.deepEqual(
|
||||
[...PL_PLAN_CERT_READY_DEFAULT_FOLLOW_STATUSES],
|
||||
['drafting', 'wait_notice', 'pending_arrange']
|
||||
)
|
||||
const scope = effectScope()
|
||||
const params = scope.run(() =>
|
||||
useServerColumnFilters(
|
||||
[
|
||||
{
|
||||
prop: 'followStatus',
|
||||
label: '跟进状态',
|
||||
type: 'enum',
|
||||
queryKey: 'followStatus'
|
||||
}
|
||||
],
|
||||
{
|
||||
initialFilters: {
|
||||
followStatus: { text: '', selected: [...PL_PLAN_CERT_READY_DEFAULT_FOLLOW_STATUSES] }
|
||||
}
|
||||
}
|
||||
).toQueryParams()
|
||||
)
|
||||
scope.stop()
|
||||
assert.deepEqual(params, { followStatusIn: 'drafting,wait_notice,pending_arrange' })
|
||||
})
|
||||
|
||||
test('default plan dates run from yesterday through seven days later', () => {
|
||||
|
||||
@@ -452,6 +452,13 @@ export const PL_PLAN_DEFAULT_FOLLOW_STATUSES = PL_PLAN_FOLLOW_STATUS_OPTIONS.fil
|
||||
(opt) => opt.value !== 'cancelled'
|
||||
).map((opt) => opt.value)
|
||||
|
||||
/** 证书齐备列表默认勾选:草稿中、等通知、待安排 */
|
||||
export const PL_PLAN_CERT_READY_DEFAULT_FOLLOW_STATUSES = [
|
||||
'drafting',
|
||||
'wait_notice',
|
||||
'pending_arrange'
|
||||
] as const
|
||||
|
||||
export function getPlPlanFollowStatusTagType(status?: string) {
|
||||
const map: Record<string, string> = {
|
||||
drafting: 'info',
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
const props = defineProps<{
|
||||
keyword: string
|
||||
waived: string
|
||||
followStatus: string
|
||||
planDateFrom: string
|
||||
planDateTo: string
|
||||
}>()
|
||||
@@ -85,6 +86,7 @@
|
||||
pageSize: 20,
|
||||
keyword: props.keyword || undefined,
|
||||
waived: props.waived || undefined,
|
||||
followStatusIn: props.followStatus || undefined,
|
||||
planDateFrom: props.planDateFrom || undefined,
|
||||
planDateTo: props.planDateTo || undefined
|
||||
})
|
||||
@@ -126,7 +128,10 @@
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [props.keyword, props.waived, props.planDateFrom, props.planDateTo].join('\0'),
|
||||
() =>
|
||||
[props.keyword, props.waived, props.followStatus, props.planDateFrom, props.planDateTo].join(
|
||||
'\0'
|
||||
),
|
||||
() => reload()
|
||||
)
|
||||
</script>
|
||||
@@ -47,6 +47,23 @@
|
||||
</van-dropdown-menu>
|
||||
<van-dropdown-menu v-else-if="tab === 'ready'" class="mp-customer-dd">
|
||||
<van-dropdown-item v-model="readyState" :options="readyStateOptions" />
|
||||
<van-dropdown-item :title="readyFollowTitle">
|
||||
<van-cell
|
||||
v-for="option in readyFollowOptions"
|
||||
:key="option.value || 'all'"
|
||||
clickable
|
||||
:title="option.text"
|
||||
class="van-dropdown-item__option"
|
||||
:class="{ 'van-dropdown-item__option--active': readyFollowActive(option.value) }"
|
||||
role="menuitemcheckbox"
|
||||
:aria-checked="readyFollowActive(option.value)"
|
||||
@click="toggleReadyFollow(option.value)"
|
||||
>
|
||||
<template v-if="readyFollowActive(option.value)" #right-icon>
|
||||
<van-icon name="success" class="van-dropdown-item__icon" />
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-dropdown-item>
|
||||
<van-dropdown-item
|
||||
ref="readyDateFilter"
|
||||
:title="readyDateTitle"
|
||||
@@ -118,6 +135,7 @@
|
||||
:key="session + committed"
|
||||
:keyword="committed"
|
||||
:waived="readyState"
|
||||
:follow-status="readyFollowQuery"
|
||||
:plan-date-from="readyDateFrom"
|
||||
:plan-date-to="readyDateTo"
|
||||
/>
|
||||
@@ -130,6 +148,10 @@
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import { goToMiniWorkbench } from '@/utils/mp-webview'
|
||||
import { certReadyDefaultPlanDates } from '@/utils/cert-ready-plan-date'
|
||||
import {
|
||||
PL_PLAN_CERT_READY_DEFAULT_FOLLOW_STATUSES,
|
||||
PL_PLAN_FOLLOW_STATUS_OPTIONS
|
||||
} from '@/utils/pl-display'
|
||||
import PlanDateField from '../plan/PlanDateField.vue'
|
||||
import ArchiveTab from './ArchiveTab.vue'
|
||||
import ContractTab from './ContractTab.vue'
|
||||
@@ -164,6 +186,40 @@
|
||||
const showAllPlans = computed(() => planScope.value === '1')
|
||||
const defaultReadyDates = certReadyDefaultPlanDates()
|
||||
const readyState = ref('0')
|
||||
const readyFollow = ref<string[]>([...PL_PLAN_CERT_READY_DEFAULT_FOLLOW_STATUSES])
|
||||
const readyFollowOptions = [
|
||||
{ text: '全部跟进状态', value: '' },
|
||||
...PL_PLAN_FOLLOW_STATUS_OPTIONS.filter((item) => item.value !== 'cancelled').map((item) => ({
|
||||
text: item.label,
|
||||
value: item.value
|
||||
}))
|
||||
]
|
||||
const readyFollowQuery = computed(() =>
|
||||
readyFollowOptions
|
||||
.filter((item) => item.value && readyFollow.value.includes(item.value))
|
||||
.map((item) => item.value)
|
||||
.join(',')
|
||||
)
|
||||
const readyFollowTitle = computed(() => {
|
||||
const labels = readyFollowOptions
|
||||
.filter((item) => item.value && readyFollow.value.includes(item.value))
|
||||
.map((item) => item.text)
|
||||
if (labels.length === 1) return labels[0]
|
||||
if (labels.length > 1) return `${labels[0]}等${labels.length}项`
|
||||
return '全部跟进状态'
|
||||
})
|
||||
function readyFollowActive(value: string) {
|
||||
return value ? readyFollow.value.includes(value) : readyFollow.value.length === 0
|
||||
}
|
||||
function toggleReadyFollow(value: string) {
|
||||
if (!value) {
|
||||
readyFollow.value = []
|
||||
return
|
||||
}
|
||||
readyFollow.value = readyFollow.value.includes(value)
|
||||
? readyFollow.value.filter((item) => item !== value)
|
||||
: [...readyFollow.value, value]
|
||||
}
|
||||
const readyDateFrom = ref(defaultReadyDates.from)
|
||||
const readyDateTo = ref(defaultReadyDates.to)
|
||||
const readyDateFromDraft = ref(defaultReadyDates.from)
|
||||
|
||||
@@ -112,6 +112,7 @@
|
||||
import { certReadyDefaultPlanDates } from '@/utils/cert-ready-plan-date'
|
||||
import { certReadyErrorText, formatCertReadyTime } from '@/utils/pl-quota-cert-waiver'
|
||||
import {
|
||||
PL_PLAN_CERT_READY_DEFAULT_FOLLOW_STATUSES,
|
||||
PL_PLAN_FOLLOW_STATUS_OPTIONS,
|
||||
getPlPlanFollowStatusLabel,
|
||||
getPlPlanFollowStatusTagType
|
||||
@@ -193,6 +194,7 @@
|
||||
} = useServerColumnFilters(columns, {
|
||||
initialFilters: {
|
||||
quotaCertWaived: { text: '', selected: ['0'] },
|
||||
followStatus: { text: '', selected: [...PL_PLAN_CERT_READY_DEFAULT_FOLLOW_STATUSES] },
|
||||
planDate: { from: defaultPlanDates.from, to: defaultPlanDates.to }
|
||||
},
|
||||
onChange: search
|
||||
|
||||
Reference in new issue
Block a user