task-98(店铺中心): 实现店铺中心通用筛选栏
新增 shop-filter-bar-state.ts:筛选草稿→已应用快照与重置语义,筛选变更标记 回到第 1 页重新加载;纯逻辑可测。 TDD: task-98.test.ts 8 用例先 RED 后 GREEN。
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
/** 店铺中心通用筛选栏状态(任务 98):筛选草稿/已应用快照与“变更回首页”语义,纯逻辑。 */
|
||||
import type { ShopManageFilter } from './shop-manage-list-state.ts'
|
||||
|
||||
export interface ShopFilterBarState {
|
||||
/** 已应用(触发过加载)的筛选快照;null 表示尚未应用任何筛选。 */
|
||||
applied: ShopManageFilter | null
|
||||
/** 本次操作是否要求回到第 1 页重新加载。 */
|
||||
returnFirstPage: boolean
|
||||
}
|
||||
|
||||
export function createShopFilterBarState(): ShopFilterBarState {
|
||||
return { applied: null, returnFirstPage: false }
|
||||
}
|
||||
|
||||
function positiveGroupOrNull(value: string | number | null | undefined): number | null {
|
||||
if (typeof value === 'number') return Number.isFinite(value) && value >= 1 ? Math.floor(value) : null
|
||||
if (typeof value === 'string' && /^\d+$/.test(value.trim())) {
|
||||
const parsed = Number(value.trim())
|
||||
return parsed >= 1 ? Math.floor(parsed) : null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** 由界面输入(分组下拉文本/店铺名输入)生成筛选草稿。 */
|
||||
export function shopFilterDraftFromInput(input: { groupId?: string | number | null; shopName?: string }): ShopManageFilter {
|
||||
const shopName = typeof input.shopName === 'string' ? input.shopName.trim() : ''
|
||||
return { groupId: positiveGroupOrNull(input.groupId), shopName }
|
||||
}
|
||||
|
||||
function cloneFilter(filter: ShopManageFilter): ShopManageFilter {
|
||||
return { groupId: filter.groupId, shopName: typeof filter.shopName === 'string' ? filter.shopName.trim() : '' }
|
||||
}
|
||||
|
||||
/** 提交筛选草稿:固化为已应用并标记回到第 1 页。 */
|
||||
export function commitShopFilterDraft(_state: ShopFilterBarState, draft: ShopManageFilter): ShopFilterBarState {
|
||||
return { applied: cloneFilter(draft), returnFirstPage: true }
|
||||
}
|
||||
|
||||
/** 重置筛选:清空已应用条件并标记回到第 1 页。 */
|
||||
export function clearShopFilterState(_state: ShopFilterBarState): ShopFilterBarState {
|
||||
return { applied: null, returnFirstPage: true }
|
||||
}
|
||||
|
||||
/** 草稿是否与已应用筛选一致(无差异则无需重新加载)。 */
|
||||
export function isShopFilterDraftApplied(draft: ShopManageFilter, applied: ShopManageFilter | null): boolean {
|
||||
if (!applied) return false
|
||||
return cloneFilter(draft).groupId === applied.groupId && cloneFilter(draft).shopName === applied.shopName
|
||||
}
|
||||
Reference in New Issue
Block a user