route.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import dbConnect from "../../lib/dbConnect";
  2. import ExchangeHistory from "../../models/ExchangeHistory";
  3. import ExchangeItem from "../../models/ExchangeItem";
  4. import User from "../../models/User";
  5. import PointHistory from "../../models/PointHistory";
  6. import { NextResponse } from "next/server";
  7. import { setCORSHeaders, handleError } from "../../lib/apiUtils";
  8. export async function GET(request) {
  9. await dbConnect();
  10. console.log("GET请求已接收");
  11. try {
  12. const { searchParams } = new URL(request.url);
  13. let query = {};
  14. let itemQuery = {};
  15. for (const [key, value] of searchParams.entries()) {
  16. switch (key) {
  17. case "username":
  18. query.username = { $regex: value, $options: "i" };
  19. break;
  20. case "userId":
  21. query.userId = value;
  22. break;
  23. case "item":
  24. try {
  25. const itemObj = JSON.parse(value);
  26. if (itemObj.title) {
  27. itemQuery.title = {
  28. $regex: itemObj.title,
  29. $options: "i",
  30. };
  31. }
  32. if (itemObj.type) {
  33. itemQuery.type = itemObj.type;
  34. }
  35. } catch (e) {
  36. console.error("Error parsing item JSON:", e);
  37. }
  38. break;
  39. case "status":
  40. query.status = value;
  41. break;
  42. case "exchangeTime":
  43. const [start, end] = value.split(",");
  44. query.exchangeTime = {
  45. $gte: new Date(start),
  46. $lte: new Date(end),
  47. };
  48. break;
  49. }
  50. }
  51. console.log("Query:", query);
  52. console.log("Item Query:", itemQuery);
  53. // 首先查找符合条件的 ExchangeItem
  54. const matchedItems = await ExchangeItem.find(itemQuery).select("_id");
  55. const itemIds = matchedItems.map((item) => item._id);
  56. // 将匹配的 item ID 添加到主查询中
  57. if (itemIds.length > 0) {
  58. query.item = { $in: itemIds };
  59. }
  60. const exchangeHistories = await ExchangeHistory.find(query).populate(
  61. "item",
  62. "title type points"
  63. );
  64. const message =
  65. exchangeHistories.length > 0
  66. ? "成功获取兑换历史"
  67. : "当前没有任何兑换历史";
  68. const response = NextResponse.json(
  69. {
  70. success: true,
  71. data: exchangeHistories,
  72. message,
  73. total: exchangeHistories.length,
  74. },
  75. { status: 200 }
  76. );
  77. return setCORSHeaders(response);
  78. } catch (error) {
  79. console.error("Error in GET /api/exchange-history:", error);
  80. return handleError(error);
  81. }
  82. }
  83. export async function POST(request) {
  84. await dbConnect();
  85. try {
  86. const {
  87. userId,
  88. username,
  89. item,
  90. status,
  91. exchangeInfo,
  92. exchangeTime,
  93. exchangeCount,
  94. } = await request.json();
  95. // 获取用户当前积分
  96. const user = await User.findById(userId);
  97. if (!user) {
  98. return setCORSHeaders(
  99. NextResponse.json(
  100. { success: false, error: "未找到用户" },
  101. { status: 404 }
  102. )
  103. );
  104. }
  105. const currentPoints = user.points;
  106. const pointsToDeduct = item.points;
  107. // 检查用户积分是否足够
  108. if (currentPoints < pointsToDeduct) {
  109. return setCORSHeaders(
  110. NextResponse.json(
  111. {
  112. success: false,
  113. error: "积分不足",
  114. currentPoints: currentPoints,
  115. requiredPoints: pointsToDeduct,
  116. },
  117. { status: 400 }
  118. )
  119. );
  120. }
  121. // 创建新的兑换历史记录
  122. const newExchangeHistory = new ExchangeHistory({
  123. userId,
  124. username,
  125. item,
  126. status,
  127. exchangeInfo,
  128. exchangeTime,
  129. exchangeCount,
  130. });
  131. await newExchangeHistory.save();
  132. // 更新用户积分
  133. const updatedUser = await User.findByIdAndUpdate(
  134. userId,
  135. { $inc: { points: -pointsToDeduct } },
  136. { new: true, runValidators: true }
  137. );
  138. if (!updatedUser) {
  139. throw new Error("更新用户积分失败");
  140. }
  141. console.log(
  142. `用户 ${updatedUser.username} 的积分已扣除 ${pointsToDeduct} 点`
  143. );
  144. // 创建积分加减历史记录
  145. const reason = `兑换: ${item.title.replace(/<[^>]*>/g, "").trim()}`;
  146. const pointHistory = new PointHistory({
  147. user: updatedUser._id,
  148. points: -pointsToDeduct,
  149. reason: reason,
  150. });
  151. await pointHistory.save();
  152. const response = NextResponse.json(
  153. {
  154. success: true,
  155. message: "兑换历史创建成功",
  156. data: newExchangeHistory,
  157. },
  158. { status: 201 }
  159. );
  160. return setCORSHeaders(response);
  161. } catch (error) {
  162. console.error("创建兑换历史时出错:", error);
  163. return handleError(error);
  164. }
  165. }
  166. export async function PUT(request) {
  167. await dbConnect();
  168. try {
  169. const { id, ...updateData } = await request.json();
  170. console.log(id, updateData);
  171. const updatedExchangeHistory = await ExchangeHistory.findByIdAndUpdate(
  172. id,
  173. updateData,
  174. {
  175. new: true,
  176. runValidators: true,
  177. }
  178. );
  179. if (!updatedExchangeHistory) {
  180. return NextResponse.json(
  181. { success: false, error: "未找到兑换历史" },
  182. { status: 404 }
  183. );
  184. }
  185. const response = NextResponse.json(
  186. { success: true, data: updatedExchangeHistory },
  187. { status: 200 }
  188. );
  189. return setCORSHeaders(response);
  190. } catch (error) {
  191. return handleError(error);
  192. }
  193. }
  194. export async function DELETE(request) {
  195. await dbConnect();
  196. try {
  197. const url = new URL(request.url);
  198. const id = url.searchParams.get("id");
  199. if (!id) {
  200. return NextResponse.json(
  201. { success: false, error: "需要提供兑换历史ID" },
  202. { status: 400 }
  203. );
  204. }
  205. const deletedExchangeHistory = await ExchangeHistory.findByIdAndDelete(id);
  206. if (!deletedExchangeHistory) {
  207. return NextResponse.json(
  208. { success: false, error: "未找到兑换历史" },
  209. { status: 404 }
  210. );
  211. }
  212. const response = NextResponse.json(
  213. { success: true, message: "兑换历史删除成功" },
  214. { status: 200 }
  215. );
  216. return setCORSHeaders(response);
  217. } catch (error) {
  218. return handleError(error);
  219. }
  220. }
  221. export async function OPTIONS() {
  222. const response = new NextResponse(null, { status: 204 });
  223. return setCORSHeaders(response);
  224. }