| | |
| | | package com.dsh.guns.modular.system.controller.system; |
| | | |
| | | import com.dsh.course.feignClient.account.AppUserClient; |
| | | import com.dsh.course.feignClient.account.CoachClient; |
| | | import com.dsh.course.feignClient.account.RefereeClient; |
| | | import com.dsh.course.feignClient.account.model.CoachSerchVO; |
| | | import com.dsh.course.feignClient.account.model.RefereeList; |
| | | import com.dsh.guns.config.UserExt; |
| | | import com.dsh.guns.core.common.exception.BizExceptionEnum; |
| | | import com.dsh.guns.core.exception.GunsException; |
| | | import com.dsh.guns.modular.system.audit.ManagementAuditWriter; |
| | | import com.dsh.guns.modular.system.model.SiteBooking; |
| | | import com.dsh.guns.modular.system.model.TOperator; |
| | | import com.dsh.guns.modular.system.model.CoachQuery; |
| | | import com.dsh.guns.modular.system.service.ISiteBookingService; |
| | | import com.dsh.guns.modular.system.service.TOperatorService; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PathVariable; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | |
| | | import javax.annotation.Resource; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.UUID; |
| | | |
| | |
| | | @Resource private AppUserClient appUserClient; |
| | | @Resource private ManagementAuditWriter auditWriter; |
| | | @Resource private IUserService userService; |
| | | @Resource private ISiteBookingService siteBookingService; |
| | | @Resource private CoachClient coachClient; |
| | | @Resource private RefereeClient refereeClient; |
| | | @Resource private TOperatorService operatorService; |
| | | |
| | | @GetMapping("/app-user/{id}") |
| | | public Map<String, Object> appUser(@PathVariable Integer id) { |
| | | assertAdmin(); |
| | | Map<String, Object> result = appUserClient.sensitiveAppUser(id); |
| | | writeAudit("app-user", id, result == null ? "NOT_FOUND" : "SUCCESS"); |
| | | writeAudit("app-user", id, userName(result), result == null ? "NOT_FOUND" : "SUCCESS"); |
| | | return result; |
| | | } |
| | | |
| | |
| | | result.put("phone", employee.getPhone()); |
| | | result.put("idCard", employee.getIdCard()); |
| | | } |
| | | writeAudit("employee", id, result == null ? "NOT_FOUND" : "SUCCESS"); |
| | | writeAudit("employee", id, employee == null ? null : employee.getName(), result == null ? "NOT_FOUND" : "SUCCESS"); |
| | | return result; |
| | | } |
| | | |
| | | @GetMapping("/student/{id}") |
| | | public Map<String, Object> student(@PathVariable Integer id) { |
| | | assertAdmin(); |
| | | Map<String, Object> result = appUserClient.sensitiveStudent(id); |
| | | writeAudit("student", id, userName(result), result == null ? "NOT_FOUND" : "SUCCESS"); |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 预约管理查看关联预约人的敏感信息。 |
| | | * |
| | | * <p>仅通过预约记录定位用户,避免前端以任意用户 ID 查询;该接口保留在 |
| | | * /system/sensitive 路径下,以使用全局的脱敏豁免和网关放行策略。</p> |
| | | */ |
| | | @GetMapping("/booking/{bookingId}") |
| | | public Map<String, Object> booking(@PathVariable Integer bookingId) { |
| | | assertAdmin(); |
| | | SiteBooking booking = siteBookingService.getById(bookingId); |
| | | if (booking == null || booking.getAppUserId() == null) { |
| | | writeBookingAudit(bookingId, booking, null, "NOT_FOUND"); |
| | | return null; |
| | | } |
| | | |
| | | Map<String, Object> result = appUserClient.sensitiveAppUser(booking.getAppUserId()); |
| | | writeBookingAudit(bookingId, booking, result, result == null ? "NOT_FOUND" : "SUCCESS"); |
| | | return result; |
| | | } |
| | | |
| | | @GetMapping("/coach/{id}") |
| | | public Map<String, Object> coach(@PathVariable Integer id) { |
| | | assertAdmin(); |
| | | // 与教练管理页 /tCoach/list 使用同一个查询入口,确保返回字段和数据权限一致。 |
| | | CoachQuery query = new CoachQuery(); |
| | | query.setId(id); |
| | | List<CoachSerchVO> coaches = coachClient.listAll(query); |
| | | CoachSerchVO coach = coaches == null || coaches.isEmpty() ? null : coaches.get(0); |
| | | Map<String, Object> result = null; |
| | | if (coach != null) { |
| | | result = new HashMap<String, Object>(); |
| | | result.put("id", coach.getId()); |
| | | result.put("name", coach.getName()); |
| | | result.put("phone", coach.getPhone()); |
| | | result.put("idCard", coach.getIdcard()); |
| | | } |
| | | writeAudit("coach", id, coach == null ? null : coach.getName(), result == null ? "NOT_FOUND" : "SUCCESS"); |
| | | return result; |
| | | } |
| | | |
| | | @GetMapping("/referee/{id}") |
| | | public Map<String, Object> referee(@PathVariable Integer id) { |
| | | assertAdmin(); |
| | | // 使用裁判管理页 /referee/listAll 对应的列表查询接口精确查询该裁判。 |
| | | RefereeList query = new RefereeList(); |
| | | query.setId(id); |
| | | query.setOffset(0); |
| | | query.setLimit(1); |
| | | Map<String, Object> listResult = refereeClient.getRefereeList(query); |
| | | List<Map<String, Object>> referees = listResult == null ? null |
| | | : (List<Map<String, Object>>) listResult.get("rows"); |
| | | Map<String, Object> referee = referees == null || referees.isEmpty() ? null : referees.get(0); |
| | | Map<String, Object> result = null; |
| | | if (referee != null) { |
| | | result = new HashMap<String, Object>(); |
| | | result.put("id", referee.get("id")); |
| | | result.put("name", referee.get("name")); |
| | | result.put("phone", referee.get("phone")); |
| | | } |
| | | writeAudit("referee", id, referee == null ? null : String.valueOf(referee.get("name")), |
| | | result == null ? "NOT_FOUND" : "SUCCESS"); |
| | | return result; |
| | | } |
| | | |
| | | @GetMapping("/operator/{id}") |
| | | public Map<String, Object> operator(@PathVariable Integer id) { |
| | | assertAdmin(); |
| | | TOperator operator = operatorService.getById(id); |
| | | User employee = operator == null ? null : userService.getById(operator.getUserId()); |
| | | Map<String, Object> result = null; |
| | | if (employee != null) { |
| | | result = new HashMap<String, Object>(); |
| | | result.put("id", employee.getId()); |
| | | result.put("name", employee.getName()); |
| | | result.put("phone", employee.getPhone()); |
| | | result.put("idCard", employee.getIdCard()); |
| | | } |
| | | writeAudit("operator", id, operator == null ? null : operator.getName(), result == null ? "NOT_FOUND" : "SUCCESS"); |
| | | return result; |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | private void writeAudit(String resource, Integer targetUserId, String result) { |
| | | private void writeAudit(String resource, Integer targetUserId, String targetUserName, String result) { |
| | | Map<String, Object> audit = new HashMap<String, Object>(); |
| | | audit.put("traceId", UUID.randomUUID().toString().replace("-", "")); |
| | | audit.put("sourceService", "mb-cloud-management"); |
| | |
| | | audit.put("operationName", "超级管理员查看敏感信息"); |
| | | audit.put("requestMethod", "GET"); |
| | | audit.put("requestUri", "/system/sensitive/" + resource + "/" + targetUserId); |
| | | audit.put("requestParams", "targetUserId=" + targetUserId); |
| | | // 敏感信息访问需同时记录对象名称,避免日志中只有无法识别的 ID。 |
| | | audit.put("requestParams", "targetUserId=" + targetUserId + ", targetUserName=" |
| | | + (targetUserName == null ? "-" : targetUserName)); |
| | | audit.put("userId", UserExt.getUser().getId()); |
| | | audit.put("userAccount", "admin"); |
| | | audit.put("result", result); |
| | | audit.put("createdAt", new Date()); |
| | | auditWriter.append(audit); |
| | | } |
| | | |
| | | private void writeBookingAudit(Integer bookingId, SiteBooking booking, |
| | | Map<String, Object> user, String result) { |
| | | Map<String, Object> audit = new HashMap<String, Object>(); |
| | | audit.put("traceId", UUID.randomUUID().toString().replace("-", "")); |
| | | audit.put("sourceService", "mb-cloud-management"); |
| | | audit.put("sourceType", "HTTP"); |
| | | audit.put("operationType", "VIEW_SENSITIVE"); |
| | | audit.put("riskLevel", "SENSITIVE"); |
| | | audit.put("operationName", "超级管理员从预约管理查看敏感信息"); |
| | | audit.put("requestMethod", "GET"); |
| | | audit.put("requestUri", "/system/sensitive/booking/" + bookingId); |
| | | // 审计记录只存预约、用户标识和查询结果,绝不写入手机号、身份证号等明文。 |
| | | audit.put("requestParams", "bookingId=" + bookingId + ", appUserId=" |
| | | + (booking == null || booking.getAppUserId() == null ? "-" : booking.getAppUserId()) |
| | | + ", targetUserName=" + (userName(user) == null ? "-" : userName(user))); |
| | | audit.put("userId", UserExt.getUser().getId()); |
| | | audit.put("userAccount", "admin"); |
| | | audit.put("result", result); |
| | | audit.put("createdAt", new Date()); |
| | | auditWriter.append(audit); |
| | | } |
| | | |
| | | private String userName(Map<String, Object> user) { |
| | | if (user == null || user.get("name") == null) return null; |
| | | return String.valueOf(user.get("name")); |
| | | } |
| | | } |