component-documentation.md 11 KB

项目组件文档

目录

  1. 管理后台组件
  2. 移动端组件
  3. 通用工具方法
  4. 使用示例

管理后台组件

1. MinioUploader - MinIO文件上传组件

位置: src/client/admin/components/MinioUploader.tsx

作用: 提供完整的文件上传功能,支持拖拽上传、进度显示、多文件上传等

属性:

interface MinioUploaderProps {
  uploadPath: string;           // 上传路径
  accept?: string;             // 允许的文件类型
  maxSize?: number;            // 最大文件大小(MB)
  multiple?: boolean;          // 是否支持多文件
  onUploadSuccess?: (fileKey: string, fileUrl: string, file: File) => void;
  onUploadError?: (error: Error, file: File) => void;
  buttonText?: string;         // 自定义按钮文本
  tipText?: string;           // 自定义提示文本
}

使用方法:

<MinioUploader
  uploadPath="/documents/"
  accept=".pdf,.doc,.docx"
  maxSize={10}
  multiple={true}
  onUploadSuccess={(fileKey, fileUrl, file) => {
    console.log('上传成功:', fileUrl);
  }}
  buttonText="上传文档"
  tipText="支持PDF、Word格式,最大10MB"
/>

2. AttachmentUploader - 附件上传组件

位置: src/client/admin/components/AttachmentUploader.tsx

作用: 专门用于上传附件文件,支持多种文档格式

支持格式: PDF、DOC、DOCX、XLS、XLSX、PPT、PPTX、TXT、ZIP、RAR

使用方法:

<AttachmentUploader
  value={attachmentUrl}
  fileName={attachmentName}
  onChange={(url, name) => {
    setAttachmentUrl(url);
    setAttachmentName(name);
  }}
/>

3. CoverImageUploader - 封面图片上传组件

位置: src/client/admin/components/CoverImageUploader.tsx

作用: 专门用于上传封面图片,支持图片预览

支持格式: JPG、PNG、GIF,最大5MB

使用方法:

<CoverImageUploader
  value={coverUrl}
  onChange={(url) => setCoverUrl(url)}
/>

4. CompanySelect - 公司选择器

位置: src/client/admin/components/CompanySelect.tsx

作用: 从已认证公司列表中选择公司,支持搜索功能

属性:

interface CompanySelectProps {
  value?: number;
  onChange?: (value: number) => void;
  placeholder?: string;
  allowClear?: boolean;
  showSearch?: boolean;
}

使用方法:

<CompanySelect
  value={selectedCompanyId}
  onChange={setSelectedCompanyId}
  placeholder="选择合作公司"
/>

5. KnowledgeCategoryTreeSelect - 知识分类树形选择器

位置: src/client/admin/components/KnowledgeCategoryTreeSelect.tsx

作用: 以树形结构选择知识分类,支持多级分类

属性:

interface KnowledgeCategoryTreeSelectProps {
  value?: number | null;
  onChange?: (value: number | null) => void;
  placeholder?: string;
  allowClear?: boolean;
  multiple?: boolean;
  showRoot?: boolean;
  rootLabel?: string;
}

使用方法:

<KnowledgeCategoryTreeSelect
  value={categoryId}
  onChange={setCategoryId}
  placeholder="选择知识分类"
  showRoot={true}
  rootLabel="全部分类"
/>

6. StatCard - 统计卡片组件

位置: src/client/admin/components/StatCard.tsx

作用: 显示统计数据的卡片组件,带趋势指示

属性:

interface StatCardProps {
  title: string;
  value: number;
  prefix?: React.ReactNode;
  suffix?: string;
  trend?: 'up' | 'down';
  trendValue?: string;
  color: string; // 'blue' | 'green' | 'orange' | 'purple' | 'red' | 'pink'
  icon: React.ReactNode;
}

使用方法:

<StatCard
  title="总用户数"
  value={12580}
  trend="up"
  trendValue="+12.5%"
  color="blue"
  icon={<UserOutlined />}
  suffix="本月新增"
/>

移动端组件

1. AvatarUpload - 头像上传组件 (移动端)

位置: src/client/mobile/components/AvatarUpload.tsx

作用: 移动端头像上传,支持图片裁剪和压缩

属性:

interface AvatarUploadProps {
  currentAvatar?: string | null;
  onUploadSuccess?: (avatarUrl: string) => void;
  size?: number; // 头像大小,默认96px
}

特色功能:

  • 图片压缩
  • 圆形裁剪
  • 水墨风格UI
  • 实时预览

使用方法:

<AvatarUpload
  currentAvatar={user.avatar}
  onUploadSuccess={(url) => updateUserAvatar(url)}
  size={120}
/>

2. AvatarCropper - 头像裁剪组件

位置: src/client/mobile/components/AvatarCropper.tsx

作用: 提供图片裁剪功能,支持拖拽和缩放

属性:

interface AvatarCropperProps {
  imageUrl: string;
  onCrop: (croppedBlob: Blob) => void;
  onCancel: () => void;
  size?: number; // 裁剪区域大小
}

使用方法:

<AvatarCropper
  imageUrl={previewImage}
  onCrop={(blob) => handleCropComplete(blob)}
  onCancel={() => setShowCropper(false)}
  size={300}
/>

3. SmartAssistant - 智能助手组件

位置: src/client/mobile/components/SmartAssistant/

作用: 智能对话助手,支持多种AI Agent

主要组件:

  • SmartAssistant: 主组件
  • ChatWindow: 聊天窗口
  • MessageBubble: 消息气泡
  • AgentSelector: Agent选择器
  • FloatingButton: 悬浮按钮

使用方法:

import { SmartAssistant } from '@/client/mobile/components/SmartAssistant';

<SmartAssistant />

通用工具方法

1. 文件上传工具 - minio.ts

位置: src/client/utils/minio.ts

主要功能:

  • MinIO文件上传
  • 分段上传大文件
  • 进度回调
  • 上传策略获取

使用方法:

基础上传

import { uploadFile } from '@/client/utils/minio';

const url = await uploadFile(file, 'avatars');

带进度上传

import { uploadMinIOWithPolicy } from '@/client/utils/minio';

const result = await uploadMinIOWithPolicy(
  'avatars',
  file,
  `user-${userId}.jpg`,
  {
    onProgress: (event) => {
      console.log(`进度: ${event.progress}%`);
    }
  }
);

2. 图片处理工具 - upload.ts

位置: src/client/utils/upload.ts

主要功能:

  • 图片压缩
  • Base64转换
  • 文件类型检查
  • 文件大小验证

使用方法:

图片压缩

import { compressImage } from '@/client/utils/upload';

const compressedFile = await compressImage(file, 800, 800, 0.8);

文件验证

import { isImageFile, checkFileSize } from '@/client/utils/upload';

if (!isImageFile(file)) {
  alert('请选择图片文件');
}

if (!checkFileSize(file, 2)) {
  alert('文件大小不能超过2MB');
}

3. API客户端 - api.ts

位置: src/client/api.ts

主要功能:

  • 统一的API调用接口
  • 类型安全的API调用
  • 自动处理认证

使用方法:

import { userClient } from '@/client/api';

// 获取用户信息
const response = await userClient[userId].$get();
const userData = await response.json();

// 更新用户信息
await userClient[userId].$put({
  json: { username: 'newName' }
});

使用示例

1. 完整的上传流程示例

import React, { useState } from 'react';
import { MinioUploader } from '@/client/admin/components/MinioUploader';
import { message } from 'antd';

const DocumentUploadExample: React.FC = () => {
  const [fileUrl, setFileUrl] = useState<string>('');

  const handleUploadSuccess = (fileKey: string, fileUrl: string, file: File) => {
    setFileUrl(fileUrl);
    message.success(`文件 ${file.name} 上传成功`);
  };

  const handleUploadError = (error: Error, file: File) => {
    message.error(`文件 ${file.name} 上传失败: ${error.message}`);
  };

  return (
    <div>
      <MinioUploader
        uploadPath="/documents/2024/"
        accept=".pdf,.doc,.docx"
        maxSize={10}
        multiple={false}
        onUploadSuccess={handleUploadSuccess}
        onUploadError={handleUploadError}
        buttonText="上传文档"
        tipText="支持PDF、Word格式,最大10MB"
      />
      
      {fileUrl && (
        <div className="mt-4">
          <a href={fileUrl} target="_blank" rel="noopener noreferrer">
            查看已上传文件
          </a>
        </div>
      )}
    </div>
  );
};

2. 移动端头像上传示例

import React, { useState } from 'react';
import { AvatarUpload } from '@/client/mobile/components/AvatarUpload';
import { useAuth } from '@/client/mobile/hooks/AuthProvider';

const ProfileAvatar: React.FC = () => {
  const { user, updateUser } = useAuth();
  const [avatar, setAvatar] = useState(user?.avatar);

  const handleAvatarUpload = (avatarUrl: string) => {
    setAvatar(avatarUrl);
    updateUser({ avatar: avatarUrl });
  };

  return (
    <div className="flex flex-col items-center">
      <AvatarUpload
        currentAvatar={avatar}
        onUploadSuccess={handleAvatarUpload}
        size={120}
      />
      <p className="mt-2 text-gray-600">点击头像更换</p>
    </div>
  );
};

3. 公司选择器使用示例

import React, { useState } from 'react';
import { CompanySelect } from '@/client/admin/components/CompanySelect';

const JobForm: React.FC = () => {
  const [companyId, setCompanyId] = useState<number>();

  const handleCompanyChange = (value: number) => {
    setCompanyId(value);
    // 触发其他逻辑,如加载公司详情
  };

  return (
    <div>
      <label>选择公司</label>
      <CompanySelect
        value={companyId}
        onChange={handleCompanyChange}
        placeholder="请选择发布职位的公司"
      />
    </div>
  );
};

4. 批量文件上传示例

import React, { useState } from 'react';
import { MinioUploader } from '@/client/admin/components/MinioUploader';
import type { UploadFile } from 'antd';

const BatchUploadExample: React.FC = () => {
  const [uploadedFiles, setUploadedFiles] = useState<string[]>([]);

  const handleUploadSuccess = (fileKey: string, fileUrl: string, file: File) => {
    setUploadedFiles(prev => [...prev, fileUrl]);
  };

  return (
    <div>
      <h3>批量上传图片</h3>
      <MinioUploader
        uploadPath="/gallery/2024/"
        accept="image/*"
        maxSize={5}
        multiple={true}
        onUploadSuccess={handleUploadSuccess}
        buttonText="选择图片"
        tipText="支持JPG、PNG、GIF格式,每张最大5MB"
      />
      
      <div className="mt-4">
        <h4>已上传文件:</h4>
        {uploadedFiles.map((url, index) => (
          <img key={index} src={url} alt={`uploaded-${index}`} className="w-32 h-32" />
        ))}
      </div>
    </div>
  );
};

注意事项

  1. 文件大小限制: 不同类型的上传组件有不同的文件大小限制
  2. 文件格式验证: 上传前务必验证文件格式和大小
  3. 进度显示: 大文件上传建议使用进度条显示
  4. 错误处理: 所有上传操作都应该有完善的错误处理
  5. 安全性: 敏感文件上传需要额外的权限验证

最佳实践

  1. 统一文件命名: 使用时间戳或UUID避免文件名冲突
  2. 分目录存储: 按类型、日期或用户分目录存储
  3. 压缩优化: 大图片上传前先压缩
  4. 缓存清理: 定期清理无用文件
  5. 权限控制: 根据用户角色限制上传权限