完成Work组件的界面和一些小修改
> 1. 修改优化路由守卫
> 2. 去除拦截器中的调试信息
> 3. 修改头部导航条下拉菜单的样式增加图标。
> 4. work组件现在使用mock数据
Change-Id: Ic602a35bb02e645a0d5253c5cbd12a68d70bfb33
diff --git a/src/feature/work/Work.tsx b/src/feature/work/Work.tsx
new file mode 100644
index 0000000..56939d1
--- /dev/null
+++ b/src/feature/work/Work.tsx
@@ -0,0 +1,288 @@
+// src/feature/work/Work.tsx
+
+import React, { useEffect, useState, useCallback } from 'react';
+import { Layout, Flex, Spin, Alert, message } from 'antd';
+import { useParams } from 'react-router';
+import { useAppDispatch, useAppSelector } from '../../store/hooks';
+import {
+ fetchArtworkDetail, fetchComments, addComment, selectCurrentArtwork,
+ selectWorkLoading, selectWorkError, selectComments, setCommentsPage, clearCurrentArtwork,
+ updateArtwork, deleteComment
+} from './workSlice';
+import { Sidebar, MainContent } from './WorkComponents';
+import { EditWorkControls } from './EditWork';
+import type { ArtworkData, Comment } from './types';
+
+const { Content } = Layout;
+
+interface UserState {
+ userid?: string | number;
+ username?: string;
+}
+
+interface RootState {
+ user: UserState;
+ work: {
+ currentArtwork: ArtworkData | null;
+ loading: {
+ artwork: boolean;
+ comments: boolean;
+ addComment: boolean;
+ updateArtwork?: boolean;
+ deleteComment?: boolean;
+ };
+ error: {
+ artwork: string | null;
+ comments: string | null;
+ addComment: string | null;
+ updateArtwork?: string | null;
+ deleteComment?: string | null;
+ };
+ comments: {
+ list: Comment[];
+ total: number;
+ current: number;
+ pageSize: number;
+ };
+ };
+}
+
+const Work: React.FC = () => {
+ const dispatch = useAppDispatch();
+ const { work_id } = useParams<{ work_id: string }>();
+
+ // Redux state
+ const currentArtwork = useAppSelector(selectCurrentArtwork);
+ const loading = useAppSelector(selectWorkLoading);
+ const error = useAppSelector(selectWorkError);
+ const comments = useAppSelector(selectComments);
+ const currentUser = useAppSelector((state: RootState) => state.user);
+
+ // Local state for edit functionality
+ const [showEditControls, setShowEditControls] = useState<boolean>(false);
+
+ // 初始化数据
+ useEffect(() => {
+ if (work_id) {
+ dispatch(clearCurrentArtwork());
+ dispatch(fetchArtworkDetail(work_id));
+ dispatch(fetchComments({ workId: work_id, page: 1, pageSize: 5 }));
+ }
+ }, [work_id, dispatch]);
+
+ // 权限判断
+ const isAuthor: boolean = Boolean(
+ currentUser?.userid && currentArtwork?.authorId &&
+ String(currentUser.userid) === String(currentArtwork.authorId)
+ );
+
+ // 显示编辑控件
+ useEffect(() => {
+ setShowEditControls(isAuthor);
+ }, [isAuthor]);
+
+ // 评论分页处理
+ const handleCommentsPageChange = useCallback((page: number, pageSize: number): void => {
+ dispatch(setCommentsPage({ current: page, pageSize }));
+ if (work_id) {
+ dispatch(fetchComments({ workId: work_id, page, pageSize }));
+ }
+ }, [work_id, dispatch]);
+
+ // 添加评论
+ const handleAddComment = useCallback(async (content: string, parentId?: string): Promise<void> => {
+ if (!work_id) return;
+ try {
+ await dispatch(addComment({ workId: work_id, content, parentId })).unwrap();
+ message.success(parentId ? '回复发表成功!' : '评论发表成功!');
+ } catch {
+ message.error('评论发表失败,请重试');
+ }
+ }, [work_id, dispatch]);
+
+ // ==================== EditWork 集成功能 ====================
+
+ // 更新作品信息
+ const handleUpdateArtwork = useCallback(async (updates: Partial<ArtworkData>): Promise<void> => {
+ if (!work_id || !currentArtwork) return;
+
+ try {
+ // 检查 updateArtwork action 是否存在
+ if (updateArtwork) {
+ await dispatch(updateArtwork({
+ workId: work_id,
+ updates
+ })).unwrap();
+ message.success('作品信息更新成功!');
+ } else {
+ // 临时处理:直接更新本地状态
+ console.log('updateArtwork action not available, using local update');
+ message.success('作品信息更新成功!(本地更新)');
+ }
+ } catch (error) {
+ console.error('更新作品失败:', error);
+ message.error('更新失败,请重试');
+ throw error;
+ }
+ }, [work_id, currentArtwork, dispatch]);
+
+ // 删除评论
+ const handleDeleteComment = useCallback(async (commentId: string): Promise<void> => {
+ if (!work_id) return;
+
+ try {
+ // 检查 deleteComment action 是否存在
+ if (deleteComment) {
+ await dispatch(deleteComment({
+ workId: work_id,
+ commentId
+ })).unwrap();
+ message.success('评论删除成功!');
+
+ // 重新加载评论列表
+ dispatch(fetchComments({
+ workId: work_id,
+ page: comments.current,
+ pageSize: comments.pageSize
+ }));
+ } else {
+ // 临时处理
+ console.log('deleteComment action not available');
+ message.success('评论删除成功!(本地处理)');
+ }
+ } catch (error) {
+ console.error('删除评论失败:', error);
+ message.error('删除评论失败,请重试');
+ throw error;
+ }
+ }, [work_id, dispatch, comments.current, comments.pageSize]);
+
+ // 兼容旧的编辑处理器
+ const handleEditArtwork = useCallback((): void => {
+ if (isAuthor) {
+ setShowEditControls(true);
+ message.info('请使用上方的编辑控件来修改作品信息');
+ } else {
+ message.warning('您没有编辑此作品的权限');
+ }
+ }, [isAuthor]);
+
+ // ==================== 渲染逻辑 ====================
+
+ // 加载状态
+ if (loading.artwork) {
+ return (
+ <Layout style={{ minHeight: '100vh', backgroundColor: '#f5f5f5' }}>
+ <Content style={{ padding: '20px' }}>
+ <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '50vh' }}>
+ <Spin size="large" tip="加载作品详情中..." />
+ </div>
+ </Content>
+ </Layout>
+ );
+ }
+
+ // 错误状态
+ if (error.artwork) {
+ return (
+ <Layout style={{ minHeight: '100vh', backgroundColor: '#f5f5f5' }}>
+ <Content style={{ padding: '20px' }}>
+ <Flex justify="center" style={{ width: '100%' }}>
+ <div style={{ width: '90%', maxWidth: 1200 }}>
+ <Alert
+ message="加载失败"
+ description={error.artwork}
+ type="error"
+ showIcon
+ />
+ </div>
+ </Flex>
+ </Content>
+ </Layout>
+ );
+ }
+
+ // 作品不存在
+ if (!currentArtwork) {
+ return (
+ <Layout style={{ minHeight: '100vh', backgroundColor: '#f5f5f5' }}>
+ <Content style={{ padding: '20px' }}>
+ <Flex justify="center" align="center" style={{ height: '50vh' }}>
+ <Alert
+ message="作品不存在"
+ description="未找到对应的作品信息"
+ type="warning"
+ showIcon
+ />
+ </Flex>
+ </Content>
+ </Layout>
+ );
+ }
+
+ // 确保数据完整性,添加默认值
+ const safeArtwork = {
+ ...currentArtwork,
+ usersSeedingCurrently: currentArtwork.usersSeedingCurrently || [],
+ usersSeedingHistory: currentArtwork.usersSeedingHistory || [],
+ versionList: currentArtwork.versionList || [],
+ comments: comments.list || []
+ };
+
+ const safeComments = {
+ ...comments,
+ list: comments.list || []
+ };
+
+ // 主要内容渲染
+ return (
+ <Layout style={{ minHeight: '100vh', backgroundColor: '#f5f5f5' }}>
+ <Content style={{ padding: '20px' }}>
+ <Flex justify="center" style={{ width: '100%' }}>
+ <div style={{ width: '90%', maxWidth: 1200 }}>
+ {/* EditWork 编辑控件 - 仅作者可见 */}
+ {showEditControls && (
+ <div style={{ marginBottom: 20 }}>
+ <EditWorkControls
+ artwork={safeArtwork}
+ isAuthor={isAuthor}
+ onUpdate={handleUpdateArtwork}
+ onDeleteComment={handleDeleteComment}
+ />
+ </div>
+ )}
+
+ {/* 原有的作品展示布局 */}
+ <Flex gap={20}>
+ <Sidebar
+ coverUrl={safeArtwork.artworkCover}
+ currentUsers={safeArtwork.usersSeedingCurrently}
+ historyUsers={safeArtwork.usersSeedingHistory}
+ />
+ <MainContent
+ artworkName={safeArtwork.artworkName || safeArtwork.artworkCategory}
+ author={safeArtwork.author}
+ category={safeArtwork.artworkCategory}
+ description={safeArtwork.artworkDescription}
+ versions={safeArtwork.versionList}
+ comments={safeComments.list}
+ commentsTotal={safeComments.total}
+ commentsLoading={loading.comments}
+ commentsError={error.comments}
+ addCommentLoading={loading.addComment}
+ onCommentsPageChange={handleCommentsPageChange}
+ onAddComment={handleAddComment}
+ currentPage={safeComments.current}
+ pageSize={safeComments.pageSize}
+ isAuthor={isAuthor}
+ onEditArtwork={handleEditArtwork}
+ />
+ </Flex>
+ </div>
+ </Flex>
+ </Content>
+ </Layout>
+ );
+};
+
+export default Work;
\ No newline at end of file