本地 RAG 知识库
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.
 
 
 
 
 
 

215 lines
8.3 KiB

package com.wok.supportbot.controller;
import com.wok.supportbot.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* 系统用户管理控制器
*/
@Slf4j
@RestController
@RequestMapping("/sys-user")
public class SysUserController {
private final SysUserService sysUserService;
public SysUserController(SysUserService sysUserService) {
this.sysUserService = sysUserService;
}
/**
* 分页查询用户列表
*/
@GetMapping("/list")
@PreAuthorize("hasRole('admin')")
public ResponseEntity<Map<String, Object>> list(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(required = false) String keyword,
@RequestParam(required = false) Boolean enabled,
@RequestParam(required = false) String sortField,
@RequestParam(required = false) String sortOrder) {
try {
Map<String, Object> data = sysUserService.listUsers(page, size, keyword, enabled, sortField, sortOrder);
return ResponseEntity.ok(Map.of("success", true, "data", data));
} catch (Exception e) {
log.error("查询用户列表失败", e);
return ResponseEntity.internalServerError().body(Map.of(
"success", false, "message", "查询失败: " + e.getMessage()
));
}
}
/**
* 获取用户详情
*/
@GetMapping("/{id}")
@PreAuthorize("hasRole('admin')")
public ResponseEntity<Map<String, Object>> detail(@PathVariable Long id) {
try {
var user = sysUserService.getUserById(id);
if (user == null) {
return ResponseEntity.ok(Map.of("success", false, "message", "用户不存在"));
}
return ResponseEntity.ok(Map.of("success", true, "data", user));
} catch (Exception e) {
log.error("查询用户详情失败", e);
return ResponseEntity.internalServerError().body(Map.of(
"success", false, "message", "查询失败: " + e.getMessage()
));
}
}
/**
* 创建用户
*/
@PostMapping
@PreAuthorize("hasRole('admin')")
public ResponseEntity<Map<String, Object>> create(@RequestBody Map<String, Object> body) {
try {
String username = (String) body.get("username");
String password = (String) body.get("password");
String nickname = (String) body.get("nickname");
String email = (String) body.get("email");
String phone = (String) body.get("phone");
List<Long> roleIds = parseRoleIds(body.get("roleIds"));
var user = sysUserService.createUser(username, password, nickname, email, phone, roleIds);
return ResponseEntity.ok(Map.of("success", true, "message", "创建成功", "data", Map.of("id", user.getId().toString())));
} catch (IllegalArgumentException e) {
return ResponseEntity.ok(Map.of("success", false, "message", e.getMessage()));
} catch (Exception e) {
log.error("创建用户失败", e);
return ResponseEntity.internalServerError().body(Map.of(
"success", false, "message", "创建失败: " + e.getMessage()
));
}
}
/**
* 更新用户信息
*/
@PutMapping("/{id}")
@PreAuthorize("hasRole('admin')")
public ResponseEntity<Map<String, Object>> update(@PathVariable Long id, @RequestBody Map<String, Object> body) {
try {
String nickname = (String) body.get("nickname");
String email = (String) body.get("email");
String phone = (String) body.get("phone");
sysUserService.updateUser(id, nickname, email, phone);
return ResponseEntity.ok(Map.of("success", true, "message", "更新成功"));
} catch (IllegalArgumentException e) {
return ResponseEntity.ok(Map.of("success", false, "message", e.getMessage()));
} catch (Exception e) {
log.error("更新用户失败", e);
return ResponseEntity.internalServerError().body(Map.of(
"success", false, "message", "更新失败: " + e.getMessage()
));
}
}
/**
* 启用/禁用用户
*/
@PutMapping("/{id}/toggle")
@PreAuthorize("hasRole('admin')")
public ResponseEntity<Map<String, Object>> toggle(@PathVariable Long id, @RequestParam boolean enabled) {
try {
sysUserService.toggleUser(id, enabled);
return ResponseEntity.ok(Map.of("success", true, "message", enabled ? "已启用" : "已禁用"));
} catch (IllegalArgumentException e) {
return ResponseEntity.ok(Map.of("success", false, "message", e.getMessage()));
} catch (Exception e) {
log.error("切换用户状态失败", e);
return ResponseEntity.internalServerError().body(Map.of(
"success", false, "message", "操作失败: " + e.getMessage()
));
}
}
/**
* 分配角色
*/
@PutMapping("/{id}/roles")
@PreAuthorize("hasRole('admin')")
public ResponseEntity<Map<String, Object>> assignRoles(@PathVariable Long id, @RequestBody Map<String, Object> body) {
try {
List<Long> roleIds = parseRoleIds(body.get("roleIds"));
sysUserService.assignRoles(id, roleIds);
return ResponseEntity.ok(Map.of("success", true, "message", "角色分配成功"));
} catch (Exception e) {
log.error("分配角色失败", e);
return ResponseEntity.internalServerError().body(Map.of(
"success", false, "message", "分配失败: " + e.getMessage()
));
}
}
/**
* 修改密码
*/
@PutMapping("/{id}/password")
@PreAuthorize("hasRole('admin')")
public ResponseEntity<Map<String, Object>> changePassword(@PathVariable Long id, @RequestBody Map<String, String> body) {
try {
String newPassword = body.get("newPassword");
if (newPassword == null || newPassword.isBlank()) {
return ResponseEntity.ok(Map.of("success", false, "message", "新密码不能为空"));
}
sysUserService.changePassword(id, newPassword);
return ResponseEntity.ok(Map.of("success", true, "message", "密码修改成功"));
} catch (IllegalArgumentException e) {
return ResponseEntity.ok(Map.of("success", false, "message", e.getMessage()));
} catch (Exception e) {
log.error("修改密码失败", e);
return ResponseEntity.internalServerError().body(Map.of(
"success", false, "message", "修改失败: " + e.getMessage()
));
}
}
/**
* 获取所有角色(用于分配角色时的下拉选择)
*/
@GetMapping("/roles")
@PreAuthorize("hasRole('admin')")
public ResponseEntity<Map<String, Object>> allRoles() {
try {
var roles = sysUserService.getAllRoles();
return ResponseEntity.ok(Map.of("success", true, "data", roles));
} catch (Exception e) {
log.error("查询角色列表失败", e);
return ResponseEntity.internalServerError().body(Map.of(
"success", false, "message", "查询失败: " + e.getMessage()
));
}
}
/**
* 解析请求体中的 roleIds 字段为 Long 列表。
* 兼容前端传数字 ID 或字符串 ID 两种情况(雪花 ID 超过 JS 精度时前端通常传字符串)。
*/
private List<Long> parseRoleIds(Object roleIdsObj) {
if (roleIdsObj == null) {
return List.of();
}
if (!(roleIdsObj instanceof List<?> list)) {
return List.of();
}
return list.stream()
.filter(java.util.Objects::nonNull)
.map(item -> {
if (item instanceof Number number) {
return number.longValue();
}
return Long.parseLong(String.valueOf(item));
})
.toList();
}
}