前端简单界面
Change-Id: I7df9774daf4df8d92b13e659effe426ab0b6180b
diff --git a/pt--frontend/src/components/RequestBoard.jsx b/pt--frontend/src/components/RequestBoard.jsx
new file mode 100644
index 0000000..f90f2fb
--- /dev/null
+++ b/pt--frontend/src/components/RequestBoard.jsx
@@ -0,0 +1,300 @@
+import React, { useState, useEffect } from 'react';
+import {
+ createRequest,
+ deleteRequest,
+ updateMoney,
+ findByUserid,
+ findByName,
+ getTotalMoneyByName,
+ updateLoaduserByName,
+} from '../api/request';
+
+const RequestBoard = ({ currentUserId }) => {
+ const [requests, setRequests] = useState([]); // 始终存储当前用户的求助帖
+ const [searchedRequests, setSearchedRequests] = useState([]); // 存储搜索结果
+ const [formData, setFormData] = useState({
+ userid: currentUserId,
+ name: '',
+ plot: '',
+ money: '',
+ year: '',
+ country: '',
+ photo: null,
+ });
+ const [searchName, setSearchName] = useState('');
+ const [totalMoney, setTotalMoney] = useState(null);
+
+ // 获取当前用户求助帖
+ const loadUserRequests = async () => {
+ const data = await findByUserid(currentUserId);
+ setRequests(data);
+ };
+
+ useEffect(() => {
+ loadUserRequests();
+ }, []);
+
+ // 表单变更处理
+ const handleChange = (e) => {
+ const { name, value, files } = e.target;
+ setFormData((prev) => ({
+ ...prev,
+ [name]: files ? files[0] : value,
+ }));
+ };
+
+ // 提交创建
+ const handleCreate = async (e) => {
+ e.preventDefault();
+ const fd = new FormData();
+ Object.entries(formData).forEach(([key, value]) => {
+ if (value !== '' && value !== null) fd.append(key, value);
+ });
+
+ const res = await createRequest(fd);
+ if (res.data === true) {
+ alert('创建成功');
+ setFormData(prev => ({
+ ...prev,
+ name: '',
+ plot: '',
+ money: '',
+ year: '',
+ country: '',
+ photo: null,
+ }));
+ loadUserRequests(); // 创建成功后刷新当前用户帖子
+ } else {
+ alert('创建失败');
+ }
+ };
+
+ // 删除
+ const handleDelete = async (id) => {
+ await deleteRequest(id);
+ loadUserRequests(); // 删除后刷新当前用户帖子
+ };
+
+ // 更新金额
+ const handleUpdateMoney = async (id, newMoney) => {
+ if (!newMoney) return;
+ await updateMoney(id, newMoney);
+ loadUserRequests(); // 更新金额后刷新当前用户帖子
+ };
+
+ // 按名称搜索并计算总金额
+ const handleSearch = async () => {
+ const data = await findByName(searchName);
+ const total = await getTotalMoneyByName(searchName);
+ setSearchedRequests(data); // 搜索结果存储到独立状态
+ setTotalMoney(total);
+ };
+
+ // 上传更新被协助用户 ID(批量更新同名求助帖)
+ const handleUploadLoaduser = async (name) => {
+ try {
+ await updateLoaduserByName(name, currentUserId);
+ alert('更新成功');
+ loadUserRequests(); // 更新后刷新当前用户帖子
+ setSearchedRequests([]); // 同步清空搜索结果(可选)
+ } catch (error) {
+ alert('更新失败,请稍后重试');
+ console.error(error);
+ }
+ };
+
+ return (
+ <div className="p-4 max-w-4xl mx-auto">
+ <h2 className="text-2xl font-bold mb-4">发布求助帖</h2>
+ <form className="grid grid-cols-2 gap-4 mb-6" onSubmit={handleCreate}>
+ <input
+ name="name"
+ placeholder="标题/名称"
+ className="border p-2"
+ value={formData.name}
+ onChange={handleChange}
+ />
+ <textarea
+ name="plot"
+ placeholder="内容/情节"
+ className="border p-2 col-span-2"
+ value={formData.plot}
+ onChange={handleChange}
+ />
+ <input
+ name="money"
+ type="number"
+ placeholder="金额"
+ className="border p-2"
+ value={formData.money}
+ onChange={handleChange}
+ />
+ <input
+ name="year"
+ type="number"
+ placeholder="年份"
+ className="border p-2"
+ value={formData.year}
+ onChange={handleChange}
+ />
+ <input
+ name="country"
+ placeholder="国家"
+ className="border p-2"
+ value={formData.country}
+ onChange={handleChange}
+ />
+ <input
+ name="photo"
+ type="file"
+ className="border p-2 col-span-2"
+ onChange={handleChange}
+ />
+ <button
+ type="submit"
+ className="bg-blue-500 text-white p-2 col-span-2 rounded"
+ >
+ 发布
+ </button>
+ </form>
+
+ <div className="mb-6">
+ <h3 className="text-xl font-semibold mb-2">查找求助帖</h3>
+ <div className="flex gap-2 mb-2">
+ <input
+ type="text"
+ placeholder="输入标题"
+ value={searchName}
+ onChange={(e) => setSearchName(e.target.value)}
+ className="border p-2 flex-1"
+ />
+ <button
+ onClick={handleSearch}
+ className="bg-green-500 text-white p-2 rounded"
+ >
+ 查找
+ </button>
+ </div>
+ {totalMoney !== null && (
+ <p className="text-gray-700">
+ 该名称对应的总金额:<strong>{totalMoney}</strong>
+ </p>
+ )}
+ </div>
+
+ {/* 搜索结果展示(有搜索结果时显示) */}
+ {searchedRequests.length > 0 && (
+ <div className="mb-6">
+ <h3 className="text-xl font-semibold mb-2">搜索结果</h3>
+ <button
+ onClick={() => {
+ setSearchedRequests([]);
+ setSearchName('');
+ setTotalMoney(null);
+ }}
+ className="bg-gray-500 text-white p-1 px-2 rounded mb-2"
+ >
+ ← 返回我的求助帖
+ </button>
+ {searchedRequests.length === 0 ? (
+ <p className="text-gray-500">无匹配的求助帖</p>
+ ) : (
+ <div className="grid grid-cols-1 gap-4">
+ {searchedRequests.map((request) => (
+ <div key={request.requestid} className="border p-3 rounded shadow">
+ <h4 className="text-lg font-semibold">{request.name}</h4>
+ <p className="text-gray-600 mb-2">{request.plot}</p>
+ <div className="flex gap-2 mb-2">
+ <span>金额:{request.money}</span>
+ <span>年份:{request.year || '未填写'}</span>
+ <span>国家:{request.country || '未填写'}</span>
+ </div>
+ {request.photo && (
+ <img
+ src={`http://localhost:8080${request.photo}`}
+ alt="求助帖"
+ className="w-32 h-auto mb-2"
+ />
+ )}
+ <div className="flex gap-2">
+ <input
+ type="number"
+ placeholder="新金额"
+ onChange={(e) => handleUpdateMoney(request.requestid, e.target.value)}
+ className="border p-1 flex-1"
+ />
+ <button
+ onClick={() => handleDelete(request.requestid)}
+ className="bg-red-500 text-white p-1 px-2 rounded"
+ >
+ 删除
+ </button>
+ <button
+ onClick={() => handleUploadLoaduser(request.name)}
+ className="bg-blue-500 text-white p-1 px-2 rounded"
+ >
+ 上传更新loaduser
+ </button>
+ </div>
+ </div>
+ ))}
+ </div>
+ )}
+ </div>
+ )}
+
+ {/* 我的求助帖展示(无搜索结果时显示) */}
+ {searchedRequests.length === 0 && (
+ <div className="mb-6">
+ <h3 className="text-xl font-semibold mb-2">我的求助帖</h3>
+ {requests.length === 0 ? (
+ <p className="text-gray-500">暂无求助帖</p>
+ ) : (
+ <div className="grid grid-cols-1 gap-4">
+ {requests.map((request) => (
+ <div key={request.requestid} className="border p-3 rounded shadow">
+ <h4 className="text-lg font-semibold">{request.name}</h4>
+ <p className="text-gray-600 mb-2">{request.plot}</p>
+ <div className="flex gap-2 mb-2">
+ <span>金额:{request.money}</span>
+ <span>年份:{request.year || '未填写'}</span>
+ <span>国家:{request.country || '未填写'}</span>
+ </div>
+ {request.photo && (
+ <img
+ src={`http://localhost:8080${request.photo}`}
+ alt="求助帖"
+ className="w-32 h-auto mb-2"
+ />
+ )}
+ <div className="flex gap-2">
+ <input
+ type="number"
+ placeholder="新金额"
+ onChange={(e) => handleUpdateMoney(request.requestid, e.target.value)}
+ className="border p-1 flex-1"
+ />
+ <button
+ onClick={() => handleDelete(request.requestid)}
+ className="bg-red-500 text-white p-1 px-2 rounded"
+ >
+ 删除
+ </button>
+ <button
+ onClick={() => handleUploadLoaduser(request.name)}
+ className="bg-blue-500 text-white p-1 px-2 rounded"
+ >
+ 上传更新loaduser
+ </button>
+ </div>
+ </div>
+ ))}
+ </div>
+ )}
+ </div>
+ )}
+ </div>
+ );
+};
+
+export default RequestBoard;