Files
geg-gas-web/.claude/CLAUDE.md

486 lines
14 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.

# 交互规范
1、使用中文交互
---
# 项目架构概览
## 技术栈
| 层级 | 技术 |
| --------- | ---------------------------- |
| 框架 | Vue 3 + TypeScript 5 |
| 构建 | Vite 4 |
| UI 组件库 | Ant Design Vue 3 |
| 状态管理 | Pinia 2 |
| 路由 | Vue Router 4 |
| HTTP | Axios自定义封装`defHttp` |
| 样式 | Less + Windi CSS |
| 国际化 | Vue I18n 9 |
| 基础框架 | Vben Admin深度定制 |
| 包管理 | pnpm |
> 注意:本项目与 Vue 3.4.x 不兼容,请保持 Vue ~3.3.4。
---
## 目录结构
```
src/
├── api/ # HTTP 请求模块,按业务域分组
│ └── <domain>/
│ └── <module>/
│ ├── index.ts # 请求函数
│ └── model/ # 请求/响应 TS 类型
├── assets/ # 静态资源、全局样式
├── components/ # 可复用组件BasicTable、BasicForm、Modal 等)
├── design/ # 全局 Less 主题入口
├── hooks/ # 组合式函数composables
├── layouts/ # 布局组件header、sider、tabs
├── locales/ # i18n 配置
├── router/ # 路由配置、守卫
├── store/ # Pinia 状态模块
│ └── modules/ # app / user / permission / locale / lock / multipleTab
├── utils/ # 工具函数
│ └── http/axios/ # HTTP 封装核心
└── views/ # 业务页面,按业务域分组
└── <domain>/ # erp / system / workflow / contract / sales ...
```
---
## 路径别名
| 别名 | 指向 |
| --------- | --------------------------------- |
| `/@/` | `src/` |
| `/#/` | `types/` |
| `/@bpmn/` | `src/views/workflow/design/bpmn/` |
**始终使用别名,禁止使用相对路径 `../../`。**
---
# 代码规范
## 1. Vue 组件
### 新文件优先使用 `<script setup>`
```vue
<script setup lang="ts">
import { ref } from 'vue';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
const visible = ref(false);
</script>
```
存量代码中存在 `defineComponent` 写法,维护时保持原有风格,新增代码统一用 `<script setup>`
### 文件命名
| 场景 | 规范 | 示例 |
| ----------- | ----------- | ----------------------------------- |
| 页面入口 | `index.vue` | `src/views/system/user/index.vue` |
| 弹窗/子组件 | PascalCase | `UserModal.vue``DetailDrawer.vue` |
| 组合式函数 | camelCase | `useUserList.ts` |
### 事件处理函数命名
统一以 `handle` 开头:`handleEdit``handleDelete``handleSubmit`
---
## 2. API 模块
每个业务模块的 API 结构:
```
src/api/<domain>/<module>/
├── index.ts # 导出请求函数
└── model/
└── index.ts # 请求/响应类型定义
```
**示例:**
```ts
// src/api/erp/purchase/apply/index.ts
import { defHttp } from '/@/utils/http/axios';
import type { ApplyListParams, ApplyListResult } from './model';
enum Api {
List = '/erp/purchase/apply/list',
Save = '/erp/purchase/apply/save',
}
export const getApplyList = (params: ApplyListParams) =>
defHttp.get<ApplyListResult>({ url: Api.List, params });
export const saveApply = (data: ApplyListParams) =>
defHttp.post({ url: Api.Save, data });
```
- 所有 HTTP 请求必须通过 `defHttp`,禁止直接使用 axios。
- 接口路径统一用 `enum Api` 管理。
- 错误提示通过 `errorMessageMode` 控制(`'modal'` | `'message'` | `'none'`)。
---
## 3. 状态管理Pinia
```ts
// src/store/modules/xxx.ts
import { defineStore } from 'pinia';
import { store } from '/@/store';
export const useXxxStore = defineStore({
id: 'app-xxx',
state: () => ({ ... }),
getters: { ... },
actions: { ... },
});
// 在 setup 外使用
export function useXxxStoreWithOut() {
return useXxxStore(store);
}
```
- Store 命名:`useXxxStore`
- 需要在 setup 外调用时,导出 `useXxxStoreWithOut`
---
## 4. 表格页面CRUD 标准模式)
```vue
<template>
<PageWrapper>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleAdd">新增</a-button>
</template>
<template #action="{ record }">
<TableAction :actions="getActions(record)" />
</template>
</BasicTable>
<XxxModal @register="registerModal" @success="reload" />
</PageWrapper>
</template>
<script setup lang="ts">
import { useTable } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { PageWrapper } from '/@/components/Page';
import { TableAction } from '/@/components/Table';
const [registerTable, { reload }] = useTable({
api: getXxxList,
columns,
useSearchForm: true,
formConfig: { schemas },
showTableSetting: true,
bordered: true,
});
const [registerModal, { openModal }] = useModal();
function handleAdd() {
openModal(true, { isUpdate: false });
}
function getActions(record) {
return [
{ label: '编辑', onClick: () => openModal(true, { record, isUpdate: true }) },
{ label: '删除', color: 'error', popConfirm: { title: '确认删除?', confirm: () => handleDelete(record) } },
];
}
</script>
```
---
## 5. 样式规范
- 组件内样式:`<style lang="less" scoped>`
- 全局主题变量在 `src/design/``src/assets/style/theme/` 中定义
- 工具类优先使用 Windi CSS`flex``items-center``mt-4`
- 项目自定义主题类前缀:`lng-`
- 禁止在 scoped 样式中直接穿透 AntD 组件,改用 `:deep()`
```less
// 正确
:deep(.ant-table-cell) {
padding: 8px;
}
```
---
## 6. TypeScript 规范
- 严格模式已开启(`strict: true`),但项目对 `any` 较宽松
- API 请求/响应类型放在对应 `model/` 目录
- 通用类型放在 `types/` 目录,通过 `/#/` 别名引用
- 变量命名:
- `ref` 变量加 `Ref` 后缀:`visibleRef``loadingRef`
- computed 可加 `ComputedRef` 后缀
---
## 7. 国际化
所有用户可见文本必须通过 i18n
```ts
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
// 使用
t('common.okText')
```
---
## 8. 权限控制
按钮级权限通过 `v-auth` 指令或 `usePermission` 控制:
```vue
<a-button v-auth="'system:user:add'">新增</a-button>
```
```ts
import { usePermission } from '/@/hooks/web/usePermission';
const { hasPermission } = usePermission();
if (hasPermission('system:user:edit')) { ... }
```
---
## 9. 工作流路由约定
特殊路由格式(在 `src/router/routes/basic.ts` 中定义):
| 路由 | 用途 |
| ----------------------------------- | ------------ |
| `/flow/:arg1/:arg2/createFlow` | 发起流程 |
| `/flow/:arg1/:arg2/approveFlowPage` | 审批流程 |
| `/form/:module/:id/createForm` | 通用表单新建 |
| `/form/:module/:id/updateForm` | 通用表单编辑 |
| `/flowList/todo` | 待办列表 |
---
## 10. 提交规范
遵循 Conventional Commits
```
feat: 新增功能
fix: 修复 bug
refactor: 重构
style: 样式调整
docs: 文档更新
chore: 构建/工具变更
```
---
## 新增页面检查清单
- [ ]`src/views/<domain>/` 下创建目录
- [ ] 页面入口为 `index.vue`,弹窗为 `XxxModal.vue`
- [ ] API 模块放在 `src/api/<domain>/<module>/index.ts`
- [ ] 类型定义放在 `model/index.ts`
- [ ] 使用 `PageWrapper` + `BasicTable` + `useTable` + `useModal` 标准结构
- [ ] 文本通过 `useI18n` 国际化
- [ ] 按钮权限通过 `v-auth` 控制
- [ ] 样式使用 `<style lang="less" scoped>`
- [ ] 路径使用 `/@/` 别名
---
# 代码生成器generator规范
## 目录结构
```
src/views/generator/
├── codeTemplate/ # 模板管理列表(草稿增删改查)
├── designer/ # 表单设计器演示/测试页
├── dev/ # 代码生成器核心入口
│ ├── choose.vue # 模式选择入口页
│ └── components/
│ ├── DataFirstModal.vue # 数据优先向导
│ ├── CodeFirstModal.vue # 界面优先向导
│ ├── SimpleTemplateModal.vue # 简易模板向导
│ ├── PreviewCodeStep.vue # 代码预览步骤(三种模式共用)
│ └── SelectDatabase.vue # 选择数据库表弹窗
├── desktop/ # 桌面/首页可视化设计器
├── order/ # 示例产物(订单模块演示)
└── print/ # 打印模板设计器
```
步骤子组件统一放在 `/@/components/CreateCodeStep/src/` 下。
---
## 三种生成模式
| 维度 | 数据优先 | 界面优先 | 简易模板 |
|------|---------|---------|---------|
| `designType` | `'data'` | `'code'` | `'template'` |
| `outputConfig.type` | `0` | `1` | `2` |
| 起点 | 选数据库表 | 设计表单 | 设计表单(固定 master 库) |
| 表配置字段 | `tableConfigs` | `tableStructureConfigs` | `tableStructureConfigs` |
| 生成接口 | `dataFirstGeneratorCode` | `codeFirstGeneratorCode` | `codeFirstGeneratorCode` |
| 预览接口 | `dataFirstPreviewCode` | `codeFirstPreviewCode` | `codeFirstPreviewCode` |
| 特殊逻辑 | 无 | 自动推导主表名 | 额外判断字段大小写Oracle/DM 等) |
简易模板本质是界面优先的变体,复用同一套后端生成接口,仅 `type` 不同。
---
## 核心设计模式
### 1. provide/inject 共享生成状态
父 Modal 通过 `provide` 下发,子步骤通过 `inject` 直接读写,禁止 props 层层传递:
```ts
provide('generatorConfig', generatorConfig) // 核心配置reactive
provide('tableInfo', tableInfo) // 表结构信息
provide('current', current) // 当前步骤索引
provide('designType', 'data') // 生成模式标识
provide('widgetForm', widgetForm) // 表单设计器状态
provide('mainTableName', mainTableName) // 主表名(界面优先/简易模板)
provide('isFieldUpper', isFieldUpper) // 字段大小写(简易模板)
```
### 2. ref + defineExpose 控制步骤流转
每个步骤子组件必须暴露 `validateStep()`,父组件通过 ref 统一调用:
```ts
// 子组件
defineExpose({ validateStep, initStep?, getFormData?, editFieldsValue? })
// 父组件
const stepValidate = {
0: () => tableConfigStepRef.value.validateStep(),
1: () => formDesignStepRef.value.validateStep(),
// ...
}
```
### 3. 前端本地生成 + 后端补全的混合模式
```
前端本地 buildCode() 后端接口 previewCode()
───────────────────── ──────────────────────
listCode列表页 controllerCode控制器
formCode表单页 entityCode实体类
apiCodeAPI 模块)
modelCodeTS 类型)
configJsonCode路由配置
```
### 4. hiddenComponent 生命周期
```ts
// 编辑模板时:从列表剔除,不在设计器中展示
formJson.list = formJson.list.filter(x => x.type !== 'hiddenComponent')
// 正式生成时:重新塞回,参与代码生成
generatorConfig.formJson.list.push(...generatorConfig.formJson.hiddenComponent)
```
### 5. 两段式下载
```
生成接口 → 返回 uuid → downloadCodes(uuid) → 下载 zip
```
---
## 核心数据结构
```ts
GeneratorConfig {
databaseId: string | null
listConfig: {
isLeftMenu, queryConfigs, leftMenuConfig,
columnConfigs, buttonConfigs, defaultOrder, isPage
}
tableConfigs: TableConfig[] // 仅数据优先
tableStructureConfigs: [] // 界面优先/简易模板
formJson: FormJson // 表单设计结果
menuConfig: MenuConfig
outputConfig: {
creator, isMenu,
type: 0 | 1 | 2 // 生成模式
}
formEventConfig: FormEventColumnConfig
isDataAuth: boolean
dataAuthList: []
}
```
类型定义文件:`src/api/system/generator/model/index.ts`
---
## API 接口
所有接口在 `src/api/system/generator/index.ts`
| 函数 | 方法 | 路径 |
|------|------|------|
| `dataFirstGeneratorCode` | POST | `/system/generator/generator-code/data-first` |
| `codeFirstGeneratorCode` | POST | `/system/generator/generator-code/code-first` |
| `dataFirstPreviewCode` | POST | `/system/generator/preview-code/data-first` |
| `codeFirstPreviewCode` | POST | `/system/generator/preview-code/code-first` |
| `saveDraftGeneratorCode` | POST | `/system/code-schema` |
| `updateDraftGeneratorCode` | PUT | `/system/code-schema` |
| `getCodeTemplateInfo` | GET | `/system/code-schema/info` |
| `getCodeTemplateList` | GET | `/system/code-schema/page` |
| `deleteCodeTemplate` | DELETE | `/system/code-schema` |
| `getMasterInfo` | GET | `/system/databaselink/master-info` |
| `batchGeneratorCode` | POST | `/system/generator/generator-code/batch` |
| `downloadCodes` | GET | `/system/generator/downloadCodes/{uuid}` |
---
## 功能扩展指南
### 新增生成模式
1. 复制 `CodeFirstModal.vue`,修改 `designType``outputConfig.type`
2.`choose.vue` 加入入口卡片
3.`codeTemplate/index.vue` 的路由名判断中加入新类型
4. 后端新增对应生成/预览接口
### 新增向导步骤
1.`/@/components/CreateCodeStep/src/` 下新建步骤组件,暴露 `validateStep()`
2. 在主 Modal 的 `<a-steps>` 中加入新步骤
3.`stepValidate` 对象中加入对应索引的校验函数
4.`generatorConfig` 中加入新步骤的配置字段,并通过 `provide` 下发
### 扩展代码预览输出类型
1.`FrontCode` 类型中加入新字段
2.`PreviewCodeStep.vue``<a-tabs>` 中加入新 tab
3.`validateStep()` 中加入非空校验
4.`buildCode()``previewCode()` 中补充生成逻辑