hookehuyr

feat(familyForm): 新增家庭报名表单模块

添加家庭报名表单页面、路由、服务及模拟数据
- 创建表单页面,包含幼儿园班级选择、参赛人数、孩童姓名、手机号、证件登记和服装尺码等字段
- 添加路由配置,支持 /family-form 路径访问
- 实现服务层,提供获取学校选项和提交报名信息的功能
- 添加模拟数据,包含幼儿园列表和本地存储的报名记录
1 +const familyFormRoutes = [
2 + {
3 + path: '/family-form',
4 + name: '家庭报名表单',
5 + component: () => import('@/views/familyForm/index.vue'),
6 + meta: {
7 + title: '家庭表单录入'
8 + },
9 + children: []
10 + }
11 +];
12 +
13 +export default familyFormRoutes;
This diff is collapsed. Click to expand it.
1 +const STORAGE_KEY = 'family-form-registrations';
2 +
3 +const mockSchoolList = [
4 + {
5 + id: 'kg_001',
6 + name: '上海市杨浦区科技幼儿园',
7 + classes: [
8 + { id: 'kg_001_c_001', name: '小一班' },
9 + { id: 'kg_001_c_002', name: '中二班' },
10 + { id: 'kg_001_c_003', name: '大三班' }
11 + ]
12 + },
13 + {
14 + id: 'kg_002',
15 + name: '上海市黄浦区蓓蕾幼儿园',
16 + classes: [
17 + { id: 'kg_002_c_001', name: '小太阳班' },
18 + { id: 'kg_002_c_002', name: '星星班' },
19 + { id: 'kg_002_c_003', name: '彩虹班' }
20 + ]
21 + },
22 + {
23 + id: 'kg_003',
24 + name: '上海市徐汇区童心幼儿园',
25 + classes: [
26 + { id: 'kg_003_c_001', name: '亲子一班' },
27 + { id: 'kg_003_c_002', name: '亲子二班' },
28 + { id: 'kg_003_c_003', name: '亲子三班' }
29 + ]
30 + }
31 +];
32 +
33 +const delay = (data, timeout = 200) => new Promise((resolve) => {
34 + setTimeout(() => resolve(data), timeout);
35 +});
36 +
37 +const readRegistrations = () => {
38 + try {
39 + return JSON.parse(localStorage.getItem(STORAGE_KEY)) || [];
40 + } catch (error) {
41 + console.warn('读取家庭报名 mock 缓存失败', error);
42 + return [];
43 + }
44 +};
45 +
46 +const writeRegistrations = (list) => {
47 + localStorage.setItem(STORAGE_KEY, JSON.stringify(list));
48 +};
49 +
50 +export const getMockSchoolList = () => delay({
51 + code: 1,
52 + data: mockSchoolList
53 +});
54 +
55 +export const saveMockRegistration = (params) => {
56 + const list = readRegistrations();
57 + const now = Date.now();
58 + const nextItem = {
59 + ...params,
60 + id: `family_${now}`,
61 + updated_at: now
62 + };
63 +
64 + list.unshift(nextItem);
65 + writeRegistrations(list);
66 +
67 + return delay({
68 + code: 1,
69 + msg: '保存成功',
70 + data: nextItem
71 + }, 300);
72 +};
1 +import {
2 + getMockSchoolList,
3 + saveMockRegistration
4 +} from './mock';
5 +
6 +const normalizeSchoolList = (list = []) => list.map((school) => ({
7 + text: school.name,
8 + value: school.id,
9 + children: (school.classes || []).map((item) => ({
10 + text: item.name,
11 + value: item.id
12 + }))
13 +}));
14 +
15 +export const fetchSchoolOptions = async () => {
16 + const res = await getMockSchoolList();
17 + if (res.code !== 1) {
18 + throw new Error(res.msg || '获取幼儿园信息失败');
19 + }
20 +
21 + return normalizeSchoolList(res.data);
22 +};
23 +
24 +export const submitRegistration = async (formData) => {
25 + const res = await saveMockRegistration(formData);
26 + if (res.code !== 1) {
27 + throw new Error(res.msg || '保存报名信息失败');
28 + }
29 +
30 + return res.data;
31 +};