# 史诗008 - Allin System UI模块移植到独立UI包

## 史诗目标

在史诗007完成Allin系统后端模块移植的基础上，将allin_system-master/client目录中的UI模块移植到allin-packages目录下，作为独立的UI包，遵循项目现有的UI包结构和命名规范，实现UI模块的现代化重构和标准化管理。

## 史诗描述

### 现有系统上下文

- **当前相关功能**：allin_system-master/client是一个基于Next.js + Ant Design的前端系统，根据分析有以下UI模块：
  1. channel管理页面 - 渠道管理界面
  2. company管理页面 - 公司管理界面
  3. disability管理页面 - 残疾人管理界面
  4. disability_person管理页面 - 残疾人个人管理界面
  5. order管理页面 - 订单管理界面
  6. platform管理页面 - 平台管理界面
  7. salary管理页面 - 薪资管理界面
  **注**：region管理页面已有`@d8d/area-management-ui`包提供，直接复用即可，无需移植

- **技术栈**：Next.js、React 19、Ant Design 5、Jotai、Tailwind CSS、自定义fetch API
- **集成点**：通过自定义API客户端与后端API集成，使用Jotai进行状态管理

### 增强详情

- **新增/变更内容**：将7个现有UI模块从allin_system-master/client移植到allin-packages目录下的独立UI包
- **集成方式**：每个UI模块将重构为独立的npm包，遵循@d8d/allin-命名规范，通过workspace依赖管理
- **技术栈转换**：从Ant Design + Jotai转换为@d8d/shared-ui-components + React Query + Hono RPC
- **成功标准**：
  1. 7个UI模块成功移植为独立UI包
  2. 保持原有功能完整性
  3. 遵循现有UI包结构模式
  4. 通过组件测试和集成测试验证
  5. 与史诗007移植的后端模块无缝集成
  6. 区域管理功能复用现有`@d8d/area-management-ui`包

## 参考文档

执行本史诗时，必须参考以下架构文档：
- **[UI包开发规范](../architecture/ui-package-standards.md)**：UI包的结构、RPC客户端实现、组件开发、测试等规范
- **[后端模块包开发规范](../architecture/backend-module-package-standards.md)**：对应的后端模块规范
- **[组件架构](../architecture/component-architecture.md)**：前端组件架构设计
- **[编码标准和测试策略](../architecture/coding-standards.md)**：编码规范和测试要求

**特别强调**：所有UI包开发必须严格遵循[UI包开发规范](../architecture/ui-package-standards.md)，包括包结构、RPC客户端模式、组件开发、测试规范等。

## 模块分析结果

### 1. 模块依赖关系分析

根据对每个模块页面的分析，依赖关系如下：

1. **channel管理页面** (`app/admin/dashboard/channel/page.tsx`)
   - 依赖：Ant Design组件、自定义API客户端、Jotai状态管理
   - 功能：渠道CRUD管理、搜索、分页
   - 复杂度：中等

2. **company管理页面** (`app/admin/dashboard/company/page.tsx`)
   - 依赖：Ant Design组件、自定义API客户端、Jotai状态管理
   - 功能：公司CRUD管理、平台关联、搜索、分页
   - 复杂度：中等（依赖platform数据）

3. **disability管理页面** (`app/admin/dashboard/disability/page.tsx`)
   - 依赖：Ant Design组件、自定义API客户端、Jotai状态管理
   - 功能：残疾人信息管理、搜索、分页
   - 复杂度：中等

4. **disability_person管理页面** (`app/admin/dashboard/disability_person/`)
   - 依赖：Ant Design组件、自定义API服务、复杂表单
   - 功能：残疾人个人详细信息管理、照片上传、备注管理
   - 复杂度：高（多个子组件、复杂表单）

5. **order管理页面** (`app/admin/dashboard/order/`)
   - 依赖：Ant Design组件、自定义API服务、复杂业务逻辑
   - 功能：订单管理、人员分配、资产关联
   - 复杂度：高（复杂业务逻辑、多实体关联）

6. **platform管理页面** (`app/admin/dashboard/platform/page.tsx`)
   - 依赖：Ant Design组件、自定义API客户端、Jotai状态管理
   - 功能：平台CRUD管理、搜索、分页
   - 复杂度：低

7. **region管理页面** (`app/admin/dashboard/region/page.tsx`)
   - 依赖：Ant Design组件、自定义API客户端、树形结构
   - 功能：区域树形管理、CRUD操作
   - 复杂度：中等（树形结构）
   - **重要说明**：已有`@d8d/area-management-ui`包提供相同功能，直接复用即可

8. **salary管理页面** (`app/admin/dashboard/salary/page.tsx`)
   - 依赖：Ant Design组件、自定义API客户端、复杂表单验证
   - 功能：薪资水平管理、区域关联、数值计算
   - 复杂度：中等（复杂表单验证）

### 2. 模块到独立UI包的映射方案

基于现有项目UI包命名规范，并考虑这是Allin系统专属模块，制定以下映射方案：

| 原页面名 | 独立UI包名 | 目录名 | 对应后端模块 | 说明 |
|---------|-----------|--------|-------------|------|
| channel | `@d8d/allin-channel-management-ui` | `channel-management-ui` | `@d8d/allin-channel-module` | 渠道管理UI |
| company | `@d8d/allin-company-management-ui` | `company-management-ui` | `@d8d/allin-company-module` | 公司管理UI |
| disability | `@d8d/allin-disability-management-ui` | `disability-management-ui` | `@d8d/allin-disability-module` | 残疾人管理UI |
| disability_person | `@d8d/allin-disability-person-management-ui` | `disability-person-management-ui` | `@d8d/allin-disability-module` | 残疾人个人管理UI |
| order | `@d8d/allin-order-management-ui` | `order-management-ui` | `@d8d/allin-order-module` | 订单管理UI |
| platform | `@d8d/allin-platform-management-ui` | `platform-management-ui` | `@d8d/allin-platform-module` | 平台管理UI |
| region | **复用现有`@d8d/area-management-ui`** | - | `@d8d/geo-areas` | 区域管理UI（已有现成包） |
| salary | `@d8d/allin-salary-management-ui` | `salary-management-ui` | `@d8d/allin-salary-module` | 薪资管理UI |

**命名原则**：
1. **包名前缀**：使用`@d8d/allin-`前缀，明确表明是Allin系统专属包
2. **包名后缀**：使用`-management-ui`后缀，遵循现有UI包命名规范
3. **目录名**：使用`{模块名}-management-ui`格式，便于在`allin-packages`目录中管理
4. **非多租户**：不使用`-mt`后缀（本次移植为非多租户版本）

### 3. 目录结构和包规范

#### 目录结构决策
由于这些UI模块是`allin_system-master`项目独有的业务模块（非通用模块），将在`allin-packages`目录下创建：

```
项目根目录/
├── allin-packages/                    # Allin系统专属包目录
│   ├── channel-management-ui/         # 渠道管理UI
│   ├── company-management-ui/         # 公司管理UI
│   ├── disability-management-ui/      # 残疾人管理UI
│   ├── disability-person-management-ui/ # 残疾人个人管理UI
│   ├── order-management-ui/           # 订单管理UI
│   ├── platform-management-ui/        # 平台管理UI
│   # 区域管理UI已有`@d8d/area-management-ui`，无需创建新包
│   ├── salary-management-ui/          # 薪资管理UI
│   ├── channel-module/                # 后端模块（已存在）
│   ├── company-module/                # 后端模块（已存在）
│   ├── disability-module/             # 后端模块（已存在）
│   ├── platform-module/               # 后端模块（已存在）
│   ├── salary-module/                 # 后端模块（已存在）
│   └── enums/                         # 枚举常量包（已存在）
├── packages/                          # 现有通用包目录（保持不变）
└── allin_system-master/               # 原始代码目录（移植源）
```

#### UI包结构规范
参考现有`advertisement-management-ui`结构，每个独立UI包应包含：

```
allin-packages/{module-name}-management-ui/
├── package.json          # 包配置，workspace依赖管理
├── tsconfig.json        # TypeScript配置
├── vitest.config.ts     # 测试配置
├── src/
│   ├── index.ts         # 主导出文件
│   ├── components/      # React组件
│   │   ├── index.ts     # 组件导出
│   │   ├── {Module}Table.tsx  # 数据表格组件
│   │   ├── {Module}Form.tsx   # 表单组件
│   │   ├── {Module}Modal.tsx  # 模态框组件
│   │   └── {Module}Filter.tsx # 筛选组件
│   ├── hooks/           # 自定义Hook
│   │   ├── index.ts
│   │   ├── use{Module}Query.ts  # 数据查询Hook
│   │   └── use{Module}Mutation.ts # 数据变更Hook
│   ├── api/             # API客户端
│   │   ├── index.ts
│   │   ├── client.ts    # Hono RPC客户端
│   │   └── types.ts     # API类型定义
│   └── utils/           # 工具函数
│       ├── index.ts
│       └── formatters.ts
├── tests/               # 测试文件
│   ├── components/      # 组件测试
│   └── integration/     # 集成测试
└── dist/                # 构建输出
```

**关键配置要求**：
1. `package.json`中设置`"type": "module"`
2. 主入口为`src/index.ts`
3. 使用workspace依赖：`"@d8d/allin-{module}-module": "workspace:*"`（对应后端模块）
4. 包名使用`@d8d/allin-`前缀，如`@d8d/allin-channel-management-ui`
5. 导出必要的组件和Hook

### 4. 技术栈差异分析与移植方案

#### 技术栈对比分析

| 方面 | 当前项目（目标） | allin_system-master（源） | 差异程度 |
|------|------------------|---------------------------|----------|
| **UI框架** | React 19 + @d8d/shared-ui-components | React 19 + Ant Design 5 | **重大** |
| **状态管理** | React Query + React状态（useState/useContext） | Jotai | **中等** |
| **表单处理** | React Hook Form + Zod | Ant Design Form | **重大** |
| **API客户端** | Hono RPC (rpcClient + ClientManager模式) | 自定义fetch API | **重大** |
| **样式方案** | Tailwind CSS + shadcn/ui | Ant Design + Tailwind CSS | **中等** |
| **组件库** | @d8d/shared-ui-components组件 | Ant Design组件 | **重大** |
| **构建工具** | unbuild | Next.js构建 | **重大** |
| **测试框架** | Vitest + Testing Library | 无测试 | **新增** |

#### 关键依赖对比
- **当前项目**：`@d8d/shared-ui-components`、`@tanstack/react-query`、`react-hook-form`、`zod`、`hono`、`shadcn/ui`
- **allin_system**：`antd`、`jotai`、自定义API客户端、`dayjs`

#### 移植调整方案

##### A. 架构转换策略
1. **Ant Design组件 → @d8d/shared-ui-components组件**：重写所有UI组件，遵循[UI包开发规范](../architecture/ui-package-standards.md#组件开发规范)
2. **Jotai状态 → React Query + React状态（useState/useContext）**：重构状态管理，遵循[UI包开发规范](../architecture/ui-package-standards.md#状态管理规范)
3. **Ant Design Form → React Hook Form + Zod**：转换表单逻辑
4. **自定义fetch API → Hono RPC (rpcClient + ClientManager模式)**：重构API客户端，使用项目现有的rpcClient工具和ClientManager单例模式，遵循[UI包开发规范](../architecture/ui-package-standards.md#rpc客户端实现规范)
5. **Next.js页面 → React组件库**：将页面转换为可复用组件，遵循[UI包开发规范](../architecture/ui-package-standards.md#包结构规范)

##### B. 组件层转换示例
```typescript
// 原Ant Design表格组件
import { Table, Button, Space } from 'antd';

const ChannelTable = ({ data, loading, onEdit, onDelete }) => {
  const columns = [
    { title: '渠道名称', dataIndex: 'channel_name', key: 'channel_name' },
    { title: '操作', key: 'action', render: (_, record) => (
      <Space>
        <Button onClick={() => onEdit(record)}>编辑</Button>
        <Button danger onClick={() => onDelete(record)}>删除</Button>
      </Space>
    )}
  ];

  return <Table dataSource={data} columns={columns} loading={loading} />;
};

// 转换后@d8d/shared-ui-components表格组件（使用rpcClient + ClientManager模式）
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@d8d/shared-ui-components/components/ui/table';
import { Button } from '@d8d/shared-ui-components/components/ui/button';
import { useQuery } from '@tanstack/react-query';
import { channelClientManager } from './api/channelClient';

const ChannelTable = () => {
  const { data: channels, isLoading } = useQuery({
    queryKey: ['channels'],
    queryFn: async () => {
      const res = await channelClientManager.get().channel.getChannelList.$get();
      if (res.status !== 200) throw new Error('获取渠道列表失败');
      return await res.json();
    }
  });

  return (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHead>渠道名称</TableHead>
          <TableHead>操作</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {channels?.map((channel) => (
          <TableRow key={channel.id}>
            <TableCell>{channel.channelName}</TableCell>
            <TableCell>
              <Button variant="outline" onClick={() => onEdit(channel)}>编辑</Button>
              <Button variant="destructive" onClick={() => onDelete(channel)}>删除</Button>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  );
};
```

##### C. 表单转换示例
```typescript
// 原Ant Design表单
import { Form, Input, Button } from 'antd';

const ChannelForm = ({ initialValues, onSubmit }) => {
  const [form] = Form.useForm();

  return (
    <Form form={form} initialValues={initialValues} onFinish={onSubmit}>
      <Form.Item name="channel_name" label="渠道名称" rules={[{ required: true }]}>
        <Input />
      </Form.Item>
      <Form.Item>
        <Button type="primary" htmlType="submit">提交</Button>
      </Form.Item>
    </Form>
  );
};

// 转换后React Hook Form + Zod
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@d8d/shared-ui-components/components/ui/form';
import { Input } from '@d8d/shared-ui-components/components/ui/input';
import { Button } from '@d8d/shared-ui-components/components/ui/button';

const channelSchema = z.object({
  channelName: z.string().min(1, '渠道名称不能为空')
});

const ChannelForm = ({ initialValues, onSubmit }) => {
  const form = useForm({
    resolver: zodResolver(channelSchema),
    defaultValues: initialValues
  });

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        <FormField
          control={form.control}
          name="channelName"
          render={({ field }) => (
            <FormItem>
              <FormLabel>渠道名称</FormLabel>
              <FormControl>
                <Input {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit">提交</Button>
      </form>
    </Form>
  );
};
```

##### D. API客户端转换示例
```typescript
// 原自定义fetch API
const api = {
  getChannels: async () => {
    const response = await fetch('/api/channel/getChannelList');
    return response.json();
  },
  createChannel: async (data) => {
    const response = await fetch('/api/channel/createChannel', {
      method: 'POST',
      body: JSON.stringify(data)
    });
    return response.json();
  }
};

// 转换后Hono RPC客户端（遵循现有项目模式）
import { channelRoutes } from '@d8d/allin-channel-module';
import { rpcClient } from '@d8d/shared-ui-components/utils/hc'

class ChannelClientManager {
  private static instance: ChannelClientManager;
  private client: ReturnType<typeof rpcClient<typeof channelRoutes>> | null = null;

  private constructor() {}

  public static getInstance(): ChannelClientManager {
    if (!ChannelClientManager.instance) {
      ChannelClientManager.instance = new ChannelClientManager();
    }
    return ChannelClientManager.instance;
  }

  // 初始化客户端
  public init(baseUrl: string = '/'): ReturnType<typeof rpcClient<typeof channelRoutes>> {
    return this.client = rpcClient<typeof channelRoutes>(baseUrl);
  }

  // 获取客户端实例
  public get(): ReturnType<typeof rpcClient<typeof channelRoutes>> {
    if (!this.client) {
      return this.init()
    }
    return this.client;
  }

  // 重置客户端（用于测试或重新初始化）
  public reset(): void {
    this.client = null;
  }
}

// 导出单例实例
const channelClientManager = ChannelClientManager.getInstance();

// 导出默认客户端实例（延迟初始化）
export const channelClient = channelClientManager.get()

// 在React组件中的使用示例
import { channelClientManager } from './api/channelClient';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';

// 类型定义（使用导出的channelClient进行类型推导）
import type { InferResponseType, InferRequestType } from 'hono/client';
import { channelClient } from './api/channelClient';

type ChannelResponse = InferResponseType<typeof channelClient.channel.getChannelList.$get, 200>['data'][0];
type CreateChannelRequest = InferRequestType<typeof channelClient.channel.createChannel.$post>['json'];

// React组件中的实际调用
const ChannelManagement: React.FC = () => {
  const queryClient = useQueryClient();

  // 查询数据 - 使用channelClientManager.get()获取客户端实例
  const { data: channels, isLoading } = useQuery({
    queryKey: ['channels'],
    queryFn: async () => {
      const res = await channelClientManager.get().channel.getChannelList.$get();
      if (res.status !== 200) throw new Error('获取渠道列表失败');
      return await res.json();
    }
  });

  // 创建数据
  const createMutation = useMutation({
    mutationFn: async (data: CreateChannelRequest) => {
      const res = await channelClientManager.get().channel.createChannel.$post({ json: data });
      if (res.status !== 201) throw new Error('创建渠道失败');
      return await res.json();
    },
    onSuccess: () => {
      // 刷新数据
      queryClient.invalidateQueries({ queryKey: ['channels'] });
    }
  });

  // ...组件其他代码
};
```

##### E. 状态管理转换
```typescript
// 原Jotai状态管理
import { atom, useAtom } from 'jotai';

const channelsAtom = atom([]);
const loadingAtom = atom(false);

const useChannels = () => {
  const [channels, setChannels] = useAtom(channelsAtom);
  const [loading, setLoading] = useAtom(loadingAtom);

  const fetchChannels = async () => {
    setLoading(true);
    const data = await api.getChannels();
    setChannels(data);
    setLoading(false);
  };

  return { channels, loading, fetchChannels };
};

// 转换后React Query（使用rpcClient + ClientManager模式）
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { channelClientManager } from './api/channelClient';
import type { InferRequestType } from 'hono/client';
import { channelClient } from './api/channelClient';

type CreateChannelRequest = InferRequestType<typeof channelClient.channel.createChannel.$post>['json'];

const useChannels = () => {
  const queryClient = useQueryClient();

  const { data: channels, isLoading } = useQuery({
    queryKey: ['channels'],
    queryFn: async () => {
      const res = await channelClientManager.get().channel.getChannelList.$get();
      if (res.status !== 200) throw new Error('获取渠道列表失败');
      return await res.json();
    }
  });

  const createMutation = useMutation({
    mutationFn: async (data: CreateChannelRequest) => {
      const res = await channelClientManager.get().channel.createChannel.$post({ json: data });
      if (res.status !== 201) throw new Error('创建渠道失败');
      return await res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['channels'] });
    }
  });

  return { channels, isLoading, createChannel: createMutation.mutateAsync };
};
```

#### 移植顺序策略

**建议移植顺序**：
1. **基础UI包**：先移植简单的CRUD页面（channel、platform）
2. **中等复杂度**：移植有依赖关系的页面（company、salary）
3. **高复杂度**：最后移植复杂页面（disability_person、order）
4. **特殊处理**：region页面已有`@d8d/area-management-ui`包，直接复用

**具体顺序**：
1. `allin-platform-management-ui`（最简单）
2. `allin-channel-management-ui`（独立）
3. `allin-company-management-ui`（依赖platform）
4. `allin-salary-management-ui`（中等复杂度）
5. `allin-disability-management-ui`（中等复杂度）
6. `allin-disability-person-management-ui`（高复杂度）
7. `allin-order-management-ui`（高复杂度）
**注**：region管理UI已有`@d8d/area-management-ui`包，无需移植

#### 兼容性保证
- **保持**：业务逻辑、数据模型、用户交互流程
- **调整**：UI组件库、状态管理、API调用方式
- **新增**：类型安全、测试覆盖、更好的开发体验

## 故事分解（按模块拆分）

**注**：每个故事对应一个UI模块的完整移植，包括技术栈转换和组件测试。

### 故事1：移植平台管理UI（platform → @d8d/allin-platform-management-ui）
**目标**：移植基础平台管理页面

**验收标准**：
1. 创建`allin-packages/platform-management-ui`目录结构
2. 完成组件转换：平台管理组件
3. 完成API客户端转换：基础CRUD API（使用rpcClient + ClientManager模式）
4. 完成状态管理转换：基础数据状态
5. 完成表单转换：简单验证表单
6. 配置package.json：基础依赖
7. 编写组件测试：验证基础功能
8. 通过类型检查和基本测试验证

### 故事2：移植渠道管理UI（channel → @d8d/allin-channel-management-ui）
**目标**：将channel管理页面移植为独立UI包，完成技术栈转换并验证功能完整性

**验收标准**：
1. 创建`allin-packages/channel-management-ui`目录结构
2. 完成组件转换：从Ant Design转换为@d8d/shared-ui-components组件
3. 完成API客户端转换：从自定义fetch API转换为Hono RPC (rpcClient + ClientManager模式) (rpcClient + ClientManager模式)
4. 完成状态管理转换：从Jotai转换为React Query
5. 完成表单转换：从Ant Design Form转换为React Hook Form + Zod
6. 配置package.json：使用`@d8d/allin-channel-management-ui`包名，workspace依赖
7. 编写组件测试：覆盖所有组件
8. 通过类型检查和基本测试验证
9. 与`@d8d/allin-channel-module`后端模块集成验证

**组件测试要求**：
- 测试文件：`tests/components/ChannelTable.test.tsx`等
- 测试覆盖：表格组件、表单组件、模态框组件
- 验证：数据渲染、用户交互、表单验证
- 遵循现有组件测试模式

### 故事3：移植公司管理UI（company → @d8d/allin-company-management-ui）
**目标**：将company管理页面移植为独立UI包，处理对platform数据的依赖

**验收标准**：
1. 创建`allin-packages/company-management-ui`目录结构
2. 完成组件转换：公司管理相关组件
3. 处理数据依赖：正确集成platform数据选择器
4. 完成API客户端转换：处理跨模块API调用（使用rpcClient + ClientManager模式）
5. 完成状态管理转换：复杂数据关联状态
6. 完成表单转换：包含平台选择的下拉表单
7. 配置package.json：依赖`@d8d/allin-platform-management-ui`
8. 编写组件测试：验证跨模块数据集成
9. 通过类型检查和基本测试验证

### 故事4：移植薪资管理UI（salary → @d8d/allin-salary-management-ui）
**目标**：移植薪资管理页面，包含复杂表单验证

**验收标准**：
1. 创建`allin-packages/salary-management-ui`目录结构
2. 完成组件转换：薪资表格、复杂表单组件
3. **区域包集成**：集成`@d8d/area-management-ui`的区域选择器组件
4. 完成API客户端转换：薪资计算API（使用rpcClient + ClientManager模式）
5. 完成状态管理转换：数值计算状态
6. 完成表单转换：复杂数值验证
7. 配置package.json：依赖`@d8d/area-management-ui`
8. 编写组件测试：验证数值计算和验证
9. 通过类型检查和基本测试验证

### 故事5：移植残疾人管理UI（disability → @d8d/allin-disability-management-ui）
**目标**：将disability管理页面移植为独立UI包

**验收标准**：
1. 创建`allin-packages/disability-management-ui`目录结构
2. 完成组件转换：残疾人列表管理组件
3. **区域包集成**：集成`@d8d/area-management-ui`的区域选择器组件用于残疾人区域信息管理
4. 完成API客户端转换：与disability-module集成
5. 完成状态管理转换：残疾人数据状态
6. 完成表单转换：基础残疾人信息表单（包含区域选择）
7. 配置package.json：依赖`@d8d/allin-disability-module`和`@d8d/area-management-ui`
8. 编写组件测试：验证残疾人管理功能（包含区域选择验证）
9. 通过类型检查和基本测试验证

### 故事6：移植残疾人个人管理UI（disability_person → @d8d/allin-disability-person-management-ui）
**目标**：移植最复杂的残疾人个人管理页面，包含照片上传、备注管理等

**验收标准**：
1. 创建`allin-packages/disability-person-management-ui`目录结构
2. 完成组件转换：复杂表单、照片上传、备注管理组件
3. **文件上传集成**：与`@d8d/file-management-ui`集成
4. **区域包集成**：集成`@d8d/area-management-ui`的区域选择器组件用于残疾人详细地址管理（省份→城市→区县三级联动）
5. **枚举常量集成**：使用`@d8d/allin-enums`包中的枚举
6. 完成API客户端转换：复杂API调用链（使用rpcClient + ClientManager模式）
7. 完成状态管理转换：多步骤表单状态
8. 完成表单转换：复杂验证逻辑（包含区域选择验证）
9. 配置package.json：多依赖管理（包含`@d8d/area-management-ui`）
10. 编写组件测试：覆盖所有复杂场景（包含区域选择功能测试）
11. 通过类型检查和基本测试验证

### 故事7：移植订单管理UI（order → @d8d/allin-order-management-ui）
**目标**：移植复杂的订单管理页面，包含人员分配、资产关联、考勤打卡等

**验收标准**：
1. 创建`allin-packages/order-management-ui`目录结构
2. 完成组件转换：订单表格、人员选择、资产关联组件
3. **文件上传集成**：资产文件关联组件
4. **区域包集成**：集成`@d8d/area-management-ui`的区域选择器组件用于订单相关区域信息管理
5. **枚举常量集成**：使用`@d8d/allin-enums`包中的订单状态枚举
6. 完成API客户端转换：复杂业务API（使用rpcClient + ClientManager模式）
7. 完成状态管理转换：订单工作流状态
8. 完成表单转换：多实体关联表单（包含区域选择）
9. **考勤打卡功能移植**：移植出勤表导出功能
   - 创建`AttendanceModal`组件，从Ant Design转换为@d8d/shared-ui-components组件
   - 集成到订单管理UI中，保持原有交互流程
   - 完成技术栈转换：Modal、DatePicker、Select等组件转换
   - 保持Excel导出功能（使用xlsx库）
   - 编写组件测试：`tests/components/AttendanceModal.test.tsx`
10. 配置package.json：复杂依赖管理（包含`@d8d/area-management-ui`、`xlsx`等）
11. 编写组件测试：覆盖订单全生命周期（包含区域相关功能测试）
12. 通过类型检查和基本测试验证

### 故事8：将Allin系统UI包集成到Web client admin
**目标**：将史诗008中创建的7个Allin系统UI包集成到Web client admin中，对应史诗007的最后一个任务（故事8：将Allin系统模块集成到packages/server）

**验收标准**：
1. **依赖配置**：在`web/package.json`中添加所有7个Allin系统UI包的workspace依赖
   - `@d8d/allin-channel-management-ui`
   - `@d8d/allin-company-management-ui`
   - `@d8d/allin-disability-management-ui`
   - `@d8d/allin-disability-person-management-ui`
   - `@d8d/allin-order-management-ui`
   - `@d8d/allin-platform-management-ui`
   - `@d8d/allin-salary-management-ui`

2. **API客户端初始化**：在`web/src/client/admin/api_init.ts`中添加所有7个Allin系统UI包的API客户端初始化，路径必须与server包中的路由配置完全一致（参考`packages/server/src/index.ts:139-144`）
   - `channelClientManager.init('/api/v1/channel')` - 对应server中的`/api/v1/channel`
   - `companyClientManager.init('/api/v1/company')` - 对应server中的`/api/v1/company`
   - `disabilityClientManager.init('/api/v1/disability')` - 对应server中的`/api/v1/disability`（注意：`disability_person`模块在server中注册为`/api/v1/disability`）
   - `orderClientManager.init('/api/v1/order')` - 对应server中的`/api/v1/order`
   - `platformClientManager.init('/api/v1/platform')` - 对应server中的`/api/v1/platform`
   - `salaryClientManager.init('/api/v1/salary')` - 对应server中的`/api/v1/salary`
   - **注意**：所有路径使用单数形式，没有`s`后缀，与server包配置保持一致

3. **路由集成**：在`web/src/client/admin/routes.tsx`中添加所有7个UI包的路由配置
   - `/admin/channels` → `@d8d/allin-channel-management-ui`
   - `/admin/companies` → `@d8d/allin-company-management-ui`
   - `/admin/disabilities` → `@d8d/allin-disability-management-ui`
   - `/admin/disability-persons` → `@d8d/allin-disability-person-management-ui`
   - `/admin/orders` → `@d8d/allin-order-management-ui`
   - `/admin/platforms` → `@d8d/allin-platform-management-ui`
   - `/admin/salaries` → `@d8d/allin-salary-management-ui`

4. **菜单集成**：在`web/src/client/admin/menu.tsx`中添加对应的菜单项
   - 渠道管理
   - 公司管理
   - 残疾人管理
   - 残疾人个人管理
   - 订单管理
   - 平台管理
   - 薪资管理

5. **权限配置**：为每个菜单项配置相应的权限（参考现有权限模式）
6. **图标配置**：为每个菜单项配置合适的图标（使用lucide-react图标库）
7. **API路径配置**：确保API路径与后端路由对应（参考史诗007的server集成）
8. **集成验证**：验证所有路由正常工作，UI包正确加载，API客户端初始化成功
9. **测试验证**：通过E2E测试验证集成功能

**技术要点**：
- 遵循现有路由和菜单集成模式
- 保持权限系统一致性
- 确保路由路径与后端API路径对应
- 验证UI包与后端模块的集成（对应史诗007的故事8）

**与史诗007的对应关系**：
- 本故事对应史诗007的**故事8：将Allin系统模块集成到packages/server**
- 确保前端UI包与后端模块的集成时间点对齐
- 验证前后端集成功能完整性

### **区域管理UI说明**
**目标**：复用现有`@d8d/area-management-ui`包，无需重新移植

**现状分析**：
1. **已有包**：`@d8d/area-management-ui`已提供完整的区域管理功能
2. **技术栈**：与目标技术栈一致（@d8d/shared-ui-components + React Query + Hono RPC）
3. **功能匹配**：提供树形区域管理、CRUD操作、搜索等功能
4. **集成点**：与`@d8d/geo-areas`后端模块已集成

**实施策略**：
1. **直接复用**：在Allin系统中直接使用`@d8d/area-management-ui`包
2. **依赖配置**：在需要区域选择功能的UI包中添加对`@d8d/area-management-ui`的依赖
3. **组件集成**：使用`AreaSelector`、`AreaTree`等现有组件
4. **无需移植**：节省开发工作量，保持技术栈一致性

## 文件上传集成方案

### 现状分析

#### 1. allin_system-master中的文件上传
- **照片上传**：`DisabledPhoto`相关页面使用直接文件上传
- **资产文件上传**：`OrderPersonAsset`相关页面使用文件上传
- **实现方式**：直接调用后端上传接口，存储URL到数据库

#### 2. 当前项目的文件上传
- **文件管理UI包**：`@d8d/file-management-ui`
- **核心功能**：文件选择器组件、上传进度、预览功能
- **集成方式**：通过`fileId`关联业务实体

### 集成方案

#### 架构设计原则
**核心思想**：复用现有的`@d8d/file-management-ui`包，保持统一的文件上传体验

#### 实施步骤
1. **组件集成**：
   ```typescript
   // 在disability-person-management-ui中集成文件选择器
   import { FileSelector } from '@d8d/file-management-ui';

   const PhotoUploadField = ({ value, onChange }) => {
     return (
       <div>
         <Label>照片上传</Label>
         <FileSelector
           accept="image/*"
           onFileSelected={(fileId) => onChange(fileId)}
         />
         {value && <FilePreview fileId={value} />}
       </div>
     );
   };
   ```

2. **表单集成**：
   ```typescript
   // 残疾人照片表单
   const disabilityPersonSchema = z.object({
     // ...其他字段
     photoFileId: z.number().optional(), // 文件ID字段
   });

   // 提交时只传递fileId
   const onSubmit = (data) => {
     // data.photoFileId 包含文件ID
     await api.createDisabledPerson(data);
   };
   ```

3. **数据显示**：
   ```typescript
   // 显示照片时使用文件预览组件
   import { FilePreview } from '@d8d/file-management-ui';

   const PhotoDisplay = ({ fileId }) => {
     return <FilePreview fileId={fileId} />;
   };
   ```

### 影响的故事

需要调整以下故事的文件上传处理：

1. **故事6（disability-person-management-ui）**：
   - 集成文件选择器组件用于照片上传
   - 修改表单接收`fileId`而非文件内容
   - 使用文件预览组件显示照片

2. **故事7（order-management-ui）**：
   - 集成文件选择器组件用于资产文件上传
   - 根据资产类型限制文件类型（图片/视频）
   - 使用文件预览组件显示资产文件

## 兼容性要求

- [ ] 现有功能保持不变
- [ ] 用户交互流程保持一致
- [ ] 数据模型兼容后端API
- [ ] 遵循现有TypeScript配置和构建模式
- [ ] 性能影响最小化

## 风险缓解

- **主要风险**：技术栈差异大，移植过程中可能破坏现有交互体验
- **缓解措施**：逐个模块移植，每个模块完成后进行用户验收测试
- **回滚计划**：保留原始allin_system-master/client目录作为备份

## 完成定义

- [ ] 所有8个故事完成，验收标准满足
  - [x] 故事1：平台管理UI（故事008.001已完成）
  - [x] 故事2：渠道管理UI（故事008.002已完成）
  - [x] 故事3：公司管理UI（故事008.003已完成）
  - [x] 故事4：薪资管理UI（故事008.004已完成）
  - [x] 故事5：残疾人管理UI（故事008.005已完成）
  - [x] 故事6：残疾人个人管理UI（故事008.006已完成）
  - [x] 故事7：订单管理UI（故事008.007已完成）
  - [ ] 故事8：将Allin系统UI包集成到Web client admin（对应史诗007故事8）
- [x] 区域管理功能复用`@d8d/area-management-ui`包
- [x] 现有功能通过测试验证
- [x] 集成点正常工作
- [x] 文档更新适当
- [x] 现有功能无回归

## 验证清单

### 范围验证
- [ ] 史诗可在8个故事内完成
- [ ] 不需要架构文档变更
- [ ] 增强遵循现有模式
- [ ] 集成复杂度可管理

### 风险评估
- [ ] 对现有系统风险较低
- [ ] 回滚计划可行
- [ ] 测试方法覆盖现有功能
- [ ] 团队对集成点有足够了解

### 完整性检查
- [ ] 史诗目标清晰可实现
- [ ] 故事范围适当
- [ ] 成功标准可衡量
- [ ] 依赖关系已识别

---

## 故事经理交接说明

"UI模块分析和技术栈分析已完成，关键发现：

1. **依赖关系分析完成**：7个UI模块的依赖关系已明确（region复用现有包），新增故事8用于集成到Web client admin
2. **技术栈差异分析完成**：源系统使用Ant Design + Jotai，目标系统使用@d8d/shared-ui-components + React Query，存在重大架构差异
3. **命名方案确定**：使用`@d8d/allin-`前缀，`-management-ui`后缀，非多租户版本
4. **目录结构**：在`allin-packages/`目录下创建UI包，与后端模块保持相同目录，遵循[UI包开发规范](../architecture/ui-package-standards.md#包结构规范)
5. **移植顺序建议**：从简单到复杂，先移植基础CRUD页面
6. **技术栈转换方案**：已制定从Ant Design到@d8d/shared-ui-components的详细转换策略，遵循[UI包开发规范](../architecture/ui-package-standards.md)
7. **故事拆分完成**：按模块拆分为7个移植故事+1个集成故事（共8个故事，按执行顺序编号），每个移植故事包含组件测试要求，遵循[UI包开发规范](../architecture/ui-package-standards.md#测试规范)

**新的故事拆分方案（按执行顺序编号）**：
- **故事1**：移植平台管理UI（platform → @d8d/allin-platform-management-ui） - 最简单，无依赖
- **故事2**：移植渠道管理UI（channel → @d8d/allin-channel-management-ui） - 独立模块
- **故事3**：移植公司管理UI（company → @d8d/allin-company-management-ui） - 依赖platform数据
- **故事4**：移植薪资管理UI（salary → @d8d/allin-salary-management-ui） - 中等复杂度
- **故事5**：移植残疾人管理UI（disability → @d8d/allin-disability-management-ui） - 中等复杂度
- **故事6**：移植残疾人个人管理UI（disability_person → @d8d/allin-disability-person-management-ui） - 高复杂度，依赖disability
- **故事7**：移植订单管理UI（order → @d8d/allin-order-management-ui） - 高复杂度，可能依赖其他模块
- **故事8**：将Allin系统UI包集成到Web client admin - 对应史诗007故事8，完成前后端集成
- **区域管理**：复用现有`@d8d/area-management-ui`包（无需移植）

**每个故事的关键要求**：
1. **技术栈转换**：必须完成组件、API客户端、状态管理、表单的完整转换，严格遵循[UI包开发规范](../architecture/ui-package-standards.md)
2. **组件测试**：必须编写`tests/components/`测试文件，遵循[UI包开发规范](../architecture/ui-package-standards.md#测试规范)
3. **测试覆盖**：必须覆盖所有主要组件，验证用户交互
4. **遵循现有模式**：参考advertisement-management-ui的组件模式，并遵循[UI包开发规范](../architecture/ui-package-standards.md)
5. **集成验证**：必须与对应的后端模块集成验证

**执行顺序**：
按故事编号顺序执行即可：**故事1 → 故事2 → 故事3 → 故事4 → 故事5 → 故事6 → 故事7 → 故事8**

**特别说明**：
- **故事8**必须在所有UI包移植完成后执行，对应史诗007的**故事8**（将Allin系统模块集成到packages/server）
- 确保前后端集成时间点对齐，验证完整的Allin系统功能

**依赖关系说明**：
- **故事3**（company-management-ui）依赖platform数据，必须在**故事1**（platform-management-ui）之后
- **故事6**（disability-person-management-ui）是disability的详细管理，应在**故事5**（disability-management-ui）之后
- **故事7**（order-management-ui）可能涉及多个实体关联，放在最后

**技术栈转换关键点**：
- **Ant Design组件 → @d8d/shared-ui-components组件**：使用现有共享UI组件库
- **Jotai状态 → React Query + React状态（useState/useContext）**：使用TanStack Query进行服务端数据管理，React状态管理本地状态
- **Ant Design Form → React Hook Form + Zod**：使用hook form + zod验证
- **自定义fetch API → Hono RPC (rpcClient + ClientManager模式)**：使用类型安全的RPC客户端，遵循项目现有的rpcClient工具和ClientManager单例模式
- **文件上传**：集成`@d8d/file-management-ui`文件选择器组件

**组件测试模板参考**：
参考`/packages/advertisement-management-ui/tests/components/`
- 使用`@testing-library/react`进行组件测试
- 模拟用户交互（点击、输入、表单提交）
- 验证组件渲染和状态变化
- 每个主要组件都要有测试

**文件上传集成方案**：
发现allin_system-master中有文件上传功能（照片、资产文件），需要与现有`@d8d/file-management-ui`集成。

**采用方案**：复用现有文件管理UI包
1. **架构原则**：使用统一的文件选择器组件，后端只接收文件ID
2. **故事4（disability-person-management-ui）**：
   - 集成`FileSelector`组件用于照片上传
   - 表单接收`fileId`参数（而非文件内容）
   - 使用`FilePreview`组件显示照片
3. **故事5（order-management-ui）**：
   - 集成`FileSelector`组件用于资产文件上传
   - 根据资产类型限制文件类型
   - 使用文件预览组件显示资产
4. **优势**：统一用户体验，复用现有组件，简化后端逻辑

**实施要点**：
- UI层使用现有文件选择器组件上传文件
- 后端API只接收文件ID，不处理文件上传
- 保持API兼容性，制定数据迁移方案
- 注意组件性能，合理使用memoization

**故事8（Web client admin集成）关键要求**：
1. **依赖管理**：在`web/package.json`中添加所有7个Allin系统UI包的workspace依赖
2. **API客户端初始化**：在`web/src/client/admin/api_init.ts`中添加所有7个Allin系统UI包的API客户端初始化，**API路径必须与server包中的路由配置完全一致**（参考`packages/server/src/index.ts:139-144`）
   - 使用单数形式路径：`/api/v1/channel`、`/api/v1/company`等（没有`s`后缀）
   - `disability_person`模块对应`/api/v1/disability`路径
3. **路由配置**：在`web/src/client/admin/routes.tsx`中添加7个路由路径，对应每个UI包
4. **菜单集成**：在`web/src/client/admin/menu.tsx`中添加对应的菜单项，配置权限和图标
5. **API路径对齐**：**必须确保前端API路径与后端路由完全对应**（参考史诗007的server集成）
6. **集成验证**：验证所有路由正常工作，API客户端初始化成功，与后端模块集成完整
7. **对应关系**：本故事对应史诗007的**故事8**，确保前后端集成同步完成

史诗应在保持用户体验一致性的同时实现将UI模块从Ant Design架构移植到@d8d/shared-ui-components架构的标准化独立UI包，每个模块都要有完整的组件测试验证，并完成与现有文件管理UI包的集成，最后通过故事8将所有UI包集成到Web client admin中。"

**新增考勤打卡功能说明**：
- **发现**：原系统中存在考勤打卡功能（出勤表导出），位于订单管理模块
- **功能位置**：`allin_system-master/client/app/admin/dashboard/order/AttendanceModal.tsx`
- **功能描述**：为订单人员生成月度出勤Excel表，支持选择月份和每周出勤天数，模拟出勤数据
- **移植方案**：在**故事7（order-management-ui）** 中新增考勤打卡功能移植任务
- **具体任务**：
  1. 创建`AttendanceModal`组件，从Ant Design转换为@d8d/shared-ui-components组件
  2. 集成到订单管理UI中，保持原有交互流程
  3. 完成技术栈转换：Modal、DatePicker、Select等组件转换
  4. 保持Excel导出功能（使用xlsx库）
  5. 编写组件测试：`tests/components/AttendanceModal.test.tsx`
- **依赖更新**：在package.json中添加`xlsx`依赖
- **测试要求**：验证出勤表导出功能正常工作，Excel文件正确生成"