完成Work组件的界面和一些小修改
> 1. 修改优化路由守卫
> 2. 去除拦截器中的调试信息
> 3. 修改头部导航条下拉菜单的样式增加图标。
> 4. work组件现在使用mock数据

Change-Id: Ic602a35bb02e645a0d5253c5cbd12a68d70bfb33
diff --git a/src/feature/work/WorkComponents.tsx b/src/feature/work/WorkComponents.tsx
new file mode 100644
index 0000000..64ef37a
--- /dev/null
+++ b/src/feature/work/WorkComponents.tsx
@@ -0,0 +1,368 @@
+import React, { useState } from 'react';
+import { Card, Typography, Tag, Flex, Table, Collapse, List, Spin, Alert, Button, Input, Form, message } from 'antd';
+import { EditOutlined, SendOutlined } from '@ant-design/icons';
+import ReactMarkdown from 'react-markdown';
+import type { ColumnsType } from 'antd/es/table';
+import type { PaginationConfig } from 'antd/es/pagination';
+import type { FormInstance } from 'antd/es/form';
+import type { Comment, Version, User, HistoryUser } from './types';
+import { parseUploadSize } from './types';
+
+const { Title, Paragraph } = Typography;
+const { Panel } = Collapse;
+const { TextArea } = Input;
+
+// 作品封面组件
+export const ArtworkCover: React.FC<{ coverUrl: string }> = ({ coverUrl }) => (
+    <Card cover={<img alt="作品封面" src={coverUrl} style={{ height: 250, objectFit: 'cover' }} />} />
+);
+
+// 当前做种用户组件
+export const CurrentSeedingUsers: React.FC<{ users: User[] }> = ({ users }) => (
+    <Card>
+        <Title level={4} style={{ marginBottom: 12 }}>当前做种用户</Title>
+        <Flex wrap="wrap" gap={8}>
+            {users.map((user) => (
+                <Tag key={user.userId} color="green">{user.username}</Tag>
+            ))}
+        </Flex>
+    </Card>
+);
+
+// 历史做种用户组件
+export const HistorySeedingUsers: React.FC<{ users: HistoryUser[] }> = ({ users }) => {
+    const sortedUsers = [...users].sort((a, b) => parseUploadSize(b.uploadTotal) - parseUploadSize(a.uploadTotal));
+
+    const columns: ColumnsType<HistoryUser> = [
+        { title: '用户名', dataIndex: 'username', key: 'username' },
+        {
+            title: '上传总量',
+            dataIndex: 'uploadTotal',
+            key: 'uploadTotal',
+            sorter: (a: HistoryUser, b: HistoryUser) => parseUploadSize(a.uploadTotal) - parseUploadSize(b.uploadTotal),
+        },
+    ];
+
+    return (
+        <Card>
+            <Title level={4} style={{ marginBottom: 12 }}>历史做种用户</Title>
+            <Table columns={columns} dataSource={sortedUsers} rowKey="username" pagination={false} size="small" />
+        </Card>
+    );
+};
+
+// 作品描述组件
+export const ArtworkDescription: React.FC<{
+    name: string;
+    author: string;
+    category: string;
+    description: string;
+    isAuthor?: boolean;
+    onEdit?: () => void;
+}> = ({ name, author, category, description, isAuthor = false, onEdit }) => (
+    <Card style={{ marginBottom: 20 }}>
+        <Flex justify="space-between" align="flex-start">
+            <div style={{ flex: 1 }}>
+                <Title level={2} style={{ marginBottom: 8 }}>{name}</Title>
+                <Paragraph style={{ marginBottom: 8, fontSize: 16 }}>
+                    <strong>作者:</strong>{author}
+                </Paragraph>
+                <div style={{ marginBottom: 16 }}>
+                    <Tag color="blue">{category}</Tag>
+                </div>
+                <div style={{ lineHeight: 1.6 }}>
+                    <ReactMarkdown>{description}</ReactMarkdown>
+                </div>
+            </div>
+            {isAuthor && (
+                <Button type="primary" icon={<EditOutlined />} onClick={onEdit} style={{ marginLeft: 16 }}>
+                    编辑作品
+                </Button>
+            )}
+        </Flex>
+    </Card>
+);
+
+// 版本历史组件
+export const VersionHistory: React.FC<{ versions: Version[] }> = ({ versions }) => (
+    <Card title="版本历史" style={{ marginBottom: 20 }}>
+        <Collapse>
+            {versions.map((version, index) => (
+                <Panel
+                    header={`版本 ${version.version}`}
+                    key={`version-${index}`}
+                    extra={<Tag color="blue">v{version.version}</Tag>}
+                >
+                    <div style={{ marginBottom: 16 }}>
+                        <strong>版本描述:</strong>
+                        <div style={{ marginTop: 8, lineHeight: 1.6 }}>
+                            <ReactMarkdown>{version.versionDescription}</ReactMarkdown>
+                        </div>
+                    </div>
+                    <div>
+                        <strong>种子文件:</strong>
+                        <a href={version.seedFile} target="_blank" rel="noopener noreferrer" style={{ marginLeft: 8 }}>
+                            下载链接
+                        </a>
+                    </div>
+                </Panel>
+            ))}
+        </Collapse>
+    </Card>
+);
+
+// 评论项组件(递归)
+export const CommentItem: React.FC<{
+    comment: Comment;
+    level?: number;
+    onReply?: (parentId: string, parentAuthor: string) => void;
+}> = ({ comment, level = 0, onReply }) => (
+    <div style={{ marginLeft: level * 20 }}>
+        <div style={{ marginBottom: 8 }}>
+            <Paragraph style={{ marginBottom: 4 }}>
+                <strong>{comment.author}:</strong>{comment.content}
+            </Paragraph>
+            <div style={{ fontSize: 12, color: '#999', marginBottom: 4 }}>
+                {comment.createdAt && <span style={{ marginRight: 16 }}>{comment.createdAt}</span>}
+                {onReply && (
+                    <Button
+                        type="link"
+                        size="small"
+                        style={{ padding: 0, height: 'auto', fontSize: 12 }}
+                        onClick={() => onReply(comment.id || comment.author, comment.author)}
+                    >
+                        回复
+                    </Button>
+                )}
+            </div>
+        </div>
+        {comment.child && comment.child.length > 0 && (
+            <div style={{
+                borderLeft: level === 0 ? '2px solid #f0f0f0' : 'none',
+                paddingLeft: level === 0 ? 12 : 0
+            }}>
+                {comment.child.map((child, index) => (
+                    <CommentItem
+                        key={child.id || `child-${level}-${index}`}
+                        comment={child}
+                        level={level + 1}
+                        onReply={onReply}
+                    />
+                ))}
+            </div>
+        )}
+    </div>
+);
+
+// 发表评论组件
+export const CommentForm: React.FC<{
+    loading?: boolean;
+    onSubmit: (content: string, parentId?: string) => void;
+    replyTo?: { id: string; author: string } | null;
+    onCancelReply?: () => void;
+}> = ({ loading = false, onSubmit, replyTo, onCancelReply }) => {
+    const [form]: [FormInstance] = Form.useForm();
+    const [content, setContent] = useState('');
+
+    const handleSubmit = (): void => {
+        if (!content.trim()) {
+            message.warning('请输入评论内容');
+            return;
+        }
+        onSubmit(content.trim(), replyTo?.id);
+        setContent('');
+        form.resetFields();
+    };
+
+    const placeholder = replyTo ? `回复 @${replyTo.author}:` : "发表你的看法...";
+
+    return (
+        <Card
+            size="small"
+            style={{ marginBottom: 16 }}
+            title={replyTo ? (
+                <div style={{ fontSize: 14 }}>
+                    <span>回复 @{replyTo.author}</span>
+                    <Button type="link" size="small" onClick={onCancelReply} style={{ padding: '0 0 0 8px', fontSize: 12 }}>
+                        取消
+                    </Button>
+                </div>
+            ) : undefined}
+        >
+            <Form form={form} layout="vertical">
+                <Form.Item>
+                    <TextArea
+                        value={content}
+                        onChange={(e) => setContent(e.target.value)}
+                        placeholder={placeholder}
+                        rows={3}
+                        maxLength={500}
+                        showCount
+                    />
+                </Form.Item>
+                <Form.Item style={{ marginBottom: 0 }}>
+                    <Flex justify="flex-end" gap={8}>
+                        {replyTo && <Button onClick={onCancelReply}>取消</Button>}
+                        <Button
+                            type="primary"
+                            icon={<SendOutlined />}
+                            loading={loading}
+                            onClick={handleSubmit}
+                            disabled={!content.trim()}
+                        >
+                            {replyTo ? '发表回复' : '发表评论'}
+                        </Button>
+                    </Flex>
+                </Form.Item>
+            </Form>
+        </Card>
+    );
+};
+
+// 评论区组件
+export const CommentSection: React.FC<{
+    comments: Comment[];
+    total: number;
+    loading?: boolean;
+    error?: string | null;
+    addCommentLoading?: boolean;
+    onPageChange: (page: number, pageSize: number) => void;
+    onAddComment: (content: string, parentId?: string) => void;
+    currentPage: number;
+    pageSize: number;
+}> = ({ comments, total, loading, error, addCommentLoading, onPageChange, onAddComment, currentPage, pageSize }) => {
+    const [replyTo, setReplyTo] = useState<{ id: string; author: string } | null>(null);
+
+    const handleReply = (parentId: string, parentAuthor: string): void => {
+        setReplyTo({ id: parentId, author: parentAuthor });
+    };
+
+    const handleCancelReply = (): void => {
+        setReplyTo(null);
+    };
+
+    const handleSubmitComment = (content: string, parentId?: string): void => {
+        onAddComment(content, parentId);
+        setReplyTo(null);
+    };
+
+    const paginationConfig: PaginationConfig = {
+        current: currentPage,
+        pageSize,
+        total,
+        showSizeChanger: true,
+        showQuickJumper: true,
+        showTotal: (total, range) => `第 ${range[0]}-${range[1]} 条,共 ${total} 条评论`,
+        pageSizeOptions: ['5', '10', '20'],
+        onChange: onPageChange,
+        onShowSizeChange: onPageChange,
+    };
+
+    return (
+        <Card title={`评论 (${total})`} style={{ marginBottom: 20 }}>
+            <CommentForm
+                loading={addCommentLoading}
+                onSubmit={handleSubmitComment}
+                replyTo={replyTo}
+                onCancelReply={handleCancelReply}
+            />
+
+            {error ? (
+                <Alert message="加载评论失败" description={error} type="error" showIcon />
+            ) : loading ? (
+                <Flex justify="center" align="center" style={{ minHeight: 200 }}>
+                    <Spin size="large" />
+                </Flex>
+            ) : comments.length > 0 ? (
+                <List
+                    dataSource={comments}
+                    pagination={paginationConfig}
+                    renderItem={(comment, index) => (
+                        <List.Item
+                            key={comment.id || `comment-${index}`}
+                            style={{ border: 'none', padding: '16px 0', borderBottom: '1px solid #f0f0f0' }}
+                        >
+                            <CommentItem comment={comment} onReply={handleReply} />
+                        </List.Item>
+                    )}
+                />
+            ) : (
+                <Paragraph style={{ textAlign: 'center', color: '#999', margin: '20px 0' }}>
+                    暂无评论,来发表第一条评论吧!
+                </Paragraph>
+            )}
+        </Card>
+    );
+};
+
+// 侧边栏组合组件
+export const Sidebar: React.FC<{
+    coverUrl: string;
+    currentUsers: User[];
+    historyUsers: HistoryUser[];
+    loading?: boolean;
+    error?: string | null;
+}> = ({ coverUrl, currentUsers, historyUsers, loading, error }) => (
+    <Flex flex={1} vertical gap={20}>
+        <ArtworkCover coverUrl={coverUrl} />
+        {loading ? (
+            <Flex justify="center" align="center" style={{ minHeight: 200 }}>
+                <Spin size="large" />
+            </Flex>
+        ) : error ? (
+            <Alert message="加载用户信息失败" description={error} type="error" showIcon />
+        ) : (
+            <>
+                <CurrentSeedingUsers users={currentUsers} />
+                <HistorySeedingUsers users={historyUsers} />
+            </>
+        )}
+    </Flex>
+);
+
+// 主内容区组合组件
+export const MainContent: React.FC<{
+    artworkName: string;
+    author: string;
+    category: string;
+    description: string;
+    versions: Version[];
+    comments: Comment[];
+    commentsTotal: number;
+    commentsLoading?: boolean;
+    commentsError?: string | null;
+    addCommentLoading?: boolean;
+    onCommentsPageChange: (page: number, pageSize: number) => void;
+    onAddComment: (content: string, parentId?: string) => void;
+    currentPage: number;
+    pageSize: number;
+    isAuthor?: boolean;
+    onEditArtwork?: () => void;
+}> = ({
+    artworkName, author, category, description, versions, comments, commentsTotal,
+    commentsLoading, commentsError, addCommentLoading, onCommentsPageChange, onAddComment,
+    currentPage, pageSize, isAuthor, onEditArtwork
+}) => (
+        <Flex flex={4} vertical>
+            <ArtworkDescription
+                name={artworkName}
+                author={author}
+                category={category}
+                description={description}
+                isAuthor={isAuthor}
+                onEdit={onEditArtwork}
+            />
+            <VersionHistory versions={versions} />
+            <CommentSection
+                comments={comments}
+                total={commentsTotal}
+                loading={commentsLoading}
+                error={commentsError}
+                addCommentLoading={addCommentLoading}
+                onPageChange={onCommentsPageChange}
+                onAddComment={onAddComment}
+                currentPage={currentPage}
+                pageSize={pageSize}
+            />
+        </Flex>
+    );
\ No newline at end of file