# CRMEB 页面设计规范与 Uni-App-X UVue 复刻指南

## 📋 目录

1. [CRMEB 项目架构分析](#crmeb-项目架构分析)
2. [页面布局模式](#页面布局模式)
3. [样式系统设计](#样式系统设计)
4. [组件设计规范](#组件设计规范)
5. [工程化配置](#工程化配置)
6. [UVue 复刻方案](#uvue-复刻方案)
7. [迁移检查清单](#迁移检查清单)

---

## CRMEB 项目架构分析

### 1. 项目结构概览

```
CRMEB/template/admin/
├── src/
│   ├── layout/              # 布局系统
│   │   ├── index.vue        # 主布局容器（支持多种布局模式）
│   │   ├── main/            # 主要布局模式
│   │   │   ├── defaults.vue       # 默认布局
│   │   │   ├── classic.vue        # 经典布局
│   │   │   ├── transverse.vue     # 横向布局
│   │   │   └── columns.vue        # 分栏布局
│   │   ├── navBars/         # 导航栏系统
│   │   │   ├── breadcrumb/  # 面包屑
│   │   │   └── tagsView/    # 标签页
│   │   ├── navMenu/         # 侧边栏菜单
│   │   ├── footer/          # 页脚
│   │   └── component/       # 布局相关组件
│   ├── components/          # 全局可复用组件（60+）
│   │   ├── cards/           # 卡片组件
│   │   ├── from/            # 表单相关
│   │   ├── searchFrom/      # 搜索表单
│   │   └── ...
│   ├── pages/               # 页面模块（16个大类）
│   │   ├── account/         # 账户管理
│   │   ├── agent/           # 代理管理
│   │   ├── app/             # APP管理
│   │   ├── cms/             # CMS内容
│   │   ├── finance/         # 财务
│   │   ├── order/           # 订单
│   │   ├── product/         # 商品
│   │   ├── system/          # 系统设置
│   │   ├── user/            # 用户管理
│   │   └── ...
│   ├── styles/              # 全局样式
│   ├── router/              # 路由配置
│   ├── store/               # 状态管理（Vuex）
│   ├── utils/               # 工具函数
│   └── ...
├── package.json             # 项目依赖（Vue 2）
├── vue.config.js            # Webpack 配置
├── .prettierrc.js           # 代码格式化规则
└── babel.config.js          # Babel 配置
```

### 2. 核心设计特点

#### 2.1 多布局支持

CRMEB 支持 4 种布局模式：

- **Defaults**: 侧边栏 + 顶部菜单 + 内容区
- **Classic**: 经典布局（左菜单 + 内容）
- **Transverse**: 顶部菜单 + 内容
- **Columns**: 三栏布局（侧菜单 + 侧栏 + 内容）

#### 2.2 标签页系统

- 每个打开的页面都生成一个标签
- 支持标签页关闭、固定、刷新
- 与路由历史联动

#### 2.3 面包屑导航

- 动态生成，根据路由元信息
- 支持多级导航回溯

#### 2.4 响应式设计

- 自动监听窗口大小
- < 1000px 时自动切换移动端布局
- 侧边栏自动收起

---

## 页面布局模式

### CRMEB 的四种布局

#### 模式 1: Defaults（默认布局 - 最常用）

```
┌─────────────────────────────────────────┐
│  Logo  │  Breadcrumb  │  Tags  │  User  │ ← NavBars
├─────────┼─────────────────────────────────┤
│ Menu    │                                 │
│         │  Content Area                   │
│         │  (Page Components)              │
│         │                                 │
├─────────┴─────────────────────────────────┤
│  Footer                                   │
└─────────────────────────────────────────┘
```

**特点**:

- 左侧固定菜单栏
- 顶部面包屑 + 标签页
- 主内容区占据剩余空间

#### 模式 2: Classic（经典布局）

```
┌─────────────────────────────────────────┐
│ Logo │ Breadcrumb │ Tags │ User Settings │ ← NavBars
├──────┴─────────────────────────────────────┤
│ Menu │  Content Area                      │
│      │  (Page Components)                 │
│      │                                    │
├──────┴─────────────────────────────────────┤
│ Footer                                     │
└─────────────────────────────────────────────┘
```

#### 模式 3: Transverse（横向菜单）

```
┌────────────────────────────────────────┐
│ Logo │ Menu 1 │ Menu 2 │ ... │ Settings│ ← Top Menu
├────────────────────────────────────────┤
│ Breadcrumb │ Tags │ Actions            │
├────────────────────────────────────────┤
│                                        │
│  Content Area                          │
│  (Page Components)                     │
│                                        │
└────────────────────────────────────────┘
```

#### 模式 4: Columns（三栏布局）

```
┌──────────────────────────────────────────┐
│  NavBars (Breadcrumb + Tags)             │
├─────────┬──────────┬──────────────────────┤
│ Menu    │ SubMenu  │  Content Area        │
│         │          │  (Page Components)   │
│         │          │                      │
└─────────┴──────────┴──────────────────────┘
```

---

## 样式系统设计

### 1. 全局样式架构

```scss
styles/
├── common.scss          # 通用样式重置、基础类名
├── variables.scss       # CSS 变量、主题颜色
├── animate.scss         # 动画库
├── element-ui.scss      # Element UI 主题覆盖
└── index.scss           # 主入口文件
```

### 2. 颜色系统

CRMEB 使用标准设计系统颜色：

- **主颜色**: `#1890ff`（蓝色）
- **成功**: `#52c41a`（绿色）
- **警告**: `#faad14`（黄色）
- **错误**: `#ff4d4f`（红色）
- **边框**: `#d9d9d9`（灰色）
- **文字**: `#000000` / `#666666` / `#999999`

### 3. 间距系统

```scss
$space-xs: 4px;
$space-sm: 8px;
$space: 12px;
$space-md: 16px;
$space-lg: 24px;
$space-xl: 32px;
```

### 4. 圆角系统

```scss
$radius-xs: 2px;
$radius-sm: 4px;
$radius: 6px;
$radius-lg: 8px;
$radius-xl: 12px;
```

### 5. 阴影系统

```scss
$shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.06);
$shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
$shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.15);
```

---

## 组件设计规范

### 1. 组件命名规范

```
常用组件类型：
- Cards/           # 卡片展示（数据统计卡、信息卡）
- Form/            # 表单相关（表单控件、表单验证）
- List/            # 列表显示（表格、数据列表）
- Modal/           # 模态框（确认框、详情框）
- Table/           # 表格组件（支持排序、分页、筛选）
- Upload/          # 上传组件（图片、视频、文件）
- Search/          # 搜索组件（高级搜索、快速搜索）
```

### 2. 常用组件库

CRMEB 使用 Element UI 作为基础组件库：

- `el-button` - 按钮
- `el-input` - 输入框
- `el-select` - 选择器
- `el-table` - 表格
- `el-form` - 表单
- `el-dialog` - 对话框
- `el-tree` - 树形控件
- `el-pagination` - 分页

### 3. 页面组件结构

```vue
<template>
  <div class="page-container">
    <!-- 页面标题 / 操作栏 -->
    <div class="page-header">
      <h1>{{ pageTitle }}</h1>
      <div class="page-actions">
        <el-button type="primary">新增</el-button>
        <el-button>导出</el-button>
      </div>
    </div>

    <!-- 搜索表单 -->
    <div class="search-container">
      <SearchForm @search="handleSearch" />
    </div>

    <!-- 列表 / 内容区 -->
    <div class="content-container">
      <el-table :data="tableData" />
    </div>

    <!-- 分页 -->
    <div class="pagination-container">
      <el-pagination @current-change="handlePageChange" />
    </div>
  </div>
</template>

<script>
export default {
  name: "PageName",
  components: {
    SearchForm: () => import("@/components/searchFrom/index"),
  },
  data() {
    return {
      pageTitle: "页面标题",
      tableData: [],
    };
  },
};
</script>

<style scoped lang="scss">
.page-container {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;

  h1 {
    font-size: 20px;
    font-weight: 600;
  }
}

.search-container {
  margin-bottom: 20px;
}

.content-container {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  margin-bottom: 20px;
}

.pagination-container {
  display: flex;
  justify-content: flex-end;
}
</style>
```

---

## 工程化配置

### 1. 构建工具配置

**vue.config.js** (Webpack):

```javascript
module.exports = {
  productionSourceMap: false,
  configureWebpack: {
    resolve: {
      alias: {
        "@": path.resolve(__dirname, "./src"),
      },
    },
  },
  chainWebpack: (config) => {
    // 优化大文件分割
    config.optimization.splitChunks({
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: "chunk-vendors",
          priority: 10,
        },
        common: {
          minChunks: 2,
          priority: 5,
          reuseExistingChunk: true,
        },
      },
    });
  },
};
```

### 2. 代码格式化配置

**.prettierrc.js**:

```javascript
module.exports = {
  printWidth: 100,
  tabWidth: 2,
  useTabs: false,
  semi: true,
  singleQuote: true,
  trailingComma: "es5",
  bracketSpacing: true,
  arrowParens: "always",
};
```

### 3. ESLint 配置

**.eslintrc.js**:

```javascript
module.exports = {
  root: true,
  env: {
    node: true,
    browser: true,
    es2021: true,
  },
  extends: ["plugin:vue/essential", "eslint:recommended"],
  parserOptions: {
    parser: "babel-eslint",
    ecmaVersion: 2020,
  },
  rules: {
    "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
    "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
  },
};
```

### 4. Babel 配置

**babel.config.js**:

```javascript
module.exports = {
  presets: ["@vue/cli-plugin-babel/preset"],
  plugins: [],
};
```

---

## UVue 复刻方案

### 1. 布局系统复刻

#### 1.1 AdminLayout 增强版

**layouts/admin/AdminLayout.uvue** - 支持多种布局：

```uvue
<template>
  <view class="admin-layout" :class="layoutClass">
    <!-- 模式1: Defaults（默认布局） -->
    <template v-if="layoutMode === 'defaults'">
      <AdminAside :collapsed="isCollapsed" @toggle="toggleCollapse" />
      <view class="admin-main-defaults">
        <AdminNavBar :breadcrumb="breadcrumb" />
        <AdminTagsView :tabs="tabs" />
        <view class="admin-content-defaults">
          <slot></slot>
        </view>
        <AdminFooter />
      </view>
    </template>

    <!-- 模式2: Classic（经典布局） -->
    <template v-else-if="layoutMode === 'classic'">
      <view class="admin-sidebar-classic">
        <AdminAside :collapsed="isCollapsed" @toggle="toggleCollapse" />
      </view>
      <view class="admin-main-classic">
        <AdminNavBar />
        <view class="admin-content-classic">
          <slot></slot>
        </view>
      </view>
    </template>

    <!-- 模式3: Columns（三栏布局） -->
    <template v-else-if="layoutMode === 'columns'">
      <AdminAside :collapsed="isCollapsed" @toggle="toggleCollapse" />
      <AdminSubSider :collapsed="isSubCollapsed" @toggle="toggleSubCollapse" />
      <view class="admin-main-columns">
        <AdminNavBar />
        <view class="admin-content-columns">
          <slot></slot>
        </view>
      </view>
    </template>
  </view>
</template>

<script setup lang="uts">
import { ref, computed, watch, onMounted, provide } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import AdminAside from './components/AdminAside.uvue'
import AdminSubSider from './components/AdminSubSider.uvue'
import AdminNavBar from './components/AdminNavBar.uvue'
import AdminTagsView from './components/AdminTagsView.uvue'
import AdminFooter from './components/AdminFooter.uvue'

// Props
interface AdminLayoutProps {
  currentPage: string
  layoutMode?: 'defaults' | 'classic' | 'columns'
}

const props = withDefaults(defineProps<AdminLayoutProps>(), {
  layoutMode: 'defaults'
})

// State
const isCollapsed = ref(false)
const isSubCollapsed = ref(false)
const tabs = ref([])
const breadcrumb = ref('')

// Computed
const layoutClass = computed(() => `layout-${props.layoutMode}`)

// Methods
const toggleCollapse = () => {
  isCollapsed.value = !isCollapsed.value
}

const toggleSubCollapse = () => {
  isSubCollapsed.value = !isSubCollapsed.value
}

// Provide to children
provide('layoutMode', props.layoutMode)
provide('isCollapsed', isCollapsed)
</script>

<style scoped lang="uts">
.admin-layout {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #f5f5f5;
}

/* Defaults 布局样式 */
.layout-defaults {
  flex-direction: row;
}

.admin-main-defaults {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.admin-content-defaults {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
}

/* Classic 布局样式 */
.layout-classic {
  flex-direction: row;
}

.admin-sidebar-classic {
  width: 200px;
  height: 100vh;
  overflow: hidden;
}

.admin-main-classic {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.admin-content-classic {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
}

/* Columns 布局样式 */
.layout-columns {
  flex-direction: row;
}

.admin-main-columns {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.admin-content-columns {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
}
</style>
```

### 2. 样式系统复刻

#### 2.1 主样式文件

**uni.scss** - 全局 SCSS 变量：

```scss
// 颜色系统
$primary-color: #1890ff;
$success-color: #52c41a;
$warning-color: #faad14;
$error-color: #ff4d4f;
$info-color: #1890ff;

$text-primary: #000000;
$text-secondary: #666666;
$text-disabled: #999999;

$border-color: #d9d9d9;
$background-color: #f5f5f5;

// 间距系统
$space-xs: 4px;
$space-sm: 8px;
$space: 12px;
$space-md: 16px;
$space-lg: 24px;
$space-xl: 32px;

// 圆角系统
$radius-xs: 2px;
$radius-sm: 4px;
$radius: 6px;
$radius-lg: 8px;
$radius-xl: 12px;

// 阴影系统
$shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.06);
$shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
$shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.15);

// 字体大小
$font-size-xs: 12px;
$font-size-sm: 13px;
$font-size: 14px;
$font-size-md: 16px;
$font-size-lg: 18px;
$font-size-xl: 20px;

// 行高
$line-height-xs: 1.2;
$line-height-sm: 1.4;
$line-height: 1.6;
$line-height-lg: 1.8;

// 过渡动画
$transition-duration: 0.3s;
$transition-timing: cubic-bezier(0.645, 0.045, 0.355, 1);
```

#### 2.2 通用样式类

**styles/common.scss** - 常用工具类：

```scss
// 布局相关
.flex {
  display: flex;
}

.flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

.flex-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.flex-col {
  display: flex;
  flex-direction: column;
}

// 间距相关
.m-xs {
  margin: $space-xs;
}
.m-sm {
  margin: $space-sm;
}
.m {
  margin: $space;
}
.m-md {
  margin: $space-md;
}
.m-lg {
  margin: $space-lg;
}
.m-xl {
  margin: $space-xl;
}

.p-xs {
  padding: $space-xs;
}
.p-sm {
  padding: $space-sm;
}
.p {
  padding: $space;
}
.p-md {
  padding: $space-md;
}
.p-lg {
  padding: $space-lg;
}
.p-xl {
  padding: $space-xl;
}

// 文字相关
.text-center {
  text-align: center;
}
.text-left {
  text-align: left;
}
.text-right {
  text-align: right;
}

.text-primary {
  color: $text-primary;
}
.text-secondary {
  color: $text-secondary;
}
.text-disabled {
  color: $text-disabled;
}

.text-xs {
  font-size: $font-size-xs;
}
.text-sm {
  font-size: $font-size-sm;
}
.text {
  font-size: $font-size;
}
.text-md {
  font-size: $font-size-md;
}
.text-lg {
  font-size: $font-size-lg;
}

// 显示/隐藏
.hidden {
  display: none;
}
.block {
  display: block;
}
.inline-block {
  display: inline-block;
}

// 溢出处理
.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.line-clamp-2 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

// 边框
.border {
  border: 1px solid $border-color;
}
.border-top {
  border-top: 1px solid $border-color;
}
.border-bottom {
  border-bottom: 1px solid $border-color;
}
.border-left {
  border-left: 1px solid $border-color;
}
.border-right {
  border-right: 1px solid $border-color;
}

// 圆角
.rounded {
  border-radius: $radius;
}
.rounded-sm {
  border-radius: $radius-sm;
}
.rounded-lg {
  border-radius: $radius-lg;
}

// 阴影
.shadow-sm {
  box-shadow: $shadow-sm;
}
.shadow {
  box-shadow: $shadow;
}
.shadow-lg {
  box-shadow: $shadow-lg;
}

// 背景色
.bg-white {
  background-color: #ffffff;
}
.bg-light {
  background-color: $background-color;
}
.bg-primary {
  background-color: $primary-color;
}

// 透明度
.opacity-50 {
  opacity: 0.5;
}
.opacity-75 {
  opacity: 0.75;
}
```

### 3. 页面模板复刻

#### 3.1 标准列表页面

**pages/mall/admin/template/ListPage.uvue**：

```uvue
<template>
  <AdminLayout :currentPage="currentPage">
    <view class="list-page">
      <!-- 页面标题和操作栏 -->
      <view class="page-header flex-between">
        <text class="page-title">{{ pageTitle }}</text>
        <view class="page-actions">
          <button @click="handleAdd" class="btn btn-primary">{{ addButtonText }}</button>
          <button @click="handleExport" class="btn btn-default">导出</button>
        </view>
      </view>

      <!-- 搜索表单 -->
      <view class="search-form-container bg-white p-md rounded shadow-sm">
        <SearchForm :fields="searchFields" @search="handleSearch" />
      </view>

      <!-- 列表内容 -->
      <view class="list-container bg-white p-md rounded shadow-sm">
        <view class="list-toolbar flex-between mb-md">
          <text class="text-secondary">共 {{ total }} 条记录</text>
          <view class="list-tools">
            <button @click="handleRefresh" class="btn btn-sm">刷新</button>
            <button @click="handleDelete" class="btn btn-sm">删除</button>
          </view>
        </view>

        <view class="list-table">
          <table-view :data="listData" :columns="columns" @row-click="handleRowClick" />
        </view>
      </view>

      <!-- 分页 -->
      <view class="pagination-container flex-center mt-lg">
        <pagination
          :current="pagination.current"
          :pageSize="pagination.pageSize"
          :total="total"
          @change="handlePageChange"
        />
      </view>
    </view>
  </AdminLayout>
</template>

<script setup lang="uts">
import { ref, reactive } from 'vue'
import AdminLayout from '@/layouts/admin/AdminLayout.uvue'
import SearchForm from '@/layouts/admin/components/SearchForm.uvue'
import TableView from '@/components/TableView.uvue'
import Pagination from '@/components/Pagination.uvue'

// 页面配置
const currentPage = 'list-page'
const pageTitle = '数据列表'
const addButtonText = '新增'

// 数据状态
const listData = ref([])
const total = ref(0)

// 分页信息
const pagination = reactive({
  current: 1,
  pageSize: 20,
})

// 搜索字段配置
const searchFields = ref([
  { key: 'name', label: '名称', type: 'text', placeholder: '请输入名称' },
  { key: 'status', label: '状态', type: 'select', options: [
    { label: '启用', value: 1 },
    { label: '禁用', value: 0 },
  ]},
  { key: 'date', label: '日期', type: 'daterange' },
])

// 表格列配置
const columns = ref([
  { prop: 'id', label: 'ID', width: 60 },
  { prop: 'name', label: '名称', minWidth: 120 },
  { prop: 'status', label: '状态', width: 80, formatter: (row: any) => row.status ? '启用' : '禁用' },
  { prop: 'createTime', label: '创建时间', width: 160 },
  { label: '操作', width: 120, fixed: 'right', slots: ['actions'] },
])

// 方法
const handleSearch = (filters: any) => {
  pagination.current = 1
  fetchList(filters)
}

const handlePageChange = (page: number) => {
  pagination.current = page
  fetchList()
}

const handleAdd = () => {
  uni.navigateTo({ url: '/pages/mall/admin/list/add' })
}

const handleRefresh = () => {
  fetchList()
}

const handleDelete = () => {
  // 删除逻辑
}

const handleRowClick = (row: any) => {
  uni.navigateTo({ url: `/pages/mall/admin/list/edit?id=${row.id}` })
}

const handleExport = () => {
  // 导出逻辑
}

const fetchList = async (filters?: any) => {
  // API 请求逻辑
  // listData.value = response.data
  // total.value = response.total
}
</script>

<style scoped lang="scss">
.list-page {
  padding: 20px;
}

.page-header {
  margin-bottom: 20px;
}

.page-title {
  font-size: $font-size-lg;
  font-weight: 600;
  color: $text-primary;
}

.page-actions {
  display: flex;
  gap: 10px;
}

.search-form-container {
  margin-bottom: 20px;
}

.list-container {
  margin-bottom: 20px;
}

.list-toolbar {
  border-bottom: 1px solid $border-color;
  padding-bottom: 12px;
}

.list-tools {
  display: flex;
  gap: 10px;
}

.pagination-container {
  margin: 20px 0;
}

.btn {
  padding: 8px 16px;
  border: none;
  border-radius: $radius;
  font-size: $font-size;
  cursor: pointer;
  transition: all $transition-duration $transition-timing;
}

.btn-primary {
  background-color: $primary-color;
  color: #fff;
}

.btn-primary:active {
  opacity: 0.8;
}

.btn-default {
  background-color: $background-color;
  color: $text-primary;
  border: 1px solid $border-color;
}

.btn-sm {
  padding: 6px 12px;
  font-size: $font-size-sm;
}
</style>
```

#### 3.2 表单页面

**pages/mall/admin/template/FormPage.uvue**：

```uvue
<template>
  <AdminLayout :currentPage="currentPage">
    <view class="form-page">
      <!-- 页面标题 -->
      <view class="page-header">
        <text class="page-title">{{ pageTitle }}</text>
      </view>

      <!-- 表单容器 -->
      <form-view
        ref="formRef"
        :model="formData"
        :fields="formFields"
        :loading="loading"
        @submit="handleSubmit"
      />
    </view>
  </AdminLayout>
</template>

<script setup lang="uts">
import { ref, reactive } from 'vue'
import AdminLayout from '@/layouts/admin/AdminLayout.uvue'
import FormView from '@/components/FormView.uvue'

const currentPage = 'form-page'
const pageTitle = '编辑数据'
const loading = ref(false)

const formData = reactive({
  name: '',
  description: '',
  status: 1,
  category: '',
  tags: [],
  attachments: [],
})

const formFields = ref([
  {
    key: 'name',
    label: '名称',
    type: 'text',
    required: true,
    placeholder: '请输入名称',
    rules: [{ required: true, message: '名称不能为空' }],
  },
  {
    key: 'description',
    label: '描述',
    type: 'textarea',
    placeholder: '请输入描述',
    rows: 4,
  },
  {
    key: 'category',
    label: '分类',
    type: 'select',
    required: true,
    options: [
      { label: '分类1', value: 1 },
      { label: '分类2', value: 2 },
    ],
  },
  {
    key: 'status',
    label: '状态',
    type: 'radio',
    options: [
      { label: '启用', value: 1 },
      { label: '禁用', value: 0 },
    ],
  },
  {
    key: 'tags',
    label: '标签',
    type: 'checkbox',
    options: [
      { label: '热销', value: 'hot' },
      { label: '新品', value: 'new' },
      { label: '推荐', value: 'recommend' },
    ],
  },
  {
    key: 'attachments',
    label: '附件',
    type: 'upload',
    multiple: true,
    accept: 'file',
  },
])

const handleSubmit = async (data: any) => {
  loading.value = true
  try {
    // API 提交逻辑
    uni.showToast({ title: '提交成功', icon: 'success' })
    setTimeout(() => {
      uni.navigateBack()
    }, 1500)
  } catch (error) {
    uni.showToast({ title: '提交失败', icon: 'error' })
  } finally {
    loading.value = false
  }
}
</script>

<style scoped lang="scss">
.form-page {
  padding: 20px;
  max-width: 800px;
  margin: 0 auto;
}

.page-header {
  margin-bottom: 24px;
}

.page-title {
  font-size: $font-size-lg;
  font-weight: 600;
  color: $text-primary;
}
</style>
```

---

## 组件库清单

### 必须实现的组件

#### 1. 基础组件

- [ ] Button（按钮）
- [ ] Input（输入框）
- [ ] Select（选择器）
- [ ] Checkbox（复选框）
- [ ] Radio（单选框）
- [ ] Switch（开关）
- [ ] DatePicker（日期选择器）

#### 2. 容器组件

- [ ] Card（卡片）
- [ ] Modal（模态框）
- [ ] Drawer（抽屉）
- [ ] Tabs（标签页）
- [ ] Collapse（折叠面板）

#### 3. 数据展示

- [ ] Table（表格）
- [ ] List（列表）
- [ ] Pagination（分页）
- [ ] Tree（树形控件）
- [ ] Empty（空状态）

#### 4. 表单组件

- [ ] Form（表单）
- [ ] Upload（上传）
- [ ] SearchForm（搜索表单）
- [ ] Filter（高级筛选）

#### 5. 反馈组件

- [ ] Message（消息）
- [ ] Toast（提示）
- [ ] Confirm（确认框）
- [ ] Loading（加载中）

#### 6. 导航组件

- [ ] Menu（菜单）
- [ ] Breadcrumb（面包屑）
- [ ] Tabs（标签）
- [ ] Pagination（分页）

---

## 迁移检查清单

### Phase 1: 基础设施

- [ ] 创建样式系统文件
  - [ ] uni.scss（全局变量）
  - [ ] styles/common.scss（通用类）
  - [ ] styles/animate.scss（动画）

- [ ] 更新 AdminLayout 支持多布局
  - [ ] Defaults 布局
  - [ ] Classic 布局
  - [ ] Columns 布局

- [ ] 配置工程化工具
  - [ ] .eslintrc 配置
  - [ ] .prettierrc 配置
  - [ ] tsconfig.json 优化

### Phase 2: 核心组件

- [ ] 实现基础 UI 组件库
- [ ] 实现 FormView 表单组件
- [ ] 实现 TableView 表格组件
- [ ] 实现 SearchForm 搜索组件

### Phase 3: 页面模板

- [ ] 创建列表页面模板
- [ ] 创建表单页面模板
- [ ] 创建详情页面模板
- [ ] 创建仪表板页面模板

### Phase 4: 样式规范化

- [ ] 统一所有页面的样式
- [ ] 规范间距使用
- [ ] 规范颜色使用
- [ ] 规范排版样式

### Phase 5: 文档完善

- [ ] 编写组件使用文档
- [ ] 编写样式规范文档
- [ ] 编写页面开发指南
- [ ] 维护变更日志

---

## 推荐阅读

- [ADMIN_SIDEBAR_COMPLETE_GUIDE.md](ADMIN_SIDEBAR_COMPLETE_GUIDE.md) - 侧边栏完整指南
- [CRMEB_DASHBOARD_GUIDE.md](CRMEB_DASHBOARD_GUIDE.md) - 仪表板设计指南
- [UNI_APP_X_PAGE_FIX_GUIDE.md](UNI_APP_X_PAGE_FIX_GUIDE.md) - uni-app-x 页面修复指南

---

**文档维护者**: AI Assistant  
**最后更新**: 2026-01-31  
**版本**: 1.0
