103 lines
3.5 KiB
TypeScript
103 lines
3.5 KiB
TypeScript
import { computed, unref, type ComputedRef, type Ref } from 'vue'
|
|
import type { Plan } from '@/api/pl'
|
|
import {
|
|
buildPlPlanListSpanMethod,
|
|
flattenPlanArchivePairRows,
|
|
flattenPlanListRows,
|
|
getPlanListDisplayIndex,
|
|
type PlPlanListDisplayRow,
|
|
type PlPlanListDisplayRowKind
|
|
} from '@/utils/pl-plan-list-display-rows'
|
|
|
|
export function usePlPlanMergeListTable(options: {
|
|
planList: Ref<Plan[]> | ComputedRef<Plan[]>
|
|
visiblePlanMergeProps: ComputedRef<string[]>
|
|
selectedRows: Ref<Plan[]>
|
|
pagination: { page: number; pageSize: number }
|
|
onView?: (plan: Plan) => void
|
|
/** 计划区固定合并列数:默认 3(勾选+序号+计划编号);无勾选列时传 2 */
|
|
fixedMergeColCount?: number
|
|
/** 仅展示装货或送货段;未传或两种都选时展示全部段次 */
|
|
stopKinds?: Ref<PlPlanListDisplayRowKind[] | null> | ComputedRef<PlPlanListDisplayRowKind[] | null>
|
|
/** 客户列多关键字:只保留名称包含任一关键字的段次 */
|
|
stopCustomerKeywords?: Ref<string[] | null> | ComputedRef<string[] | null>
|
|
/**
|
|
* 归档配对模式:一行 = 装货 × 一送货。
|
|
* 为 true 时忽略 stopKinds,改用装/送客户关键字过滤。
|
|
*/
|
|
archivePairMode?: boolean | Ref<boolean> | ComputedRef<boolean>
|
|
loadCustomerKeywords?: Ref<string[] | null> | ComputedRef<string[] | null>
|
|
deliveryCustomerKeywords?: Ref<string[] | null> | ComputedRef<string[] | null>
|
|
}) {
|
|
const displayRows = computed(() => {
|
|
const pairMode = !!unref(options.archivePairMode)
|
|
if (pairMode) {
|
|
return flattenPlanArchivePairRows(unref(options.planList), {
|
|
loadCustomerKeywords: options.loadCustomerKeywords
|
|
? unref(options.loadCustomerKeywords)
|
|
: null,
|
|
deliveryCustomerKeywords: options.deliveryCustomerKeywords
|
|
? unref(options.deliveryCustomerKeywords)
|
|
: null,
|
|
customerKeywords: options.stopCustomerKeywords
|
|
? unref(options.stopCustomerKeywords)
|
|
: null
|
|
})
|
|
}
|
|
return flattenPlanListRows(unref(options.planList), {
|
|
kinds: options.stopKinds ? unref(options.stopKinds) : null,
|
|
customerKeywords: options.stopCustomerKeywords ? unref(options.stopCustomerKeywords) : null
|
|
})
|
|
})
|
|
|
|
const planListSpanMethod = computed(() =>
|
|
buildPlPlanListSpanMethod(
|
|
[...options.visiblePlanMergeProps.value],
|
|
options.fixedMergeColCount
|
|
)
|
|
)
|
|
|
|
function getDisplayRowIndex(index: number) {
|
|
return getPlanListDisplayIndex(
|
|
displayRows.value,
|
|
index,
|
|
options.pagination.page,
|
|
options.pagination.pageSize
|
|
)
|
|
}
|
|
|
|
function isPlanFirstRowSelectable(row: PlPlanListDisplayRow) {
|
|
return row.isPlanFirstRow
|
|
}
|
|
|
|
function handleDisplaySelectionChange(selection: PlPlanListDisplayRow[]) {
|
|
const seen = new Set<string>()
|
|
const plans: Plan[] = []
|
|
for (const item of selection || []) {
|
|
const plan = item?.plan
|
|
if (!plan?.id || seen.has(plan.id)) continue
|
|
seen.add(plan.id)
|
|
plans.push(plan)
|
|
}
|
|
options.selectedRows.value = plans
|
|
}
|
|
|
|
function handleDisplayRowDblClick(row: PlPlanListDisplayRow) {
|
|
if (row?.plan && options.onView) options.onView(row.plan)
|
|
}
|
|
|
|
function findPlanFirstDisplayRow(planId: string) {
|
|
return displayRows.value.find((item) => item.plan.id === planId && item.isPlanFirstRow)
|
|
}
|
|
|
|
return {
|
|
displayRows,
|
|
planListSpanMethod,
|
|
getDisplayRowIndex,
|
|
isPlanFirstRowSelectable,
|
|
handleDisplaySelectionChange,
|
|
handleDisplayRowDblClick,
|
|
findPlanFirstDisplayRow
|
|
}
|
|
}
|