Explorar o código

📝 docs(shadcn): 完善管理页面文档,添加高级组件集成指南

- 添加DataTablePagination分页组件使用说明和参数文档
- 增加关联实体Selector组件开发模式和示例
- 添加复杂字段展示模式(关联实体、状态、图片等)
- 新增表单字段类型映射表,规范不同类型字段的组件使用
- 补充空数据状态显示和分页组件的代码示例
yourname hai 3 meses
pai
achega
920f4ec40c
Modificáronse 1 ficheiros con 225 adicións e 1 borrados
  1. 225 1
      .roo/commands/shadcn-manage-page.md

+ 225 - 1
.roo/commands/shadcn-manage-page.md

@@ -162,6 +162,19 @@ const { data, isLoading, refetch } = useQuery({
     </TableBody>
   </Table>
 </div>
+
+{data?.data.length === 0 && !isLoading && (
+  <div className="text-center py-8">
+    <p className="text-muted-foreground">暂无数据</p>
+  </div>
+)}
+
+<DataTablePagination
+  currentPage={searchParams.page}
+  pageSize={searchParams.limit}
+  totalCount={data?.pagination.total || 0}
+  onPageChange={(page, limit) => setSearchParams(prev => ({ ...prev, page, limit }))}
+/>
 ```
 
 ## 表单开发模式
@@ -422,4 +435,215 @@ const [entityToDelete, setEntityToDelete] = useState<number | null>(null);
 - 保持相同的CRUD操作模式
 - 复用分页、搜索、排序逻辑
 - 统一的状态管理模式
-- 一致的表单验证和错误处理
+- 一致的表单验证和错误处理
+
+## 高级组件集成
+
+### 1. DataTablePagination 分页组件
+
+#### 1.1 使用方式
+```tsx
+import { DataTablePagination } from '@/client/admin-shadcn/components/DataTablePagination';
+
+<DataTablePagination
+  currentPage={searchParams.page}
+  pageSize={searchParams.limit}
+  totalCount={data?.pagination.total || 0}
+  onPageChange={(page, limit) => setSearchParams(prev => ({ ...prev, page, limit }))}
+/>
+```
+
+#### 1.2 参数说明
+| 参数 | 类型 | 描述 |
+|------|------|------|
+| currentPage | number | 当前页码 |
+| pageSize | number | 每页显示条数 |
+| totalCount | number | 总记录数 |
+| onPageChange | function | 页码变化回调函数 |
+
+#### 1.3 集成到状态管理
+```typescript
+const [searchParams, setSearchParams] = useState({
+  page: 1,
+  limit: 10,
+  search: ''
+});
+
+// 在数据查询中
+const { data } = useQuery({
+  queryKey: ['entities', searchParams],
+  queryFn: async () => {
+    const res = await client.$get({
+      query: {
+        page: searchParams.page,
+        pageSize: searchParams.limit,
+        keyword: searchParams.search
+      }
+    });
+    return await res.json();
+  }
+});
+```
+
+### 2. 关联实体Selector组件
+
+#### 2.1 AdvertisementTypeSelector 示例
+```tsx
+import AdvertisementTypeSelector from '@/client/admin-shadcn/components/AdvertisementTypeSelector';
+
+<FormField
+  control={form.control}
+  name="typeId"
+  render={({ field }) => (
+    <FormItem>
+      <FormLabel>广告类型</FormLabel>
+      <FormControl>
+        <AdvertisementTypeSelector
+          value={field.value}
+          onChange={field.onChange}
+          placeholder="请选择广告类型"
+        />
+      </FormControl>
+      <FormMessage />
+    </FormItem>
+  )}
+/>
+```
+
+#### 2.2 自定义Selector开发模式
+```typescript
+// 通用Selector接口设计
+interface EntitySelectorProps {
+  value?: number;
+  onChange?: (value: number) => void;
+  placeholder?: string;
+  disabled?: boolean;
+}
+
+// 实现模式
+const EntitySelector: React.FC<EntitySelectorProps> = ({
+  value,
+  onChange,
+  placeholder = "请选择",
+  disabled
+}) => {
+  const { data } = useQuery({
+    queryKey: ['entities'],
+    queryFn: async () => {
+      const res = await entityClient.$get();
+      return await res.json();
+    }
+  });
+
+  return (
+    <Select value={value?.toString()} onValueChange={(v) => onChange?.(parseInt(v))}>
+      <SelectTrigger disabled={disabled}>
+        <SelectValue placeholder={placeholder} />
+      </SelectTrigger>
+      <SelectContent>
+        {data?.data.map((item) => (
+          <SelectItem key={item.id} value={item.id.toString()}>
+            {item.name}
+          </SelectItem>
+        ))}
+      </SelectContent>
+    </Select>
+  );
+};
+```
+
+#### 2.3 图片选择器集成
+```tsx
+import ImageSelector from '@/client/admin-shadcn/components/ImageSelector';
+
+<FormField
+  control={form.control}
+  name="imageFileId"
+  render={({ field }) => (
+    <FormItem>
+      <FormLabel>广告图片</FormLabel>
+      <FormControl>
+        <ImageSelector
+          value={field.value || undefined}
+          onChange={field.onChange}
+          maxSize={2} // MB
+          uploadPath="/advertisements"
+          uploadButtonText="上传广告图片"
+          previewSize="medium"
+          placeholder="选择广告图片"
+          title="选择广告图片"
+          description="上传新图片或从已有图片中选择"
+        />
+      </FormControl>
+      <FormDescription>推荐尺寸:1200x400px,支持jpg、png格式</FormDescription>
+      <FormMessage />
+    </FormItem>
+  )}
+/>
+```
+
+### 3. 复杂字段展示模式
+
+#### 3.1 关联实体字段展示
+```tsx
+<TableCell>
+  {advertisement.advertisementType?.name || '-'}
+</TableCell>
+```
+
+#### 3.2 状态字段展示
+```tsx
+<TableCell>
+  <Badge variant={advertisement.status === 1 ? 'default' : 'secondary'}>
+    {advertisement.status === 1 ? '启用' : '禁用'}
+  </Badge>
+</TableCell>
+```
+
+#### 3.3 图片字段展示
+```tsx
+<TableCell>
+  {advertisement.imageFile?.fullUrl ? (
+    <img
+      src={advertisement.imageFile.fullUrl}
+      alt={advertisement.title || '图片'}
+      className="w-16 h-10 object-cover rounded"
+      onError={(e) => {
+        e.currentTarget.src = '/placeholder.png';
+      }}
+    />
+  ) : (
+    <span className="text-muted-foreground text-xs">无图片</span>
+  )}
+</TableCell>
+```
+
+### 4. 表单字段类型映射
+
+#### 4.1 标准字段映射
+| 字段类型 | 组件 | 示例 |
+|----------|------|------|
+| 文本输入 | Input | `<Input placeholder="请输入标题" {...field} />` |
+| 长文本 | Textarea | `<Textarea placeholder="请输入描述" {...field} />` |
+| 选择器 | Select | `<Select value={field.value} onValueChange={field.onChange}>` |
+| 数字输入 | Input | `<Input type="number" {...field} />` |
+| 日期选择 | DatePicker | `<DatePicker selected={field.value} onChange={field.onChange} />` |
+| 开关 | Switch | `<Switch checked={field.value} onCheckedChange={field.onChange} />` |
+| 文件上传 | ImageSelector | `<ImageSelector value={field.value} onChange={field.onChange} />` |
+
+#### 4.2 关联实体选择
+```tsx
+// 直接使用Selector组件
+<FormField
+  control={form.control}
+  name="typeId"
+  render={({ field }) => (
+    <FormItem>
+      <FormLabel>广告类型</FormLabel>
+      <FormControl>
+        <AdvertisementTypeSelector {...field} />
+      </FormControl>
+    </FormItem>
+  )}
+/>
+```