feat: 1.05需求处理

This commit is contained in:
ZhuRui
2026-08-28 14:40:40 +08:00
parent a581f64ccb
commit 8c023e63ec
6 changed files with 107 additions and 4 deletions
+4
View File
@@ -76,6 +76,10 @@ export interface EventListQueryParams {
idCardImg?: string; idCardImg?: string;
/** 是否要求提供证件号码;0=无需,1=需要 */ /** 是否要求提供证件号码;0=无需,1=需要 */
idCardNo?: string; idCardNo?: string;
/** 报名人数起始(含) */
scBegin?: string;
/** 报名人数结束(含) */
scEnd?: string;
} }
/** 分页数据 */ /** 分页数据 */
+39
View File
@@ -20,6 +20,8 @@ import {
} from './model/useEventListModel'; } from './model/useEventListModel';
import { useEventListColumns } from './model/useEventListColumns'; import { useEventListColumns } from './model/useEventListColumns';
import { getProvinceCityCascaderOptions } from '@/utils/areaData'; import { getProvinceCityCascaderOptions } from '@/utils/areaData';
import { toIntegerOnly } from '@/utils/form';
import { handleIntegerInput, handleIntegerBlur, blockNonDigitKey } from './model/integerInput';
import { useContainerSize } from '@/hooks'; import { useContainerSize } from '@/hooks';
import { usePermissionStore } from '@/stores/permissionStore'; import { usePermissionStore } from '@/stores/permissionStore';
import EventRegulationModal from './components/EventRegulationModal'; import EventRegulationModal from './components/EventRegulationModal';
@@ -266,6 +268,43 @@ export default defineComponent({
onUpdate:value={(val: any) => (filterForm.region = val || [])} onUpdate:value={(val: any) => (filterForm.region = val || [])}
/> />
</Form.Item> </Form.Item>
<Form.Item label="报名人数">
<Space.Compact>
<Input
value={filterForm.scBegin}
placeholder="请输入"
style={{ width: '100px' }}
allowClear
onInput={(e: Event) => handleIntegerInput(e, (v) => (filterForm.scBegin = v))}
onKeydown={blockNonDigitKey}
onBlur={(e: Event) => handleIntegerBlur(e, (v) => (filterForm.scBegin = v))}
onUpdate:value={(val: string) => (filterForm.scBegin = toIntegerOnly(val))}
onPressEnter={handleSearch}
/>
<Input
style={{
width: '40px',
textAlign: 'center',
backgroundColor: '#fafafa',
pointerEvents: 'none',
color: 'rgba(0,0,0,0.45)',
}}
value="至"
disabled
/>
<Input
value={filterForm.scEnd}
placeholder="请输入"
style={{ width: '100px' }}
allowClear
onInput={(e: Event) => handleIntegerInput(e, (v) => (filterForm.scEnd = v))}
onKeydown={blockNonDigitKey}
onBlur={(e: Event) => handleIntegerBlur(e, (v) => (filterForm.scEnd = v))}
onUpdate:value={(val: string) => (filterForm.scEnd = toIntegerOnly(val))}
onPressEnter={handleSearch}
/>
</Space.Compact>
</Form.Item>
<Form.Item> <Form.Item>
<Space> <Space>
<Button type="primary" onClick={handleSearch} loading={loading.value}> <Button type="primary" onClick={handleSearch} loading={loading.value}>
+4
View File
@@ -15,6 +15,8 @@ export const FILTER_DEFAULTS = {
isPublic: '', isPublic: '',
idCardNo: '', idCardNo: '',
idCardImg: '', idCardImg: '',
scBegin: '',
scEnd: '',
}; };
export type FieldMapping = [ export type FieldMapping = [
@@ -35,6 +37,8 @@ export const FIELD_MAPPINGS: FieldMapping[] = [
['createDateRange', 'createDateEnd', (v) => v?.[1]], ['createDateRange', 'createDateEnd', (v) => v?.[1]],
['startDateRange', 'startDate', (v) => v?.[0]], ['startDateRange', 'startDate', (v) => v?.[0]],
['startDateRange', 'startDateEnd', (v) => v?.[1]], ['startDateRange', 'startDateEnd', (v) => v?.[1]],
['scBegin', 'scBegin'],
['scEnd', 'scEnd'],
]; ];
/** 赛事状态选项(value 对应 API status */ /** 赛事状态选项(value 对应 API status */
@@ -0,0 +1,43 @@
/** 报名人数筛选项 — 整数输入处理(页面特有逻辑) */
import { toIntegerOnly } from '@/utils/form';
/** 整数规范化:去除前导零,如 055 → 55;空值保持为空 */
function normalizeIntegerString(value: unknown): string {
const digits = toIntegerOnly(value);
if (!digits) return '';
return String(parseInt(digits, 10));
}
/** 整数 Input 事件处理:同步过滤 DOM 值与外部状态 */
export function handleIntegerInput(e: Event, setter: (value: string) => void): void {
const el = e.target as HTMLInputElement | null;
if (!el) return;
const next = toIntegerOnly(el.value);
if (el.value !== next) {
el.value = next;
}
setter(next);
}
/** 整数 Input 失焦处理:规范化数字并同步状态 */
export function handleIntegerBlur(e: Event, setter: (value: string) => void): void {
const el = e.target as HTMLInputElement | null;
if (!el) return;
const next = normalizeIntegerString(el.value);
if (el.value !== next) {
el.value = next;
}
setter(next);
}
/** 阻止非数字键入(含小数点),配合 handleIntegerInput 处理粘贴 */
export function blockNonDigitKey(e: KeyboardEvent): void {
if (e.ctrlKey || e.metaKey || e.altKey) return;
if (e.key.length !== 1) return;
if (!/^\d$/.test(e.key)) {
e.preventDefault();
}
}
@@ -92,11 +92,24 @@ export function useEventListModel() {
f.region.length > 0 || f.region.length > 0 ||
!!f.isPublic || !!f.isPublic ||
!!f.idCardNo || !!f.idCardNo ||
!!f.idCardImg !!f.idCardImg ||
!!f.scBegin?.trim() ||
!!f.scEnd?.trim()
); );
}); });
/** 报名人数区间:起始大于结束时对调 */
const normalizeSignupCountRange = () => {
const begin = filterForm.scBegin.trim();
const end = filterForm.scEnd.trim();
if (begin && end && Number(begin) > Number(end)) {
filterForm.scBegin = end;
filterForm.scEnd = begin;
}
};
const handleSearch = () => { const handleSearch = () => {
normalizeSignupCountRange();
pagination.reset(); pagination.reset();
fetchList(); fetchList();
}; };
+3 -3
View File
@@ -34,8 +34,8 @@ export const REAL_NAME_REGEX = /^[\u4e00-\u9fa5A-Za-z0-9·]{1,8}$/;
export const IMAGE_TYPE_REGEX = /^image\//; export const IMAGE_TYPE_REGEX = /^image\//;
/** /**
* 数字(整数) * 数字字符
* - 用于过滤非数字字符 * - 用于过滤 0-9 以外的字符(含小数点、字母、符号等)
*/ */
export const INTEGER_ONLY_REGEX = /\D/g; export const INTEGER_ONLY_REGEX = /\D/g;
@@ -63,7 +63,7 @@ export function isImageFile(file: { type: string }): boolean {
return IMAGE_TYPE_REGEX.test(file.type); return IMAGE_TYPE_REGEX.test(file.type);
} }
/** 过滤非数字字符,只保留整数 */ /** 只保留数字字符 */
export function toIntegerOnly(value: unknown): string { export function toIntegerOnly(value: unknown): string {
return String(value ?? '').replace(INTEGER_ONLY_REGEX, ''); return String(value ?? '').replace(INTEGER_ONLY_REGEX, '');
} }