task-102(任务与重复分析中心): 实现视频任务筛选状态
新增 src/pages/tasks/image-video-filter.ts:用户名/user/状态/executeId/ 提交时间区间筛选归一与 snake 查询序列化,页大小钳制 [10,100]。 TDD: task-102.test.ts 8 用例先 RED 后 GREEN。
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
/** 视频任务筛选与分页(任务 102):图生视频任务列表筛选/分页归一,与 Java AdminImageVideoTaskController
|
||||
* snake_case 查询契约对齐;纯逻辑。 */
|
||||
|
||||
export const IMAGE_VIDEO_DEFAULT_PAGE_SIZE = 20
|
||||
export const IMAGE_VIDEO_MIN_PAGE_SIZE = 10
|
||||
export const IMAGE_VIDEO_MAX_PAGE_SIZE = 100
|
||||
export const IMAGE_VIDEO_PAGE_MIN = 1
|
||||
|
||||
const ALLOWED_STATUS: readonly string[] = ['PENDING', 'RUNNING', 'SUCCESS', 'FAILED', 'CANCELLED']
|
||||
const LOCAL_DATETIME = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?$/
|
||||
|
||||
export interface ImageVideoFilter {
|
||||
username: string
|
||||
userId: number | null
|
||||
status: string
|
||||
executeId: string
|
||||
submittedFrom: string
|
||||
submittedTo: string
|
||||
}
|
||||
|
||||
export interface ImageVideoQuery {
|
||||
page: number
|
||||
page_size: number
|
||||
user_id?: number
|
||||
username?: string
|
||||
status?: string
|
||||
coze_execute_id?: string
|
||||
submitted_from?: string
|
||||
submitted_to?: string
|
||||
}
|
||||
|
||||
export function createImageVideoFilter(): ImageVideoFilter {
|
||||
return { username: '', userId: null, status: '', executeId: '', submittedFrom: '', submittedTo: '' }
|
||||
}
|
||||
|
||||
function textOrUndefined(value: unknown): string | undefined {
|
||||
const text = typeof value === 'string' ? value.trim() : ''
|
||||
return text || undefined
|
||||
}
|
||||
|
||||
function positiveIdOrNull(value: unknown): 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
|
||||
}
|
||||
|
||||
function statusOrUndefined(value: unknown): string | undefined {
|
||||
const text = typeof value === 'string' ? value.trim().toUpperCase() : ''
|
||||
return ALLOWED_STATUS.includes(text) ? text : undefined
|
||||
}
|
||||
|
||||
function datetimeOrUndefined(value: unknown): string | undefined {
|
||||
if (typeof value !== 'string') return undefined
|
||||
const text = value.trim()
|
||||
return LOCAL_DATETIME.test(text) ? text : undefined
|
||||
}
|
||||
|
||||
/** 归一筛选状态:去空白、非法状态/日期/负数 id 置空。 */
|
||||
export function normalizeImageVideoFilter(raw: Partial<ImageVideoFilter>): ImageVideoFilter {
|
||||
return {
|
||||
username: typeof raw.username === 'string' ? raw.username.trim() : '',
|
||||
userId: positiveIdOrNull(raw.userId),
|
||||
status: statusOrUndefined(raw.status) ?? '',
|
||||
executeId: typeof raw.executeId === 'string' ? raw.executeId.trim() : '',
|
||||
submittedFrom: datetimeOrUndefined(raw.submittedFrom) ?? '',
|
||||
submittedTo: datetimeOrUndefined(raw.submittedTo) ?? '',
|
||||
}
|
||||
}
|
||||
|
||||
export function imageVideoFilterActive(filter: ImageVideoFilter): boolean {
|
||||
return Boolean(
|
||||
filter.username.trim() ||
|
||||
filter.userId !== null ||
|
||||
filter.status ||
|
||||
filter.executeId.trim() ||
|
||||
filter.submittedFrom ||
|
||||
filter.submittedTo,
|
||||
)
|
||||
}
|
||||
|
||||
function finiteInt(value: unknown): number | null {
|
||||
return typeof value === 'number' && Number.isFinite(value) ? Math.floor(value) : null
|
||||
}
|
||||
|
||||
/** 前端状态 → Java 查询参数(snake_case,仅下发非空)。 */
|
||||
export function toImageVideoQuery(filter: ImageVideoFilter, page: unknown, pageSize: unknown): ImageVideoQuery {
|
||||
const safePage = Math.max(finiteInt(page) ?? IMAGE_VIDEO_PAGE_MIN, IMAGE_VIDEO_PAGE_MIN)
|
||||
const rawSize = finiteInt(pageSize)
|
||||
const pageSizeClamped =
|
||||
rawSize === null || rawSize < 1
|
||||
? IMAGE_VIDEO_DEFAULT_PAGE_SIZE
|
||||
: Math.min(Math.max(rawSize, IMAGE_VIDEO_MIN_PAGE_SIZE), IMAGE_VIDEO_MAX_PAGE_SIZE)
|
||||
const query: ImageVideoQuery = { page: safePage, page_size: pageSizeClamped }
|
||||
const username = filter.username.trim()
|
||||
if (username) query.username = username
|
||||
if (filter.userId !== null) query.user_id = filter.userId
|
||||
if (filter.status) query.status = filter.status
|
||||
const executeId = filter.executeId.trim()
|
||||
if (executeId) query.coze_execute_id = executeId
|
||||
if (filter.submittedFrom) query.submitted_from = filter.submittedFrom
|
||||
if (filter.submittedTo) query.submitted_to = filter.submittedTo
|
||||
return query
|
||||
}
|
||||
Reference in New Issue
Block a user