前端代码结构
SurveyKing Pro 前端采用 Umi.js 4 + React 18 + TypeScript + Ant Design 5 + Formily 2 技术栈,是一个现代化的企业级前端应用架构。
🛠️ 技术栈概览
基于 package.json
的实际依赖:
- 核心框架: Umi.js 4.0.73 (React 全家桶)
- UI 组件库: Ant Design 5.23.1 + Ant Design Pro Components 2.6.8
- 状态管理: Formily Reactive (基于 @formily/reactive)
- 表单方案: Formily 2.2.27 (阿里巴巴表单解决方案)
- 类型支持: TypeScript 4+
- 样式方案: Less + CSS-in-JS (@emotion/css、@emotion/styled)
- 图表库: BizCharts 4.1.22 + ECharts 5.4.3
- 移动端: Ant Design Mobile 5.37.0
- 工具库: ahooks 3.7.4、lodash 4.17.21、dayjs 1.11.10
- 构建工具: Umi Max (内置 Webpack)
📁 项目目录结构
client/
├── public/ # 静态资源目录
│ ├── favicon.ico # 网站图标
│ ├── logo.svg # Logo 图片
│ ├── CNAME # 域名配置
│ ├── assets/ # 公共资源
│ └── icons/ # PWA 图标集合
├── src/ # 源代码目录
│ ├── components/ # 公共组件库 (44个组件)
│ │ ├── Answer/ # 答题相关组件
│ │ ├── AudioRecord/ # 音频录制组件
│ │ ├── Charts/ # 图表组件
│ │ ├── FormulaEditor/ # 公式编辑器
│ │ ├── QuillEditor/ # Quill富文本编辑器
│ │ ├── Quill2/ # Quill 2.0版本
│ │ ├── ReactQuill/ # React Quill组件
│ │ ├── CanvasDatagrid/ # 高性能表格组件
│ │ ├── FortuneSheet/ # 在线表格(类Excel)
│ │ ├── AuthComponent/ # 权限控制组件
│ │ ├── DynamicGrid/ # 动态网格布局
│ │ ├── SliderCaptcha/ # 滑块验证码
│ │ ├── QrScanner/ # 二维码扫描
│ │ ├── ReactViewer/ # 文件预览
│ │ ├── FormilyAntd/ # Formily Antd适配器
│ │ └── ... # 其他30+个组件
│ ├── pages/ # 页面组件
│ │ ├── Home/ # 首页
│ │ ├── Survey/ # 问卷相关页面
│ │ ├── exam/ # 考试相关页面
│ │ ├── Exercise/ # 练习页面
│ │ ├── project/ # 项目管理
│ │ ├── system/ # 系统管理
│ │ ├── user/ # 用户相关页面
│ │ ├── Template/ # 模板页面
│ │ ├── repo/ # 题库页面
│ │ ├── infra/ # 基础设施页面
│ │ ├── Access/ # 访问控制页面
│ │ ├── mobile/ # 移动端页面
│ │ │ ├── Account/ # 移动端账户
│ │ │ ├── Exercise/ # 移动端练习
│ │ │ └── Home/ # 移动端首页
│ │ ├── 401.tsx # 401错误页面
│ │ ├── 404.tsx # 404错误页面
│ │ └── Loading.tsx # 加载页面
│ ├── services/ # API 服务层
│ │ ├── auth/ # 认证服务
│ │ ├── survey/ # 问卷服务
│ │ ├── system/ # 系统服务
│ │ ├── exam/ # 考试服务
│ │ ├── project/ # 项目服务
│ │ ├── home/ # 首页服务
│ │ ├── repo/ # 题库服务
│ │ ├── infra/ # 基础设施服务
│ │ ├── demo/ # 演示服务
│ │ └── types.ts # API 通用类型
│ ├── store/ # Formily响应式状态管理
│ │ ├── index.ts # Store 配置
│ │ ├── UserStore.ts # 用户状态管理
│ │ ├── ProjectStore.ts # 项目状态管理
│ │ ├── AnswerStore.ts # 答题状态管理
│ │ ├── DictStore.ts # 字典数据管理
│ │ ├── HomeStore.ts # 首页状态管理
│ │ ├── SystemStore.ts # 系统状态管理
│ │ ├── TemplateStore.ts # 模板状态管理
│ │ └── FlowStore.ts # 流程状态管理
│ ├── shared/ # 共享工具库 (30+个文件)
│ │ ├── types.ts # 全局类型定义
│ │ ├── utils.ts # 工具函数集合
│ │ ├── api.ts # API 请求工具
│ │ ├── auth.ts # 认证工具
│ │ ├── useAxios.ts # HTTP 客户端 Hook
│ │ ├── tree.ts # 树形数据处理
│ │ ├── exam.ts # 考试相关工具
│ │ ├── download.ts # 下载工具
│ │ ├── jsencrypt.ts # 加密工具
│ │ ├── useIsMobile.ts # 移动端检测
│ │ ├── useDebouncedCallback.ts # 防抖回调
│ │ ├── useThrottleCallback.ts # 节流回调
│ │ └── ... # 其他工具 Hooks
│ ├── layouts/ # 布局组件
│ │ ├── WorkspaceLayout.tsx # 工作台布局
│ │ ├── BasicLayout.tsx # 基础布局
│ │ ├── BasicPcLayout.tsx # PC端布局
│ │ ├── BasicMobileLayout.tsx # 移动端布局
│ │ ├── AppLayout.tsx # 应用布局
│ │ ├── WorkspaceLayout.less # 工作台样式
│ │ └── mobile.less # 移动端样式
│ ├── types/ # TypeScript 类型定义
│ ├── utils/ # 工具函数
│ ├── constants/ # 常量定义
│ ├── locales/ # 国际化文件
│ ├── models/ # Umi Model 数据流
│ ├── assets/ # 本地资源
│ ├── app.tsx # 应用入口组件
│ ├── app.less # 全局样式
│ ├── access.ts # 权限配置
│ ├── loading.tsx # 全局加载组件
│ └ ── loading.less # 加载组件样式
├── .umirc.ts # Umi 开发配置
├── .umirc.prod.ts # Umi 生产配置
├── package.json # 项目配置
├── tsconfig.json # TypeScript 配置
└── patches/ # 第三方库补丁
├── core-js+3.28.0.patch
└── quill+1.3.7.patch
🧩 核心模块详解
1. 状态管理架构 (store/)
项目使用 Formily Reactive 进行状态管理,这是阿里巴巴开源的响应式状态管理方案:
// store/index.ts - 全局 Store 配置
import { createContext } from 'react';
import { HomeStore } from './HomeStore';
import { SystemStore } from './SystemStore';
import { TemplateStore } from './TemplateStore';
import type { ProjectStore } from './ProjectStore';
import DictStore from './DictStore';
export default class AppStore {
dictStore: DictStore;
homeStore: HomeStore;
systemStore: SystemStore;
publicTemplateStore: TemplateStore;
privateTemplateStore: TemplateStore;
projectStoreObj: Record<string, ProjectStore> = {};
constructor() {
this.dictStore = new DictStore();
this.homeStore = new HomeStore();
this.systemStore = new SystemStore();
this.publicTemplateStore = new TemplateStore(1);
this.privateTemplateStore = new TemplateStore(0);
}
}
export const AppContext = createContext<AppStore>({} as AppStore);
UserStore 实现示例
// store/UserStore.ts - 用户状态管理
import { action, define, observable } from '@formily/reactive';
export class UserStore {
system: SystemInfo = {
name: '卷王问卷',
id: '1',
description: '做更好的调查问卷系统',
locale: 'zh-CN',
// ...
};
userInfo?: UserInfoVO;
isMobile: boolean = false;
loading: boolean = false;
userOverview?: UserOverview;
users: UserInfo[] = [];
constructor() {
this.makeObservable();
this.isMobile = checkIsMobile();
this.getSystemInfo();
}
// 使用 Formily 的响应式系统
makeObservable() {
define(this, {
userInfo: observable,
system: observable,
loading: observable.ref,
userOverview: observable.ref,
users: observable.shallow,
user: observable.computed,
logout: action,
listUserByIds: action,
permStyle: action,
filterItemByPerm: action,
});
}
// 权限检查
hasPermission(...permission: string[]) {
if (
this.userInfo &&
permission.every((perm) =>
(this.userInfo?.permissions || []).includes(perm)
)
) {
return true;
}
return false;
}
// 根据权限过滤项目
filterItemByPerm<T extends { perm?: string }>(items: T[]): T[] {
return items.filter(
(x) => !x.perm || this.userInfo?.permissions.includes(x.perm)
);
}
}
2. API 服务层 (services/)
按业务模块组织,每个模块包含 index.ts
和 types.ts
:
// services/types.ts - 通用类型
export type PaginationProps = {
pageNo?: number;
current?: number;
pageSize?: number;
};
export type PaginationResult<T> = {
current: number;
pageSize: number;
data: T[];
total: number;
success: boolean;
};
// services/auth/index.ts - 认证服务
export const getPermissionApi = (): Promise<UserInfoVO> => {
return request('/system/auth/get-permission-info');
};
export const socialLoginApi = (
data: SocialLoginVO
): Promise<CommonResult<string>> => {
return request('/system/auth/social-login', {
method: 'POST',
data,
});
};
// services/survey/index.ts - 问卷服务
export const getSurveyApi = (id: string): Promise<Survey> => {
return request(`/survey/${id}`);
};
export const createSurveyApi = (data: CreateSurveyRequest): Promise<Survey> => {
return request('/survey/create', {
method: 'POST',
data,
});
};
3. 组件库架构 (components/)
项目拥有 44 个自定义业务组件:
核心组件分类
// 答题相关组件
components/Answer/ # 问卷答题核心组件
components/AudioRecord/ # 音频录制组件
// 编辑器组件
components/QuillEditor/ # Quill.js 富文本编辑器封装
components/Quill2/ # Quill 2.0 版本
components/ReactQuill/ # React Quill 组件
components/FormulaEditor/ # 数学公式编辑器
// 数据展示组件
components/Charts/ # 图表组件集合
components/CanvasDatagrid/ # 高性能Canvas表格
components/FortuneSheet/ # 在线表格(类似Excel)
components/ReactViewer/ # 文件预览组件
// 交互组件
components/DynamicGrid/ # 动态网格布局
components/SliderCaptcha/ # 滑块验证码
components/QrScanner/ # 二维码扫描
components/ImageView/ # 图片查看器
// 权限相关组件
components/AuthComponent/ # 权限控制组件
components/PermissionWrapper/ # 权限包装器
components/AuthProvider/ # 认证提供者
// Formily 相关组件
components/FormilyAntd/ # Formily + Ant Design 适配
components/DecoratorField/ # 装饰器字段
components/ProFormFields/ # Pro 表单字段
// 业务组件
components/ExamQuestionPickModal/ # 考试题目选择弹窗
components/LogicConditionGroup/ # 逻辑条件组
components/Poster/ # 海报生成