增加:管理员->用户模块接口

This commit is contained in:
moyangzhan 2024-05-28 18:54:36 +08:00
parent a6ec5689f1
commit d4f41a0166
15 changed files with 439 additions and 12 deletions

View File

@ -0,0 +1,39 @@
package com.moyz.adi.admin.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.moyz.adi.common.dto.AiModelDto;
import com.moyz.adi.common.service.AiModelService;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/admin/model")
@Validated
public class AdminModelController {
@Resource
private AiModelService aiModelService;
@GetMapping("/list")
public Page<AiModelDto> page(@RequestParam String platform, @NotNull @Min(1) Integer currentPage, @NotNull @Min(10) Integer pageSize) {
return aiModelService.page(platform, currentPage, pageSize);
}
@PostMapping("/disable/{id}")
public void disable(@PathVariable Long id) {
aiModelService.disable(id);
}
@PostMapping("/enable/{id}")
public void enable(@PathVariable Long id) {
aiModelService.enable(id);
}
@PostMapping("/delete/{id}")
public void delete(@PathVariable Long id) {
aiModelService.softDelete(id);
}
}

View File

@ -0,0 +1,68 @@
package com.moyz.adi.admin.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.moyz.adi.common.base.ThreadContext;
import com.moyz.adi.common.dto.UserAddReq;
import com.moyz.adi.common.dto.UserEditReq;
import com.moyz.adi.common.dto.UserInfoDto;
import com.moyz.adi.common.dto.UsersReq;
import com.moyz.adi.common.entity.User;
import com.moyz.adi.common.service.UserService;
import com.talanlabs.avatargenerator.Avatar;
import com.talanlabs.avatargenerator.cat.CatAvatar;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
@RestController
@RequestMapping("/admin/user")
@Validated
public class AdminUserController {
@Resource
private UserService userService;
@PostMapping("/list")
public Page<UserInfoDto> userList(@RequestBody UsersReq usersReq, @NotNull @Min(1) Integer currentPage, @NotNull @Min(10) Integer pageSize) {
return userService.listUsers(usersReq, currentPage, pageSize);
}
@Operation(summary = "用户信息")
@GetMapping("/info/{uuid}")
public UserInfoDto info(@PathVariable String uuid) {
User user = userService.getByUuidOrThrow(uuid);
UserInfoDto result = new UserInfoDto();
BeanUtils.copyProperties(user, result);
return result;
}
@PostMapping("/addOne")
public UserInfoDto addOne(@Validated @RequestBody UserAddReq addUserReq) {
return userService.addUser(addUserReq);
}
@PostMapping("/active/{uuid}")
public void activeByUuid(@PathVariable String uuid) {
userService.activeByUuid(uuid);
}
@PostMapping("/freeze/{uuid}")
public void freezeByUuid(@PathVariable String uuid) {
userService.freeze(uuid);
}
@PostMapping("/edit")
public void editUser(@Validated @RequestBody UserEditReq userEditReq) {
userService.editUser(userEditReq);
}
}

View File

@ -1,6 +1,7 @@
package com.moyz.adi.admin.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.moyz.adi.common.dto.SysConfigDto;
import com.moyz.adi.common.entity.SysConfig;
import com.moyz.adi.common.service.KnowledgeBaseService;
import com.moyz.adi.common.service.SysConfigService;
@ -8,8 +9,7 @@ import jakarta.annotation.Resource;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/admin/sys-config")
@ -19,7 +19,18 @@ public class SystemConfigController {
@Resource
private SysConfigService sysConfigService;
public Page<SysConfig> list(String keyword, @NotNull @Min(1) Integer currentPage, @NotNull @Min(10) Integer pageSize) {
@GetMapping("/list")
public Page<SysConfig> list(@RequestParam String keyword, @NotNull @Min(1) Integer currentPage, @NotNull @Min(10) Integer pageSize) {
return sysConfigService.search(keyword, currentPage, pageSize);
}
@PostMapping("/edit")
public void edit(@Validated @RequestBody SysConfigDto sysConfigDto) {
sysConfigService.edit(sysConfigDto);
}
@PostMapping("/delete/{id}")
public void delete(@PathVariable Long id) {
sysConfigService.softDelete(id);
}
}

View File

@ -83,13 +83,16 @@ public class UserController {
if(null != user){
userId = user.getId();
}
Avatar avatar = CatAvatar.newAvatarBuilder().build();
BufferedImage bufferedImage = avatar.create(userId);
//把图片写给浏览器
try {
ImageIO.write(bufferedImage, "png", response.getOutputStream());
writeToResponse(userId, response);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private synchronized void writeToResponse(Long userId, HttpServletResponse response) throws IOException{
Avatar avatar = CatAvatar.newAvatarBuilder().size(64, 64).build();
BufferedImage bufferedImage = avatar.create(userId);
ImageIO.write(bufferedImage, "png", response.getOutputStream());
}
}

View File

@ -0,0 +1,26 @@
package com.moyz.adi.common.dto;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class AiModelDto {
private Long id;
private String type;
private String name;
private String platform;
private String remark;
private Boolean isEnable;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,18 @@
package com.moyz.adi.common.dto;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.springframework.validation.annotation.Validated;
@Data
@Validated
public class SysConfigDto {
@Min(1)
private Long id;
@NotBlank
private String name;
@NotBlank
private String value;
}

View File

@ -0,0 +1,17 @@
package com.moyz.adi.common.dto;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.springframework.validation.annotation.Validated;
@Data
@Validated
public class UserAddReq {
String name;
@NotBlank
String email;
@NotBlank
String password;
}

View File

@ -0,0 +1,28 @@
package com.moyz.adi.common.dto;
import com.moyz.adi.common.enums.UserStatusEnum;
import lombok.Data;
@Data
public class UserEditReq {
private String uuid;
private String name;
private UserStatusEnum userStatus;
private Integer quotaByTokenDaily;
private Integer quotaByTokenMonthly;
private Integer quotaByRequestDaily;
private Integer quotaByRequestMonthly;
private Integer quotaByImageDaily;
private Integer quotaByImageMonthly;
private Boolean isAdmin;
}

View File

@ -0,0 +1,40 @@
package com.moyz.adi.common.dto;
import com.moyz.adi.common.enums.UserStatusEnum;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class UserInfoDto{
private Long id;
private String name;
private String email;
private String uuid;
private Integer quotaByTokenDaily;
private Integer quotaByTokenMonthly;
private Integer quotaByRequestDaily;
private Integer quotaByRequestMonthly;
private Integer quotaByImageDaily;
private Integer quotaByImageMonthly;
private UserStatusEnum userStatus;
private LocalDateTime activeTime;
private Boolean isAdmin;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,15 @@
package com.moyz.adi.common.dto;
import com.moyz.adi.common.enums.UserStatusEnum;
import lombok.Data;
@Data
public class UsersReq {
String name;
String email;
String uuid;
UserStatusEnum userStatus;
Boolean isAdmin;
}

View File

@ -23,6 +23,7 @@ public enum ErrorEnum {
A_QA_ASK_LIMIT("A0019", "请求次数太多"),
A_QA_ITEM_LIMIT("A0020", "知识点生成已超额度"),
A_CONVERSATION_EXIST("A0021", "对话已存在"),
A_MODEL_NOT_FOUND("A0022", "模型不存在"),
B_UNCAUGHT_ERROR("B0001", "未捕捉异常"),
B_COMMON_ERROR("B0002", "业务出错"),
B_GLOBAL_ERROR("B0003", "全局异常"),

View File

@ -72,6 +72,11 @@ public class TokenFilter extends OncePerRequestFilter {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
if (!user.getIsAdmin() && requestUri.startsWith("/admin/")) {
log.warn("无管理权限:{}", requestUri);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
ThreadContext.setCurrentUser(user);
ThreadContext.setToken(token);
log.info("response::" + response);

View File

@ -1,10 +1,21 @@
package com.moyz.adi.common.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.moyz.adi.common.dto.AiModelDto;
import com.moyz.adi.common.entity.AiModel;
import com.moyz.adi.common.enums.ErrorEnum;
import com.moyz.adi.common.exception.BaseException;
import com.moyz.adi.common.mapper.AiModelMapper;
import com.moyz.adi.common.util.MPPageUtil;
import dev.langchain4j.agent.tool.P;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@ -48,4 +59,48 @@ public class AiModelService extends ServiceImpl<AiModelMapper, AiModel> {
return null == aiModel ? 0l : aiModel.getId();
}
public AiModel getByIdOrThrow(Long id) {
AiModel existModel = baseMapper.selectById(id);
if (null == existModel) {
throw new BaseException(ErrorEnum.A_MODEL_NOT_FOUND);
}
return existModel;
}
public Page<AiModelDto> page(String platform, Integer currentPage, Integer pageSize) {
LambdaQueryWrapper<AiModel> lambdaQueryWrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(platform)) {
lambdaQueryWrapper.eq(AiModel::getPlatform, platform);
}
lambdaQueryWrapper.eq(AiModel::getIsDeleted, false);
lambdaQueryWrapper.orderByDesc(AiModel::getUpdateTime);
Page<AiModel> aiModelPage = baseMapper.selectPage(new Page<>(currentPage, pageSize), lambdaQueryWrapper);
return MPPageUtil.convertToPage(aiModelPage, new Page<>(), AiModelDto.class);
}
public void disable(Long id) {
AiModel model = new AiModel();
model.setId(id);
model.setIsEnable(false);
baseMapper.updateById(model);
}
public void enable(Long id) {
AiModel model = new AiModel();
model.setId(id);
model.setIsEnable(true);
baseMapper.updateById(model);
}
public void softDelete(Long id) {
AiModel existModel = getByIdOrThrow(id);
AiModel model = new AiModel();
model.setId(id);
model.setIsDeleted(true);
baseMapper.updateById(model);
MODEL_NAME_TO_OBJ.remove(existModel.getName());
MODEL_ID_TO_OBJ.remove(existModel.getId());
}
}

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moyz.adi.common.cosntant.AdiConstant;
import com.moyz.adi.common.dto.SysConfigDto;
import com.moyz.adi.common.entity.SysConfig;
import com.moyz.adi.common.mapper.SysConfigMapper;
import com.moyz.adi.common.util.JsonUtil;
@ -11,6 +12,7 @@ import com.moyz.adi.common.util.LocalCache;
import com.moyz.adi.common.vo.RequestRateLimit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@ -52,6 +54,23 @@ public class SysConfigService extends ServiceImpl<SysConfigMapper, SysConfig> {
LocalCache.IMAGE_RATE_LIMIT_CONFIG.setType(RequestRateLimit.TYPE_IMAGE);
}
public void edit(SysConfigDto sysConfigDto) {
SysConfig sysConfig = new SysConfig();
BeanUtils.copyProperties(sysConfigDto, sysConfig);
baseMapper.updateById(sysConfig);
reload();
}
public void softDelete(Long id) {
SysConfig sysConfig = new SysConfig();
sysConfig.setIsDeleted(true);
sysConfig.setId(id);
baseMapper.updateById(sysConfig);
reload();
}
public int getConversationMaxNum() {
String maxNum = LocalCache.CONFIGS.get(AdiConstant.SysConfigKey.CONVERSATION_MAX_NUM);
return Integer.parseInt(maxNum);

View File

@ -1,15 +1,13 @@
package com.moyz.adi.common.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.moyz.adi.common.base.ThreadContext;
import com.moyz.adi.common.cosntant.AdiConstant;
import com.moyz.adi.common.cosntant.RedisKeyConstant;
import com.moyz.adi.common.dto.ConfigResp;
import com.moyz.adi.common.dto.LoginReq;
import com.moyz.adi.common.dto.LoginResp;
import com.moyz.adi.common.dto.UserUpdateReq;
import com.moyz.adi.common.dto.*;
import com.moyz.adi.common.entity.User;
import com.moyz.adi.common.enums.ErrorEnum;
import com.moyz.adi.common.enums.UserStatusEnum;
@ -18,6 +16,7 @@ import com.moyz.adi.common.helper.AdiMailSender;
import com.moyz.adi.common.mapper.UserMapper;
import com.moyz.adi.common.util.JsonUtil;
import com.moyz.adi.common.util.LocalCache;
import com.moyz.adi.common.util.MPPageUtil;
import com.moyz.adi.common.vo.CostStat;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@ -29,6 +28,7 @@ import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@ -169,6 +169,7 @@ public class UserService extends ServiceImpl<UserMapper, User> {
User updateUser = new User();
updateUser.setId(user.getId());
updateUser.setUserStatus(UserStatusEnum.NORMAL);
updateUser.setActiveTime(LocalDateTime.now());
baseMapper.updateById(updateUser);
setLoginToken(user);
@ -177,6 +178,31 @@ public class UserService extends ServiceImpl<UserMapper, User> {
conversationService.createDefault(user.getId());
}
public void activeByUuid(String uuid) {
User user = this.getByUuidOrThrow(uuid);
User updateUser = new User();
updateUser.setId(user.getId());
updateUser.setUserStatus(UserStatusEnum.NORMAL);
updateUser.setActiveTime(LocalDateTime.now());
baseMapper.updateById(updateUser);
}
public void freeze(String uuid) {
User user = this.getByUuidOrThrow(uuid);
User updateUser = new User();
updateUser.setId(user.getId());
updateUser.setUserStatus(UserStatusEnum.FREEZE);
baseMapper.updateById(updateUser);
}
public void editUser(UserEditReq userEditReq) {
User user = this.getByUuidOrThrow(userEditReq.getUuid());
User editUser = new User();
editUser.setId(user.getId());
BeanUtils.copyProperties(userEditReq, editUser);
baseMapper.updateById(editUser);
}
public LoginResp login(LoginReq loginReq) {
//captcha check
String failCountKey = MessageFormat.format(RedisKeyConstant.LOGIN_FAIL_COUNT, loginReq.getEmail());
@ -314,10 +340,66 @@ public class UserService extends ServiceImpl<UserMapper, User> {
adiMailSender.send("欢迎注册AIDeepIn", "激活链接(" + AdiConstant.AUTH_ACTIVE_CODE_EXPIRE + "小时内有效):" + backendUrl + "/auth/active?code=" + activeCode, email);
}
public User getByUuid(String uuid){
public User getByUuid(String uuid) {
return ChainWrappers.lambdaQueryChain(baseMapper)
.eq(User::getUuid, uuid)
.one();
}
public User getByUuidOrThrow(String uuid) {
User user = this.getByUuid(uuid);
if (null == user) {
throw new BaseException(A_USER_NOT_EXIST);
}
return user;
}
public Page<UserInfoDto> listUsers(UsersReq usersReq, Integer currentPage, Integer pageSize) {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(usersReq.getName())) {
wrapper.eq(User::getName, usersReq.getName());
}
if (StringUtils.isNotBlank(usersReq.getUuid())) {
wrapper.eq(User::getUuid, usersReq.getUuid());
}
if (StringUtils.isNotBlank(usersReq.getEmail())) {
wrapper.eq(User::getEmail, usersReq.getEmail());
}
if (null != usersReq.getUserStatus()) {
wrapper.eq(User::getUserStatus, usersReq.getUserStatus());
}
wrapper.orderByDesc(User::getUpdateTime);
Page<User> page = baseMapper.selectPage(new Page<>(currentPage, pageSize), wrapper);
Page<UserInfoDto> result = new Page<>();
return MPPageUtil.convertToPage(page, result, UserInfoDto.class);
}
public UserInfoDto addUser(UserAddReq addUserReq) {
User user = this.lambdaQuery()
.eq(User::getIsDeleted, false)
.eq(User::getEmail, addUserReq.getEmail())
.one();
if (null != user) {
throw new BaseException(A_USER_EXIST);
}
String hashed = BCrypt.hashpw(addUserReq.getPassword(), BCrypt.gensalt());
String uuid = UUID.randomUUID().toString().replace("-", "");
User newOne = new User();
if (StringUtils.isNotBlank(addUserReq.getName())) {
newOne.setName(addUserReq.getName());
} else {
newOne.setName(StringUtils.substringBefore(addUserReq.getEmail(), "@"));
}
newOne.setUuid(uuid);
newOne.setEmail(addUserReq.getEmail());
newOne.setPassword(hashed);
newOne.setUserStatus(UserStatusEnum.NORMAL);
baseMapper.insert(newOne);
UserInfoDto result = new UserInfoDto();
User newUser = this.getByUuid(uuid);
BeanUtils.copyProperties(newUser, result);
return result;
}
}