位置: 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"
/>
位置: 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);
}}
/>
位置: src/client/admin/components/CoverImageUploader.tsx
作用: 专门用于上传封面图片,支持图片预览
支持格式: JPG、PNG、GIF,最大5MB
使用方法:
<CoverImageUploader
value={coverUrl}
onChange={(url) => setCoverUrl(url)}
/>
位置: 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="选择合作公司"
/>
位置: 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="全部分类"
/>
位置: 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="本月新增"
/>
位置: src/client/mobile/components/AvatarUpload.tsx
作用: 移动端头像上传,支持图片裁剪和压缩
属性:
interface AvatarUploadProps {
currentAvatar?: string | null;
onUploadSuccess?: (avatarUrl: string) => void;
size?: number; // 头像大小,默认96px
}
特色功能:
使用方法:
<AvatarUpload
currentAvatar={user.avatar}
onUploadSuccess={(url) => updateUserAvatar(url)}
size={120}
/>
位置: 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}
/>
位置: src/client/mobile/components/SmartAssistant/
作用: 智能对话助手,支持多种AI Agent
主要组件:
SmartAssistant: 主组件ChatWindow: 聊天窗口MessageBubble: 消息气泡AgentSelector: Agent选择器FloatingButton: 悬浮按钮使用方法:
import { SmartAssistant } from '@/client/mobile/components/SmartAssistant';
<SmartAssistant />
位置: src/client/utils/minio.ts
主要功能:
使用方法:
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}%`);
}
}
);
位置: src/client/utils/upload.ts
主要功能:
使用方法:
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');
}
位置: src/client/api.ts
主要功能:
使用方法:
import { userClient } from '@/client/api';
// 获取用户信息
const response = await userClient[userId].$get();
const userData = await response.json();
// 更新用户信息
await userClient[userId].$put({
json: { username: 'newName' }
});
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>
);
};
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>
);
};
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>
);
};
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>
);
};