You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
7.0 KiB
148 lines
7.0 KiB
package com.campus.controller;
|
|
|
|
import com.campus.common.Result;
|
|
import com.campus.dto.request.XuexinSubmitRequest;
|
|
import com.campus.entity.User;
|
|
import com.campus.entity.UserPoints;
|
|
import com.campus.entity.XuexinReport;
|
|
import com.campus.service.AuthorizationService;
|
|
import com.campus.service.UserPointsService;
|
|
import com.campus.service.UserService;
|
|
import com.campus.service.ProfileService;
|
|
import com.campus.service.XuexinReportService;
|
|
import com.campus.util.OssUtil;
|
|
import com.campus.util.UserContext;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.http.MediaType;
|
|
import org.springframework.web.bind.annotation.*;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
import java.util.LinkedHashMap;
|
|
import java.util.Map;
|
|
|
|
@Slf4j
|
|
@RestController
|
|
@RequestMapping("/api/profile")
|
|
@RequiredArgsConstructor
|
|
public class ProfileController {
|
|
|
|
private final UserService userService;
|
|
private final ProfileService profileService;
|
|
private final UserPointsService userPointsService;
|
|
private final OssUtil ossUtil;
|
|
private final AuthorizationService authorizationService;
|
|
private final XuexinReportService xuexinReportService;
|
|
|
|
@GetMapping
|
|
public Result<User> getMyProfile() {
|
|
String userId = UserContext.getCurrentUserId();
|
|
return Result.success(userService.getUserById(userId));
|
|
}
|
|
|
|
@GetMapping("/other")
|
|
public Result<User> getProfile(@RequestParam String userId) {
|
|
return Result.success(userService.getPublicUserById(userId));
|
|
}
|
|
|
|
@PutMapping
|
|
public Result<User> updateProfile(@RequestBody User updateData) {
|
|
String userId = UserContext.getCurrentUserId();
|
|
return Result.success(profileService.updateProfile(UserContext.getCurrentUserId(), userId, updateData));
|
|
}
|
|
|
|
@PutMapping("/other")
|
|
public Result<User> updateProfile(
|
|
@RequestParam String userId,
|
|
@RequestBody User updateData) {
|
|
authorizationService.requireAdmin();
|
|
return Result.success(profileService.updateProfile(UserContext.getCurrentUserId(), userId, updateData));
|
|
}
|
|
|
|
/**
|
|
* 学信网认证 — 提交接口。
|
|
*
|
|
* <p>前置条件:Step1 调 {@code POST /api/ocr/chsi-report} 已拿到 {@code reportId},
|
|
* 且其结果里 {@code dedup.status=AVAILABLE}。</p>
|
|
*
|
|
* <p>本接口<b>不再信任请求体里的教育字段</b>:姓名/学校/学历等一律以
|
|
* {@code xuexin_report} 表中的 OCR 记录为准,请求体只需 {@code reportId}
|
|
* 且客户端不能覆盖 PDF 中识别出的认证字段。
|
|
* 这样即使前端伪造 {@code validChsiReport},也拿不到认证。</p>
|
|
*
|
|
* <p>完整校验与写入逻辑见 {@link XuexinReportService#submit}:</p>
|
|
* <ul>
|
|
* <li>材料不存在 / 不属于当前用户 → 400「未找到认证材料,请重新上传报告」</li>
|
|
* <li>材料已过期或被替换 → 400「该认证材料已失效,请重新上传报告」</li>
|
|
* <li>已认证且换更低学历 → 400「…不支持更换为更低学历…」</li>
|
|
* <li>已认证未满冷静期 → 400「认证通过后 3 天内不可更换认证材料,请在 … 后重试」</li>
|
|
* <li>重复提交同一份材料 → 幂等成功,原样返回当前用户</li>
|
|
* </ul>
|
|
*/
|
|
@PostMapping("/xuexin/submit")
|
|
public Result<User> submitXuexin(@RequestBody XuexinSubmitRequest req) {
|
|
String userId = UserContext.getCurrentUserId();
|
|
return Result.success(xuexinReportService.submit(userId, req));
|
|
}
|
|
|
|
/** 上传并立即保存当前用户头像,不依赖编辑资料页的其他字段保存。 */
|
|
@PostMapping(value = "/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
|
public Result<User> uploadAvatar(@RequestParam("file") MultipartFile file) {
|
|
String userId = UserContext.getCurrentUserId();
|
|
User user = userService.getUserById(userId);
|
|
String avatarUrl = ossUtil.uploadAvatar(file);
|
|
user.setAvatar(avatarUrl);
|
|
userService.saveUser(user);
|
|
return Result.success(user);
|
|
}
|
|
|
|
/**
|
|
* 查询当前用户学信网认证状态和已确认的学籍信息。
|
|
*
|
|
* <p>新增 {@code certifiedAt}(认证时间)、{@code reportId}(当前生效材料),
|
|
* 以及新版报告上的分院、系所、日期、民族、学历类别、学习形式和在线验证码。</p>
|
|
*/
|
|
@GetMapping("/xuexin/status")
|
|
public Result<Map<String, Object>> xuexinStatus() {
|
|
String userId = UserContext.getCurrentUserId();
|
|
User user = userService.getUserById(userId);
|
|
XuexinReport activeReport = xuexinReportService.findActiveReport(userId);
|
|
Map<String, Object> result = new LinkedHashMap<>();
|
|
result.put("certified", Boolean.TRUE.equals(user.getXuexinCertified()));
|
|
result.put("number", user.getNumber());
|
|
result.put("school", user.getUniversityName());
|
|
result.put("department", user.getCollegeName());
|
|
result.put("major", user.getMajorName());
|
|
result.put("level", user.getEducation());
|
|
result.put("grade", user.getGrade());
|
|
result.put("enrollmentStatus", user.getXuexinEnrollmentStatus());
|
|
result.put("certifiedAt", user.getXuexinCertifiedAt());
|
|
result.put("reportId", user.getXuexinReportId());
|
|
result.put("reportName", activeReport == null ? null : activeReport.getReportName());
|
|
result.put("reportUpdatedDate", activeReport == null ? null : activeReport.getReportUpdatedDate());
|
|
result.put("name", activeReport == null ? null : activeReport.getName());
|
|
result.put("gender", activeReport == null ? null : activeReport.getGender());
|
|
result.put("birthDate", activeReport == null ? null : activeReport.getBirthDate());
|
|
result.put("ethnicity", activeReport == null ? null : activeReport.getEthnicity());
|
|
result.put("studyDuration", activeReport == null ? null : activeReport.getStudyDuration());
|
|
result.put("educationCategory", activeReport == null ? null : activeReport.getEducationCategory());
|
|
result.put("studyForm", activeReport == null ? null : activeReport.getStudyForm());
|
|
result.put("branchCampus", activeReport == null ? null : activeReport.getBranchCampus());
|
|
result.put("enrollmentDate", activeReport == null ? null : activeReport.getEnrollmentDate());
|
|
result.put("departureDate", activeReport == null ? null : activeReport.getDepartureDate());
|
|
result.put("onlineVerificationCode", activeReport == null ? null : activeReport.getOnlineVerificationCode());
|
|
return Result.success(result);
|
|
}
|
|
|
|
@GetMapping("/points")
|
|
public Result<UserPoints> getMyPoints() {
|
|
String userId = UserContext.getCurrentUserId();
|
|
return Result.success(userPointsService.getUserPoints(userId));
|
|
}
|
|
|
|
@GetMapping("/points-other")
|
|
public Result<UserPoints> getUserPoints(@RequestParam String userId) {
|
|
authorizationService.requireAdmin();
|
|
return Result.success(userPointsService.getUserPoints(userId));
|
|
}
|
|
}
|
|
|