98 lines
3.8 KiB
Markdown
98 lines
3.8 KiB
Markdown
# 步骤三:前端 UI 适配
|
||
|
||
> 前置条件:step-02 已完成。
|
||
> 实施依据:`docs/crm-migration/plans/{module}/06-steps.md` 中的前端适配步骤。
|
||
> 同步参考:[ref-frontend-diff.md](ref-frontend-diff.md)、[ref-ui-standards.md](ref-ui-standards.md)
|
||
> 模块方案:`docs/crm-migration/plans/{module}/03-frontend-spec.md`(前端功能规格)
|
||
|
||
---
|
||
|
||
## 核心原则
|
||
|
||
**逐行阅读理解后修改,不要机械式查找替换。** 不同页面上下文不同,适配方式可能不同。
|
||
|
||
## 操作流程
|
||
|
||
对每个 `.vue` 文件执行以下审阅:
|
||
|
||
### 1. 审阅 `<script>` 部分
|
||
|
||
逐行阅读,理解数据流和调用链后逐处修改:
|
||
|
||
- `getCurrentInstance()` / `proxy` → 理解用途后改用 shanxia2.0 等价 API
|
||
- `proxy?.useDict('xxx')` → `useDictTag('xxx')` 或 `dictStore.getLabel('xxx', val)`
|
||
- `proxy?.$modal.msgSuccess(msg)` → `ElMessage.success(msg)`
|
||
- `proxy?.$modal.confirm(msg)` → `ElMessageBox.confirm(msg, '提示', { type: 'warning' })`
|
||
- `request({ url, method, data })` → `request.post('/web/crm/xxx', data)`
|
||
- `hasPermi(['crm:xxx:add'])` → `v-auth="'add'"`
|
||
- 手动 `import { ElXxx }` / `import { ref, reactive }` → 删除(自动导入)
|
||
|
||
### 2. 审阅 `<template>` 部分
|
||
|
||
逐行阅读,理解结构意图后逐处修改:
|
||
|
||
- `<el-drawer>` → `<el-dialog>`(统一用弹窗,禁止抽屉)
|
||
- `<dict-tag>` → `<el-tag :type="getTagType(val)" size="small">{{ getLabel(val) }}</el-tag>`
|
||
- `<right-toolbar>` → `<div class="list-toolbar"><div class="list-toolbar-row">...</div></div>`
|
||
- `label-width="120px"` → `label-position="top"`
|
||
- `<el-row :gutter="20"><el-col :span="12">` → `.dialog-form-layout` + `.form-grid-2`
|
||
- RuoYi 上传组件 → MinIO `fetchUploadAttachment`
|
||
- 所有 `el-button` 添加 `<el-icon>`
|
||
|
||
### 3. 审阅 `<style>` 部分
|
||
|
||
逐行阅读,理解样式意图后适配:
|
||
|
||
- UnoCSS 工具类 → Tailwind CSS 等价类
|
||
- 复杂样式用 SCSS
|
||
- 应用门户标准 CSS 类(dialog-form-layout、form-grid-2、form-col-span-2 等)
|
||
|
||
### 4. 弹窗统一规范
|
||
|
||
所有弹窗必须符合以下模板:
|
||
|
||
```vue
|
||
<el-dialog v-model="innerVisible" :title="..." width="960px"
|
||
destroy-on-close align-center :close-on-click-modal="false"
|
||
style="backdrop-filter: none" class="dialog-form-layout">
|
||
<el-form ref="formRef" :model="formData" :rules="formRules" label-position="top" scroll-to-error>
|
||
<div class="form-grid-2">...</div>
|
||
</el-form>
|
||
<template #footer>
|
||
<el-button @click="innerVisible = false"><el-icon><Close /></el-icon>取消</el-button>
|
||
<el-button type="primary" @click="handleSubmit"><el-icon><Check /></el-icon>确定</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
```
|
||
|
||
### 5. 编写/更新前端 API 模块
|
||
|
||
为该模块创建 `web-admin/src/api/crm/{module}.ts`,每个接口对应一个函数,使用 `request.post()` 调用。
|
||
|
||
### 6. 注册路由
|
||
|
||
在路由配置中添加该模块的页面路由。
|
||
|
||
### 7. UI 规范合规检查
|
||
|
||
对照 [ref-ui-standards.md](ref-ui-standards.md) 逐条检查。
|
||
|
||
### 8. 查看详情与导出
|
||
|
||
- **查看**:只读详情 SHALL 使用 `SystemViewDialog`(勿保留 `el-drawer`);状态/类型字段配 `tagType` + `dictStore.getLabel`(见 OpenSpec P09)。
|
||
- **导出**:API 层 `responseType: 'blob'` + `showErrorMessage: false`;详见 [ref-frontend-diff.md](ref-frontend-diff.md) §「Excel / Blob 导出」。
|
||
- **权限**:若路由未配置 `authList`,使用 `useXxxPerm` + `menu-codes`(见 `ref-lessons-learned.md` §28)。
|
||
|
||
## 完成标准
|
||
|
||
- [ ] 所有 `.vue` 文件的 script/template/style 已逐行审阅并适配
|
||
- [ ] 无 proxy/useDict/dict-tag/right-toolbar/el-drawer 残留
|
||
- [ ] 弹窗符合标准模板
|
||
- [ ] API 模块已创建
|
||
- [ ] 路由已注册
|
||
- [ ] UI 规范合规检查通过
|
||
|
||
## 下一步
|
||
|
||
完成后加载 [step-04-backend.md](step-04-backend.md) 实现后端。
|