feat: 本次提交更新内容如下

编辑素材构建完成
This commit is contained in:
笔记本里的永平
2025-07-15 14:51:02 +08:00
parent 3955821f42
commit 721feafa7d
3 changed files with 96 additions and 17 deletions

18
nkebao/src/api/upload.ts Normal file
View File

@@ -0,0 +1,18 @@
import { request } from './request';
import type { AxiosResponse } from 'axios';
// 上传图片,返回图片地址
export async function uploadImage(file: File): Promise<string> {
const formData = new FormData();
formData.append('file', file);
const response: AxiosResponse<any> = await request.post('/v1/attachment/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
const res = response.data || response;
if (res?.url) {
return res.url;
}
throw new Error(res?.msg || '图片上传失败');
}

View File

@@ -0,0 +1,56 @@
import React, { useState, useEffect } from 'react';
import { Upload } from 'tdesign-mobile-react';
import type { UploadFile as TDesignUploadFile } from 'tdesign-mobile-react/es/upload/type';
import { uploadImage } from '@/api/upload';
interface UploadImageProps {
value?: string[];
onChange?: (urls: string[]) => void;
max?: number;
accept?: string;
disabled?: boolean;
}
const UploadImage: React.FC<UploadImageProps> = ({ value = [], onChange, ...props }) => {
// 处理上传
const requestMethod = async (file: TDesignUploadFile) => {
try {
const url = await uploadImage(file.raw as File);
return {
status: 'success' as const,
response: {
url
},
};
} catch (e: any) {
return {
status: 'fail' as const,
error: e.message || '上传失败',
response: {},
};
}
};
// 处理文件变更
const handleChange = (newFiles: TDesignUploadFile[]) => {
console.log(newFiles);
const urls = newFiles.map(f => f.url).filter((url): url is string => Boolean(url));
onChange?.(urls);
};
return (
<Upload
requestMethod={requestMethod}
onChange={handleChange}
multiple
accept={props.accept}
max={props.max}
disabled={props.disabled}
// 不传 filesUpload 组件自己管理
/>
);
};
export default UploadImage;

View File

@@ -11,7 +11,9 @@ import UnifiedHeader from '@/components/UnifiedHeader';
import { get, post } from '@/api/request';
import { UploadCloud } from 'lucide-react';
import { Upload } from 'tdesign-mobile-react';
import type { UploadFile } from 'tdesign-mobile-react/es/upload/type';
import type { UploadFile as TDesignUploadFile } from 'tdesign-mobile-react/es/upload/type';
import { uploadImage } from '@/api/upload';
import UploadImage from '@/components/UploadImage';
export default function NewMaterial() {
const navigate = useNavigate();
@@ -28,6 +30,8 @@ export default function NewMaterial() {
const [sendTime, setSendTime] = useState('');
const [images, setImages] = useState<string[]>([]);
const [isFirstLoad, setIsFirstLoad] = useState(true);
// 优化图片上传逻辑,确保每次选择图片后立即上传并回显
const [uploadFiles, setUploadFiles] = useState<TDesignUploadFile[]>([]);
// 判断模式并拉取详情
useEffect(() => {
@@ -116,16 +120,14 @@ export default function NewMaterial() {
}
};
// 上传图片模拟
const handleUploadImage = () => {
// 这里应对接真实上传逻辑
const mock = [
'https://picsum.photos/id/237/200/300',
'https://picsum.photos/id/238/200/300',
'https://picsum.photos/id/239/200/300',
];
const random = mock[Math.floor(Math.random() * mock.length)];
if (!images.includes(random)) setImages([...images, random]);
// 上传图片,接入接口
const handleUploadImage = async (file: File) => {
try {
const url = await uploadImage(file);
setImages(prev => [...prev, url]);
} catch (e: any) {
toast({ title: '上传失败', description: e.message || '图片上传失败', variant: 'destructive' });
}
};
return (
@@ -240,12 +242,15 @@ export default function NewMaterial() {
<div className="text-xs text-gray-400 mb-2 tracking-widest">9</div>
{contentType === 1 && (
<div className="mb-6">
<Upload
files={images.map(url => ({ url }))}
onChange={(files: UploadFile[]) => setImages(files.map((f: any) => f.url))}
multiple
accept="image/*"
<UploadImage
value={images}
onChange={urls => {
setImages(urls);
setUploadFiles(urls.map(url => ({ url })));
}}
max={9}
accept="image/*"
disabled={isSubmitting}
/>
</div>
)}
@@ -257,7 +262,7 @@ export default function NewMaterial() {
<Input id="appId" placeholder="请输入AppID" className="w-full h-12 rounded-2xl border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-100 px-4 text-base placeholder:text-gray-300" />
<Label className="font-bold mb-2"></Label>
<div className="border border-dashed border-gray-300 rounded-2xl p-4 text-center bg-gray-50">
<Button type="button" variant="outline" onClick={handleUploadImage} className="w-full py-4 flex flex-col items-center justify-center rounded-2xl border-2 border-dashed border-blue-300 bg-white hover:bg-blue-50">
<Button type="button" variant="outline" onClick={() => handleUploadImage(new File([], ''))} className="w-full py-4 flex flex-col items-center justify-center rounded-2xl border-2 border-dashed border-blue-300 bg-white hover:bg-blue-50">
<UploadCloud className="h-6 w-6 mb-2 text-gray-400" />
<span></span>
</Button>