|
@@ -1,167 +1,188 @@
|
|
|
-package com.etotem.num.controller;
|
|
|
|
|
-
|
|
|
|
|
-import com.etotem.num.common.Result;
|
|
|
|
|
-import com.etotem.num.entity.User;
|
|
|
|
|
-import com.etotem.num.service.ChartService;
|
|
|
|
|
-import com.etotem.num.service.CommissionService;
|
|
|
|
|
-import com.etotem.num.service.ConfigService;
|
|
|
|
|
-import com.etotem.num.service.UserService;
|
|
|
|
|
-import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
-import org.springframework.web.bind.annotation.PostMapping;
|
|
|
|
|
-import org.springframework.web.bind.annotation.RequestBody;
|
|
|
|
|
-import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
|
-import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
-
|
|
|
|
|
-import java.time.LocalDate;
|
|
|
|
|
-import java.util.HashMap;
|
|
|
|
|
-import java.util.Map;
|
|
|
|
|
-
|
|
|
|
|
-@RestController
|
|
|
|
|
-@RequestMapping("/api/profile")
|
|
|
|
|
-public class ProfileController {
|
|
|
|
|
-
|
|
|
|
|
- private final UserService userService;
|
|
|
|
|
- private final CommissionService commissionService;
|
|
|
|
|
- private final ChartService chartService;
|
|
|
|
|
- private final ConfigService configService;
|
|
|
|
|
-
|
|
|
|
|
- public ProfileController(UserService userService, CommissionService commissionService,
|
|
|
|
|
- ChartService chartService, ConfigService configService) {
|
|
|
|
|
- this.userService = userService;
|
|
|
|
|
- this.commissionService = commissionService;
|
|
|
|
|
- this.chartService = chartService;
|
|
|
|
|
- this.configService = configService;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @PostMapping("/info")
|
|
|
|
|
- public Result<Map<String, Object>> getInfo(HttpServletRequest request) {
|
|
|
|
|
- Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
- User user = userService.getById(userId);
|
|
|
|
|
- Map<String, Object> info = new HashMap<>();
|
|
|
|
|
- info.put("id", user.getId());
|
|
|
|
|
- info.put("nickname", user.getNickname());
|
|
|
|
|
- info.put("avatarUrl", user.getAvatarUrl());
|
|
|
|
|
- info.put("referralCode", user.getReferralCode());
|
|
|
|
|
- info.put("isAdmin", user.getIsAdmin());
|
|
|
|
|
- info.put("vipEndTime", user.getVipEndTime());
|
|
|
|
|
- info.put("isVip", userService.isVip(userId));
|
|
|
|
|
- info.put("isSeedPriceUser", userService.isSeedPriceUser(userId));
|
|
|
|
|
- info.put("dailyChartCount", user.getDailyChartCount());
|
|
|
|
|
- info.put("dailyChatCount", user.getDailyChatCount());
|
|
|
|
|
- // US-5.1 profile fields
|
|
|
|
|
- info.put("gender", user.getGender());
|
|
|
|
|
- info.put("birthDate", user.getBirthDate());
|
|
|
|
|
- info.put("bio", user.getBio());
|
|
|
|
|
- info.put("city", user.getCity());
|
|
|
|
|
- info.put("tags", user.getTags());
|
|
|
|
|
- info.put("lookingFor", user.getLookingFor());
|
|
|
|
|
- info.put("profileComplete", user.getProfileComplete());
|
|
|
|
|
- info.put("birthYear", user.getBirthYear());
|
|
|
|
|
- info.put("birthMonth", user.getBirthMonth());
|
|
|
|
|
- info.put("birthDay", user.getBirthDay());
|
|
|
|
|
- return Result.success(info);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Complete user profile on first registration (US-5.1).
|
|
|
|
|
- */
|
|
|
|
|
- @PostMapping("/complete")
|
|
|
|
|
- public Result<?> completeProfile(HttpServletRequest request, @RequestBody Map<String, Object> body) {
|
|
|
|
|
- Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
- Integer gender = body.containsKey("gender") ? ((Number) body.get("gender")).intValue() : null;
|
|
|
|
|
- String birthDateStr = (String) body.get("birthDate");
|
|
|
|
|
- LocalDate birthDate = birthDateStr != null ? LocalDate.parse(birthDateStr) : null;
|
|
|
|
|
- String bio = (String) body.get("bio");
|
|
|
|
|
- String city = (String) body.get("city");
|
|
|
|
|
- String tags = (String) body.get("tags");
|
|
|
|
|
- Integer lookingFor = body.containsKey("lookingFor") ? ((Number) body.get("lookingFor")).intValue() : null;
|
|
|
|
|
- String nickname = (String) body.get("nickname");
|
|
|
|
|
- String avatarUrl = (String) body.get("avatarUrl");
|
|
|
|
|
- userService.completeProfile(userId, gender, birthDate, bio, city, tags, lookingFor, nickname, avatarUrl);
|
|
|
|
|
- return Result.success(null);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Update individual profile fields (US-5.3).
|
|
|
|
|
- */
|
|
|
|
|
- @PostMapping("/update")
|
|
|
|
|
- public Result<?> updateProfile(HttpServletRequest request, @RequestBody Map<String, Object> body) {
|
|
|
|
|
- Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
- Integer gender = body.containsKey("gender") ? ((Number) body.get("gender")).intValue() : null;
|
|
|
|
|
- String birthDateStr = (String) body.get("birthDate");
|
|
|
|
|
- LocalDate birthDate = birthDateStr != null ? LocalDate.parse(birthDateStr) : null;
|
|
|
|
|
- String bio = (String) body.get("bio");
|
|
|
|
|
- String city = (String) body.get("city");
|
|
|
|
|
- String tags = (String) body.get("tags");
|
|
|
|
|
- Integer lookingFor = body.containsKey("lookingFor") ? ((Number) body.get("lookingFor")).intValue() : null;
|
|
|
|
|
- String nickname = (String) body.get("nickname");
|
|
|
|
|
- String avatarUrl = (String) body.get("avatarUrl");
|
|
|
|
|
- userService.completeProfile(userId, gender, birthDate, bio, city, tags, lookingFor, nickname, avatarUrl);
|
|
|
|
|
- return Result.success(null);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @PostMapping("/vip-status")
|
|
|
|
|
- public Result<Map<String, Object>> vipStatus(HttpServletRequest request) {
|
|
|
|
|
- Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
- boolean isVip = userService.isVip(userId);
|
|
|
|
|
- Map<String, Object> result = new HashMap<>();
|
|
|
|
|
- result.put("isVip", isVip);
|
|
|
|
|
- User user = userService.getById(userId);
|
|
|
|
|
- result.put("vipEndTime", user.getVipEndTime());
|
|
|
|
|
- return Result.success(result);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @PostMapping("/quota")
|
|
|
|
|
- public Result<Map<String, Object>> quota(HttpServletRequest request) {
|
|
|
|
|
- Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
- // Reset daily counters if a new day has arrived, so frontend sees fresh data
|
|
|
|
|
- User user = userService.getAndResetDailyQuota(userId);
|
|
|
|
|
- boolean isVip = userService.isVip(userId);
|
|
|
|
|
- Map<String, Object> result = new HashMap<>();
|
|
|
|
|
- result.put("isVip", isVip);
|
|
|
|
|
- result.put("dailyChartCount", user.getDailyChartCount());
|
|
|
|
|
- result.put("dailyChatCount", user.getDailyChatCount());
|
|
|
|
|
- result.put("dailyShareCount", user.getDailyShareCount());
|
|
|
|
|
- result.put("chartLimit", isVip ? -1 : configService.getQuota("chart"));
|
|
|
|
|
- result.put("chatLimit", isVip ? -1 : configService.getQuota("chat"));
|
|
|
|
|
- result.put("shareLimit", isVip ? -1 : configService.getQuota("share"));
|
|
|
|
|
- result.put("dailyAcademicCount", user.getDailyAcademicCount());
|
|
|
|
|
- result.put("academicLimit", isVip ? -1 : configService.getQuota("academic"));
|
|
|
|
|
- return Result.success(result);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Track a share action and consume share quota (US-2.1).
|
|
|
|
|
- */
|
|
|
|
|
- @PostMapping("/share/track")
|
|
|
|
|
- public Result<Map<String, Object>> trackShare(HttpServletRequest request) {
|
|
|
|
|
- Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
- userService.consumeQuota(userId, "share");
|
|
|
|
|
- User user = userService.getById(userId);
|
|
|
|
|
- boolean isVip = userService.isVip(userId);
|
|
|
|
|
- int shareLimit = isVip ? -1 : configService.getQuota("share");
|
|
|
|
|
- Map<String, Object> result = new HashMap<>();
|
|
|
|
|
- result.put("dailyShareCount", user.getDailyShareCount());
|
|
|
|
|
- result.put("shareLimit", shareLimit);
|
|
|
|
|
- result.put("exceeded", !isVip && shareLimit > 0 && user.getDailyShareCount() >= shareLimit);
|
|
|
|
|
- return Result.success(result);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @PostMapping("/commission-summary")
|
|
|
|
|
- public Result<Map<String, Object>> commissionSummary(HttpServletRequest request) {
|
|
|
|
|
- Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
- Map<String, Object> result = new HashMap<>();
|
|
|
|
|
- result.put("totalEarnings", commissionService.getTotalCommission(userId));
|
|
|
|
|
- result.put("availableBalance", commissionService.getAvailableBalance(userId));
|
|
|
|
|
- return Result.success(result);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @PostMapping("/chart-count")
|
|
|
|
|
- public Result<Map<String, Object>> chartCount(HttpServletRequest request) {
|
|
|
|
|
- Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
- int count = chartService.getByUserId(userId).size();
|
|
|
|
|
- Map<String, Object> result = new HashMap<>();
|
|
|
|
|
- result.put("count", count);
|
|
|
|
|
- return Result.success(result);
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
|
|
+package com.etotem.num.controller;
|
|
|
|
|
+
|
|
|
|
|
+import com.etotem.num.common.Result;
|
|
|
|
|
+import com.etotem.num.entity.User;
|
|
|
|
|
+import com.etotem.num.service.ChartService;
|
|
|
|
|
+import com.etotem.num.service.CommissionService;
|
|
|
|
|
+import com.etotem.num.service.ConfigService;
|
|
|
|
|
+import com.etotem.num.service.QrCodeService;
|
|
|
|
|
+import com.etotem.num.service.UserService;
|
|
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
+import org.springframework.web.bind.annotation.GetMapping;
|
|
|
|
|
+import org.springframework.web.bind.annotation.PostMapping;
|
|
|
|
|
+import org.springframework.web.bind.annotation.RequestBody;
|
|
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
+
|
|
|
|
|
+import java.time.LocalDate;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+
|
|
|
|
|
+@RestController
|
|
|
|
|
+@RequestMapping("/api/profile")
|
|
|
|
|
+public class ProfileController {
|
|
|
|
|
+
|
|
|
|
|
+ private final UserService userService;
|
|
|
|
|
+ private final CommissionService commissionService;
|
|
|
|
|
+ private final ChartService chartService;
|
|
|
|
|
+ private final ConfigService configService;
|
|
|
|
|
+ private final QrCodeService qrCodeService;
|
|
|
|
|
+
|
|
|
|
|
+ public ProfileController(UserService userService, CommissionService commissionService,
|
|
|
|
|
+ ChartService chartService, ConfigService configService,
|
|
|
|
|
+ QrCodeService qrCodeService) {
|
|
|
|
|
+ this.userService = userService;
|
|
|
|
|
+ this.commissionService = commissionService;
|
|
|
|
|
+ this.chartService = chartService;
|
|
|
|
|
+ this.configService = configService;
|
|
|
|
|
+ this.qrCodeService = qrCodeService;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/info")
|
|
|
|
|
+ public Result<Map<String, Object>> getInfo(HttpServletRequest request) {
|
|
|
|
|
+ Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
+ User user = userService.getById(userId);
|
|
|
|
|
+ Map<String, Object> info = new HashMap<>();
|
|
|
|
|
+ info.put("id", user.getId());
|
|
|
|
|
+ info.put("nickname", user.getNickname());
|
|
|
|
|
+ info.put("avatarUrl", user.getAvatarUrl());
|
|
|
|
|
+ info.put("referralCode", user.getReferralCode());
|
|
|
|
|
+ info.put("isAdmin", user.getIsAdmin());
|
|
|
|
|
+ info.put("vipEndTime", user.getVipEndTime());
|
|
|
|
|
+ info.put("isVip", userService.isVip(userId));
|
|
|
|
|
+ info.put("isSeedPriceUser", userService.isSeedPriceUser(userId));
|
|
|
|
|
+ info.put("dailyChartCount", user.getDailyChartCount());
|
|
|
|
|
+ info.put("dailyChatCount", user.getDailyChatCount());
|
|
|
|
|
+ // US-5.1 profile fields
|
|
|
|
|
+ info.put("gender", user.getGender());
|
|
|
|
|
+ info.put("birthDate", user.getBirthDate());
|
|
|
|
|
+ info.put("bio", user.getBio());
|
|
|
|
|
+ info.put("city", user.getCity());
|
|
|
|
|
+ info.put("tags", user.getTags());
|
|
|
|
|
+ info.put("lookingFor", user.getLookingFor());
|
|
|
|
|
+ info.put("profileComplete", user.getProfileComplete());
|
|
|
|
|
+ info.put("birthYear", user.getBirthYear());
|
|
|
|
|
+ info.put("birthMonth", user.getBirthMonth());
|
|
|
|
|
+ info.put("birthDay", user.getBirthDay());
|
|
|
|
|
+ return Result.success(info);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Complete user profile on first registration (US-5.1).
|
|
|
|
|
+ */
|
|
|
|
|
+ @PostMapping("/complete")
|
|
|
|
|
+ public Result<?> completeProfile(HttpServletRequest request, @RequestBody Map<String, Object> body) {
|
|
|
|
|
+ Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
+ Integer gender = body.containsKey("gender") ? ((Number) body.get("gender")).intValue() : null;
|
|
|
|
|
+ String birthDateStr = (String) body.get("birthDate");
|
|
|
|
|
+ LocalDate birthDate = birthDateStr != null ? LocalDate.parse(birthDateStr) : null;
|
|
|
|
|
+ String bio = (String) body.get("bio");
|
|
|
|
|
+ String city = (String) body.get("city");
|
|
|
|
|
+ String tags = (String) body.get("tags");
|
|
|
|
|
+ Integer lookingFor = body.containsKey("lookingFor") ? ((Number) body.get("lookingFor")).intValue() : null;
|
|
|
|
|
+ String nickname = (String) body.get("nickname");
|
|
|
|
|
+ String avatarUrl = (String) body.get("avatarUrl");
|
|
|
|
|
+ userService.completeProfile(userId, gender, birthDate, bio, city, tags, lookingFor, nickname, avatarUrl);
|
|
|
|
|
+ return Result.success(null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Update individual profile fields (US-5.3).
|
|
|
|
|
+ */
|
|
|
|
|
+ @PostMapping("/update")
|
|
|
|
|
+ public Result<?> updateProfile(HttpServletRequest request, @RequestBody Map<String, Object> body) {
|
|
|
|
|
+ Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
+ Integer gender = body.containsKey("gender") ? ((Number) body.get("gender")).intValue() : null;
|
|
|
|
|
+ String birthDateStr = (String) body.get("birthDate");
|
|
|
|
|
+ LocalDate birthDate = birthDateStr != null ? LocalDate.parse(birthDateStr) : null;
|
|
|
|
|
+ String bio = (String) body.get("bio");
|
|
|
|
|
+ String city = (String) body.get("city");
|
|
|
|
|
+ String tags = (String) body.get("tags");
|
|
|
|
|
+ Integer lookingFor = body.containsKey("lookingFor") ? ((Number) body.get("lookingFor")).intValue() : null;
|
|
|
|
|
+ String nickname = (String) body.get("nickname");
|
|
|
|
|
+ String avatarUrl = (String) body.get("avatarUrl");
|
|
|
|
|
+ userService.completeProfile(userId, gender, birthDate, bio, city, tags, lookingFor, nickname, avatarUrl);
|
|
|
|
|
+ return Result.success(null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/vip-status")
|
|
|
|
|
+ public Result<Map<String, Object>> vipStatus(HttpServletRequest request) {
|
|
|
|
|
+ Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
+ boolean isVip = userService.isVip(userId);
|
|
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
|
|
+ result.put("isVip", isVip);
|
|
|
|
|
+ User user = userService.getById(userId);
|
|
|
|
|
+ result.put("vipEndTime", user.getVipEndTime());
|
|
|
|
|
+ return Result.success(result);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/quota")
|
|
|
|
|
+ public Result<Map<String, Object>> quota(HttpServletRequest request) {
|
|
|
|
|
+ Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
+ // Reset daily counters if a new day has arrived, so frontend sees fresh data
|
|
|
|
|
+ User user = userService.getAndResetDailyQuota(userId);
|
|
|
|
|
+ boolean isVip = userService.isVip(userId);
|
|
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
|
|
+ result.put("isVip", isVip);
|
|
|
|
|
+ result.put("dailyChartCount", user.getDailyChartCount());
|
|
|
|
|
+ result.put("dailyChatCount", user.getDailyChatCount());
|
|
|
|
|
+ result.put("dailyShareCount", user.getDailyShareCount());
|
|
|
|
|
+ result.put("chartLimit", isVip ? -1 : configService.getQuota("chart"));
|
|
|
|
|
+ result.put("chatLimit", isVip ? -1 : configService.getQuota("chat"));
|
|
|
|
|
+ result.put("shareLimit", isVip ? -1 : configService.getQuota("share"));
|
|
|
|
|
+ result.put("dailyAcademicCount", user.getDailyAcademicCount());
|
|
|
|
|
+ result.put("academicLimit", isVip ? -1 : configService.getQuota("academic"));
|
|
|
|
|
+ return Result.success(result);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Track a share action and consume share quota (US-2.1).
|
|
|
|
|
+ */
|
|
|
|
|
+ @PostMapping("/share/track")
|
|
|
|
|
+ public Result<Map<String, Object>> trackShare(HttpServletRequest request) {
|
|
|
|
|
+ Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
+ userService.consumeQuota(userId, "share");
|
|
|
|
|
+ User user = userService.getById(userId);
|
|
|
|
|
+ boolean isVip = userService.isVip(userId);
|
|
|
|
|
+ int shareLimit = isVip ? -1 : configService.getQuota("share");
|
|
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
|
|
+ result.put("dailyShareCount", user.getDailyShareCount());
|
|
|
|
|
+ result.put("shareLimit", shareLimit);
|
|
|
|
|
+ result.put("exceeded", !isVip && shareLimit > 0 && user.getDailyShareCount() >= shareLimit);
|
|
|
|
|
+ return Result.success(result);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/commission-summary")
|
|
|
|
|
+ public Result<Map<String, Object>> commissionSummary(HttpServletRequest request) {
|
|
|
|
|
+ Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
|
|
+ result.put("totalEarnings", commissionService.getTotalCommission(userId));
|
|
|
|
|
+ result.put("availableBalance", commissionService.getAvailableBalance(userId));
|
|
|
|
|
+ return Result.success(result);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/chart-count")
|
|
|
|
|
+ public Result<Map<String, Object>> chartCount(HttpServletRequest request) {
|
|
|
|
|
+ Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
+ int count = chartService.getByUserId(userId).size();
|
|
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
|
|
+ result.put("count", count);
|
|
|
|
|
+ return Result.success(result);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Generate a QR code image URL for the user's referral/promotion page.
|
|
|
|
|
+ * GET /api/profile/qrcode
|
|
|
|
|
+ */
|
|
|
|
|
+ @GetMapping("/qrcode")
|
|
|
|
|
+ public Result<Map<String, Object>> getQrCode(HttpServletRequest request) {
|
|
|
|
|
+ Long userId = (Long) request.getAttribute("userId");
|
|
|
|
|
+ User user = userService.getById(userId);
|
|
|
|
|
+ String referralCode = user.getReferralCode();
|
|
|
|
|
+ String qrUrl = qrCodeService.generateQrCode(referralCode);
|
|
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
|
|
+ result.put("qrCodeUrl", qrUrl);
|
|
|
|
|
+ result.put("referralCode", referralCode);
|
|
|
|
|
+ return Result.success(result);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|