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

Change-Id: Ic602a35bb02e645a0d5253c5cbd12a68d70bfb33
diff --git a/src/feature/auth/authSlice.ts b/src/feature/auth/authSlice.ts
index 607a6fd..289ce16 100644
--- a/src/feature/auth/authSlice.ts
+++ b/src/feature/auth/authSlice.ts
@@ -1,5 +1,7 @@
+// src/feature/auth/authSlice.ts
+
 import { createAsyncThunk, createSlice, type PayloadAction } from "@reduxjs/toolkit";
-import type { AuthState } from "../../store/types";
+import type { AuthState } from "./types";
 import type { LoginRequest } from "../../api/Auth/type";
 import AuthAPI from "../../api/Auth/AuthApi";
 
@@ -9,9 +11,9 @@
 const initialState: AuthState = {
   token: storedToken || '',
   loading: false,
-  isAuth: false,
-  error: ''
-}
+  isAuth: !!storedToken, // 如果有token就设为true
+  error: '',
+};
 
 export const loginUser = createAsyncThunk<
   {token: string},
@@ -33,17 +35,47 @@
   }
 );
 
+// 新增:从localStorage恢复登录状态
+export const loginFromLocalStorage = createAsyncThunk<
+  {token: string} | {empty: true},
+  void,
+  { rejectValue: string }
+>(
+  'auth/loginFromLocalStorage',
+  async (_, { rejectWithValue, dispatch }) => {
+    try {
+      const token = localStorage.getItem('token');
+      if (!token) {
+        // 返回空状态而不是错误
+        return { empty: true };
+      }
+      
+      // 直接使用refreshToken来验证token有效性
+      const result = await dispatch(refreshToken(token));
+      if (refreshToken.fulfilled.match(result)) {
+        // refresh成功,返回新的token
+        return { token: result.payload.token };
+      } else {
+        // refresh失败,token无效
+        localStorage.removeItem('token');
+        return rejectWithValue('token已失效,需要重新登录');
+      }
+    } catch {
+      localStorage.removeItem('token');
+      return rejectWithValue('恢复登录状态失败');
+    }
+  }
+);
+
 export const refreshToken = createAsyncThunk<
   {token: string},
   string,
   { rejectValue: string }
 >(
-
   'auth/refresh',
   async (oldToken: string, { rejectWithValue }) => {
     try {
       const response = await AuthAPI.refreshToken(oldToken);
-      console.log(response);
       if(response.data.code == 0)
         return {token: response.data.data};
       else 
@@ -61,42 +93,77 @@
     logout: (state) => {
       state.token = '';
       state.isAuth = false;
-      localStorage.clear()
-    },
-  },extraReducers: (builder) => {
-      // 处理登录的异步操作
-      builder
-        .addCase(loginUser.pending, (state) => {
-          state.loading = true;
-        })
-        .addCase(loginUser.fulfilled, (state, action: PayloadAction<{token: string}>) => {
-          state.loading = false;
-          state.token = action.payload.token;
-          state.isAuth = true;
-
-          localStorage.setItem('token', state.token);
-        })
-        .addCase(loginUser.rejected, (state, action) => {
-          state.loading = false;
-          state.error = action.payload ? action.payload : '' // 错误处理
-        })
-
-        // 处理刷新 token 的异步操作
-        .addCase(refreshToken.pending, (state) => {
-          state.loading = true;
-        })
-        .addCase(refreshToken.fulfilled, (state, action) => {
-          state.loading = false;
-          state.token = action.payload.token; 
-          localStorage.setItem('token', state.token);
-        })
-        .addCase(refreshToken.rejected, (state, action) => {
-          state.loading = false;
-          state.error = action.payload ? action.payload : ''
-        });
+      localStorage.clear();
     },
     
+    // 清除错误信息
+    clearError: (state) => {
+      state.error = '';
+    },
+  },
+  extraReducers: (builder) => {
+    // 处理普通登录的异步操作
+    builder
+      .addCase(loginUser.pending, (state) => {
+        state.loading = true;
+        state.error = '';
+      })
+      .addCase(loginUser.fulfilled, (state, action: PayloadAction<{token: string}>) => {
+        state.loading = false;
+        state.token = action.payload.token;
+        state.isAuth = true;
+        localStorage.setItem('token', state.token);
+      })
+      .addCase(loginUser.rejected, (state, action) => {
+        state.loading = false;
+        state.error = action.payload ? action.payload : '';
+      });
+      
+    // 处理从localStorage恢复登录状态
+    builder
+      .addCase(loginFromLocalStorage.pending, (state) => {
+        state.loading = true;
+        state.error = '';
+      })
+      .addCase(loginFromLocalStorage.fulfilled, (state, action) => {
+        state.loading = false;
+        if ('token' in action.payload) {
+          // 有token的情况
+          state.token = action.payload.token;
+          state.isAuth = true;
+        } else {
+          // 空token的情况
+          state.token = '';
+          state.isAuth = false;
+        }
+      })
+      .addCase(loginFromLocalStorage.rejected, (state, action) => {
+        state.loading = false;
+        state.token = '';
+        state.isAuth = false;
+        state.error = action.payload ? action.payload : '';
+        localStorage.removeItem('token');
+      });
+      
+    // 处理刷新 token 的异步操作
+    builder
+      .addCase(refreshToken.pending, (state) => {
+        state.loading = true;
+        state.error = '';
+      })
+      .addCase(refreshToken.fulfilled, (state, action) => {
+        state.loading = false;
+        state.token = action.payload.token;
+        state.isAuth = true;
+        localStorage.setItem('token', state.token);
+      })
+      .addCase(refreshToken.rejected, (state, action) => {
+        state.loading = false;
+        state.error = action.payload ? action.payload : '';
+        state.isAuth = false;
+      });
+  },
 });
 
-export const { logout } = authSlice.actions;
+export const { logout, clearError } = authSlice.actions;
 export default authSlice.reducer;
\ No newline at end of file
diff --git a/src/feature/auth/types.ts b/src/feature/auth/types.ts
new file mode 100644
index 0000000..6d91e01
--- /dev/null
+++ b/src/feature/auth/types.ts
@@ -0,0 +1,7 @@
+// 定义认证状态
+export interface AuthState {
+    token: string;
+    loading: boolean;
+    isAuth: boolean;
+    error: string
+}
\ No newline at end of file
diff --git a/src/feature/Home.tsx b/src/feature/home/Home.tsx
similarity index 100%
rename from src/feature/Home.tsx
rename to src/feature/home/Home.tsx
diff --git a/src/feature/user/userSlice.ts b/src/feature/user/userSlice.ts
index d6200af..c3f7e44 100644
--- a/src/feature/user/userSlice.ts
+++ b/src/feature/user/userSlice.ts
@@ -32,12 +32,8 @@
     async (_, { rejectWithValue }) => {
         const response = await UserAPi.getMe();
         if (response.data.code == 0) {
-            console.log("xixi")
-            console.log(response)
             return response.data.data;
         } else {
-            console.log("buxixi")
-            console.log(response)
             return rejectWithValue(response.data.message);
         }
     } 
diff --git a/src/feature/work/CreatWorkComponents.tsx b/src/feature/work/CreatWorkComponents.tsx
new file mode 100644
index 0000000..12766ee
--- /dev/null
+++ b/src/feature/work/CreatWorkComponents.tsx
@@ -0,0 +1,545 @@
+import React, { useState, useCallback } from 'react';
+import {
+    Form, Input, Select, Upload, Button, Card, message, Space, Modal,
+    Divider, Row, Col, Typography, Alert, List, Tag,
+    type FormInstance
+} from 'antd';
+import {
+    PlusOutlined, InboxOutlined, DeleteOutlined, EditOutlined,
+    CheckCircleOutlined, SendOutlined, FileTextOutlined
+} from '@ant-design/icons';
+import ReactMarkdown from 'react-markdown';
+import type {
+    UploadFile, UploadProps, UploadChangeParam, RcFile,
+} from 'antd/es/upload';
+import { type StepFormProps, type BasicInfo, ARTWORK_CATEGORIES, type VersionFormData } from './types';
+import { getBase64 } from './utils';
+
+const { TextArea } = Input;
+const { Dragger } = Upload;
+const { Title, Text, Paragraph } = Typography;
+
+// ==================== 描述组件 ====================
+interface DescriptionsProps {
+    bordered?: boolean;
+    column?: number;
+    children: React.ReactNode;
+}
+
+interface DescriptionsItemProps {
+    label: string;
+    children: React.ReactNode;
+}
+
+export const Descriptions: React.FC<DescriptionsProps> & {
+    Item: React.FC<DescriptionsItemProps>;
+} = ({ children }) => {
+    return <div style={{ marginBottom: 16 }}>{children}</div>;
+};
+
+Descriptions.Item = ({ label, children }: DescriptionsItemProps) => {
+    return (
+        <div style={{ marginBottom: 12 }}>
+            <Text strong style={{ marginRight: 16 }}>{label}:</Text>
+            <span>{children}</span>
+        </div>
+    );
+};
+
+// ==================== 步骤1:基础信息 ====================
+export const BasicInfoStep: React.FC<StepFormProps> = ({ data, onUpdate, onNext }) => {
+    const [form]: [FormInstance<BasicInfo>] = Form.useForm<BasicInfo>();
+    const [previewMode, setPreviewMode] = useState<boolean>(false);
+
+    const handleFinish = useCallback((values: BasicInfo) => {
+        onUpdate('basicInfo', values);
+        onNext?.();
+    }, [onUpdate, onNext]);
+
+    const handlePreview = useCallback(() => {
+        form.validateFields().then((values) => {
+            onUpdate('basicInfo', values);
+            setPreviewMode(true);
+        }).catch(() => {
+            message.error('请先填写完整信息');
+        });
+    }, [form, onUpdate]);
+
+    return (
+        <>
+            <Card>
+                <Form form={form} layout="vertical" initialValues={data.basicInfo} onFinish={handleFinish} autoComplete="off">
+                    <Form.Item
+                        label="作品名称"
+                        name="artworkName"
+                        rules={[
+                            { required: true, message: '请输入作品名称' },
+                            { min: 2, message: '作品名称至少2个字符' },
+                            { max: 50, message: '作品名称最多50个字符' },
+                        ]}
+                    >
+                        <Input placeholder="请输入作品名称,例如:未来城市概念设计" size="large" showCount maxLength={50} />
+                    </Form.Item>
+
+                    <Form.Item label="作品分类" name="artworkCategory" rules={[{ required: true, message: '请选择作品分类' }]}>
+                        <Select placeholder="请选择作品分类" size="large" options={ARTWORK_CATEGORIES} />
+                    </Form.Item>
+
+                    <Form.Item
+                        label="作品描述"
+                        name="artworkDescription"
+                        rules={[
+                            { required: true, message: '请输入作品描述' },
+                            { min: 20, message: '作品描述至少20个字符' },
+                            { max: 2000, message: '作品描述最多2000个字符' },
+                        ]}
+                        extra="支持 Markdown 格式,可以使用 # 标题、**粗体**、*斜体* 等格式"
+                    >
+                        <TextArea
+                            placeholder="请详细描述你的作品,包括创作理念、技术特点、使用说明等"
+                            rows={10}
+                            showCount
+                            maxLength={2000}
+                        />
+                    </Form.Item>
+
+                    <Form.Item>
+                        <Space size="middle">
+                            <Button type="primary" htmlType="submit" size="large">下一步</Button>
+                            <Button onClick={handlePreview} size="large">预览描述</Button>
+                        </Space>
+                    </Form.Item>
+                </Form>
+            </Card>
+
+            <Modal title="作品描述预览" open={previewMode} onCancel={() => setPreviewMode(false)} footer={null} width={800}>
+                <div style={{ maxHeight: '60vh', overflow: 'auto' }}>
+                    <ReactMarkdown>{form.getFieldValue('artworkDescription') || ''}</ReactMarkdown>
+                </div>
+            </Modal>
+        </>
+    );
+};
+
+// ==================== 步骤2:封面上传 ====================
+export const CoverUploadStep: React.FC<StepFormProps> = ({ data, onUpdate, onNext, onPrev }) => {
+    const [fileList, setFileList] = useState<UploadFile[]>(data.coverInfo.coverFile ? [data.coverInfo.coverFile] : []);
+    const [previewImage, setPreviewImage] = useState<string>('');
+    const [previewOpen, setPreviewOpen] = useState<boolean>(false);
+
+    const handleChange: UploadProps['onChange'] = useCallback((info: UploadChangeParam<UploadFile>) => {
+        const { fileList: newFileList } = info;
+        setFileList(newFileList);
+        onUpdate('coverInfo', { coverFile: newFileList[0] });
+    }, [onUpdate]);
+
+    const handlePreview = useCallback(async (file: UploadFile): Promise<void> => {
+        if (!file.url && !file.preview) {
+            file.preview = await getBase64(file.originFileObj as RcFile);
+        }
+        setPreviewImage(file.url || (file.preview as string));
+        setPreviewOpen(true);
+    }, []);
+
+    const beforeUpload = useCallback((file: RcFile): boolean => {
+        const isImage = file.type.startsWith('image/');
+        if (!isImage) {
+            message.error('只能上传图片文件!');
+            return false;
+        }
+        const isLt5M = file.size / 1024 / 1024 < 5;
+        if (!isLt5M) {
+            message.error('图片大小不能超过 5MB!');
+            return false;
+        }
+        return false;
+    }, []);
+
+    const handleNext = useCallback((): void => {
+        if (fileList.length === 0) {
+            message.error('请上传作品封面');
+            return;
+        }
+        onNext?.();
+    }, [fileList, onNext]);
+
+    return (
+        <Card>
+            <Alert
+                message="封面图片要求"
+                description={
+                    <ul style={{ marginBottom: 0, paddingLeft: 20 }}>
+                        <li>图片格式:JPG、PNG、GIF</li>
+                        <li>图片大小:不超过 5MB</li>
+                        <li>建议尺寸:宽高比 3:4,最小分辨率 600x800</li>
+                        <li>内容要求:清晰展示作品特色,避免模糊或像素化</li>
+                    </ul>
+                }
+                type="info"
+                showIcon
+                style={{ marginBottom: 24 }}
+            />
+
+            <Upload
+                listType="picture-card"
+                fileList={fileList}
+                onChange={handleChange}
+                onPreview={handlePreview}
+                beforeUpload={beforeUpload}
+                maxCount={1}
+                accept="image/*"
+            >
+                {fileList.length === 0 && (
+                    <div>
+                        <PlusOutlined />
+                        <div style={{ marginTop: 8 }}>上传封面</div>
+                    </div>
+                )}
+            </Upload>
+
+            <Modal open={previewOpen} title="封面预览" footer={null} onCancel={() => setPreviewOpen(false)}>
+                <img alt="封面预览" style={{ width: '100%' }} src={previewImage} />
+            </Modal>
+
+            <Divider />
+            <Space size="middle">
+                <Button onClick={onPrev} size="large">上一步</Button>
+                <Button type="primary" onClick={handleNext} size="large">下一步</Button>
+            </Space>
+        </Card>
+    );
+};
+
+// ==================== 版本管理相关组件 ====================
+const VersionItem: React.FC<{
+    version: VersionFormData;
+    index: number;
+    onEdit: (index: number) => void;
+    onDelete: (index: number) => void;
+}> = ({ version, index, onEdit, onDelete }) => {
+    return (
+        <Row align="middle">
+            <Col span={20}>
+                <Space direction="vertical" style={{ width: '100%' }}>
+                    <Space>
+                        <Tag color="blue">v{version.version}</Tag>
+                        <Text strong>{version.versionDescription}</Text>
+                    </Space>
+                    {version.seedFile && (
+                        <Space>
+                            <FileTextOutlined />
+                            <Text type="secondary">{version.seedFile.name}</Text>
+                        </Space>
+                    )}
+                </Space>
+            </Col>
+            <Col span={4} style={{ textAlign: 'right' }}>
+                <Space>
+                    <Button type="text" icon={<EditOutlined />} onClick={() => onEdit(index)} />
+                    <Button type="text" danger icon={<DeleteOutlined />} onClick={() => onDelete(index)} />
+                </Space>
+            </Col>
+        </Row>
+    );
+};
+
+const VersionEditForm: React.FC<{
+    form: FormInstance<VersionFormData>;
+    version: VersionFormData;
+    onSave: () => void;
+    onCancel: () => void;
+    onFileChange: (file: UploadFile | undefined) => void;
+}> = ({ form, version, onSave, onCancel, onFileChange }) => {
+    const beforeUpload = useCallback((file: RcFile): boolean => {
+        const isLt100M = file.size / 1024 / 1024 < 100;
+        if (!isLt100M) {
+            message.error('种子文件大小不能超过 100MB!');
+            return false;
+        }
+        return false;
+    }, []);
+
+    return (
+        <Form form={form} layout="vertical" initialValues={version}>
+            <Row gutter={16}>
+                <Col span={6}>
+                    <Form.Item label="版本号" name="version" rules={[{ required: true, message: '请输入版本号' }]}>
+                        <Input placeholder="例如:1.0" />
+                    </Form.Item>
+                </Col>
+                <Col span={18}>
+                    <Form.Item
+                        label="版本描述"
+                        name="versionDescription"
+                        rules={[
+                            { required: true, message: '请输入版本描述' },
+                            { min: 10, message: '版本描述至少10个字符' },
+                        ]}
+                    >
+                        <TextArea placeholder="描述此版本的更新内容、新增功能等" rows={3} showCount maxLength={500} />
+                    </Form.Item>
+                </Col>
+            </Row>
+
+            <Form.Item label="种子文件">
+                <Dragger
+                    maxCount={1}
+                    beforeUpload={beforeUpload}
+                    fileList={version.seedFile ? [version.seedFile] : []}
+                    onChange={({ fileList }) => onFileChange(fileList[0])}
+                    onRemove={() => onFileChange(undefined)}
+                >
+                    <p className="ant-upload-drag-icon"><InboxOutlined /></p>
+                    <p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
+                    <p className="ant-upload-hint">支持单个文件上传,文件大小不超过 100MB</p>
+                </Dragger>
+            </Form.Item>
+
+            <Space>
+                <Button type="primary" onClick={onSave}>保存</Button>
+                <Button onClick={onCancel}>取消</Button>
+            </Space>
+        </Form>
+    );
+};
+
+// ==================== 步骤3:版本管理 ====================
+export const VersionManagementStep: React.FC<StepFormProps> = ({ data, onUpdate, onNext, onPrev }) => {
+    const [versions, setVersions] = useState<VersionFormData[]>(
+        data.versions.length > 0 ? data.versions : [{ version: '1.0', versionDescription: '', seedFile: undefined }]
+    );
+    const [editingIndex, setEditingIndex] = useState<number | null>(null);
+    const [form]: [FormInstance<VersionFormData>] = Form.useForm<VersionFormData>();
+
+    const handleAddVersion = useCallback(() => {
+        const newVersion: VersionFormData = {
+            version: `${versions.length + 1}.0`,
+            versionDescription: '',
+            seedFile: undefined,
+        };
+        setVersions([...versions, newVersion]);
+        setEditingIndex(versions.length);
+    }, [versions]);
+
+    const handleSaveVersion = useCallback((index: number) => {
+        form.validateFields().then((values) => {
+            const newVersions = [...versions];
+            newVersions[index] = { ...newVersions[index], ...values };
+            setVersions(newVersions);
+            setEditingIndex(null);
+            form.resetFields();
+            message.success('版本信息已保存');
+        }).catch(() => {
+            message.error('请完整填写版本信息');
+        });
+    }, [form, versions]);
+
+    const handleDeleteVersion = useCallback((index: number) => {
+        Modal.confirm({
+            title: '确认删除',
+            content: '确定要删除这个版本吗?',
+            onOk: () => {
+                const newVersions = versions.filter((_, i) => i !== index);
+                setVersions(newVersions);
+                if (editingIndex === index) {
+                    setEditingIndex(null);
+                }
+            },
+        });
+    }, [versions, editingIndex]);
+
+    const handleFileChange = useCallback((index: number, file: UploadFile | undefined) => {
+        const newVersions = [...versions];
+        newVersions[index].seedFile = file;
+        setVersions(newVersions);
+    }, [versions]);
+
+    const handleNext = useCallback(() => {
+        if (versions.length === 0) {
+            message.error('至少需要添加一个版本');
+            return;
+        }
+
+        const incompleteVersion = versions.find((v, index) =>
+            !v.version || !v.versionDescription || !v.seedFile || index === editingIndex
+        );
+
+        if (incompleteVersion) {
+            message.error('请完成所有版本的信息填写');
+            return;
+        }
+
+        onUpdate('versions', versions);
+        onNext?.();
+    }, [versions, editingIndex, onUpdate, onNext]);
+
+    return (
+        <Card>
+            <div style={{ marginBottom: 16 }}>
+                <Title level={4}>版本列表</Title>
+                <Paragraph type="secondary">每个版本需要包含版本号、版本描述和种子文件</Paragraph>
+            </div>
+
+            <List
+                dataSource={versions}
+                renderItem={(version, index) => (
+                    <List.Item
+                        key={index}
+                        style={{
+                            background: editingIndex === index ? '#fafafa' : 'transparent',
+                            padding: 16,
+                            marginBottom: 16,
+                            border: '1px solid #f0f0f0',
+                            borderRadius: 8,
+                        }}
+                    >
+                        {editingIndex === index ? (
+                            <VersionEditForm
+                                form={form}
+                                version={version}
+                                onSave={() => handleSaveVersion(index)}
+                                onCancel={() => setEditingIndex(null)}
+                                onFileChange={(file) => handleFileChange(index, file)}
+                            />
+                        ) : (
+                            <VersionItem
+                                version={version}
+                                index={index}
+                                onEdit={(idx) => {
+                                    setEditingIndex(idx);
+                                    form.setFieldsValue(version);
+                                }}
+                                onDelete={handleDeleteVersion}
+                            />
+                        )}
+                    </List.Item>
+                )}
+            />
+
+            {editingIndex === null && (
+                <Button
+                    type="dashed"
+                    onClick={handleAddVersion}
+                    style={{ width: '100%', marginBottom: 24 }}
+                    icon={<PlusOutlined />}
+                >
+                    添加版本
+                </Button>
+            )}
+
+            <Divider />
+            <Space size="middle">
+                <Button onClick={onPrev} size="large">上一步</Button>
+                <Button type="primary" onClick={handleNext} size="large">下一步</Button>
+            </Space>
+        </Card>
+    );
+};
+
+// ==================== 步骤4:确认发布 ====================
+export const ConfirmPublishStep: React.FC<StepFormProps & { onPublish: () => void }> = ({ data, onPrev, onPublish }) => {
+    const [publishing, setPublishing] = useState<boolean>(false);
+
+    const handlePublish = useCallback(async () => {
+        setPublishing(true);
+        try {
+            await new Promise(resolve => setTimeout(resolve, 2000));
+            message.success('作品发布成功!');
+            onPublish();
+        } catch {
+            message.error('发布失败,请重试');
+        } finally {
+            setPublishing(false);
+        }
+    }, [onPublish]);
+
+    return (
+        <Card>
+            <Title level={3} style={{ marginBottom: 24 }}>
+                <CheckCircleOutlined style={{ color: '#52c41a', marginRight: 8 }} />
+                确认发布信息
+            </Title>
+
+            <div style={{ marginBottom: 32 }}>
+                <Title level={4}>基础信息</Title>
+                <Descriptions bordered column={1}>
+                    <Descriptions.Item label="作品名称">{data.basicInfo.artworkName}</Descriptions.Item>
+                    <Descriptions.Item label="作品分类">
+                        <Tag color="blue">{data.basicInfo.artworkCategory}</Tag>
+                    </Descriptions.Item>
+                    <Descriptions.Item label="作品描述">
+                        <div style={{ maxHeight: 200, overflow: 'auto' }}>
+                            <ReactMarkdown>{data.basicInfo.artworkDescription}</ReactMarkdown>
+                        </div>
+                    </Descriptions.Item>
+                </Descriptions>
+            </div>
+
+            <div style={{ marginBottom: 32 }}>
+                <Title level={4}>作品封面</Title>
+                {data.coverInfo.coverFile && (
+                    <img
+                        src={data.coverInfo.coverFile.thumbUrl || data.coverInfo.coverFile.url}
+                        alt="作品封面"
+                        style={{ maxWidth: 300, maxHeight: 400, objectFit: 'cover' }}
+                    />
+                )}
+            </div>
+
+            <div style={{ marginBottom: 32 }}>
+                <Title level={4}>版本信息</Title>
+                <List
+                    dataSource={data.versions}
+                    renderItem={(version) => (
+                        <List.Item>
+                            <List.Item.Meta
+                                title={
+                                    <Space>
+                                        <Tag color="green">v{version.version}</Tag>
+                                        <Text>{version.versionDescription}</Text>
+                                    </Space>
+                                }
+                                description={
+                                    version.seedFile && (
+                                        <Space>
+                                            <FileTextOutlined />
+                                            <Text type="secondary">{version.seedFile.name}</Text>
+                                        </Space>
+                                    )
+                                }
+                            />
+                        </List.Item>
+                    )}
+                />
+            </div>
+
+            <Alert
+                message="发布须知"
+                description={
+                    <ul style={{ marginBottom: 0, paddingLeft: 20 }}>
+                        <li>发布后的作品将公开展示,所有用户都可以查看和下载</li>
+                        <li>请确保作品内容符合社区规范,不包含违法违规内容</li>
+                        <li>发布后您仍可以编辑作品信息和添加新版本</li>
+                        <li>请尊重他人知识产权,确保作品为原创或已获得授权</li>
+                    </ul>
+                }
+                type="warning"
+                showIcon
+                style={{ marginBottom: 24 }}
+            />
+
+            <Space size="middle">
+                <Button onClick={onPrev} size="large">上一步</Button>
+                <Button
+                    type="primary"
+                    onClick={handlePublish}
+                    loading={publishing}
+                    icon={<SendOutlined />}
+                    size="large"
+                >
+                    确认发布
+                </Button>
+            </Space>
+        </Card>
+    );
+};
\ No newline at end of file
diff --git a/src/feature/work/CreateWork.tsx b/src/feature/work/CreateWork.tsx
new file mode 100644
index 0000000..5e97433
--- /dev/null
+++ b/src/feature/work/CreateWork.tsx
@@ -0,0 +1,53 @@
+import React, { useMemo } from 'react';
+import { Layout, Steps, Card, Typography } from 'antd';
+import { FileTextOutlined, FileImageOutlined, SaveOutlined, SendOutlined } from '@ant-design/icons';
+import { BasicInfoStep, CoverUploadStep, VersionManagementStep, ConfirmPublishStep } from './CreatWorkComponents';
+import { useCreateWorkForm } from './hooks';
+
+
+const { Content } = Layout;
+const { Title, Paragraph } = Typography;
+
+const CreateWork: React.FC = () => {
+    const { currentStep, formData, handleUpdateFormData, handleNext, handlePrev, handlePublish } = useCreateWorkForm();
+
+    const steps = useMemo(() => [
+        { title: '基础信息', description: '填写作品基本信息', icon: <FileTextOutlined /> },
+        { title: '上传封面', description: '上传作品封面图片', icon: <FileImageOutlined /> },
+        { title: '版本管理', description: '添加作品版本和文件', icon: <SaveOutlined /> },
+        { title: '确认发布', description: '检查并发布作品', icon: <SendOutlined /> },
+    ], []);
+
+    const renderStepContent = useMemo(() => {
+        const commonProps = { data: formData, onUpdate: handleUpdateFormData, onNext: handleNext, onPrev: handlePrev };
+
+        switch (currentStep) {
+            case 0: return <BasicInfoStep {...commonProps} />;
+            case 1: return <CoverUploadStep {...commonProps} />;
+            case 2: return <VersionManagementStep {...commonProps} />;
+            case 3: return <ConfirmPublishStep {...commonProps} onPublish={handlePublish} />;
+            default: return null;
+        }
+    }, [currentStep, formData, handleUpdateFormData, handleNext, handlePrev, handlePublish]);
+
+    return (
+        <Layout style={{ minHeight: '100vh', backgroundColor: '#f5f5f5' }}>
+            <Content style={{ padding: '20px' }}>
+                <div style={{ maxWidth: 1000, margin: '0 auto' }}>
+                    <Card style={{ marginBottom: 24 }}>
+                        <Title level={2} style={{ marginBottom: 8 }}>创建新作品</Title>
+                        <Paragraph type="secondary">通过以下步骤发布您的创意作品,与社区分享您的才华</Paragraph>
+                    </Card>
+
+                    <Card style={{ marginBottom: 24 }}>
+                        <Steps current={currentStep} items={steps} />
+                    </Card>
+
+                    {renderStepContent}
+                </div>
+            </Content>
+        </Layout>
+    );
+};
+
+export default CreateWork;
\ No newline at end of file
diff --git a/src/feature/work/EditWork.tsx b/src/feature/work/EditWork.tsx
new file mode 100644
index 0000000..f56d42a
--- /dev/null
+++ b/src/feature/work/EditWork.tsx
@@ -0,0 +1,753 @@
+import React, { useState, useCallback } from 'react';
+import {
+    Modal, Form, Input, Upload, Button, message, Space, Card,
+    Typography, Alert, List, Tag, Popconfirm, Row, Col,
+    type FormInstance
+} from 'antd';
+import {
+    EditOutlined, DeleteOutlined, PlusOutlined, InboxOutlined,
+    SaveOutlined, FileTextOutlined, UserOutlined
+} from '@ant-design/icons';
+import ReactMarkdown from 'react-markdown';
+import type {
+    UploadFile, UploadProps, UploadChangeParam, RcFile,
+} from 'antd/es/upload';
+import type {
+    ArtworkData, VersionFormData, Comment,
+} from './types';
+
+const { TextArea } = Input;
+const { Dragger } = Upload;
+const { Text } = Typography;
+
+// ==================== 工具函数 ====================
+const getBase64 = (file: RcFile): Promise<string> =>
+    new Promise((resolve, reject) => {
+        const reader = new FileReader();
+        reader.readAsDataURL(file);
+        reader.onload = (): void => resolve(reader.result as string);
+        reader.onerror = (error): void => reject(error);
+    });
+
+// ==================== 类型定义 ====================
+interface EditCoverProps {
+    visible: boolean;
+    currentCover: string;
+    onCancel: () => void;
+    onSave: (coverUrl: string) => Promise<void>;
+}
+
+interface EditDescriptionProps {
+    visible: boolean;
+    currentDescription: string;
+    onCancel: () => void;
+    onSave: (description: string) => Promise<void>;
+}
+
+interface EditVersionsProps {
+    visible: boolean;
+    versions: VersionFormData[];
+    onCancel: () => void;
+    onSave: (versions: VersionFormData[]) => Promise<void>;
+}
+
+interface CommentItemProps {
+    comment: Comment;
+    isAuthor: boolean;
+    onDelete: (commentId: string) => Promise<void>;
+    level?: number;
+}
+
+interface EditWorkControlsProps {
+    artwork: ArtworkData;
+    isAuthor: boolean;
+    onUpdate: (updatedArtwork: Partial<ArtworkData>) => Promise<void>;
+    onDeleteComment: (commentId: string) => Promise<void>;
+}
+
+interface VersionItemProps {
+    version: VersionFormData;
+    index: number;
+    onEdit: (index: number) => void;
+    onDelete: (index: number) => void;
+}
+
+interface VersionEditFormProps {
+    form: FormInstance<VersionFormData>;
+    version: VersionFormData;
+    onSave: () => void;
+    onCancel: () => void;
+    onFileChange: (file: UploadFile | undefined) => void;
+}
+
+// ==================== 封面编辑组件 ====================
+export const EditWorkCover: React.FC<EditCoverProps> = ({
+    visible,
+    currentCover,
+    onCancel,
+    onSave
+}) => {
+    const [fileList, setFileList] = useState<UploadFile[]>([]);
+    const [previewImage, setPreviewImage] = useState<string>('');
+    const [previewOpen, setPreviewOpen] = useState<boolean>(false);
+    const [uploading, setUploading] = useState<boolean>(false);
+
+    const handleChange: UploadProps['onChange'] = useCallback((info: UploadChangeParam<UploadFile>): void => {
+        setFileList(info.fileList);
+    }, []);
+
+    const handlePreview = useCallback(async (file: UploadFile): Promise<void> => {
+        if (!file.url && !file.preview) {
+            file.preview = await getBase64(file.originFileObj as RcFile);
+        }
+        setPreviewImage(file.url || (file.preview as string));
+        setPreviewOpen(true);
+    }, []);
+
+    const beforeUpload = useCallback((file: RcFile): boolean => {
+        const isImage = file.type.startsWith('image/');
+        if (!isImage) {
+            message.error('只能上传图片文件!');
+            return false;
+        }
+        const isLt5M = file.size / 1024 / 1024 < 5;
+        if (!isLt5M) {
+            message.error('图片大小不能超过 5MB!');
+            return false;
+        }
+        return false; // 阻止自动上传
+    }, []);
+
+    const handleSave = useCallback(async (): Promise<void> => {
+        if (fileList.length === 0) {
+            message.error('请选择要上传的封面图片');
+            return;
+        }
+
+        setUploading(true);
+        try {
+            // 模拟上传过程
+            const file = fileList[0];
+            const coverUrl = file.preview || URL.createObjectURL(file.originFileObj as RcFile);
+
+            await onSave(coverUrl);
+            message.success('封面更新成功!');
+            onCancel();
+        } catch {
+            message.error('封面更新失败,请重试');
+        } finally {
+            setUploading(false);
+        }
+    }, [fileList, onSave, onCancel]);
+
+    return (
+        <>
+            <Modal
+                title="编辑作品封面"
+                open={visible}
+                onCancel={onCancel}
+                footer={[
+                    <Button key="cancel" onClick={onCancel}>
+                        取消
+                    </Button>,
+                    <Button
+                        key="save"
+                        type="primary"
+                        loading={uploading}
+                        onClick={handleSave}
+                        icon={<SaveOutlined />}
+                    >
+                        保存
+                    </Button>,
+                ]}
+                width={600}
+            >
+                <div style={{ marginBottom: 16 }}>
+                    <Text strong>当前封面:</Text>
+                    <div style={{ marginTop: 8 }}>
+                        <img
+                            src={currentCover}
+                            alt="当前封面"
+                            style={{ maxWidth: '100%', maxHeight: 200, objectFit: 'cover' }}
+                        />
+                    </div>
+                </div>
+
+                <Alert
+                    message="新封面要求"
+                    description="图片格式:JPG、PNG、GIF;大小不超过 5MB;建议尺寸:宽高比 3:4"
+                    type="info"
+                    showIcon
+                    style={{ marginBottom: 16 }}
+                />
+
+                <Upload
+                    listType="picture-card"
+                    fileList={fileList}
+                    onChange={handleChange}
+                    onPreview={handlePreview}
+                    beforeUpload={beforeUpload}
+                    maxCount={1}
+                    accept="image/*"
+                >
+                    {fileList.length === 0 && (
+                        <div>
+                            <PlusOutlined />
+                            <div style={{ marginTop: 8 }}>选择新封面</div>
+                        </div>
+                    )}
+                </Upload>
+            </Modal>
+
+            <Modal
+                open={previewOpen}
+                title="图片预览"
+                footer={null}
+                onCancel={(): void => setPreviewOpen(false)}
+            >
+                <img alt="预览" style={{ width: '100%' }} src={previewImage} />
+            </Modal>
+        </>
+    );
+};
+
+// ==================== 作品描述编辑组件 ====================
+export const EditWorkDescription: React.FC<EditDescriptionProps> = ({
+    visible,
+    currentDescription,
+    onCancel,
+    onSave
+}) => {
+    const [form] = Form.useForm<{ description: string }>();
+    const [previewMode, setPreviewMode] = useState<boolean>(false);
+    const [saving, setSaving] = useState<boolean>(false);
+
+    const handleSave = useCallback(async (): Promise<void> => {
+        try {
+            const values = await form.validateFields();
+            setSaving(true);
+            await onSave(values.description);
+            message.success('作品描述更新成功!');
+            onCancel();
+        } catch (error) {
+            if (error && typeof error === 'object' && 'errorFields' in error) {
+                message.error('请检查输入内容');
+            } else {
+                message.error('更新失败,请重试');
+            }
+        } finally {
+            setSaving(false);
+        }
+    }, [form, onSave, onCancel]);
+
+    const handlePreview = useCallback((): void => {
+        form.validateFields().then(() => {
+            setPreviewMode(true);
+        }).catch(() => {
+            message.error('请先填写完整信息');
+        });
+    }, [form]);
+
+    return (
+        <>
+            <Modal
+                title="编辑作品描述"
+                open={visible}
+                onCancel={onCancel}
+                footer={[
+                    <Button key="preview" onClick={handlePreview}>
+                        预览
+                    </Button>,
+                    <Button key="cancel" onClick={onCancel}>
+                        取消
+                    </Button>,
+                    <Button
+                        key="save"
+                        type="primary"
+                        loading={saving}
+                        onClick={handleSave}
+                        icon={<SaveOutlined />}
+                    >
+                        保存
+                    </Button>,
+                ]}
+                width={800}
+            >
+                <Form
+                    form={form}
+                    layout="vertical"
+                    initialValues={{ description: currentDescription }}
+                >
+                    <Form.Item
+                        label="作品描述"
+                        name="description"
+                        rules={[
+                            { required: true, message: '请输入作品描述' },
+                            { min: 20, message: '作品描述至少20个字符' },
+                            { max: 2000, message: '作品描述最多2000个字符' },
+                        ]}
+                        extra="支持 Markdown 格式,可以使用 # 标题、**粗体**、*斜体* 等格式"
+                    >
+                        <TextArea
+                            placeholder="请详细描述你的作品,包括创作理念、技术特点、使用说明等"
+                            rows={12}
+                            showCount
+                            maxLength={2000}
+                        />
+                    </Form.Item>
+                </Form>
+            </Modal>
+
+            <Modal
+                title="作品描述预览"
+                open={previewMode}
+                onCancel={(): void => setPreviewMode(false)}
+                footer={null}
+                width={800}
+            >
+                <div style={{ maxHeight: '60vh', overflow: 'auto' }}>
+                    <ReactMarkdown>{form.getFieldValue('description') || ''}</ReactMarkdown>
+                </div>
+            </Modal>
+        </>
+    );
+};
+
+// ==================== 版本编辑相关组件 ====================
+const VersionItem: React.FC<VersionItemProps> = ({
+    version,
+    index,
+    onEdit,
+    onDelete
+}) => {
+    return (
+        <Row align="middle" style={{ width: '100%' }}>
+            <Col span={20}>
+                <Space direction="vertical" style={{ width: '100%' }}>
+                    <Space>
+                        <Tag color="blue">v{version.version}</Tag>
+                        <Text strong>{version.versionDescription}</Text>
+                    </Space>
+                    {version.seedFile && (
+                        <Space>
+                            <FileTextOutlined />
+                            <Text type="secondary">{version.seedFile.name}</Text>
+                        </Space>
+                    )}
+                </Space>
+            </Col>
+            <Col span={4} style={{ textAlign: 'right' }}>
+                <Space>
+                    <Button
+                        type="text"
+                        icon={<EditOutlined />}
+                        onClick={(): void => onEdit(index)}
+                    />
+                    <Popconfirm
+                        title="确定要删除这个版本吗?"
+                        onConfirm={(): void => onDelete(index)}
+                        okText="确定"
+                        cancelText="取消"
+                    >
+                        <Button type="text" danger icon={<DeleteOutlined />} />
+                    </Popconfirm>
+                </Space>
+            </Col>
+        </Row>
+    );
+};
+
+const VersionEditForm: React.FC<VersionEditFormProps> = ({
+    form,
+    version,
+    onSave,
+    onCancel,
+    onFileChange
+}) => {
+    const beforeUpload = useCallback((file: RcFile): boolean => {
+        const isLt100M = file.size / 1024 / 1024 < 100;
+        if (!isLt100M) {
+            message.error('种子文件大小不能超过 100MB!');
+            return false;
+        }
+        return false;
+    }, []);
+
+    return (
+        <div style={{ width: '100%' }}>
+            <Form form={form} layout="vertical" initialValues={version}>
+                <Row gutter={16}>
+                    <Col span={6}>
+                        <Form.Item
+                            label="版本号"
+                            name="version"
+                            rules={[{ required: true, message: '请输入版本号' }]}
+                        >
+                            <Input placeholder="例如:1.0" />
+                        </Form.Item>
+                    </Col>
+                    <Col span={18}>
+                        <Form.Item
+                            label="版本描述"
+                            name="versionDescription"
+                            rules={[
+                                { required: true, message: '请输入版本描述' },
+                                { min: 10, message: '版本描述至少10个字符' },
+                            ]}
+                        >
+                            <TextArea
+                                placeholder="描述此版本的更新内容、新增功能等"
+                                rows={3}
+                                showCount
+                                maxLength={500}
+                            />
+                        </Form.Item>
+                    </Col>
+                </Row>
+
+                <Form.Item label="种子文件">
+                    <Dragger
+                        maxCount={1}
+                        beforeUpload={beforeUpload}
+                        fileList={version.seedFile ? [version.seedFile] : []}
+                        onChange={({ fileList }): void => onFileChange(fileList[0])}
+                        onRemove={(): void => onFileChange(undefined)}
+                    >
+                        <p className="ant-upload-drag-icon"><InboxOutlined /></p>
+                        <p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
+                        <p className="ant-upload-hint">支持单个文件上传,文件大小不超过 100MB</p>
+                    </Dragger>
+                </Form.Item>
+
+                <Space>
+                    <Button type="primary" onClick={onSave}>
+                        保存
+                    </Button>
+                    <Button onClick={onCancel}>
+                        取消
+                    </Button>
+                </Space>
+            </Form>
+        </div>
+    );
+};
+
+// ==================== 版本管理组件 ====================
+export const EditWorkVersions: React.FC<EditVersionsProps> = ({
+    visible,
+    versions,
+    onCancel,
+    onSave
+}) => {
+    const [localVersions, setLocalVersions] = useState<VersionFormData[]>(versions);
+    const [editingIndex, setEditingIndex] = useState<number | null>(null);
+    const [form] = Form.useForm<VersionFormData>();
+    const [saving, setSaving] = useState<boolean>(false);
+
+    const handleAddVersion = useCallback((): void => {
+        const newVersion: VersionFormData = {
+            version: `${localVersions.length + 1}.0`,
+            versionDescription: '',
+            seedFile: undefined,
+        };
+        setLocalVersions([...localVersions, newVersion]);
+        setEditingIndex(localVersions.length);
+    }, [localVersions]);
+
+    const handleSaveVersion = useCallback((index: number): void => {
+        form.validateFields().then((values) => {
+            const newVersions = [...localVersions];
+            newVersions[index] = { ...newVersions[index], ...values };
+            setLocalVersions(newVersions);
+            setEditingIndex(null);
+            form.resetFields();
+            message.success('版本信息已保存');
+        }).catch(() => {
+            message.error('请完整填写版本信息');
+        });
+    }, [form, localVersions]);
+
+    const handleDeleteVersion = useCallback((index: number): void => {
+        const newVersions = localVersions.filter((_, i) => i !== index);
+        setLocalVersions(newVersions);
+        if (editingIndex === index) {
+            setEditingIndex(null);
+        }
+    }, [localVersions, editingIndex]);
+
+    const handleFileChange = useCallback((index: number, file: UploadFile | undefined): void => {
+        const newVersions = [...localVersions];
+        newVersions[index].seedFile = file;
+        setLocalVersions(newVersions);
+    }, [localVersions]);
+
+    const handleSave = useCallback(async (): Promise<void> => {
+        if (localVersions.length === 0) {
+            message.error('至少需要保留一个版本');
+            return;
+        }
+
+        const incompleteVersion = localVersions.find((v, index) =>
+            !v.version || !v.versionDescription || !v.seedFile || index === editingIndex
+        );
+
+        if (incompleteVersion) {
+            message.error('请完成所有版本的信息填写');
+            return;
+        }
+
+        setSaving(true);
+        try {
+            await onSave(localVersions);
+            message.success('版本信息更新成功!');
+            onCancel();
+        } catch {
+            message.error('更新失败,请重试');
+        } finally {
+            setSaving(false);
+        }
+    }, [localVersions, editingIndex, onSave, onCancel]);
+
+    return (
+        <Modal
+            title="编辑版本信息"
+            open={visible}
+            onCancel={onCancel}
+            footer={[
+                <Button key="cancel" onClick={onCancel}>
+                    取消
+                </Button>,
+                <Button
+                    key="save"
+                    type="primary"
+                    loading={saving}
+                    onClick={handleSave}
+                    icon={<SaveOutlined />}
+                >
+                    保存所有更改
+                </Button>,
+            ]}
+            width={900}
+        >
+            <div style={{ maxHeight: '60vh', overflow: 'auto' }}>
+                <List
+                    dataSource={localVersions}
+                    renderItem={(version, index): React.ReactElement => (
+                        <List.Item
+                            key={index}
+                            style={{
+                                background: editingIndex === index ? '#fafafa' : 'transparent',
+                                padding: 16,
+                                marginBottom: 16,
+                                border: '1px solid #f0f0f0',
+                                borderRadius: 8,
+                            }}
+                        >
+                            {editingIndex === index ? (
+                                <VersionEditForm
+                                    form={form}
+                                    version={version}
+                                    onSave={(): void => handleSaveVersion(index)}
+                                    onCancel={(): void => setEditingIndex(null)}
+                                    onFileChange={(file): void => handleFileChange(index, file)}
+                                />
+                            ) : (
+                                <VersionItem
+                                    version={version}
+                                    index={index}
+                                    onEdit={(idx): void => {
+                                        setEditingIndex(idx);
+                                        form.setFieldsValue(version);
+                                    }}
+                                    onDelete={handleDeleteVersion}
+                                />
+                            )}
+                        </List.Item>
+                    )}
+                />
+
+                {editingIndex === null && (
+                    <Button
+                        type="dashed"
+                        onClick={handleAddVersion}
+                        style={{ width: '100%', marginTop: 16 }}
+                        icon={<PlusOutlined />}
+                    >
+                        添加新版本
+                    </Button>
+                )}
+            </div>
+        </Modal>
+    );
+};
+
+// ==================== 评论管理组件 ====================
+export const EditWorkComment: React.FC<CommentItemProps> = ({
+    comment,
+    isAuthor,
+    onDelete,
+    level = 0
+}) => {
+    const [deleting, setDeleting] = useState<boolean>(false);
+
+    const handleDelete = useCallback(async (): Promise<void> => {
+        if (!comment.id) return;
+
+        setDeleting(true);
+        try {
+            await onDelete(comment.id);
+            message.success('评论删除成功');
+        } catch {
+            message.error('删除失败,请重试');
+        } finally {
+            setDeleting(false);
+        }
+    }, [comment.id, onDelete]);
+
+    return (
+        <div style={{ marginLeft: level * 24 }}>
+            <div
+                style={{
+                    background: '#fafafa',
+                    padding: 12,
+                    borderRadius: 8,
+                    marginBottom: 8,
+                }}
+            >
+                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
+                    <div style={{ flex: 1 }}>
+                        <Space style={{ marginBottom: 8 }}>
+                            <UserOutlined />
+                            <Text strong>{comment.author}</Text>
+                            {comment.createdAt && (
+                                <Text type="secondary" style={{ fontSize: 12 }}>
+                                    {new Date(comment.createdAt).toLocaleString()}
+                                </Text>
+                            )}
+                        </Space>
+                        <div>
+                            <Text>{comment.content}</Text>
+                        </div>
+                    </div>
+
+                    {isAuthor && comment.id && (
+                        <Popconfirm
+                            title="确定要删除这条评论吗?"
+                            onConfirm={handleDelete}
+                            okText="确定"
+                            cancelText="取消"
+                        >
+                            <Button
+                                type="text"
+                                danger
+                                size="small"
+                                icon={<DeleteOutlined />}
+                                loading={deleting}
+                            />
+                        </Popconfirm>
+                    )}
+                </div>
+            </div>
+
+            {/* 递归渲染子评论 */}
+            {comment.child && comment.child.length > 0 && (
+                <div>
+                    {comment.child.map((childComment, index) => (
+                        <EditWorkComment
+                            key={childComment.id || index}
+                            comment={childComment}
+                            isAuthor={isAuthor}
+                            onDelete={onDelete}
+                            level={level + 1}
+                        />
+                    ))}
+                </div>
+            )}
+        </div>
+    );
+};
+
+// ==================== 主编辑控制器组件 ====================
+export const EditWorkControls: React.FC<EditWorkControlsProps> = ({
+    artwork,
+    isAuthor,
+    onUpdate,
+}) => {
+    const [editCoverVisible, setEditCoverVisible] = useState<boolean>(false);
+    const [editDescriptionVisible, setEditDescriptionVisible] = useState<boolean>(false);
+    const [editVersionsVisible, setEditVersionsVisible] = useState<boolean>(false);
+
+    const handleUpdateCover = useCallback(async (coverUrl: string): Promise<void> => {
+        await onUpdate({ artworkCover: coverUrl });
+    }, [onUpdate]);
+
+    const handleUpdateDescription = useCallback(async (description: string): Promise<void> => {
+        await onUpdate({ artworkDescription: description });
+    }, [onUpdate]);
+
+    const handleUpdateVersions = useCallback(async (versions: VersionFormData[]): Promise<void> => {
+        // 转换为展示用的版本格式
+        const versionList = versions.map(v => ({
+            version: v.version,
+            versionDescription: v.versionDescription,
+            seedFile: v.seedFile?.name || '',
+        }));
+        await onUpdate({ versionList });
+    }, [onUpdate]);
+
+    if (!isAuthor) {
+        return null;
+    }
+
+    return (
+        <>
+            <Card title="作者管理" style={{ marginBottom: 24 }}>
+                <Space wrap>
+                    <Button
+                        icon={<EditOutlined />}
+                        onClick={(): void => setEditCoverVisible(true)}
+                    >
+                        编辑封面
+                    </Button>
+                    <Button
+                        icon={<EditOutlined />}
+                        onClick={(): void => setEditDescriptionVisible(true)}
+                    >
+                        编辑描述
+                    </Button>
+                    <Button
+                        icon={<EditOutlined />}
+                        onClick={(): void => setEditVersionsVisible(true)}
+                    >
+                        管理版本
+                    </Button>
+                </Space>
+            </Card>
+
+            <EditWorkCover
+                visible={editCoverVisible}
+                currentCover={artwork.artworkCover}
+                onCancel={(): void => setEditCoverVisible(false)}
+                onSave={handleUpdateCover}
+            />
+
+            <EditWorkDescription
+                visible={editDescriptionVisible}
+                currentDescription={artwork.artworkDescription}
+                onCancel={(): void => setEditDescriptionVisible(false)}
+                onSave={handleUpdateDescription}
+            />
+
+            <EditWorkVersions
+                visible={editVersionsVisible}
+                versions={artwork.versionList.map(v => ({
+                    version: v.version,
+                    versionDescription: v.versionDescription,
+                    seedFile: { name: v.seedFile } as UploadFile,
+                }))}
+                onCancel={(): void => setEditVersionsVisible(false)}
+                onSave={handleUpdateVersions}
+            />
+        </>
+    );
+};
\ No newline at end of file
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
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
diff --git a/src/feature/work/hooks.ts b/src/feature/work/hooks.ts
new file mode 100644
index 0000000..f07189e
--- /dev/null
+++ b/src/feature/work/hooks.ts
@@ -0,0 +1,34 @@
+import { useCallback, useState } from "react";
+import { useNavigate } from "react-router";
+import type { 
+    WorkFormData, 
+    BasicInfo, 
+    CoverInfo, 
+    VersionFormData,
+    ArtworkCategory
+} from './types';
+
+// ==================== Hook ====================
+export const useCreateWorkForm = () => {
+    const navigate = useNavigate();
+    const [currentStep, setCurrentStep] = useState<number>(0);
+    const [formData, setFormData] = useState<WorkFormData>({
+        basicInfo: { 
+            artworkName: '', 
+            artworkCategory: '概念设计' as ArtworkCategory, 
+            artworkDescription: '' 
+        },
+        coverInfo: {},
+        versions: [],
+    });
+
+    const handleUpdateFormData = useCallback((field: keyof WorkFormData, value: BasicInfo | CoverInfo | VersionFormData[]) => {
+        setFormData(prev => ({ ...prev, [field]: value }));
+    }, []);
+
+    const handleNext = useCallback(() => setCurrentStep(prev => Math.min(prev + 1, 3)), []);
+    const handlePrev = useCallback(() => setCurrentStep(prev => Math.max(prev - 1, 0)), []);
+    const handlePublish = useCallback(() => navigate('/work/new-work-id'), [navigate]);
+
+    return { currentStep, formData, handleUpdateFormData, handleNext, handlePrev, handlePublish };
+};
\ No newline at end of file
diff --git a/src/feature/work/mockData.ts b/src/feature/work/mockData.ts
new file mode 100644
index 0000000..8470e61
--- /dev/null
+++ b/src/feature/work/mockData.ts
@@ -0,0 +1,405 @@
+import type { ArtworkData, Comment } from './types';
+
+// 生成随机时间的工具函数
+const generateRandomDate = (daysAgo: number): string => {
+    const date = new Date();
+    date.setDate(date.getDate() - Math.floor(Math.random() * daysAgo));
+    return date.toLocaleString('zh-CN', {
+        year: 'numeric',
+        month: '2-digit',
+        day: '2-digit',
+        hour: '2-digit',
+        minute: '2-digit'
+    });
+};
+
+// 通用评论数据
+const baseComments: Comment[] = [
+    {
+        id: 'comment_1',
+        content: '这个作品真的很棒!设计思路很新颖,学到了很多东西。',
+        author: '设计爱好者小王',
+        authorId: 'user_wang_001',
+        createdAt: generateRandomDate(3),
+        child: [
+            {
+                id: 'comment_1_1',
+                content: '同感!特别是色彩搭配的部分,很有启发性。',
+                author: '视觉设计师李雷',
+                authorId: 'user_lilei_002',
+                createdAt: generateRandomDate(2),
+                child: [],
+            },
+            {
+                id: 'comment_1_2',
+                content: '确实,作者的审美很在线,期待更多作品!',
+                author: '创意总监韩梅梅',
+                authorId: 'user_hanmeimei_003',
+                createdAt: generateRandomDate(2),
+                child: [
+                    {
+                        id: 'comment_1_2_1',
+                        content: '@创意总监韩梅梅 您说得对,这种风格确实很难得',
+                        author: '设计爱好者小王',
+                        authorId: 'user_wang_001',
+                        createdAt: generateRandomDate(1),
+                        child: [],
+                    }
+                ],
+            },
+        ],
+    },
+    {
+        id: 'comment_2',
+        content: '技术实现方面有什么特别的难点吗?想了解一下制作过程。',
+        author: '技术控阿明',
+        authorId: 'user_aming_004',
+        createdAt: generateRandomDate(5),
+        child: [],
+    },
+    {
+        id: 'comment_3',
+        content: '看起来很专业,请问这是用什么软件制作的?',
+        author: '新手小白',
+        authorId: 'user_xiaobai_005',
+        createdAt: generateRandomDate(4),
+        child: [
+            {
+                id: 'comment_3_1',
+                content: '从效果来看应该是用Adobe全家桶,主要是PS和AI',
+                author: '软件专家老刘',
+                authorId: 'user_laoliu_006',
+                createdAt: generateRandomDate(3),
+                child: [],
+            }
+        ],
+    },
+    {
+        id: 'comment_4',
+        content: '色彩运用得很巧妙,给人一种很舒服的视觉感受。',
+        author: '色彩搭配师小张',
+        authorId: 'user_xiaozhang_007',
+        createdAt: generateRandomDate(6),
+        child: [],
+    },
+    {
+        id: 'comment_5',
+        content: '作品质量很高,但是感觉在某些细节上还可以再优化一下。',
+        author: '完美主义者',
+        authorId: 'user_perfect_008',
+        createdAt: generateRandomDate(7),
+        child: [
+            {
+                id: 'comment_5_1',
+                content: '能具体说说哪些地方可以优化吗?我也想学习学习',
+                author: '求知者小陈',
+                authorId: 'user_xiaochen_009',
+                createdAt: generateRandomDate(6),
+                child: [],
+            }
+        ],
+    },
+    {
+        id: 'comment_6',
+        content: '已经下载收藏了,感谢分享!🎉',
+        author: '收藏家大佬',
+        authorId: 'user_collector_010',
+        createdAt: generateRandomDate(8),
+        child: [],
+    },
+    {
+        id: 'comment_7',
+        content: '这个风格很适合我正在做的项目,能不能商用呢?',
+        author: '商务合作方',
+        authorId: 'user_business_011',
+        createdAt: generateRandomDate(9),
+        child: [],
+    },
+    {
+        id: 'comment_8',
+        content: '教程什么时候出?期待大神的分享!',
+        author: '学习狂人',
+        authorId: 'user_learner_012',
+        createdAt: generateRandomDate(10),
+        child: [],
+    }
+];
+
+// 作品数据集合
+export const mockArtworks: Record<string, ArtworkData> = {
+    '12345': {
+        artworkId: '12345',
+        artworkCover: 'https://picsum.photos/300/400?random=1',
+        author: '视觉设计师张三',
+        authorId: 'author_zhangsan_001',
+        artworkName: '未来城市概念设计',
+        artworkCategory: '概念设计',
+        comments: [],
+        artworkDescription: `# 未来城市概念设计
+
+这是一个关于2050年智慧城市的概念设计作品。整个设计融合了**可持续发展**、**人工智能**和**绿色科技**的理念。
+
+## 设计理念
+
+- 🌱 **生态友好**:建筑与自然和谐共生
+- 🤖 **智能化**:AI驱动的城市管理系统
+- 🚗 **零排放**:全面电动化的交通系统
+- 🏗️ **模块化**:可扩展的建筑结构
+
+## 技术特点
+
+采用了最新的**参数化设计**方法,通过算法生成建筑形态,确保每个结构都能最大化利用自然光和风能。
+
+*希望这个设计能为未来城市规划提供一些启发。*`,
+        versionList: [
+            {
+                version: '1.0',
+                seedFile: 'magnet:?xt=urn:btih:future_city_v1_0&dn=未来城市v1.0.zip',
+                versionDescription: `## 初始版本 v1.0
+
+### 包含内容
+- 🎨 **高分辨率效果图** (4K)
+- 📐 **CAD源文件** (.dwg)
+- 🖼️ **PSD分层文件**
+- 📄 **设计说明文档**
+
+### 更新说明
+首次发布,包含完整的设计方案和素材文件。`,
+            },
+            {
+                version: '1.1',
+                seedFile: 'magnet:?xt=urn:btih:future_city_v1_1&dn=未来城市v1.1.zip',
+                versionDescription: `## 更新版本 v1.1
+
+### 新增内容
+- 🌃 **夜景渲染图**
+- 🎬 **动画演示视频** (1080p)
+- 🔧 **Blender源文件**
+
+### 修复内容
+- 修复了部分贴图丢失问题
+- 优化了文件结构
+- 添加了英文版说明文档`,
+            },
+        ],
+        usersSeedingCurrently: [
+            { username: '设计师小李', userId: 'user_xiaoli_101' },
+            { username: '建筑师王工', userId: 'user_wanggong_102' },
+            { username: '学生小赵', userId: 'user_xiaozhao_103' },
+            { username: '创意总监', userId: 'user_director_104' },
+        ],
+        usersSeedingHistory: [
+            {
+                username: '资深下载者', uploadTotal: '156.8GB',
+                userId: ''
+            },
+            {
+                username: '设计素材库', uploadTotal: '89.2GB',
+                userId: ''
+            },
+            {
+                username: '创意工作室', uploadTotal: '67.5GB',
+                userId: ''
+            },
+            {
+                username: '学院资源组', uploadTotal: '45.3GB',
+                userId: ''
+            },
+            {
+                username: '独立设计师', uploadTotal: '23.7GB',
+                userId: ''
+            },
+        ],
+    },
+    
+    '23456': {
+        artworkId: '23456',
+        artworkCover: 'https://picsum.photos/300/400?random=2',
+        author: 'UI设计师李四',
+        authorId: 'author_lisi_002',
+        artworkName: '移动应用界面设计套件',
+        artworkCategory: 'UI/UX设计',
+        comments: [],
+        artworkDescription: `# 移动应用界面设计套件
+
+一套完整的移动端UI设计规范和组件库,包含**100+个精美界面**和**500+个设计组件**。
+
+## 包含内容
+
+### 📱 界面设计
+- 登录注册页面
+- 主页和导航
+- 商品展示页面
+- 个人中心
+- 设置页面
+
+### 🎨 设计系统
+- **颜色规范**:主色调、辅助色、状态色
+- **字体系统**:标题、正文、注释文字
+- **图标库**:线性图标、填充图标
+- **组件库**:按钮、输入框、卡片等`,
+        versionList: [
+            {
+                version: '1.0',
+                seedFile: 'magnet:?xt=urn:btih:ui_kit_v1_0&dn=UI设计套件v1.0.zip',
+                versionDescription: `## 基础版本 v1.0
+
+### 核心功能
+- 📱 **50个界面模板**
+- 🎨 **基础组件库**
+- 📋 **设计规范文档**
+- 🎯 **Sketch源文件**`,
+            },
+        ],
+        usersSeedingCurrently: [
+            { username: 'UI设计新手', userId: 'user_ui_newbie_201' },
+            { username: '产品经理小王', userId: 'user_pm_wang_202' },
+        ],
+        usersSeedingHistory: [
+            {
+                username: 'UI设计公司', uploadTotal: '78.9GB',
+                userId: ''
+            },
+            {
+                username: '设计师联盟', uploadTotal: '45.6GB',
+                userId: ''
+            },
+            {
+                username: '学习小组', uploadTotal: '23.4GB',
+                userId: ''
+            },
+        ],
+    },
+
+    '67890': {
+        artworkId: '67890',
+        artworkCover: 'https://picsum.photos/300/400?random=6',
+        author: '刘松林',
+        authorId: '2', // 用户ID为2
+        artworkName: 'React组件库开发指南',
+        artworkCategory: '前端开发',
+        comments: [],
+        artworkDescription: `# React组件库开发指南
+
+一套完整的**企业级React组件库**开发教程和源码,包含从设计到发布的完整流程。
+
+## 项目特色
+
+### 🚀 技术栈
+- **React 18** + **TypeScript**
+- **Styled-components** 样式解决方案
+- **Storybook** 组件文档
+- **Jest** + **Testing Library** 测试
+
+### 📦 组件覆盖
+- **基础组件**: Button, Input, Select, Modal等
+- **布局组件**: Grid, Layout, Container等  
+- **数据展示**: Table, List, Card, Timeline等`,
+        versionList: [
+            {
+                version: '1.0',
+                seedFile: 'magnet:?xt=urn:btih:react_components_v1_0&dn=React组件库v1.0.zip',
+                versionDescription: `## 基础版本 v1.0
+
+### 核心内容
+- 📚 **完整教程文档** (50+页)
+- 💻 **基础组件源码** (20+个组件)
+- 🧪 **单元测试示例**
+- 📖 **Storybook配置**`,
+            },
+        ],
+        usersSeedingCurrently: [
+            { username: '前端新手小李', userId: 'user_frontend_newbie_601' },
+            { username: 'React爱好者', userId: 'user_react_fan_602' },
+        ],
+        usersSeedingHistory: [
+            {
+                username: '大厂前端团队', uploadTotal: '567.8GB',
+                userId: ''
+            },
+            {
+                username: '开源社区', uploadTotal: '234.5GB',
+                userId: ''
+            },
+            {
+                username: '技术培训机构', uploadTotal: '189.7GB',
+                userId: ''
+            },
+        ],
+    },
+};
+
+// 获取指定作品的评论数据
+export const getCommentsForArtwork = (artworkId: string): Comment[] => {
+    // 为不同作品生成不同的评论
+    const commentVariations: Record<string, Comment[]> = {
+        '12345': baseComments,
+        '23456': baseComments.slice(0, 5).map(comment => ({
+            ...comment,
+            id: `ui_${comment.id}`,
+            content: comment.content.replace('作品', 'UI套件').replace('设计', '界面设计'),
+        })),
+        '67890': [
+            {
+                id: 'dev_comment_1',
+                content: '这个组件库的设计思路很棒!TypeScript类型定义特别完善。',
+                author: '前端架构师张工',
+                authorId: 'user_architect_zhang',
+                createdAt: generateRandomDate(2),
+                child: [
+                    {
+                        id: 'dev_comment_1_1',
+                        content: '同感!特别是组件API的设计,很符合React的设计理念。',
+                        author: 'React核心开发者',
+                        authorId: 'user_react_core',
+                        createdAt: generateRandomDate(1),
+                        child: [],
+                    }
+                ],
+            },
+            {
+                id: 'dev_comment_2',
+                content: '构建配置写得很详细,我们团队已经参考这个搭建了自己的组件库。',
+                author: '技术负责人小刘',
+                authorId: 'user_tech_liu',
+                createdAt: generateRandomDate(3),
+                child: [],
+            },
+        ],
+    };
+    
+    return commentVariations[artworkId] || baseComments;
+};
+
+// 根据作品ID获取作品数据
+export const getArtworkById = (artworkId: string): ArtworkData | null => {
+    const artwork = mockArtworks[artworkId];
+    if (artwork) {
+        return {
+            ...artwork,
+            comments: getCommentsForArtwork(artworkId)
+        };
+    }
+    return null;
+};
+
+// 获取所有作品列表
+export const getAllArtworks = (): ArtworkData[] => {
+    return Object.values(mockArtworks);
+};
+
+// 按分类获取作品
+export const getArtworksByCategory = (category: string): ArtworkData[] => {
+    return Object.values(mockArtworks).filter(artwork => artwork.artworkCategory === category);
+};
+
+// 搜索作品
+export const searchArtworks = (keyword: string): ArtworkData[] => {
+    const lowerKeyword = keyword.toLowerCase();
+    return Object.values(mockArtworks).filter(artwork => 
+        artwork.artworkName.toLowerCase().includes(lowerKeyword) ||
+        artwork.artworkDescription.toLowerCase().includes(lowerKeyword) ||
+        artwork.author.toLowerCase().includes(lowerKeyword) ||
+        artwork.artworkCategory.toLowerCase().includes(lowerKeyword)
+    );
+};
\ No newline at end of file
diff --git a/src/feature/work/types.ts b/src/feature/work/types.ts
new file mode 100644
index 0000000..2d7dbd7
--- /dev/null
+++ b/src/feature/work/types.ts
@@ -0,0 +1,283 @@
+import type { UploadFile } from 'antd/es/upload';
+
+// ==================== 基础类型 ====================
+
+export interface User {
+    userId: string;
+    username: string;
+}
+
+export interface HistoryUser extends User {
+    uploadTotal: string;
+}
+
+// ==================== 评论相关 ====================
+
+export interface Comment {
+    id?: string;
+    content: string;
+    author: string;
+    authorId?: string;
+    createdAt?: string;
+    child: Comment[];
+}
+
+// ==================== 版本管理相关 ====================
+
+// 用于表单创建的版本信息
+export interface VersionFormData {
+    version: string;
+    versionDescription: string;
+    seedFile?: UploadFile; // 表单中的文件对象
+}
+
+// 用于展示的版本信息(后端返回)
+export interface Version {
+    version: string;
+    versionDescription: string;
+    seedFile: string; // 文件URL或路径
+    uploadedAt?: string;
+    fileSize?: number;
+}
+
+// ==================== 作品相关 ====================
+
+// 基础信息(表单用)
+export interface BasicInfo {
+    artworkName: string;
+    artworkCategory: ArtworkCategory;
+    artworkDescription: string;
+}
+
+// 封面信息(表单用)
+export interface CoverInfo {
+    coverFile?: UploadFile;
+}
+
+// 表单数据结构
+export interface WorkFormData {
+    basicInfo: BasicInfo;
+    coverInfo: CoverInfo;
+    versions: VersionFormData[];
+}
+
+// 完整的作品数据(后端返回/展示用)
+export interface ArtworkData {
+    artworkId: string;
+    artworkCover: string;
+    author: string;
+    authorId: string;
+    artworkName: string;
+    artworkCategory: ArtworkCategory;
+    artworkDescription: string;
+    versionList: Version[];
+    comments: Comment[];
+    usersSeedingCurrently: User[];
+    usersSeedingHistory: HistoryUser[];
+    createdAt?: string;
+    updatedAt?: string;
+    downloadCount?: number;
+    likeCount?: number;
+}
+
+// ==================== 表单相关 ====================
+
+export interface StepFormProps {
+    data: WorkFormData;
+    onUpdate: (field: keyof WorkFormData, value: BasicInfo | CoverInfo | VersionFormData[]) => void;
+    onNext?: () => void;
+    onPrev?: () => void;
+}
+
+// ==================== 常量定义 ====================
+
+export const ARTWORK_CATEGORIES = [
+    { label: '概念设计', value: '概念设计' },
+    { label: 'UI/UX设计', value: 'UI/UX设计' },
+    { label: '3D建模', value: '3D建模' },
+    { label: '摄影作品', value: '摄影作品' },
+    { label: '音乐制作', value: '音乐制作' },
+    { label: '前端开发', value: '前端开发' },
+    { label: '插画艺术', value: '插画艺术' },
+    { label: '动画制作', value: '动画制作' },
+    { label: '视频剪辑', value: '视频剪辑' },
+    { label: '其他', value: '其他' },
+];
+
+// 提取分类值的联合类型
+export type ArtworkCategory = '概念设计' | 'UI/UX设计' | '3D建模' | '摄影作品' | '音乐制作' | '前端开发' | '插画艺术' | '动画制作' | '视频剪辑' | '其他';
+
+// 分类选项类型(用于 Select 组件)
+export interface ArtworkCategoryOption {
+    label: string;
+    value: ArtworkCategory;
+}
+
+// ==================== 工具函数 ====================
+
+/**
+ * 解析上传大小字符串为MB数值
+ * @param uploadStr 上传大小字符串,如 "1.5GB", "500MB"
+ * @returns 大小值(以MB为单位)
+ */
+export const parseUploadSize = (uploadStr: string): number => {
+    const match = uploadStr.match(/(\d+(?:\.\d+)?)\s*(GB|MB|KB|TB)?/i);
+    if (!match) return 0;
+    
+    const size = parseFloat(match[1]);
+    const unit = (match[2] || '').toUpperCase();
+    
+    const multipliers: Record<string, number> = {
+        'TB': 1024 * 1024,
+        'GB': 1024,
+        'MB': 1,
+        'KB': 1 / 1024,
+        '': 1
+    };
+    
+    return size * (multipliers[unit] || 1);
+};
+
+/**
+ * 格式化文件大小为可读字符串
+ * @param sizeInMB 文件大小(MB)
+ * @returns 格式化后的字符串
+ */
+export const formatFileSize = (sizeInMB: number): string => {
+    if (sizeInMB >= 1024) {
+        return `${(sizeInMB / 1024).toFixed(1)}GB`;
+    } else if (sizeInMB >= 1) {
+        return `${sizeInMB.toFixed(1)}MB`;
+    } else {
+        return `${(sizeInMB * 1024).toFixed(0)}KB`;
+    }
+};
+
+/**
+ * 格式化日期
+ * @param dateString 日期字符串
+ * @returns 格式化后的日期字符串
+ */
+export const formatDate = (dateString?: string): string => {
+    if (!dateString) return '';
+    
+    const date = new Date(dateString);
+    const now = new Date();
+    const diffInHours = (now.getTime() - date.getTime()) / (1000 * 60 * 60);
+    
+    if (diffInHours < 1) {
+        return '刚刚';
+    } else if (diffInHours < 24) {
+        return `${Math.floor(diffInHours)}小时前`;
+    } else if (diffInHours < 24 * 7) {
+        return `${Math.floor(diffInHours / 24)}天前`;
+    } else {
+        return date.toLocaleDateString('zh-CN');
+    }
+};
+
+/**
+ * 验证文件大小是否符合要求
+ * @param fileSize 文件大小(字节)
+ * @param maxSizeMB 最大允许大小(MB)
+ * @returns 是否符合要求
+ */
+export const isValidFileSize = (fileSize: number, maxSizeMB: number): boolean => {
+    const fileSizeMB = fileSize / (1024 * 1024);
+    return fileSizeMB <= maxSizeMB;
+};
+
+/**
+ * 验证文件类型是否符合要求
+ * @param fileName 文件名
+ * @param allowedExtensions 允许的扩展名数组
+ * @returns 是否符合要求
+ */
+export const isValidFileType = (fileName: string, allowedExtensions: string[]): boolean => {
+    if (!fileName) return false;
+    const extension = fileName.toLowerCase().split('.').pop();
+    return extension ? allowedExtensions.includes(extension) : false;
+};
+
+/**
+ * 验证图片文件类型
+ * @param fileName 文件名
+ * @returns 是否为有效图片
+ */
+export const isValidImageFile = (fileName: string): boolean => {
+    return isValidFileType(fileName, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg']);
+};
+
+/**
+ * 安全地解析JSON字符串
+ * @param jsonString JSON字符串
+ * @returns 解析结果或null
+ */
+export const safeJsonParse = <T = unknown>(jsonString: string): T | null => {
+    try {
+        return JSON.parse(jsonString) as T;
+    } catch {
+        return null;
+    }
+};
+
+// ==================== 类型守卫 ====================
+
+export const isValidArtworkCategory = (category: string): category is ArtworkCategory => {
+    return ARTWORK_CATEGORIES.some(cat => cat.value === category);
+};
+
+export const isComment = (obj: unknown): obj is Comment => {
+    return typeof obj === 'object' && 
+           obj !== null && 
+           'content' in obj && 
+           'author' in obj && 
+           'child' in obj &&
+           typeof (obj as Record<string, unknown>).content === 'string' && 
+           typeof (obj as Record<string, unknown>).author === 'string' && 
+           Array.isArray((obj as Record<string, unknown>).child);
+};
+
+export const isUser = (obj: unknown): obj is User => {
+    return typeof obj === 'object' && 
+           obj !== null && 
+           'userId' in obj && 
+           'username' in obj &&
+           typeof (obj as Record<string, unknown>).userId === 'string' && 
+           typeof (obj as Record<string, unknown>).username === 'string';
+};
+
+export const isHistoryUser = (obj: unknown): obj is HistoryUser => {
+    return isUser(obj) && 
+           'uploadTotal' in obj &&
+           typeof (obj as Record<string, unknown>).uploadTotal === 'string';
+};
+
+export const isVersion = (obj: unknown): obj is Version => {
+    return typeof obj === 'object' && 
+           obj !== null && 
+           'version' in obj && 
+           'versionDescription' in obj && 
+           'seedFile' in obj &&
+           typeof (obj as Record<string, unknown>).version === 'string' && 
+           typeof (obj as Record<string, unknown>).versionDescription === 'string' && 
+           typeof (obj as Record<string, unknown>).seedFile === 'string';
+};
+
+export const isArtworkData = (obj: unknown): obj is ArtworkData => {
+    if (typeof obj !== 'object' || obj === null) return false;
+    
+    const artwork = obj as Record<string, unknown>;
+    
+    return typeof artwork.artworkId === 'string' &&
+           typeof artwork.artworkCover === 'string' &&
+           typeof artwork.author === 'string' &&
+           typeof artwork.authorId === 'string' &&
+           typeof artwork.artworkName === 'string' &&
+           typeof artwork.artworkCategory === 'string' &&
+           typeof artwork.artworkDescription === 'string' &&
+           Array.isArray(artwork.versionList) &&
+           Array.isArray(artwork.comments) &&
+           Array.isArray(artwork.usersSeedingCurrently) &&
+           Array.isArray(artwork.usersSeedingHistory);
+};
\ No newline at end of file
diff --git a/src/feature/work/utils.ts b/src/feature/work/utils.ts
new file mode 100644
index 0000000..a10d95f
--- /dev/null
+++ b/src/feature/work/utils.ts
@@ -0,0 +1,155 @@
+import type { RcFile } from 'antd/es/upload';
+
+// 将文件转换为Base64
+export const getBase64 = (file: RcFile): Promise<string> =>
+    new Promise((resolve, reject) => {
+        const reader = new FileReader();
+        reader.readAsDataURL(file);
+        reader.onload = () => resolve(reader.result as string);
+        reader.onerror = (error) => reject(error);
+    });
+
+// 验证图片文件
+interface ValidationResult {
+    valid: boolean;
+    message?: string;
+}
+
+export const validateImageFile = (file: RcFile): ValidationResult => {
+    const isImage = file.type.startsWith('image/');
+    if (!isImage) {
+        return { valid: false, message: '只能上传图片文件!' };
+    }
+
+    const isLt5M = file.size / 1024 / 1024 < 5;
+    if (!isLt5M) {
+        return { valid: false, message: '图片大小不能超过 5MB!' };
+    }
+
+    return { valid: true };
+};
+
+// 验证种子文件
+export const validateSeedFile = (file: RcFile): ValidationResult => {
+    const isLt100M = file.size / 1024 / 1024 < 100;
+    if (!isLt100M) {
+        return { valid: false, message: '种子文件大小不能超过 100MB!' };
+    }
+
+    return { valid: true };
+};
+
+// 格式化文件大小
+export const formatFileSize = (bytes: number): string => {
+    if (bytes === 0) return '0 Bytes';
+
+    const k = 1024;
+    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
+    const i = Math.floor(Math.log(bytes) / Math.log(k));
+
+    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
+};
+
+// 防抖函数 - 修复版本
+export const debounce = <T extends (...args: unknown[]) => unknown>(
+    func: T,
+    wait: number
+): ((...args: Parameters<T>) => void) => {
+    let timeout: ReturnType<typeof setTimeout>;
+    
+    return (...args: Parameters<T>) => {
+        clearTimeout(timeout);
+        timeout = setTimeout(() => func(...args), wait);
+    };
+};
+
+// 节流函数 - 修复版本
+export const throttle = <T extends (...args: unknown[]) => unknown>(
+    func: T,
+    limit: number
+): ((...args: Parameters<T>) => void) => {
+    let inThrottle: boolean;
+    
+    return (...args: Parameters<T>) => {
+        if (!inThrottle) {
+            func(...args);
+            inThrottle = true;
+            setTimeout(() => inThrottle = false, limit);
+        }
+    };
+};
+// 生成唯一ID
+export const generateId = (): string => {
+    return Date.now().toString(36) + Math.random().toString(36).substr(2);
+};
+
+// 安全的JSON解析
+export const safeJsonParse = <T>(str: string, defaultValue: T): T => {
+    try {
+        return JSON.parse(str) as T;
+    } catch {
+        return defaultValue;
+    }
+};
+
+// 检查是否为空值
+export const isEmpty = (value: unknown): boolean => {
+    if (value === null || value === undefined) return true;
+    if (typeof value === 'string') return value.trim() === '';
+    if (Array.isArray(value)) return value.length === 0;
+    if (typeof value === 'object') return Object.keys(value).length === 0;
+    return false;
+};
+
+// URL参数解析
+export const parseUrlParams = (url: string): Record<string, string> => {
+    const params: Record<string, string> = {};
+    const urlObj = new URL(url);
+    
+    urlObj.searchParams.forEach((value, key) => {
+        params[key] = value;
+    });
+    
+    return params;
+};
+
+// 时间格式化
+export const formatDate = (date: Date | string | number, format: string = 'YYYY-MM-DD HH:mm:ss'): string => {
+    const d = new Date(date);
+    
+    const year = d.getFullYear();
+    const month = String(d.getMonth() + 1).padStart(2, '0');
+    const day = String(d.getDate()).padStart(2, '0');
+    const hours = String(d.getHours()).padStart(2, '0');
+    const minutes = String(d.getMinutes()).padStart(2, '0');
+    const seconds = String(d.getSeconds()).padStart(2, '0');
+    
+    return format
+        .replace('YYYY', year.toString())
+        .replace('MM', month)
+        .replace('DD', day)
+        .replace('HH', hours)
+        .replace('mm', minutes)
+        .replace('ss', seconds);
+};
+
+// 相对时间格式化(例如:2小时前)
+export const formatRelativeTime = (date: Date | string | number): string => {
+    const now = new Date();
+    const target = new Date(date);
+    const diff = now.getTime() - target.getTime();
+    
+    const seconds = Math.floor(diff / 1000);
+    const minutes = Math.floor(seconds / 60);
+    const hours = Math.floor(minutes / 60);
+    const days = Math.floor(hours / 24);
+    const months = Math.floor(days / 30);
+    const years = Math.floor(months / 12);
+    
+    if (years > 0) return `${years}年前`;
+    if (months > 0) return `${months}个月前`;
+    if (days > 0) return `${days}天前`;
+    if (hours > 0) return `${hours}小时前`;
+    if (minutes > 0) return `${minutes}分钟前`;
+    return '刚刚';
+};
\ No newline at end of file
diff --git a/src/feature/work/workSlice.ts b/src/feature/work/workSlice.ts
new file mode 100644
index 0000000..6b2c12c
--- /dev/null
+++ b/src/feature/work/workSlice.ts
@@ -0,0 +1,469 @@
+import { createSlice, createAsyncThunk, type PayloadAction } from '@reduxjs/toolkit';
+import type { ArtworkData, Comment } from './types';
+import type { RootState } from '../../store/store';
+import { getArtworkById, getCommentsForArtwork } from './mockData';
+
+// ==================== 类型定义 ====================
+interface WorkState {
+    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;
+    };
+}
+
+interface FetchCommentsParams {
+    workId: string;
+    page: number;
+    pageSize: number;
+}
+
+interface AddCommentParams {
+    workId: string;
+    content: string;
+    parentId?: string;
+}
+
+interface UpdateArtworkParams {
+    workId: string;
+    updates: Partial<ArtworkData>;
+}
+
+interface DeleteCommentParams {
+    workId: string;
+    commentId: string;
+}
+
+interface SetCommentsPageParams {
+    current: number;
+    pageSize: number;
+}
+
+// ==================== 初始状态 ====================
+const initialState: WorkState = {
+    currentArtwork: null,
+    loading: {
+        artwork: false,
+        comments: false,
+        addComment: false,
+        updateArtwork: false,
+        deleteComment: false,
+    },
+    error: {
+        artwork: null,
+        comments: null,
+        addComment: null,
+        updateArtwork: null,
+        deleteComment: null,
+    },
+    comments: {
+        list: [],
+        total: 0,
+        current: 1,
+        pageSize: 5,
+    },
+};
+
+// ==================== Mock 工具函数 ====================
+
+// 模拟网络延迟
+const mockDelay = (ms: number = 800): Promise<void> => 
+    new Promise(resolve => setTimeout(resolve, ms));
+
+// 生成新评论ID
+const generateCommentId = (): string => {
+    return `comment_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
+};
+
+// 生成新评论数据
+const createNewComment = (content: string): Comment => {
+    return {
+        id: generateCommentId(),
+        content,
+        author: '当前用户', // 实际应用中从用户状态获取
+        authorId: 'current_user_id',
+        createdAt: new Date().toLocaleString('zh-CN'),
+        child: [],
+    };
+};
+
+// 递归删除评论
+const removeCommentById = (comments: Comment[], targetId: string): Comment[] => {
+    return comments.filter(comment => {
+        if (comment.id === targetId) {
+            return false;
+        }
+        if (comment.child.length > 0) {
+            comment.child = removeCommentById(comment.child, targetId);
+        }
+        return true;
+    });
+};
+
+// 递归添加回复评论
+const addReplyToComment = (comments: Comment[], parentId: string, newComment: Comment): Comment[] => {
+    return comments.map(comment => {
+        if (comment.id === parentId) {
+            return {
+                ...comment,
+                child: [...comment.child, newComment]
+            };
+        }
+        if (comment.child.length > 0) {
+            return {
+                ...comment,
+                child: addReplyToComment(comment.child, parentId, newComment)
+            };
+        }
+        return comment;
+    });
+};
+
+// 分页处理评论
+const paginateComments = (comments: Comment[], page: number, pageSize: number): Comment[] => {
+    const startIndex = (page - 1) * pageSize;
+    const endIndex = startIndex + pageSize;
+    return comments.slice(startIndex, endIndex);
+};
+
+// ==================== 异步 Actions ====================
+
+// 获取作品详情
+export const fetchArtworkDetail = createAsyncThunk<
+    ArtworkData,
+    string,
+    { rejectValue: string }
+>(
+    'work/fetchArtworkDetail',
+    async (workId: string, { rejectWithValue }) => {
+        try {
+            await mockDelay(600); // 模拟网络延迟
+            
+            const artwork = getArtworkById(workId);
+            
+            if (!artwork) {
+                throw new Error(`作品 ${workId} 不存在`);
+            }
+            
+            return artwork;
+        } catch (error) {
+            const message = error instanceof Error ? error.message : '获取作品详情失败';
+            return rejectWithValue(message);
+        }
+    }
+);
+
+// 获取评论列表
+export const fetchComments = createAsyncThunk<
+    { comments: Comment[]; total: number },
+    FetchCommentsParams,
+    { rejectValue: string }
+>(
+    'work/fetchComments',
+    async ({ workId, page, pageSize }, { rejectWithValue }) => {
+        try {
+            await mockDelay(400); // 模拟网络延迟
+            
+            const allComments = getCommentsForArtwork(workId);
+            const paginatedComments = paginateComments(allComments, page, pageSize);
+            
+            return {
+                comments: paginatedComments,
+                total: allComments.length
+            };
+        } catch (error) {
+            const message = error instanceof Error ? error.message : '获取评论失败';
+            return rejectWithValue(message);
+        }
+    }
+);
+
+// 添加评论
+export const addComment = createAsyncThunk<
+    Comment,
+    AddCommentParams,
+    { rejectValue: string }
+>(
+    'work/addComment',
+    async ({ workId, content }, { rejectWithValue }) => {
+        try {
+            await mockDelay(500); // 模拟网络延迟
+            
+            // 验证作品是否存在
+            const artwork = getArtworkById(workId);
+            if (!artwork) {
+                throw new Error('作品不存在');
+            }
+            
+            // 创建新评论
+            const newComment = createNewComment(content);
+            
+            // 模拟服务器返回完整的评论数据
+            return newComment;
+        } catch (error) {
+            const message = error instanceof Error ? error.message : '添加评论失败';
+            return rejectWithValue(message);
+        }
+    }
+);
+
+// 更新作品信息
+export const updateArtwork = createAsyncThunk<
+    ArtworkData,
+    UpdateArtworkParams,
+    { rejectValue: string }
+>(
+    'work/updateArtwork',
+    async ({ workId, updates }, { rejectWithValue }) => {
+        try {
+            await mockDelay(1000); // 模拟网络延迟
+            
+            const currentArtwork = getArtworkById(workId);
+            if (!currentArtwork) {
+                throw new Error('作品不存在');
+            }
+            
+            // 模拟文件上传处理
+            const processedUpdates = { ...updates };
+            
+            // 如果包含 blob URL,模拟转换为正式URL
+            if (updates.artworkCover && updates.artworkCover.startsWith('blob:')) {
+                // 模拟上传成功,生成新的图片URL
+                processedUpdates.artworkCover = `https://picsum.photos/300/400?random=${Date.now()}`;
+            }
+            
+            // 处理版本文件上传
+            if (updates.versionList) {
+                processedUpdates.versionList = updates.versionList.map(version => ({
+                    ...version,
+                    seedFile: version.seedFile.startsWith?.('blob:') 
+                        ? `magnet:?xt=urn:btih:updated_${Date.now()}&dn=${version.version}.zip`
+                        : version.seedFile
+                }));
+            }
+            
+            // 合并更新后的数据
+            const updatedArtwork: ArtworkData = {
+                ...currentArtwork,
+                ...processedUpdates,
+                updatedAt: new Date().toISOString(),
+            };
+            
+            return updatedArtwork;
+        } catch (error) {
+            const message = error instanceof Error ? error.message : '更新作品失败';
+            return rejectWithValue(message);
+        }
+    }
+);
+
+// 删除评论
+export const deleteComment = createAsyncThunk<
+    string,
+    DeleteCommentParams,
+    { rejectValue: string }
+>(
+    'work/deleteComment',
+    async ({ workId, commentId }, { rejectWithValue }) => {
+        try {
+            await mockDelay(300); // 模拟网络延迟
+            
+            // 验证作品是否存在
+            const artwork = getArtworkById(workId);
+            if (!artwork) {
+                throw new Error('作品不存在');
+            }
+            
+            // 模拟删除成功
+            return commentId;
+        } catch (error) {
+            const message = error instanceof Error ? error.message : '删除评论失败';
+            return rejectWithValue(message);
+        }
+    }
+);
+
+// ==================== Slice 定义 ====================
+const workSlice = createSlice({
+    name: 'work',
+    initialState,
+    reducers: {
+        // 清除当前作品
+        clearCurrentArtwork: (state) => {
+            state.currentArtwork = null;
+            state.comments.list = [];
+            state.comments.total = 0;
+            state.comments.current = 1;
+            // 清除所有错误状态
+            Object.keys(state.error).forEach(key => {
+                state.error[key as keyof typeof state.error] = null;
+            });
+        },
+        
+        // 设置评论分页
+        setCommentsPage: (state, action: PayloadAction<SetCommentsPageParams>) => {
+            state.comments.current = action.payload.current;
+            state.comments.pageSize = action.payload.pageSize;
+        },
+        
+        // 清除特定错误
+        clearError: (state, action: PayloadAction<keyof WorkState['error']>) => {
+            state.error[action.payload] = null;
+        },
+        
+        // 清除所有错误
+        clearAllErrors: (state) => {
+            Object.keys(state.error).forEach(key => {
+                state.error[key as keyof typeof state.error] = null;
+            });
+        },
+    },
+    extraReducers: (builder) => {
+        // 获取作品详情
+        builder
+            .addCase(fetchArtworkDetail.pending, (state) => {
+                state.loading.artwork = true;
+                state.error.artwork = null;
+            })
+            .addCase(fetchArtworkDetail.fulfilled, (state, action) => {
+                state.loading.artwork = false;
+                state.currentArtwork = action.payload;
+                state.error.artwork = null;
+            })
+            .addCase(fetchArtworkDetail.rejected, (state, action) => {
+                state.loading.artwork = false;
+                state.error.artwork = action.payload || '获取作品详情失败';
+            });
+
+        // 获取评论列表
+        builder
+            .addCase(fetchComments.pending, (state) => {
+                state.loading.comments = true;
+                state.error.comments = null;
+            })
+            .addCase(fetchComments.fulfilled, (state, action) => {
+                state.loading.comments = false;
+                state.comments.list = action.payload.comments;
+                state.comments.total = action.payload.total;
+                state.error.comments = null;
+            })
+            .addCase(fetchComments.rejected, (state, action) => {
+                state.loading.comments = false;
+                state.error.comments = action.payload || '获取评论失败';
+            });
+
+        // 添加评论
+        builder
+            .addCase(addComment.pending, (state) => {
+                state.loading.addComment = true;
+                state.error.addComment = null;
+            })
+            .addCase(addComment.fulfilled, (state, action) => {
+                state.loading.addComment = false;
+                
+                const newComment = action.payload;
+                const { parentId } = action.meta.arg;
+                
+                if (parentId) {
+                    // 添加回复评论
+                    state.comments.list = addReplyToComment(state.comments.list, parentId, newComment);
+                } else {
+                    // 添加顶级评论
+                    state.comments.list.unshift(newComment);
+                    state.comments.total += 1;
+                }
+                
+                state.error.addComment = null;
+            })
+            .addCase(addComment.rejected, (state, action) => {
+                state.loading.addComment = false;
+                state.error.addComment = action.payload || '添加评论失败';
+            });
+
+        // 更新作品信息
+        builder
+            .addCase(updateArtwork.pending, (state) => {
+                state.loading.updateArtwork = true;
+                state.error.updateArtwork = null;
+            })
+            .addCase(updateArtwork.fulfilled, (state, action) => {
+                state.loading.updateArtwork = false;
+                state.currentArtwork = action.payload;
+                state.error.updateArtwork = null;
+            })
+            .addCase(updateArtwork.rejected, (state, action) => {
+                state.loading.updateArtwork = false;
+                state.error.updateArtwork = action.payload || '更新作品失败';
+            });
+
+        // 删除评论
+        builder
+            .addCase(deleteComment.pending, (state) => {
+                state.loading.deleteComment = true;
+                state.error.deleteComment = null;
+            })
+            .addCase(deleteComment.fulfilled, (state, action) => {
+                state.loading.deleteComment = false;
+                
+                // 从评论列表中移除已删除的评论
+                state.comments.list = removeCommentById(state.comments.list, action.payload);
+                state.comments.total = Math.max(0, state.comments.total - 1);
+                state.error.deleteComment = null;
+            })
+            .addCase(deleteComment.rejected, (state, action) => {
+                state.loading.deleteComment = false;
+                state.error.deleteComment = action.payload || '删除评论失败';
+            });
+    },
+});
+
+// ==================== Actions 导出 ====================
+export const { 
+    clearCurrentArtwork, 
+    setCommentsPage, 
+    clearError, 
+    clearAllErrors 
+} = workSlice.actions;
+
+// ==================== Selectors 导出 ====================
+export const selectCurrentArtwork = (state: RootState): ArtworkData | null => 
+    state.work.currentArtwork;
+
+export const selectWorkLoading = (state: RootState): WorkState['loading'] => 
+    state.work.loading;
+
+export const selectWorkError = (state: RootState): WorkState['error'] => 
+    state.work.error;
+
+export const selectComments = (state: RootState): WorkState['comments'] => 
+    state.work.comments;
+
+export const selectIsAuthor = (state: RootState): boolean => {
+    const currentUser = state.user;
+    const currentArtwork = state.work.currentArtwork;
+    
+    return Boolean(
+        currentUser?.userid && 
+        currentArtwork?.authorId &&
+        String(currentUser.userid) === String(currentArtwork.authorId)
+    );
+};
+
+// ==================== Reducer 导出 ====================
+export default workSlice.reducer;
\ No newline at end of file