我是人,我做了悬赏中心,可以进行悬赏哦

Change-Id: I845de799a633be286a6fadee2b7aa533238c3652
diff --git a/src/pages/Bounty/Detail.tsx b/src/pages/Bounty/Detail.tsx
new file mode 100644
index 0000000..41a25df
--- /dev/null
+++ b/src/pages/Bounty/Detail.tsx
@@ -0,0 +1,231 @@
+import React, { useState, useEffect } from 'react';
+import { Button, Descriptions, List, message, Tag } from 'antd';
+import axios from 'axios'; // 新增 axios 导入
+import { useParams } from 'umi';
+
+import { getBountyDetail, getProfile } from '@/services/bounty/bounty';
+import { downloadAttachment,adoptSubmission } from '@/services/bounty/bounty';
+
+
+
+const BountyDetail: React.FC = () => {
+  const [bounty, setBounty] = useState<API.BountyDetail>({} as API.BountyDetail);
+  const [loading, setLoading] = useState(false); // 新增加载状态
+  const [currentUserId, setCurrentUserId] = useState<number | null>(null);
+
+  console.log('当前用户id:',currentUserId);
+  console.log('悬赏发布用户id:',bounty.creator_id);
+
+  const handleAdoptSubmission = async (submissionId: number, currentStatus: number) => {
+    console.log('【采纳请求】', {
+      submissionId,
+      currentStatus,
+      bounty: bounty,
+      currentUserId
+    });
+
+    if (currentStatus === 1) return;
+
+    try {
+      const res = await adoptSubmission(submissionId);
+      console.log('【采纳响应】', {
+        status: res.status,
+        data: res.data,
+        headers: res.headers
+      });
+
+      if (res.code === 200) {
+        message.success('采纳成功');
+        setBounty(prev => {
+          console.log('【状态更新】', {
+            old: prev.submissions,
+            new: prev.submissions?.map(sub =>
+              sub.id === submissionId ? { ...sub, status: 1 } : sub
+            )
+          });
+
+          return {
+            ...prev,
+            submissions: prev.submissions?.map(sub =>
+              sub.id === submissionId ? { ...sub, status: 1 } : sub
+            )
+          };
+        });
+      } else {
+        message.error(`采纳失败: ${res.msg}`);
+      }
+    } catch (error: any) {
+      console.error('【采纳错误】', {
+        error: error,
+        response: error.response?.data,
+        status: error.response?.status
+      });
+
+      message.error(`网络异常: ${error.message}`);
+    }
+  };
+
+  const handleDownload = async (attachmentPath: string, submissionUserId: number) => {
+    try {
+
+      // ✅ 新增权限校验
+      if (!currentUserId || (currentUserId !== bounty.creator_id && currentUserId !== submissionUserId)) {
+        message.error('无权查看此附件');
+        return;
+      }
+
+      const blob = await downloadAttachment(attachmentPath);
+      const url = window.URL.createObjectURL(blob);
+      const a = document.createElement('a');
+      a.href = url;
+      a.download = attachmentPath.split('/').pop() || 'file';
+      document.body.appendChild(a);
+      a.click();
+      a.remove();
+      window.URL.revokeObjectURL(url);
+    } catch (err) {
+      message.error('下载附件失败,请重试');
+      console.error('下载附件失败:', err);
+    }
+  };
+
+
+
+  useEffect(() => {
+    const fetchProfile = async () => {
+      try {
+        const res = await getProfile(); // 调用后端接口
+        if (res && res.code === 200) {
+          setCurrentUserId(res.data.userId); // 从接口获取 userId
+        } else {
+          message.error('获取用户信息失败');
+        }
+      } catch (err) {
+        console.error('获取用户信息失败:', err);
+      }
+    };
+    fetchProfile();
+  }, []);
+
+
+  const { id } = useParams<{ id: string }>();
+
+  // 修改加载方法(适配统一请求)✅
+  useEffect(() => {
+    if (!id) return;
+
+    const loadBountyDetail = async () => {
+      try {
+        setLoading(true);
+        const res = await getBountyDetail(id);
+        console.log('【详情响应】原始数据:', res); // 👈 关键日志
+
+        if (res && res.code === 200) {
+          setBounty(res.data);
+          // 👇 新增:检查 submissions 数据结构
+          console.log('【submissions 数据】:', res.data.submissions);
+        } else {
+          throw new Error('响应结构异常');
+        }
+      } catch (err) {
+        console.error('【详情请求】错误:', err);
+      } finally {
+        setLoading(false);
+      }
+    };
+
+    loadBountyDetail();
+  }, [id]);
+
+  return (
+    <div className="page-container">
+      <h2>悬赏详情</h2>
+
+      {/* 基础信息 */}
+      <Descriptions title="悬赏信息" bordered>
+        <Descriptions.Item label="标题">{bounty.title}</Descriptions.Item>
+        <Descriptions.Item label="发布者ID">{bounty.creator_id}</Descriptions.Item> // ✅ 新增字段
+        <Descriptions.Item label="奖励">{bounty.reward}</Descriptions.Item>
+        <Descriptions.Item label="状态">
+          {bounty.status === 0 ? '进行中' : bounty.status === 1 ? '已完成' : '已关闭'}
+        </Descriptions.Item>
+        <Descriptions.Item label="截止时间">{bounty.deadline}</Descriptions.Item>
+        <Descriptions.Item label="描述" span={3}>
+          {bounty.description}
+        </Descriptions.Item>
+      </Descriptions>
+
+      {/* 回复列表 */}
+      {bounty.submissions && (
+        <div style={{ marginTop: 24 }}>
+          <h3>回复列表</h3>
+          <List
+            dataSource={bounty.submissions}
+            renderItem={(item) => (
+              <List.Item>
+                <List.Item.Meta
+                  title={`回复人ID:${item.userId}`}
+                  description={
+                    <>
+                      {item.content}
+                      {/* 状态标签 */}
+                      <span style={{ marginLeft: 16 }}>
+          {item.status === 1 ? (
+            <Tag color="green">已采纳</Tag>
+          ) : (
+            <Tag color="red">未被采纳</Tag>
+          )}
+        </span>
+                    </>
+                  }
+                />
+
+                {/* 发布者操作按钮 */}
+                {currentUserId === bounty.creator_id && (
+                  <Button
+                    type="primary"
+                    size="small"
+                    onClick={() => handleAdoptSubmission(item.id, item.status)}
+                    disabled={item.status === 1}
+                  >
+                    {item.status === 1 ? '已采纳' : '采纳'}
+                  </Button>
+                )}
+
+                {/* 附件下载 */}
+                {item.attachment && currentUserId === bounty.creator_id && (
+                  <a onClick={(e) => handleDownload(item.attachment, item.userId)} style={{ marginLeft: 8 }}>
+                    查看附件
+                  </a>
+                )}
+              </List.Item>
+            )}
+          />
+        </div>
+      )}
+    </div>
+  );
+};
+
+// 定义类型(建议单独放在src/types.d.ts中)
+declare namespace API {
+  export interface BountyDetail {
+    id: number;
+    title: string;
+    creator_id: number; // ✅ 新增:发布者ID
+    description: string;
+    reward: number;
+    deadline: string;
+    status: number;
+    submissions: Array<{
+      id: number;
+      userId: number; // ✅ 替换 id 为 userId
+      username: string;
+      content: string;
+      attachment: string;
+      status: number;
+    }>;
+  }
+}
+
+export default BountyDetail;