2025-09-05 20:46:03 +08:00
|
|
|
import { useState } from "react";
|
2025-09-08 09:32:40 +08:00
|
|
|
import { Tooltip } from "@arco-design/web-react";
|
2025-09-05 20:46:03 +08:00
|
|
|
import toast from "@/components/Toast";
|
|
|
|
|
import InfiniteScroll from "@/components/InfiniteScroll";
|
|
|
|
|
import ProjectCasesModal from "./components/ProjectCasesModal";
|
|
|
|
|
import { getProjectsList, getProjectsdetail } from "@/services/projectLibrary";
|
2025-09-08 09:32:40 +08:00
|
|
|
// 我的项目库数据
|
|
|
|
|
const myProjectsData = [
|
|
|
|
|
{
|
|
|
|
|
unitName: "商业活动策略设计与创意策划",
|
|
|
|
|
projects: [
|
|
|
|
|
"校园特色摆摊创意策划与出摊运营项目",
|
|
|
|
|
"社区水果店节日促销创意方案设计与落地执行项目"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
unitName: "商业活动全程策划执行与运营优化",
|
|
|
|
|
projects: [
|
|
|
|
|
"社区便利店促销活动策划落地项目",
|
|
|
|
|
"校园二手物品交易活动策划执行与运营项目"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
unitName: "商业空间与文创产品设计",
|
|
|
|
|
projects: [
|
|
|
|
|
"街边小型咖啡馆主题空间布置与配套文创周边设计项目",
|
|
|
|
|
"社区书店文创体验区空间规划项目"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
unitName: "短视频与自媒体运营",
|
|
|
|
|
projects: [
|
|
|
|
|
"本地某餐厅生活服务新媒体账号运营项目",
|
|
|
|
|
"某猫咖宠物日常类短视频账号运营实操项目"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
unitName: "漫展与二次元活动策划与执行",
|
|
|
|
|
projects: [
|
|
|
|
|
"南京 Comic Festival 周边展区活动统筹项目",
|
|
|
|
|
"盐城 ICGC 动漫嘉年华品牌互动区运营项目"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
unitName: "户外音乐节主题策划与流程统筹",
|
|
|
|
|
projects: [
|
|
|
|
|
"青春旋律校园户外音乐节活动策划与实施项目",
|
|
|
|
|
"环湖露天音乐节活动策划与组织项目"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
unitName: "城市 IP 赛事活动整合与策划",
|
|
|
|
|
projects: [
|
|
|
|
|
"2025 城市电竞对抗赛整体策划与落地项目",
|
|
|
|
|
"城市龙舟赛活动统筹与文化主题策划项目",
|
|
|
|
|
"成都跑酷&街舞跨界赛事活动策划与组织项目"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
unitName: "消费电子展品牌策划与执行",
|
|
|
|
|
projects: [
|
|
|
|
|
"智能穿戴设备消费电子展展区策划与执行项目",
|
|
|
|
|
"智能生活类消费电子展策划项目"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
unitName: "品牌招商展全案策划与招商运营",
|
|
|
|
|
projects: [
|
|
|
|
|
"苏州文旅文创产业品牌招商展策划与落地运营项目",
|
|
|
|
|
"南京青年创客品牌招商展策划项目"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
unitName: "商业街区打卡空间视觉呈现",
|
|
|
|
|
projects: [
|
|
|
|
|
"南京老门东历史街区创意打卡点策划项目",
|
|
|
|
|
"苏州观前街沉浸式商业打卡体验空间设计项目",
|
|
|
|
|
"无锡拈花湾文旅商业街区夜景灯光打卡点策划项目"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
unitName: "文旅衍生文创产品设计",
|
|
|
|
|
projects: [
|
|
|
|
|
"南京云锦纹样衍生丝巾与服饰配件设计项目",
|
|
|
|
|
"苏州园林拙政园窗棂纹样衍生文创书签与文具设计项目"
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
];
|
2025-09-05 20:46:03 +08:00
|
|
|
import "./index.css";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const PAGE_SIZE = 10;
|
|
|
|
|
|
|
|
|
|
const ProjectLibrary = () => {
|
2025-09-08 09:32:40 +08:00
|
|
|
// 处理我的项目数据
|
|
|
|
|
const processMyProjects = () => {
|
|
|
|
|
const projects = [];
|
|
|
|
|
myProjectsData.forEach(unit => {
|
|
|
|
|
unit.projects.forEach(projectName => {
|
|
|
|
|
projects.push({
|
|
|
|
|
id: `my-${projects.length + 1}`,
|
|
|
|
|
unitName: unit.unitName,
|
|
|
|
|
name: projectName,
|
|
|
|
|
isMyProject: true
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
return projects;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const myProjects = processMyProjects();
|
2025-09-05 20:46:03 +08:00
|
|
|
const [modalData, setModalData] = useState(undefined);
|
|
|
|
|
const [projectList, setProjectList] = useState([]);
|
|
|
|
|
const [projectCasesModalVisible, setProjectCasesModalVisible] =
|
|
|
|
|
useState(false);
|
|
|
|
|
const [page, setPage] = useState(1);
|
|
|
|
|
const [hasMore, setHasMore] = useState(true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleProjectClick = async (item) => {
|
2025-09-08 09:32:40 +08:00
|
|
|
// 如果是我的项目,不允许点击
|
|
|
|
|
if (item?.isMyProject) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-05 20:46:03 +08:00
|
|
|
if (item?.id) {
|
|
|
|
|
const res = await getProjectsdetail(item.id);
|
|
|
|
|
if (res.success) {
|
|
|
|
|
setModalData(res.data);
|
|
|
|
|
setProjectCasesModalVisible(true);
|
|
|
|
|
} else {
|
|
|
|
|
toast.error(res.message);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
toast.error("加载数据失败,请刷新重试");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleCloseModal = () => {
|
|
|
|
|
setProjectCasesModalVisible(false);
|
|
|
|
|
setModalData(undefined);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const fetchProjects = async (pageNum) => {
|
|
|
|
|
try {
|
|
|
|
|
const res = await getProjectsList({
|
|
|
|
|
page: pageNum ?? page,
|
|
|
|
|
pageSize: PAGE_SIZE,
|
|
|
|
|
});
|
|
|
|
|
if (res.success) {
|
|
|
|
|
setProjectList((prevList) => {
|
|
|
|
|
const newList = [...prevList, ...res.data];
|
|
|
|
|
if (res.total === newList?.length) {
|
|
|
|
|
setHasMore(false);
|
|
|
|
|
} else {
|
|
|
|
|
setPage((prevPage) => prevPage + 1);
|
|
|
|
|
}
|
|
|
|
|
return newList;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to fetch projects:", error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="project-library-page">
|
|
|
|
|
<div className="project-library-wrapper">
|
|
|
|
|
<p className="project-library-title">文旅班级项目库</p>
|
|
|
|
|
<InfiniteScroll
|
|
|
|
|
loadMore={fetchProjects}
|
|
|
|
|
hasMore={hasMore}
|
|
|
|
|
empty={projectList.length === 0}
|
|
|
|
|
className="project-library-list"
|
|
|
|
|
>
|
|
|
|
|
{projectList.map((item) => (
|
|
|
|
|
<li className="project-library-item" key={item.id}>
|
|
|
|
|
<p className="project-library-item-title">{item.description}</p>
|
|
|
|
|
<div>
|
|
|
|
|
<p>{item.name}</p>
|
|
|
|
|
<span onClick={() => handleProjectClick(item)}>详情 ></span>
|
|
|
|
|
</div>
|
|
|
|
|
</li>
|
|
|
|
|
))}
|
|
|
|
|
</InfiniteScroll>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* 我的项目库板块 */}
|
|
|
|
|
<div className="project-library-wrapper my-project-library">
|
|
|
|
|
<p className="project-library-title">我完成的项目库</p>
|
2025-09-08 09:32:40 +08:00
|
|
|
<div className="project-library-list">
|
|
|
|
|
{myProjects.map((item) => (
|
|
|
|
|
<Tooltip
|
|
|
|
|
key={item.id}
|
|
|
|
|
content="非学员及导师无查看权限"
|
|
|
|
|
position="top"
|
|
|
|
|
>
|
|
|
|
|
<li className="project-library-item my-project-item">
|
|
|
|
|
<p className="project-library-item-title">{item.unitName}</p>
|
|
|
|
|
<div>
|
|
|
|
|
<p>{item.name}</p>
|
|
|
|
|
<span className="disabled-detail">详情 ></span>
|
|
|
|
|
</div>
|
|
|
|
|
</li>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
))}
|
2025-09-05 20:46:03 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<ProjectCasesModal
|
|
|
|
|
data={modalData}
|
|
|
|
|
visible={projectCasesModalVisible}
|
|
|
|
|
onClose={handleCloseModal}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default ProjectLibrary;
|