diff --git a/src/main/java/com/youlai/boot/mini/controller/MiniUserController.java b/src/main/java/com/youlai/boot/mini/controller/MiniUserController.java new file mode 100644 index 0000000..a428c46 --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/controller/MiniUserController.java @@ -0,0 +1,51 @@ +package com.youlai.boot.mini.controller; + +import com.youlai.boot.common.annotation.Log; +import com.youlai.boot.common.enums.ActionTypeEnum; +import com.youlai.boot.common.enums.LogModuleEnum; +import com.youlai.boot.common.result.Result; +import com.youlai.boot.framework.security.util.SecurityUtils; +import com.youlai.boot.mini.model.form.MiniUserUpdateForm; +import com.youlai.boot.mini.model.vo.MiniUserInfoVO; +import com.youlai.boot.mini.service.MiniUserService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +/** + * C端用户信息接口 + * + * @author youlai + * @since 2024 + */ +@Tag(name = "C端用户信息接口") +@RestController +@RequestMapping("/api/v1/mini/user") +@RequiredArgsConstructor +@Valid +public class MiniUserController { + + private final MiniUserService miniUserService; + + @Operation(summary = "获取当前登录用户基本信息") + @GetMapping("/info") + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.LIST) + public Result getCurrentUserInfo() { + Long userId = SecurityUtils.getUserId(); + MiniUserInfoVO userInfo = miniUserService.getCurrentUserInfo(userId); + return Result.success(userInfo); + } + + @Operation(summary = "修改当前登录用户基本信息") + @PostMapping(value = "/updateInfo", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.UPDATE) + public Result updateCurrentUserInfo(@Valid MiniUserUpdateForm form) { + Long userId = SecurityUtils.getUserId(); + miniUserService.updateCurrentUserInfo(userId, form); + return Result.success(); + } + +} diff --git a/src/main/java/com/youlai/boot/mini/model/form/MiniUserUpdateForm.java b/src/main/java/com/youlai/boot/mini/model/form/MiniUserUpdateForm.java new file mode 100644 index 0000000..9e2d95c --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/model/form/MiniUserUpdateForm.java @@ -0,0 +1,22 @@ +package com.youlai.boot.mini.model.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Size; +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + + +@Data +@Schema(description = "C端用户修改信息表单") +public class MiniUserUpdateForm { + + @Schema(description = "用户昵称") + @Size(max = 20, message = "昵称长度不能超过20个字符") + private String nickname; + + @Schema(description = "头像文件") + private MultipartFile avatar; + + @Schema(description = "性别:0-未知 1-男 2-女") + private Integer gender; +} diff --git a/src/main/java/com/youlai/boot/mini/model/vo/MiniUserInfoVO.java b/src/main/java/com/youlai/boot/mini/model/vo/MiniUserInfoVO.java new file mode 100644 index 0000000..0d01308 --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/model/vo/MiniUserInfoVO.java @@ -0,0 +1,28 @@ +package com.youlai.boot.mini.model.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + + +@Data +@Schema(description = "C端用户基本信息") +public class MiniUserInfoVO { + + @Schema(description = "用户UUID") + private String userUuid; + + @Schema(description = "用户昵称") + private String nickname; + + @Schema(description = "头像URL") + private String avatar; + + @Schema(description = "性别:0-未知 1-男 2-女") + private Integer gender; + + @Schema(description = "手机号(脱敏)") + private String phone; + + @Schema(description = "当前积分") + private Integer points; +} diff --git a/src/main/java/com/youlai/boot/mini/service/MiniUserService.java b/src/main/java/com/youlai/boot/mini/service/MiniUserService.java new file mode 100644 index 0000000..af3b11c --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/service/MiniUserService.java @@ -0,0 +1,11 @@ +package com.youlai.boot.mini.service; + +import com.youlai.boot.mini.model.form.MiniUserUpdateForm; +import com.youlai.boot.mini.model.vo.MiniUserInfoVO; + +public interface MiniUserService { + + MiniUserInfoVO getCurrentUserInfo(Long userId); + + void updateCurrentUserInfo(Long userId, MiniUserUpdateForm form); +} diff --git a/src/main/java/com/youlai/boot/mini/service/impl/MiniUserServiceImpl.java b/src/main/java/com/youlai/boot/mini/service/impl/MiniUserServiceImpl.java new file mode 100644 index 0000000..356d21a --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/service/impl/MiniUserServiceImpl.java @@ -0,0 +1,126 @@ +package com.youlai.boot.mini.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.youlai.boot.common.exception.MsgException; +import com.youlai.boot.common.util.RandomNumberUtils; +import com.youlai.boot.file.model.FileInfo; +import com.youlai.boot.file.service.FileService; +import com.youlai.boot.file.service.impl.AliyunFileService; +import com.youlai.boot.framework.security.util.SecurityUtils; +import com.youlai.boot.mini.model.entity.MiniStrayAnimalNoteMedia; +import com.youlai.boot.mini.model.enums.AnimalNoteMediaTypeEnum; +import com.youlai.boot.mini.model.form.MiniUserUpdateForm; +import com.youlai.boot.mini.model.vo.MiniUserInfoVO; +import com.youlai.boot.mini.service.MiniUserService; +import com.youlai.boot.mini.service.MiniPointAccountService; +import com.youlai.boot.system.model.entity.SysUser; +import com.youlai.boot.system.service.UserService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.util.Date; +import java.util.UUID; + +/** + * C端用户服务实现类 + * + * @author youlai + * @since 2024 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class MiniUserServiceImpl implements MiniUserService { + + private final UserService sysUserService; + private final FileService fileService; + private final MiniPointAccountService pointAccountService; + private final AliyunFileService aliyunFileService; + + @Override + public MiniUserInfoVO getCurrentUserInfo(Long userId) { + SysUser sysUser = sysUserService.getById(userId); + if (sysUser == null) { + throw new MsgException("用户不存在"); + } + + MiniUserInfoVO vo = new MiniUserInfoVO(); + vo.setUserUuid(sysUser.getUuid()); + vo.setNickname(sysUser.getNickname()); + vo.setAvatar(sysUser.getAvatar()); + vo.setGender(sysUser.getGender()); + // 积分从积分账户表获取 + Integer points = pointAccountService.getUserPoint(userId).getPoints(); + vo.setPoints(points); + + // 手机号脱敏 + if (sysUser.getMobile() != null) { + String mobile = sysUser.getMobile().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"); + vo.setPhone(mobile); + } + + return vo; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateCurrentUserInfo(Long userId, MiniUserUpdateForm form) { + SysUser sysUser = sysUserService.getById(userId); + if (sysUser == null) { + throw new MsgException("用户不存在"); + } + + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(SysUser::getId, userId); + + // 处理头像上传 + MultipartFile avatar = form.getAvatar(); + long currentTimestamp = System.currentTimeMillis(); + if (avatar != null && !avatar.isEmpty()) { + try { + String objectName = "user_avatar/image/" + + currentTimestamp + RandomNumberUtils.createRandomLowerLetterAndNumber(8) + + "." + + FilenameUtils.getExtension(avatar.getOriginalFilename()); + String newAvatarUrl = aliyunFileService.uploadFile(objectName, avatar.getInputStream()); + + //更新数据库头像字段 + updateWrapper.set(SysUser::getAvatar, newAvatarUrl); + + // 删除旧头像(如果存在) + String oldAvatar = sysUser.getAvatar(); + if (StringUtils.hasText(oldAvatar)) { + try { + fileService.deleteFile(oldAvatar); + } catch (Exception e) { + // 删除旧头像失败只打日志 + log.warn("删除用户旧头像失败,userId={}, oldAvatar={}", userId, oldAvatar, e); + } + } + } catch (Exception e) { + log.error("user avatar upload failed", e); + } + } + + // 处理其他字段 + if (StringUtils.hasText(form.getNickname())) { + updateWrapper.set(SysUser::getNickname, form.getNickname()); + } + if (form.getGender() != null) { + updateWrapper.set(SysUser::getGender, form.getGender()); + } + + // 执行更新 + boolean success = sysUserService.update(updateWrapper); + if (!success) { + throw new MsgException("用户信息更新失败,请重试"); + } + } +}