"use client" import type React from "react" import { useState, useEffect, use } from "react" import { useRouter } from "next/navigation" import { ChevronLeft, Plus, X, Image as ImageIcon, UploadCloud, Link, Video, FileText, Layers, CalendarDays, ChevronDown } from "lucide-react" import { Card } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Textarea } from "@/components/ui/textarea" import { Label } from "@/components/ui/label" import { toast } from "@/components/ui/use-toast" import { api } from "@/lib/api" import { showToast } from "@/lib/toast" import Image from "next/image" import { Input } from "@/components/ui/input" import { cn } from "@/lib/utils" interface ApiResponse { code: number msg: string data: T } interface Material { id: number type: string title: string content: string coverImage: string | null resUrls: string[] urls: string[] createTime: string createMomentTime: number time: string wechatId: string friendId: string | null wechatChatroomId: number senderNickname: string location: string | null lat: string lng: string comment: string | null icon: string | null videoUrl?: string } const isImageUrl = (url: string) => { return /\.(jpg|jpeg|png|gif|webp)$/i.test(url) || url.includes('oss-cn-shenzhen.aliyuncs.com') } // 素材类型枚举 const MATERIAL_TYPES = [ { id: 1, name: "图片", icon: ImageIcon }, { id: 2, name: "链接", icon: Link }, { id: 3, name: "视频", icon: Video }, { id: 4, name: "文本", icon: FileText }, { id: 5, name: "小程序", icon: Layers } ] export default function EditMaterialPage({ params }: { params: Promise<{ id: string, materialId: string }> }) { const resolvedParams = use(params) const router = useRouter() const [isLoading, setIsLoading] = useState(true) const [content, setContent] = useState("") const [images, setImages] = useState([]) const [previewUrls, setPreviewUrls] = useState([]) const [originalMaterial, setOriginalMaterial] = useState(null) const [materialType, setMaterialType] = useState(1) // 默认为图片类型 const [url, setUrl] = useState("") const [title, setTitle] = useState("") const [iconUrl, setIconUrl] = useState("") const [videoUrl, setVideoUrl] = useState("") const [publishTime, setPublishTime] = useState("") const [comment, setComment] = useState("") // 获取素材详情 useEffect(() => { const fetchMaterialDetail = async () => { setIsLoading(true) try { const response = await api.get>(`/v1/content/library/get-item-detail?id=${resolvedParams.materialId}`) if (response.code === 200 && response.data) { const material = response.data setOriginalMaterial(material) setContent(material.content) setTitle(material.title || "") setIconUrl(material.icon || "") setVideoUrl(material.videoUrl || "") setComment(material.comment || "") // 设置素材类型 setMaterialType(Number(material.type) || 1) // 如果是链接类型,设置URL if (material.type === "2" && material.urls && material.urls.length > 0) { setUrl(material.urls[0]) } // 处理图片 const imageUrls: string[] = [] // 检查内容本身是否为图片链接 if (isImageUrl(material.content)) { if (!imageUrls.includes(material.content)) { imageUrls.push(material.content) } } // 添加资源URL中的图片 material.resUrls.forEach(url => { if (isImageUrl(url) && !imageUrls.includes(url)) { imageUrls.push(url) } }) setImages(imageUrls) setPreviewUrls(imageUrls) } else { showToast(response.msg || "获取素材详情失败", "error") router.back() } } catch (error: any) { console.error("Failed to fetch material detail:", error) showToast(error?.message || "请检查网络连接", "error") router.back() } finally { setIsLoading(false) } } fetchMaterialDetail() }, [resolvedParams.materialId, router]) // 模拟上传图片 const handleUploadImage = () => { // 这里应该是真实的图片上传逻辑 // 为了演示,这里模拟添加一些示例图片URL const mockImageUrls = [ "https://picsum.photos/id/237/200/300", "https://picsum.photos/id/238/200/300", "https://picsum.photos/id/239/200/300" ] const randomIndex = Math.floor(Math.random() * mockImageUrls.length) const newImage = mockImageUrls[randomIndex] if (!images.includes(newImage)) { setImages([...images, newImage]) setPreviewUrls([...previewUrls, newImage]) } } const handleRemoveImage = (indexToRemove: number) => { setImages(images.filter((_, index) => index !== indexToRemove)) setPreviewUrls(previewUrls.filter((_, index) => index !== indexToRemove)) } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() // 根据不同类型校验不同字段 if (materialType === 1 && images.length === 0) { showToast("请上传图片", "error") return } else if (materialType === 2 && !url) { showToast("请输入链接地址", "error") return } else if ((materialType === 4 || materialType === 6) && !content) { showToast("请输入文本内容", "error") return } const loadingToast = showToast("正在更新素材...", "loading", true) try { const payload: any = { id: resolvedParams.materialId, type: materialType, content: content, title: materialType === 2 ? title : undefined, icon: materialType === 2 ? iconUrl : undefined, videoUrl: materialType === 3 ? videoUrl : undefined, comment: comment, } // 根据类型添加不同的字段 if (materialType === 1) { payload.resUrls = images } else if (materialType === 2) { payload.urls = [url] } else if (materialType === 3) { payload.urls = [url] } const response = await api.post('/v1/content/library/update-item', payload) if (response.code === 200) { showToast("素材更新成功", "success") router.push(`/content/${resolvedParams.id}/materials`) } else { showToast(response.msg || "更新失败", "error") } } catch (error: any) { console.error("Failed to update material:", error) showToast(error?.message || "更新失败", "error") } finally { loadingToast.remove && loadingToast.remove() } } if (isLoading) { return (
加载中...
) } return (

编辑素材

{/* 基础信息分组 */}
基础信息
setPublishTime(e.target.value)} 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" placeholder="请选择发布时间" style={{ width: 'auto' }} />
{/* 内容信息分组 */} {(materialType === 4 || materialType === 6 || (materialType === 1 && !isImageUrl(content))) && (
内容信息