| 'use client'; |
| import React, {useEffect, useRef, useState} from 'react'; |
| // import {TabView, TabPanel} from "primereact/tabview"; |
| import {Card} from "primereact/card"; |
| import {Image} from "primereact/image"; |
| import {Button} from "primereact/button"; |
| // 弹窗 |
| import { Dialog } from 'primereact/dialog'; |
| import {InputText} from "primereact/inputtext"; |
| import {InputTextarea} from "primereact/inputtextarea"; |
| import {FileUpload} from "primereact/fileupload"; |
| // 类型转换 |
| import {toNumber} from "lodash"; |
| // 消息提醒 |
| import {Toast} from 'primereact/toast'; |
| // 接口传输 |
| import axios from "axios"; |
| // 页面跳转 |
| import {useRouter} from "next/navigation"; |
| // 分页 |
| import { Paginator, type PaginatorPageChangeEvent } from 'primereact/paginator'; |
| // 密码 |
| import { Password } from 'primereact/password'; |
| // 样式 |
| import './resources.scss'; |
| |
| |
| |
| // 用户发布的资源 |
| interface Resource { |
| resourceId: number; |
| resourceName: string; |
| resourcePicture: string; |
| resourceSummary: string; // 资源简介(一句话) |
| resourceDetail: string; // 资源介绍 |
| uploadTime: string; // 上传时间 |
| lastUpdateTime: string; // 最近更新时间 |
| price: number; |
| downloads: number; |
| likes: number; |
| collections: number; |
| comments: number; |
| seeds: number; // 种子数 |
| classify: string; // 资源分类(材质包:resourcePack,模组:mod,整合包:modPack ,地图:map |
| } |
| |
| // 用户发布的资源列表 |
| interface ResourceList { |
| records: Resource[]; |
| total: number; // 总记录数 |
| pages: number; // 总页数 |
| current: number; // 当前页码 |
| sizes: number; // 每页大小 |
| } |
| |
| export default function UserManageResources() { |
| // 路由 |
| const router = useRouter(); |
| // 发布资源列表 |
| const [resourceList, setResourceList] = useState<Resource[]>([]); |
| // 要删除资源的id |
| const [deleteResourceId, setDeleteResourceId] = useState<number>(0); |
| // 资源封面路径 |
| const [resourcePictureUrl, setResourcePictureUrl] = useState<string>(''); |
| // 编辑资源的分类 |
| const [resourceClassify, setResourceClassify] = useState<string>(''); |
| // 消息提醒 |
| const toast = useRef<Toast>(null); |
| // 分页 |
| const [first, setFirst] = useState(0); |
| const [rows, setRows] = useState(5); |
| const [totalResources, setTotalResources] = useState<number>(0); |
| const onPageChange = (event: PaginatorPageChangeEvent) => { |
| setFirst(event.first); |
| setRows(event.rows); |
| }; |
| // 删除资源弹窗 |
| const [deleteVisible, setDeleteVisible] = useState(false); |
| const [deleteResourceFormData, setDeleteResourceFormData] = useState({ |
| password: '', |
| }); |
| |
| // 编辑资源弹窗 |
| const [editVisible, setEditVisible] = useState(false); |
| const [editResourceFormData, setEditResourceFormData] = useState({ |
| resourceId: 0, |
| resourceName: '', |
| resourceSummary: '', |
| resourceDetail: '', |
| price: '', |
| }); |
| |
| useEffect(() => { |
| fetchResourceList(); |
| }, [first, rows]); |
| |
| |
| // 获取用户发布资源 |
| const fetchResourceList = async () => { |
| try { |
| const pageNumber = first / rows + 1; |
| const response = await axios.get<ResourceList>(process.env.PUBLIC_URL + `/user/upload`, { |
| params: {userId: 22301010, pageNumber: pageNumber, rows: rows} |
| }); |
| |
| console.log('获取发布资源列表:', response.data.records); |
| setResourceList(response.data.records); |
| setTotalResources(response.data.total); |
| } catch (err) { |
| console.error('获取发布资源失败', err); |
| toast.current?.show({severity: 'error', summary: 'error', detail: '获取发布资源失败'}); |
| } |
| }; |
| |
| // 处理删除资源接口 |
| const handleDeleteSubmit = async () => { |
| try { |
| const deleteData = { |
| resourceId: deleteResourceId, |
| userId: 223010100, |
| password: deleteResourceFormData.password, |
| }; |
| // 发送DELETE请求 |
| const response = await axios.delete(process.env.PUBLIC_URL + `/resource`, { |
| params: {resourceId: deleteData.resourceId, userId: deleteData.userId, password: deleteData.password}, |
| }); |
| console.log("用户" + 22301010 + "要删除" + deleteData.resourceId + "号资源"); |
| console.log(deleteData); |
| console.log(response); |
| console.log(response.status) |
| |
| if (response.status === 204) { |
| console.log("用户成功删除资源"); |
| // setIsDeleteResource(true); |
| toast.current?.show({severity: 'success', summary: 'Success', detail: '删除资源成功'}); |
| setDeleteVisible(false); |
| // 重置表单 |
| setDeleteResourceFormData({ |
| password: '', |
| }); |
| // 重新拉取资源列表 |
| fetchResourceList(); |
| } else { |
| console.log('用户密码错误'); |
| toast.current?.show({severity: 'error', summary: 'Error', detail: '密码错误,删除资源失败'}); |
| } |
| |
| } catch (error) { |
| console.error('资源删除失败:', error); |
| toast.current?.show({ severity: 'error', summary: 'error', detail: '密码错误,资源删除失败' }); |
| } |
| }; |
| |
| // 处理编辑资源接口 |
| const handleEditSubmit = async () => { |
| try { |
| const postData = { |
| resourceId: editResourceFormData.resourceId, |
| resourceName: editResourceFormData.resourceName, |
| resourcePicture: resourcePictureUrl, |
| resourceSummary: editResourceFormData.resourceSummary, |
| resourceDetail: editResourceFormData.resourceDetail, |
| price: toNumber(editResourceFormData.price), |
| classify: resourceClassify, |
| }; |
| // 发送POST请求 |
| const response = await axios.put(process.env.PUBLIC_URL + '/resource/info', postData); |
| console.log("编辑资源的信息:", postData); |
| |
| if (response.status === 200) { |
| toast.current?.show({ severity: 'success', summary: 'Success', detail: '资源编辑成功' }); |
| // 编辑成功 |
| setEditVisible(false); |
| fetchResourceList(); |
| } |
| } catch (error) { |
| console.error('资源上传失败:', error); |
| toast.current?.show({ severity: 'error', summary: 'error', detail: '资源上传失败' }); |
| } |
| }; |
| |
| return ( |
| <div className="resources-container"> |
| <Toast ref={toast}></Toast> |
| <div className="resources-title"> |
| <h1>我上传的资源</h1> |
| </div> |
| |
| <div className="resource-list"> |
| {resourceList.map((resourceList) => ( |
| <Card key={resourceList.resourceId} className="resources-list-card" |
| onClick={() => router.push(`/resource/resource-detail/${resourceList.resourceId}`)}> |
| <Image alt="avatar" |
| src={process.env.NEXT_PUBLIC_NGINX_URL + "resource/" + resourceList.resourcePicture} |
| className="resource-avatar" width="250" height="140"/> |
| <div className="resource-header"> |
| <div className="resource-content"> |
| <h3>{resourceList.resourceName}</h3> |
| </div> |
| |
| <div className="resource-operation"> |
| <Button |
| label="编辑" |
| onClick={(e) => { |
| e.stopPropagation(); // 关键修复:阻止事件冒泡,避免触发Card的点击事件 |
| setEditVisible(true); |
| |
| setResourceClassify(resourceList.classify); |
| setEditResourceFormData({ |
| resourceId: resourceList.resourceId, |
| resourceName: resourceList.resourceName, |
| resourceSummary: resourceList.resourceSummary, |
| resourceDetail: resourceList.resourceDetail, |
| price: resourceList.price.toString(), |
| }); |
| console.log("用户编辑资源"); |
| }} |
| /> |
| <Button |
| label="删除" |
| onClick={(e) => { |
| e.stopPropagation(); // 关键修复:阻止事件冒泡,避免触发Card的点击事件 |
| setDeleteResourceId(resourceList.resourceId); |
| setDeleteVisible(true); |
| }} |
| style={{backgroundColor: "rgba(255, 87, 51, 1)"}} |
| /> |
| </div> |
| </div> |
| </Card> |
| ))} |
| {totalResources > 5 && <Paginator |
| className="Paginator" |
| first={first} |
| rows={rows} |
| totalRecords={totalResources} |
| rowsPerPageOptions={[5, 10]} |
| onPageChange={onPageChange} |
| />} |
| </div> |
| |
| {/*删除资源时,获取用户密码弹窗*/} |
| <Dialog |
| header="删除资源" |
| visible={deleteVisible} |
| onHide={() => setDeleteVisible(false)} |
| className="resource-delete-dialog" |
| modal |
| footer={ |
| <div className="dialog-footer"> |
| <Button label="确认" icon="pi pi-check" onClick={handleDeleteSubmit} autoFocus /> |
| <Button label="取消" icon="pi pi-times" onClick={() => setDeleteVisible(false)} className="p-button-text" /> |
| </div> |
| } |
| > |
| <div className="dialog-form"> |
| <div className="form-field"> |
| <div className="form-field-header"> |
| <label htmlFor="name">密码</label> |
| </div> |
| <Password |
| id="passwrod" |
| value={deleteResourceFormData.password} |
| onChange={(e) => setDeleteResourceFormData(prev => ({ |
| ...prev, |
| password: e.target.value |
| }))} |
| placeholder="请输入密码" |
| className="w-full" |
| toggleMask |
| /> |
| </div> |
| </div> |
| </Dialog> |
| |
| {/*编辑资源弹窗*/} |
| <Dialog |
| header="编辑资源" |
| visible={editVisible} |
| onHide={() => setEditVisible(false)} |
| className="resource-edit-dialog" |
| modal |
| footer={ |
| <div className="dialog-footer"> |
| <Button label="确认" icon="pi pi-check" onClick={handleEditSubmit} autoFocus /> |
| <Button label="取消" icon="pi pi-times" onClick={() => setEditVisible(false)} className="p-button-text" /> |
| </div> |
| } |
| > |
| <div className="dialog-form"> |
| <div className="form-field"> |
| <div className="form-field-header"> |
| <label htmlFor="name">资源名称</label> |
| </div> |
| <InputText |
| id="name" |
| value={editResourceFormData.resourceName} |
| onChange={(e) => setEditResourceFormData(prev => ({ |
| ...prev, |
| resourceName: e.target.value |
| }))} |
| className="w-full" |
| /> |
| </div> |
| <div className="form-field"> |
| <div className="form-field-header"> |
| <label htmlFor="summary">资源简介</label> |
| </div> |
| <InputText |
| id="summary" |
| value={editResourceFormData.resourceSummary} |
| onChange={(e) => setEditResourceFormData(prev => ({ |
| ...prev, |
| resourceSummary: e.target.value |
| }))} |
| className="w-full" |
| /> |
| </div> |
| <div className="form-field"> |
| <div className="form-field-header"> |
| <label htmlFor="detail">资源介绍</label> |
| </div> |
| <InputTextarea |
| id="detail" |
| value={editResourceFormData.resourceDetail} |
| onChange={(e) => setEditResourceFormData(prev => ({ |
| ...prev, |
| resourceDetail: e.target.value |
| }))} |
| rows={5} |
| className="w-full" |
| /> |
| </div> |
| <div className="form-field"> |
| <div className="form-field-header"> |
| <label htmlFor="price">价格</label> |
| </div> |
| <InputText |
| id="price" |
| value={editResourceFormData?.price.toString()} |
| onChange={(e) => setEditResourceFormData(prev => ({ |
| ...prev, |
| price: e.target.value |
| }))} |
| className="w-full" |
| /> |
| </div> |
| <div className="form-field"> |
| <div className="form-field-header"> |
| <span className="form-field-sign">*</span> |
| <label>封面图片</label> |
| </div> |
| |
| <FileUpload |
| mode="advanced" |
| name="resource-image" |
| customUpload |
| |
| uploadHandler={async (e) => { |
| const formData = new FormData(); |
| formData.append("file", e.files[0]); |
| |
| try { |
| const res = await axios.post(`${process.env.PUBLIC_URL}/file`, formData); |
| |
| const fileUrl = res.data.url; |
| console.log(fileUrl); |
| setResourcePictureUrl(fileUrl); |
| toast.current?.show({ severity: 'success', summary: '上传成功' }); |
| } catch (error) { |
| console.log(error); |
| toast.current?.show({ severity: 'error', summary: '上传失败' }); |
| } |
| }} |
| auto |
| accept="image/*" |
| chooseLabel="选择资源封面" |
| /> |
| </div> |
| </div> |
| </Dialog> |
| </div> |
| ) |
| }; |