Files
wukuang/项目概况-新同事快速入门.md
T
2026-05-23 14:05:22 +08:00

1427 lines
41 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 低码平台项目概况(开发者快速入门)
> **项目路径**: `/Users/admin/Desktop/myFile/project2/fe-cisdigital-lingshu-lcdp`
> **最后更新**: 2026-05-22
---
## 📋 项目简介
这是一个**低代码开发平台(LCDP - Low Code Development Platform**的前端项目,采用 Vue 3 + TypeScript 技术栈,支持 PC 端和移动端页面的可视化设计与渲染。
### 核心价值
- 🎨 **可视化设计**:通过拖拽组件快速搭建业务页面
-**高效开发**:降低开发门槛,提高开发效率
- 🔄 **多端支持**:同时支持 PC 端和移动端
- 📦 **组件复用**:丰富的物料组件库,开箱即用
### 适用人群
- 前端开发工程师(组件开发、功能迭代)
- 低码平台使用者(页面设计、业务配置)
- 新入职团队成员(快速了解项目架构)
---
## 🏗️ 项目架构
### 技术栈
| 类别 | 技术 | 版本 |
|------|------|------|
| **前端框架** | Vue 3 + TypeScript | ^3.5.13 |
| **构建工具** | Vite | ^8.0.3 |
| **包管理** | pnpm workspace (Monorepo) | 10.13.1 |
| **PC UI 库** | Element Plus | 2.11.2 |
| **移动 UI 库** | Vant | 4.9.21 |
| **表格组件** | VXE Table | 4.18.0 |
| **状态管理** | Pinia | ^3.0.2 |
| **路由** | Vue Router | ^4.5.0 |
| **工具库** | VueUse | ^12.7.0 |
| **文档工具** | Storybook | ^8.6.4 |
| **代码规范** | ESLint + Prettier + Husky | 最新 |
### Monorepo 目录结构
```
fe-cisdigital-lingshu-lcdp/
├── apps/ # 应用入口
│ └── lcdp/ # 低码平台主应用
│ ├── src/
│ │ ├── feature/ # 功能模块
│ │ │ └── modeling/ # 业务建模
│ │ ├── components/ # 应用级组件
│ │ └── locales/ # 国际化
│ └── package.json
├── packages/ # 核心包
│ ├── types/ # 共享类型定义(⭐ 重要)
│ │ ├── business-components/ # 业务组件类型
│ │ ├── widget-pc/ # PC 端组件类型
│ │ └── form-designer/ # 设计器类型
│ │
│ ├── form-designer/ # 页面设计器(⭐ 核心)
│ │ └── src/
│ │ ├── config/ # 配置中心
│ │ │ ├── Material.ts # 物料面板
│ │ │ ├── RegisterWidget.ts # 组件注册
│ │ │ ├── RegisterWidgetHelper.ts # Helper注册
│ │ │ ├── widget/ # PC组件实现
│ │ │ └── widget-helper/ # PC组件配置
│ │ └── widget-mobile/ # 移动端镜像
│ │
│ ├── business-components/ # 业务组件库
│ │ └── src/
│ │ ├── enum/ # 枚举定义
│ │ ├── utils/ # 工具函数
│ │ ├── service/ # 服务接口
│ │ └── components/ # 业务组件
│ │
│ ├── widget-pc/ # PC 端组件
│ ├── widget-mobile/ # 移动端组件
│ ├── form-create/ # 表单引擎(外部依赖)
│ ├── lowcode-create/ # 低码渲染引擎(外部依赖)
│ ├── core-utils/ # 核心工具
│ └── kindeditor/ # 富文本编辑器
├── docs/ # Storybook 文档
├── scripts/ # 构建脚本
├── patches/ # 依赖补丁
├── .husky/ # Git Hooks
├── .vscode/ # VS Code 配置
├── package.json # 根配置
├── pnpm-workspace.yaml # Workspace 配置
├── tsconfig.json # TypeScript 配置
├── eslint.config.ts # ESLint 配置
└── vitest.workspace.ts # 测试配置
```
---
## 🎯 核心概念
### 1. 字段类型(FieldType
业务模型中的字段类型定义,用于描述数据结构。
**常见字段类型**
- 基础类型:文本、数字、日期、布尔
- 业务类型:手机号码、金额、币种、邮箱
- 引用类型:人员、组织、基础数据、文档
**定义位置**
`packages/types/business-components/enum/common/Enum.ts`
### 2. 物料组件(Widget
页面设计器中可拖拽的可视化组件。
#### 三大类型
| 类型 | 说明 | 是否有 FieldType | 示例 |
|------|------|------------------|------|
| **字段 + 物料** | 有对应字段类型的表单组件 | ✅ | 输入框、选择器、日期选择器、手机号码 |
| **纯物料** | 纯 UI/交互/容器组件 | ❌ | 按钮、文本、分组面板、Tabs、列表 |
| **纯字段** | 仅用于业务模型,无页面组件 | ✅ | BinaryObject、某些后端专用字段 |
### 3. 组件开发三层架构
```
┌─────────────────────────────────────────┐
│ 共享契约层 (packages/types) │
│ - 定义所有类型、枚举、接口 │
│ - PC/移动端共享 │
│ - ⭐ 所有开发的起点 │
└────────────────┬────────────────────────┘
┌────────┴────────┐
↓ ↓
┌───────────────┐ ┌──────────────────┐
│ 建模层 │ │ 设计器层 │
│ (apps/lcdp) │ │ (form-designer) │
│ │ │ │
│ - 业务建模 │ │ - PC 设计器 │
│ - 字段属性 │ │ - 移动设计器 │
│ - 实体配置 │ │ - 物料面板 │
│ - 国际化 │ │ - 组件渲染 │
└───────────────┘ └──────────────────┘
```
### 4. 关键注册链路
#### PC 端注册流程
```
Material.ts (物料面板)
RegisterWidget.ts (组件实例映射)
RegisterWidgetHelper.ts (Helper 注册)
RegisterWeb.ts (配置装配)
register/*.ts (实际注册执行)
```
#### 移动端注册流程
```
widget-mobile/config/*.ts
widget-mobile/config/index.ts
setConfigAll(PagePlatform.MOBILE)
register/registry.ts
```
---
## 🚀 快速开始
### 环境要求
| 软件 | 版本要求 | 说明 |
|------|---------|------|
| **Node.js** | v22.x | 查看 `.nvmrc` 文件 |
| **pnpm** | 10.13.1 | 必须使用 pnpm |
| **Git** | 2.x+ | 版本控制 |
| **IDE** | VS Code | 推荐安装 Vue、ESLint 插件 |
### 1. 安装依赖
```bash
# 进入项目目录
cd /Users/admin/Desktop/myFile/project2/fe-cisdigital-lingshu-lcdp
# 安装依赖(首次安装会自动构建核心引擎)
pnpm install
# 如果遇到依赖问题,可重新安装
pnpm reinstall
```
### 2. 查看可用启动命令
```bash
# 查看所有可用脚本
cat package.json | grep -A 30 '"scripts"'
```
### 3. 启动开发服务器
根据开发需求选择对应的启动命令:
```bash
# ==================== 低码平台主应用 ====================
pnpm start:lcdp:dev # 开发环境(最常用)
pnpm start:lcdp:test # 测试环境
pnpm start:lcdp:qa # QA 环境
pnpm start:lcdp:pre # 预发环境
pnpm start:lcdp:pet # 宠物环境(演示/体验)
pnpm start:lcdp:prod # 生产环境
# ==================== 设计器独立开发 ====================
pnpm form-designer:dev # PC 端页面设计器
# ==================== 引擎独立开发 ====================
pnpm form-create:dev # 表单引擎
pnpm lowcode-create:dev # 低码渲染引擎
# ==================== 其他命令 ====================
pnpm storybook # Storybook 文档
pnpm lint:fix # 代码格式化
pnpm build:core # 构建核心引擎
```
---
## 🔧 环境配置与启动说明
### 如何查看当前启动的环境
#### 方法 1:查看终端输出(推荐)
启动项目后,终端会显示环境信息:
```bash
> pnpm start:lcdp:dev
VITE v8.x.x ready in 1234 ms
➜ Local: http://localhost:5173/
➜ Network: http://10.201.161.55:5173/
➜ Environment: dev ← 当前环境
➜ API Base: https://dsep-dev.minmetals.com.cn/api ← 接口地址
```
#### 方法 2:查看环境变量配置文件
```bash
# 查看项目中的环境配置文件
ls -la .env*
# 常见文件
.env.development # 开发环境配置
.env.test # 测试环境配置
.env.pre # 预发环境配置
.env.production # 生产环境配置
# 查看 API 基础地址
cat .env.development | grep VITE_API_BASE
```
#### 方法 3:浏览器开发者工具
1. 启动项目后,打开浏览器访问 `http://localhost:5173`
2.`F12` 打开开发者工具
3. 切换到 **Console(控制台)** 标签
4. 执行以下命令查看环境配置:
```javascript
// 查看所有环境变量
console.log(import.meta.env)
// 查看 API 地址
console.log('API Base:', import.meta.env.VITE_API_BASE)
```
#### 方法 4:查看 Network 请求
1. 打开开发者工具(F12
2. 切换到 **Network(网络)** 标签
3. 刷新页面
4. 查看请求的域名,例如:
- `dsep-dev.minmetals.com.cn` → 开发环境
- `dsep-test.minmetals.com.cn` → 测试环境
- `dsep-pre.minmetals.com.cn` → 预发环境
---
### 环境域名对照表
| 环境 | 域名 | 用途 | 启动命令 |
|------|------|------|---------|
| **开发环境** | `dsep-dev.minmetals.com.cn` | 日常开发调试 | `pnpm start:lcdp:dev` |
| **测试环境** | `dsep-test.minmetals.com.cn` | 功能测试 | `pnpm start:lcdp:test` |
| **QA 环境** | `dsep-qa.minmetals.com.cn` | 质量验证 | `pnpm start:lcdp:qa` |
| **预发环境** | `dsep-pre.minmetals.com.cn` | 发布前验证 | `pnpm start:lcdp:pre` |
| **宠物环境** | `dsep-pet.minmetals.com.cn` | 演示/体验 | `pnpm start:lcdp:pet` |
| **演示环境** | `dsep-demo.minmetals.com.cn` | 客户演示 | 单独配置 |
| **生产环境** | `dsep.minmetals.com.cn` | 线上环境 | `pnpm start:lcdp:prod` |
> **⚠️ 重要提示**:所有环境域名均解析至 `10.201.161.55`
---
### ⚠️ 配置 accessToken(必做步骤)
#### 为什么需要配置?
- 本地开发服务器(localhost)需要访问远程环境的 API
- 接口需要身份验证,通过 `accessToken` 进行鉴权
- **必须保证本地启动环境与 accessToken 来源环境一致**,否则接口请求将失败
#### 完整配置流程
**步骤 1:启动本地项目**
```bash
# 以开发环境为例
pnpm start:lcdp:dev
# 等待启动完成,访问 http://localhost:5173
```
**步骤 2:访问对应环境的线上系统**
```bash
# 如果启动的是开发环境,打开:
https://dsep-dev.minmetals.com.cn
# 如果启动的是测试环境,打开:
https://dsep-test.minmetals.com.cn
# ⚠️ 确保线上环境与本地启动环境一致!
```
**步骤 3:登录线上系统**
使用你的账号密码登录系统。
**步骤 4:获取 accessToken**
**方式 A:通过开发者工具获取**
1.`F12` 打开浏览器开发者工具
2. 切换到 **Application(应用)** 标签(Chrome)或 **Storage(存储)** 标签(Firefox
3. 左侧菜单展开 **Local Storage(本地存储)**
4. 点击当前环境域名(如 `https://dsep-dev.minmetals.com.cn`
5. 右侧列表中找到 `accessToken` 字段
6. 双击复制其值
**方式 B:通过控制台获取**
```javascript
// 在线上系统的控制台中执行
localStorage.getItem('accessToken')
// 复制输出的 token 值
```
**步骤 5:配置到本地项目**
1. 切换到本地项目的浏览器标签(`http://localhost:5173`
2.`F12` 打开开发者工具
3. 切换到 **Console(控制台)** 标签
4. 执行以下命令:
```javascript
// 设置 accessToken(替换为你的实际 token
localStorage.setItem('accessToken', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...')
// 验证是否设置成功
console.log('✅ accessToken 已配置:', localStorage.getItem('accessToken'))
// 刷新页面使配置生效
location.reload()
```
**步骤 6:验证配置**
1. 打开开发者工具 → **Network(网络)** 标签
2. 刷新页面
3. 查看接口请求:
- ✅ 状态码返回 200
- ✅ 请求头包含 `Authorization: Bearer <accessToken>`
- ✅ 请求域名与启动环境一致
---
#### 🛠️ 快速配置脚本(推荐收藏)
在本地项目控制台执行:
```javascript
/**
* 一键配置 accessToken
* @param {string} token - 从线上环境获取的 accessToken
*/
function setAccessToken(token) {
if (!token) {
console.error('❌ 请提供 accessToken 参数')
return
}
localStorage.setItem('accessToken', token)
console.log('✅ accessToken 已成功配置')
console.log('🔄 请刷新页面使配置生效(按 F5)')
console.log('📝 当前环境 token:', token.substring(0, 20) + '...')
return token
}
// 使用示例:
// setAccessToken('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...')
```
---
#### ✅ 环境一致性检查清单
每次启动项目前,请确认:
- [ ] **启动命令与环境匹配**
例如:使用 `pnpm start:lcdp:dev` 对应开发环境
- [ ] **accessToken 来源一致**
`dsep-dev.minmetals.com.cn` 获取的 token 用于开发环境
- [ ] **API 地址正确**
检查 Network 请求是否发送到对应环境域名
- [ ] **token 未过期**
accessToken 通常有时效性(2-24 小时),如请求 401 需重新获取
- [ ] **跨域配置正常**
本地 localhost 能正常访问远程 API
---
#### ❓ 常见问题排查
**Q1: 请求返回 401 Unauthorized**
```
原因:accessToken 未配置或已过期
解决:
1. 重新从对应环境获取新的 accessToken
2. 在本地控制台重新设置:localStorage.setItem('accessToken', '新token')
3. 刷新页面
```
**Q2: 请求返回 403 Forbidden**
```
原因:accessToken 环境不匹配
解决:
1. 检查当前启动的环境(查看终端输出)
2. 从相同环境的线上系统重新获取 token
3. 确保环境完全一致
```
**Q3: Network 显示 CORS 跨域错误**
```
原因:本地开发服务器未正确配置代理
解决:
1. 检查 vite.config.ts 中的 proxy 配置
2. 确认启动的环境配置正确
3. 重启开发服务器(Ctrl+C 后重新启动)
```
**Q4: 如何确认当前使用的是哪个环境的 token?**
```javascript
// 在控制台执行
const token = localStorage.getItem('accessToken')
console.log('当前 accessToken:', token)
// 解码 JWT token 查看信息(如果是 JWT 格式)
function decodeJWT(token) {
try {
const base64Url = token.split('.')[1]
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
const jsonPayload = decodeURIComponent(
atob(base64).split('').map(c =>
'%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
).join('')
)
console.log('Token 信息:', JSON.parse(jsonPayload))
} catch (e) {
console.log('Token 解码失败')
}
}
decodeJWT(token)
```
**Q5: token 有效期是多久?**
```
通常 accessToken 有效期为 2-24 小时(具体看后端配置)
如果频繁过期,建议:
1. 联系后端同事确认 token 有效期
2. 检查是否有 refresh token 机制
3. 开发期间可以临时延长 token 有效期
```
---
### 4. 验证启动成功
完成以上配置后:
1. 打开浏览器访问:`http://localhost:5173`(端口以终端输出为准)
2. 打开开发者工具(F12)→ **Network(网络)** 标签
3. 刷新页面,检查:
- ✅ 页面正常渲染,无白屏或报错
- ✅ 接口返回 200 状态码
- ✅ 请求域名与启动环境一致
- ✅ 请求头包含 `Authorization: Bearer <accessToken>`
- ✅ Console 无红色错误信息
---
## 📝 开发指南
### 场景分类
在开始开发前,先判断你属于哪一类场景:
| 场景 | 特征 | 必看章节 | 参考样板 |
|------|------|---------|---------|
| **字段 + 物料** | 有业务字段定义,又有页面物料 | 场景 A | `mobile-number` |
| **纯物料** | 只有页面组件,无业务字段 | 场景 B | `CommonBtn``GroupPanel` |
| **纯字段** | 只有业务字段,无页面组件 | 场景 C | `BinaryObject` |
---
### 场景 A:新增字段类型 + 物料组件
**典型场景**:新增"手机号码"字段,可在建模中定义,在设计器中拖拽使用
**完整开发链路**
```
1. packages/types (共享契约层)
├─ business-components/enum/common/Enum.ts → 添加 FieldType
├─ business-components/enum/settings/<field>/ → 添加字段扩展属性
├─ widget-pc/WidgetType.ts → 添加 WidgetType
└─ form-designer/components/filter/constants.ts → 添加过滤器类型(按需)
2. apps/lcdp (建模层)
├─ modeling/.../config/FieldType.ts → 字段类型映射
├─ modeling/.../helper/<field>/Schema.ts → 建模属性配置
├─ locales/model/modeling.json → 建模国际化
└─ components/common/form/RegistersFormComp.ts → 建模设置项注册(按需)
3. packages/business-components (业务组件层)
├─ src/enum/settings/<field>/ → 再导出字段扩展属性
├─ src/utils/<Field>Utils.ts → 格式化/校验工具
└─ src/service/*.ts / src/api/*.ts → 服务接口
4. packages/form-designer (设计器层 - PC)
├─ src/config/Material.ts → 物料面板注册
├─ src/config/RegisterWidget.ts → 组件实例映射
├─ src/config/RegisterWidgetHelper.ts → Helper 注册
├─ src/config/settings-helper/<Field>.ts → 属性面板配置
├─ src/config/widget-helper/<Field>Helper.ts → Widget Helper
├─ src/config/widget/<Field>.vue → 组件实现
├─ src/components/filter/constants.ts → 过滤器组件(按需)
├─ src/config/widget/table/FieldViewMap.ts → 列表只读渲染(按需)
└─ src/locales/model/Info.json → 设计器国际化
5. packages/form-designer (设计器层 - 移动端,按需)
├─ src/widget-mobile/config/widget/<Field>.vue → 移动端组件
└─ src/widget-mobile/config/widget-helper/ → 移动端 Helper
```
**开发 Checklist**
```
□ 1. packages/types
✓ FieldType
✓ WidgetType
✓ 字段扩展属性 Enum
□ 2. apps/lcdp 建模层
✓ FieldType.ts 映射
✓ Schema.ts 属性配置
✓ modeling.json 国际化
□ 3. business-components
✓ 字段扩展属性再导出
✓ 工具函数
✓ 服务接口(按需)
□ 4. form-designer PC
✓ Material.ts
✓ RegisterWidget.ts
✓ RegisterWidgetHelper.ts
✓ settings-helper
✓ widget-helper
✓ widget/*.vue
✓ Info.json
□ 5. form-designer mobile(按需)
✓ widget-mobile/widget/*.vue
✓ widget-mobile/widget-helper/*.ts
```
**参考样板**`mobile-number` 组件
---
### 场景 B:新增纯物料组件
**典型场景**:新增按钮、分组面板、文本展示等纯 UI 组件
**最小开发链路**
```
1. packages/types/widget-pc/WidgetType.ts → 添加 WidgetType
2. packages/form-designer/src/config/
├─ Material.ts → 注册物料面板
├─ RegisterWidget.ts → 注册组件实例
├─ RegisterWidgetHelper.ts → 注册 Helper
├─ widget-helper/<Helper>.ts → Helper 配置
└─ widget/<Comp>.vue → 组件实现
3. packages/form-designer/src/locales/model/Info.json → 国际化文案
```
**可跳过的层**
| 层/文件 | 是否可跳过 | 原因 |
|---------|-----------|------|
| `packages/types/business-components/enum/common/Enum.ts` | ✅ 是 | 不涉及 FieldType |
| `apps/lcdp/.../config/FieldType.ts` | ✅ 是 | 纯物料不属于业务模型 |
| `apps/lcdp/.../helper/<field>/Schema.ts` | ✅ 是 | 没有建模层字段属性 |
| `apps/lcdp/src/locales/model/modeling.json` | ✅ 是 | 没有建模文案 |
| `packages/business-components/src/enum/settings/<field>/` | ✅ 是 | 没有字段扩展属性 |
| `packages/form-designer/src/components/filter/constants.ts` | ✅ 通常是 | 除非是过滤器组件 |
| `packages/form-designer/src/config/widget/table/FieldViewMap.ts` | ✅ 通常是 | 除非参与列表渲染 |
**三种常见纯物料子类**
| 子类 | 例子 | 关注点 |
|------|------|--------|
| **通用展示/交互** | `CommonTxt``CommonBtn``CommonImg` | WidgetType、Material、RegisterWidget、Helper |
| **容器/布局** | `GroupPanel``Tabs``FlexLayout` | children、slot、拖拽规则、布局属性 |
| **运行型复杂** | `ListVxe``Filter``CommonTree` | store、service、事件配置、运行时协议 |
**开发 Checklist**
```
普通纯物料:
□ 1. packages/types
✓ WidgetType
✗ FieldType(不需要)
✗ 字段扩展属性(不需要)
□ 2. form-designer PC
✓ Material.ts
✓ RegisterWidget.ts
✓ RegisterWidgetHelper.ts
✓ widget-helper/<Helper>.ts
✓ widget/<Comp>.vue
✓ Info.json
✓ settings-helper/*.ts(如果有属性面板)
□ 3. form-designer mobile(按需)
✓ widget-mobile/config/widget/*.vue
✓ widget-mobile/config/widget-helper/*.ts
□ 4. 通常可跳过
✗ apps/lcdp 建模层
✗ business-components 字段枚举
✗ FieldViewMap
✗ filter/constants
```
**参考样板**
- 交互型:`CommonBtn`
- 容器型:`GroupPanel``Tabs`
- 展示型:`CommonTxt`
---
### 场景 C:新增纯字段类型
**典型场景**:仅在业务模型中使用,不需要页面物料组件
**开发链路**
```
1. packages/types/business-components/enum/common/Enum.ts → 添加 FieldType
2. apps/lcdp
├─ modeling/.../config/FieldType.ts → 建模映射
├─ modeling/.../helper/<field>/Schema.ts → 建模属性
└─ locales/model/modeling.json → 建模国际化
3. packages/business-components(按需)
└─ src/utils/*.ts / src/service/*.ts → 工具/服务
```
**可跳过的层**
-`packages/types/widget-pc/WidgetType.ts`
-`packages/form-designer/src/config/Material.ts`
-`packages/form-designer/src/config/RegisterWidget.ts`
-`packages/form-designer/src/config/RegisterWidgetHelper.ts`
-`packages/form-designer/src/config/widget/*.vue`
-`packages/form-designer/src/widget-mobile/**`
**参考样板**`BinaryObject`
---
## 📂 关键文件速查
### 共享契约层(packages/types
| 文件 | 作用 | 场景 |
|------|------|------|
| `business-components/enum/common/Enum.ts` | FieldType 定义 | 字段 + 物料、纯字段 |
| `business-components/enum/settings/<field>/Enum.ts` | 字段扩展属性 key | 字段 + 物料 |
| `widget-pc/WidgetType.ts` | PC 端 WidgetType | 字段 + 物料、纯物料 |
| `form-designer/SettingType.ts` | 设置项组件类型 | 自定义设置项 |
| `form-designer/components/filter/constants.ts` | 过滤器类型 | 需要过滤器的字段 |
### 设计器层 - PCpackages/form-designer
| 文件 | 作用 | 说明 |
|------|------|------|
| `src/config/Material.ts` | 物料面板配置 | 组件在左侧面板的展示 |
| `src/config/RegisterWidget.ts` | 组件实例映射 | WidgetType → Vue 组件 |
| `src/config/RegisterWidgetHelper.ts` | Helper 注册 | 注册所有 Helper |
| `src/config/RegisterSettings.ts` | 设置项组件注册 | 自定义设置项组件 |
| `src/config/settings-helper/*.ts` | 属性面板 Schema | 右侧属性面板配置 |
| `src/config/widget-helper/*.ts` | Widget Helper | 构造 widget/settings/controller |
| `src/config/widget/*.vue` | 组件实现 | 运行时渲染组件 |
| `src/components/filter/constants.ts` | 过滤器组件映射 | 过滤器输入/回显 |
| `src/config/widget/table/FieldViewMap.ts` | 列表只读渲染 | 列表/单据体详情 |
| `src/locales/model/Info.json` | 设计器国际化 | 物料名称、属性面板文案 |
### 设计器层 - 移动端(packages/form-designer/src/widget-mobile
| 文件 | 作用 |
|------|------|
| `config/Material.ts` | 移动端物料面板 |
| `config/RegisterWidget.ts` | 移动端组件注册 |
| `config/RegisterWidgetHelper.ts` | 移动端 Helper 注册 |
| `config/widget/*.vue` | 移动端组件实现 |
| `config/widget-helper/*.ts` | 移动端 Helper 配置 |
---
## 🎨 移动端开发特别说明
### 技术栈
- **框架**Vue 3 + TypeScript
- **UI 库**Vant`vant-cisdi`
- **运行方式**:H5 形式,嵌入移动端应用
### BaseField 三种使用模式
移动端字段组件基于 `BaseField` 封装,提供三种开发模式:
| 模式 | 适用场景 | 开发成本 | 推荐度 |
|------|---------|---------|--------|
| **模式一:基础模式** | 标准表单字段,零定制 | ⭐ 最低 | ⭐⭐⭐⭐⭐ |
| **模式二:插槽扩展** | 需要少量 UI 扩展(图标、按钮) | ⭐⭐ 中等 | ⭐⭐⭐⭐ |
| **模式三:完全自定义** | 强定制需求(DOM、动画、交互) | ⭐⭐⭐ 最高 | ⭐⭐⭐ |
#### 模式一:基础模式(推荐优先使用)
```vue
<script setup lang="ts">
import BaseField from "../components/BaseField.vue"
import { useField } from "./hook/useField"
const props = defineProps<WidgetProps<WidgetSchema<any>>>()
const { schema, fieldPath } = toRefs(props)
const { fieldProps, wrapperStyle, fieldSlots } = useField({ schema, attrs })
const value = defineModel<string>()
</script>
<template>
<BaseField
v-bind="fieldProps"
:style="wrapperStyle"
:field-slots="fieldSlots"
v-model="value"
/>
</template>
```
**特点**
- 零插槽开发,完全由 Schema 驱动
- 标题、占位符、校验规则全部从低码配置读取
- 适合快速开发通用输入组件
#### 模式二:插槽扩展模式
```vue
<template>
<BaseField v-bind="fieldProps" :field-slots="fieldSlots" v-model="value">
<!-- 自定义标签 -->
<template #label>
<div class="custom-label">
<span>自定义标签</span>
<i class="help-icon" />
</div>
</template>
<!-- 自定义左侧图标 -->
<template #left-icon>
<van-icon name="search" />
</template>
<!-- 自定义输入区域 -->
<template #input>
<input v-model="value" class="custom-input" />
</template>
</BaseField>
</template>
```
**特点**
- 复用 BaseField 的表单布局、事件派发
- 通过插槽自定义部分区域
- 兼顾低码配置与少量编码定制
#### 模式三:完全自定义模式
```vue
<script setup lang="ts">
import { Field } from "vant-cisdi"
import { useField } from "./hook/useField"
const { fieldProps, wrapperStyle, fieldSlots } = useField({ schema, attrs })
</script>
<template>
<Field
v-model="value"
v-bind="fieldProps"
:style="wrapperStyle"
@update:model-value="handleValueChange"
>
<!-- 完全自定义 DOM 结构 -->
<template v-if="fieldSlots.hasLabelSlot" #label>
<div class="custom-label">
{{ fieldSlots.labelData?.value?.label }}
</div>
</template>
</Field>
</template>
```
**特点**
- 不使用 BaseField,直接使用 Vant Field
- DOM 结构、样式完全由业务组件控制
- 只复用数据与配置层能力
**建议实践**
1. 通用表单场景 → **模式一**
2. 需要少量 UI 扩展 → **模式二**
3. 前两种模式无法满足 → **模式三**
### 移动端开发流程(6 步)
```
步骤 1:添加 WidgetType 枚举
└─ packages/widget-mobile/src/config/WidgetType.ts
步骤 2:创建 Vue 组件
└─ packages/widget-mobile/src/config/widget/YourWidget.vue
步骤 3:创建 WidgetHelper 配置
└─ packages/widget-mobile/src/config/widget-helper/YourWidgetHelper.ts
步骤 4:注册组件
└─ packages/widget-mobile/src/config/RegisterWidget.ts
步骤 5:注册 Helper
└─ packages/widget-mobile/src/config/RegisterWidgetHelper.ts
步骤 6:添加到物料面板
└─ packages/widget-mobile/src/config/Material.ts
```
**详细指南**:查看 `低码移动端组件开发指南.md`
---
## ✅ 开发规范
### 命名规范
| 类型 | 规范 | 示例 |
|------|------|------|
| **项目名** | `fe-` 开头 | `fe-cisdigital-lingshu-lcdp` |
| **npm 包** | `@lingshu/` 命名空间 | `@lingshu/widget-cli` |
| **内部组件** | `ls-` 前缀 | `<ls-contacts-select>` |
| **枚举值** | 大写下划线 | `MOBILE_NUMBER` |
| **组件文件** | PascalCase | `MobileNumber.vue` |
| **Helper 文件** | PascalCase + Helper | `MobileNumberHelper.ts` |
| **工具函数** | camelCase | `formatMobileNumber()` |
### 代码规范
- ✅ 使用 TypeScript 严格模式
- ✅ Vue 3 Composition API`<script setup lang="ts">`
- ✅ ESLint + Prettier 自动格式化
- ✅ Git Hook 检查(Husky + lint-staged
- ✅ 组件必须有类型定义
- ✅ 公共函数必须写注释
### Git 提交规范
遵循 Conventional Commits 规范:
```bash
# 格式
<type>(<scope>): <subject>
# type 类型
feat: 新功能
fix: 修复 bug
docs: 文档更新
style: 代码格式(不影响代码运行)
refactor: 重构(既不是新功能也不是修复)
test: 测试相关
chore: 构建过程或辅助工具变动
perf: 性能优化
# 示例
feat(widget): 新增手机号码组件
fix(form): 修复日期选择器样式问题
docs(guide): 更新开发指南
refactor(helper): 重构 Helper 注册逻辑
```
**自动检查**
```bash
# 提交前自动格式化(lint-staged
git commit -m "feat: 你的提交信息"
# 如果格式不正确,会被 Husky 拦截
```
---
## 🧪 测试与验证
### 最小验证流程
| 场景 | 验证方式 | 访问路径 |
|------|---------|---------|
| **字段 + 物料** | 启动设计器 → 拖拽组件 → 配置属性 → 预览 | `/designer/:pageId` |
| **纯物料** | 启动设计器 → 拖拽使用 | `/designer/:pageId` |
| **纯字段** | 启动建模页 → 创建字段 → 保存验证 | 建模功能入口 |
| **运行型物料** | 启动设计器 + 运行时页面 | `/form/:pageId``/list/:pageId` |
### 常用启动命令
```bash
# 页面设计器(开发纯物料)
pnpm form-designer:dev
# 访问:http://localhost:5173/designer/:pageId
# 低码平台(开发字段 + 物料)
pnpm start:lcdp:dev
# 访问:
# - 建模页
# - /form/:pageId
# - /list/:pageId
# - /designer/:pageId
```
### 验证清单
**字段 + 物料组件**
```
□ 建模页能创建该字段类型
□ 设计器左侧物料面板能看到该组件
□ 拖拽到画布能正常渲染
□ 右侧属性面板配置正常
□ 表单运行时能正常编辑/提交
□ 列表/单据体能正常只读展示(如需要)
□ 过滤器能正常使用(如需要)
□ 移动端正常渲染(如需要)
```
**纯物料组件**
```
□ 设计器左侧物料面板能看到该组件
□ 拖拽到画布能正常渲染
□ 右侧属性面板配置正常
□ 运行时能正常展示/交互
□ 移动端正常渲染(如需要)
```
**纯字段类型**
```
□ 建模页能创建该字段类型
□ 字段属性配置正常
□ 能正常保存建模数据
□ 接口协议正确
```
---
## ⚠️ 常见误区
### ❌ 误区 1:新增纯物料也要改建模层
**错误做法**:在 `apps/lcdp` 中修改建模相关配置
**正确做法**:纯物料只需关注 `packages/types` + `packages/form-designer`
---
### ❌ 误区 2:新增字段只改建模层就够了
**错误做法**:只修改 `apps/lcdp` 建模层
**正确做法**:只要它还要进入页面设计器、过滤器、列表或运行时,就还要继续补 `business-components``form-designer`
---
### ❌ 误区 3:只改 `packages/form-designer/src/types/WidgetType.ts`
**错误做法**:在 form-designer 本地修改 WidgetType
**正确做法**WidgetType 的真实定义在 `packages/types/widget-pc/WidgetType.ts`
---
### ❌ 误区 4:只改 `packages/form-designer/src/components/filter/constants.ts`
**错误做法**:只修改设计器本地的过滤器常量
**正确做法**:如果新增过滤器类型,还要先改 `packages/types/form-designer/components/filter/constants.ts`
---
### ❌ 误区 5:按旧文档补 `packages/business-components/src/index.ts`
**错误做法**:尝试创建或修改不存在的总入口文件
**正确做法**:当前包已拆分为多个子入口,没有统一的 `src/index.ts`
---
### ❌ 误区 6form-create / lowcode-create 是主开发入口
**错误做法**:在 form-create 或 lowcode-create 包中进行日常开发
**正确做法**:它们是外部依赖引擎,日常开发主要在 `form-designer`
---
### ❌ 误区 7:本地启动后直接能请求接口
**错误做法**:启动项目后不配置 accessToken 就直接使用
**正确做法**
1. 从对应环境的线上系统获取 accessToken
2. 在本地项目控制台设置
3. 刷新页面
---
## 📚 学习资源
### 必读文档
| 文档 | 位置 | 说明 |
|------|------|------|
| **字段类型与物料组件开发指南** | 根目录 | ⭐ 最重要,三类场景详解 |
| **低码移动端组件开发指南** | 根目录 | 移动端开发差异、BaseField 三种模式 |
| **AGENTS.md** | 根目录 | AI 辅助开发规范、项目约定 |
| **README.md** | 根目录 | 项目自述、Monorepo 说明 |
| **主题变量速查手册** | 根目录 | theme-变量速查手册.md |
| **用户脚本说明** | 根目录 | user-scripts.md |
### 参考样板
| 场景 | 参考组件 | 位置 |
|------|---------|------|
| **字段 + 物料** | `mobile-number` | form-designer 中搜索 |
| **纯物料(交互)** | `CommonBtn` | form-designer 中搜索 |
| **纯物料(容器)** | `GroupPanel``Tabs` | form-designer 中搜索 |
| **纯物料(展示)** | `CommonTxt` | form-designer 中搜索 |
| **纯字段** | `BinaryObject` | apps/lcdp 中搜索 |
### 快速定位文件
```bash
# 查找某个组件
find packages/form-designer -name "*MobileNumber*"
# 查找某个类型定义
grep -r "MOBILE_NUMBER" packages/types/
# 查看所有 Helper
ls packages/form-designer/src/config/widget-helper/
# 查看所有组件
ls packages/form-designer/src/config/widget/
```
---
## 💡 快速上手计划
### 📅 第 1 天:了解项目
**目标**:理解项目架构,能成功启动项目
**任务清单**
```
□ 1. 阅读本文档(约 30 分钟)
□ 2. 克隆项目,安装依赖
git clone <仓库地址>
cd fe-cisdigital-lingshu-lcdp
pnpm install
□ 3. 启动设计器,体验拖拽组件
pnpm form-designer:dev
访问 http://localhost:5173/designer/:pageId
□ 4. 阅读《字段类型与物料组件开发指南.md》
- 理解三类开发场景
- 了解各层次的作用
□ 5. 配置 accessToken
- 从对应环境获取 token
- 在本地控制台设置
- 验证接口请求正常
```
---
### 📅 第 2-3 天:理解代码
**目标**:熟悉代码结构,能看懂现有组件
**任务清单**
```
□ 1. 选择一个简单纯物料(如 CommonTxt)
- 查看 widget/CommonTxt.vue
- 查看 widget-helper/CommonTxtHelper.ts
- 理解组件实现逻辑
□ 2. 追踪注册链路
- 从 Material.ts 找到 CommonTxt
- 从 RegisterWidget.ts 找到组件实例
- 从 RegisterWidgetHelper.ts 找到 Helper
□ 3. 尝试修改组件
- 修改组件样式
- 修改属性面板配置
- 观察热更新效果
□ 4. 查看类型定义
- 打开 packages/types/widget-pc/WidgetType.ts
- 理解 WidgetType 枚举
- 查看 FieldType 定义
```
---
### 📅 第 4-5 天:尝试开发
**目标**:完成一个简单的组件开发
**任务清单**
```
□ 1. 选择开发场景
推荐:新增一个展示型纯物料(如 CommonImg)
□ 2. 按照 Checklist 开发
- 添加 WidgetType
- 创建 Vue 组件
- 创建 Helper
- 注册组件和 Helper
- 添加到物料面板
□ 3. 本地验证
- 启动设计器
- 拖拽新组件
- 配置属性
- 预览效果
□ 4. 请求 Code Review
- 提交代码
- 请同事审查
- 根据反馈修改
```
---
### 📅 第 6-10 天:独立开发
**目标**:能独立完成组件开发
**任务清单**
```
□ 1. 接受实际开发任务
- 从产品/设计获取需求
- 确认组件类型(字段+物料/纯物料/纯字段)
□ 2. 制定开发计划
- 列出必改文件
- 确定参考样板
- 预估开发时间
□ 3. 独立开发
- 按照文档逐步实现
- 遇到问题查阅文档或请教同事
□ 4. 测试验证
- 按照验证清单逐项检查
- 确保各场景正常
□ 5. 提交上线
- 代码审查
- 合并分支
- 部署测试环境
```
---
## 🤝 获取帮助
### 遇到问题怎么办?
**1. 查看文档**
```bash
# 项目根目录的文档
ls -la *.md
# 推荐阅读顺序
1. 项目概况-新同事快速入门.md(本文档)
2. 字段类型与物料组件开发指南.md
3. 低码移动端组件开发指南.md
4. AGENTS.md
```
**2. 查看样板代码**
```bash
# 参考现有组件
packages/form-designer/src/config/widget/
packages/form-designer/src/config/widget-helper/
# 参考类型定义
packages/types/
```
**3. 使用搜索**
```bash
# 搜索相关代码
grep -r "关键词" packages/
# 在 VS Code 中全局搜索
Ctrl+Shift+F (Windows/Linux)
Cmd+Shift+F (Mac)
```
**4. 请教同事**
- 技术负责人:[填写姓名]
- 前端团队:[填写群组]
- 项目群组:[填写群组]
### 常用链接
| 资源 | 地址 | 说明 |
|------|------|------|
| **Git 仓库** | [填写仓库地址] | 项目代码 |
| **NPM Registry** | http://nexus.cisdigital.cn/repository/npm/ | 私有包仓库 |
| **打包构建平台** | [填写 Poseidon 地址] | CI/CD |
| **开发环境** | https://dsep-dev.minmetals.com.cn | 日常开发 |
| **测试环境** | https://dsep-test.minmetals.com.cn | 功能测试 |
| **文档站点** | [填写 Storybook 地址] | 组件文档 |
---
## 📞 联系信息
### 团队角色
| 角色 | 姓名 | 联系方式 |
|------|------|---------|
| **项目经理** | [填写] | [填写] |
| **技术负责人** | [填写] | [填写] |
| **前端开发** | [填写] | [填写] |
| **后端开发** | [填写] | [填写] |
| **产品经理** | [填写] | [填写] |
| **UI 设计师** | [填写] | [填写] |
### 沟通渠道
- **日常沟通**:[填写即时通讯群组]
- **邮件群组**[填写邮件列表]
- **会议时间**:[填写站会/周会时间]
- **文档协作**[填写文档平台]
---
## 📝 文档更新记录
| 日期 | 版本 | 更新内容 | 更新人 |
|------|------|---------|--------|
| 2026-05-22 | v1.0 | 初始版本,整理项目概况、启动说明、开发指南 | AI Assistant |
---
## 🎉 附录
### A. 常用命令速查表
```bash
# ==================== 安装与启动 ====================
pnpm install # 安装依赖
pnpm reinstall # 重新安装依赖
pnpm start:lcdp:dev # 启动低码平台(开发环境)
pnpm form-designer:dev # 启动页面设计器
pnpm storybook # 启动 Storybook 文档
# ==================== 构建 ====================
pnpm build:core # 构建核心引擎
pnpm build:form-create # 构建表单引擎
pnpm build:lowcode-create # 构建低码引擎
pnpm build:storybook # 构建文档
# ==================== 代码质量 ====================
pnpm lint:fix # 自动修复代码格式
pnpm prepare # 安装 Git Hooks
# ==================== 依赖管理 ====================
pnpm updateDeps # 更新依赖版本
pnpm clean # 清理 node_modules
# ==================== 版本发布 ====================
pnpm release # 版本号管理
```
### B. 目录速查
```bash
# 共享类型
packages/types/
# PC 设计器配置
packages/form-designer/src/config/
# 移动端配置
packages/form-designer/src/widget-mobile/config/
# 业务组件
packages/business-components/src/
# 建模层
apps/lcdp/src/feature/modeling/
# 文档
docs/
# 环境配置
.env*
```
### C. 环境变量说明
```bash
# 常见环境变量
VITE_API_BASE # API 基础地址
VITE_ENV # 当前环境(dev/test/pre/prod
VITE_APP_TITLE # 应用标题
VITE_PORT # 开发服务器端口
```
### D. 浏览器扩展推荐
| 扩展 | 用途 | 下载 |
|------|------|------|
| **Vue DevTools** | Vue 调试 | Chrome/Firefox 商店 |
| **React DevTools** | 如需要 | Chrome/Firefox 商店 |
| **JSON Viewer** | JSON 格式化 | Chrome 商店 |
| **Postman** | 接口调试 | 独立应用 |
---
**文档结束**
> 💡 **提示**:本文档会持续更新,如有疑问或建议,请联系技术负责人。
> 📖 **推荐阅读顺序**:本文档 → 《字段类型与物料组件开发指南》 → 《低码移动端组件开发指南》 → 参考样板代码
> 🚀 **祝开发顺利!**