Bläddra i källkod

bump: 发布2.4.1

details see: https://helio.uncarbon.cc/#/i18n/zh-CN/appendix/change-log
Uncarbon 1 år sedan
förälder
incheckning
dc6a3be12d

+ 3 - 0
attachments/db/MySQL/helio_boot.sql

@@ -506,3 +506,6 @@ ALTER TABLE sys_log
     ADD COLUMN ip_location_city_name varchar(100) NOT NULL DEFAULT '' COMMENT 'IP地址属地-市级行政区名' AFTER ip_location_province_name,
     ADD COLUMN ip_location_district_name varchar(100) NOT NULL DEFAULT '' COMMENT 'IP地址属地-县级行政区名' AFTER ip_location_city_name;
 ALTER TABLE sys_log COMMENT = '系统日志';
+
+-- 新增'头像URL'字段
+ALTER TABLE sys_user ADD COLUMN avatar_url varchar(255) NULL COMMENT '头像URL';

+ 2 - 0
attachments/db/MySQL/upgrade/2.4.0_to_2.4.1.sql

@@ -0,0 +1,2 @@
+-- 新增'头像URL'字段
+ALTER TABLE sys_user ADD COLUMN avatar_url varchar(255) NULL COMMENT '头像URL';

+ 5 - 0
attachments/db/PostgreSQL/helio_boot.sql

@@ -982,3 +982,8 @@ COMMENT ON TABLE sys_log IS '系统日志';
 -- v1.8.0 - Uncarbon - 订正系统菜单-权限串缺少默认值问题
 ALTER TABLE "sys_menu"
     ALTER COLUMN "permission" SET DEFAULT '';
+
+-- 新增'头像URL'字段
+ALTER TABLE sys_user ADD COLUMN avatar_url varchar(255);
+
+COMMENT ON COLUMN sys_user.avatar_url IS '头像URL';

+ 4 - 0
attachments/db/PostgreSQL/upgrade/2.4.0_to_2.4.1.sql

@@ -0,0 +1,4 @@
+-- 新增'头像URL'字段
+ALTER TABLE sys_user ADD COLUMN avatar_url varchar(255);
+
+COMMENT ON COLUMN sys_user.avatar_url IS '头像URL';

+ 3 - 2
pom.xml

@@ -8,13 +8,14 @@
     <parent>
         <groupId>cc.uncarbon.framework</groupId>
         <artifactId>helio-starters</artifactId>
-        <version>2.4.0</version>
+        <version>2.4.1</version>
     </parent>
 
+    <groupId>cc.uncarbon.module</groupId>
     <artifactId>helio-boot</artifactId>
     <description>Helio 单模块版单体脚手架</description>
     <!-- 制品版本号,建议每次打包发布时都调整以作区分 -->
-    <version>2.4.0</version>
+    <version>2.4.1</version>
 
     <properties>
         <!-- 如果实际开发使用的是JDK 21,则下面改成'21' -->

+ 69 - 0
src/main/java/cc/uncarbon/module/adminapi/web/sys/AdminCurrentSysUserController.java

@@ -0,0 +1,69 @@
+package cc.uncarbon.module.adminapi.web.sys;
+
+import cc.uncarbon.framework.core.exception.BusinessException;
+import cc.uncarbon.framework.web.model.response.ApiResult;
+import cc.uncarbon.module.adminapi.constant.AdminApiConstant;
+import cc.uncarbon.module.adminapi.util.AdminStpUtil;
+import cc.uncarbon.module.sys.annotation.SysLog;
+import cc.uncarbon.module.sys.model.request.AdminUpdateCurrentSysUserAvatarDTO;
+import cc.uncarbon.module.sys.model.request.AdminUpdateCurrentSysUserInfoDTO;
+import cc.uncarbon.module.sys.model.request.AdminUpdateCurrentSysUserPasswordDTO;
+import cc.uncarbon.module.sys.model.response.VbenAdminUserInfoVO;
+import cc.uncarbon.module.sys.service.SysUserService;
+import cn.dev33.satoken.annotation.SaCheckLogin;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+
+@SaCheckLogin(type = AdminStpUtil.TYPE)
+@Tag(name = "当前后台用户信息接口")
+@RequestMapping(value = AdminApiConstant.HTTP_API_URL_PREFIX + "/api/v1")
+@RequiredArgsConstructor
+@RestController
+@Slf4j
+public class AdminCurrentSysUserController {
+
+    private final SysUserService sysUserService;
+
+
+    @Operation(summary = "取当前用户信息资料")
+    // 新路由与旧路由并行
+    @GetMapping(value = {"/sys/users/me/info", "/sys/users/info"})
+    public ApiResult<VbenAdminUserInfoVO> getMyInfo() {
+        return ApiResult.data(sysUserService.adminGetCurrentUserInfo());
+    }
+
+    @SysLog(value = "修改当前用户密码")
+    @Operation(summary = "修改当前用户密码")
+    @PostMapping(value = "/sys/users/me/password:update")
+    public ApiResult<Void> updatePassword(@RequestBody @Valid AdminUpdateCurrentSysUserPasswordDTO dto) {
+        if (!dto.getConfirmNewPassword().equals(dto.getNewPassword())) {
+            throw new BusinessException(400, "密码与确认密码不同,请检查");
+        }
+        sysUserService.adminUpdateCurrentUserPassword(dto);
+
+        // 用户更改密码后使其当前会话直接过期
+        AdminStpUtil.logout();
+
+        return ApiResult.success();
+    }
+
+    @Operation(summary = "更新当前用户信息资料")
+    @PutMapping(value = "/sys/users/me/info")
+    public ApiResult<Void> updateMyInfo(@RequestBody @Valid AdminUpdateCurrentSysUserInfoDTO dto) {
+        sysUserService.adminUpdateCurrentUserInfo(dto);
+        return ApiResult.success();
+    }
+
+    @Operation(summary = "更新当前用户头像")
+    @PutMapping(value = "/sys/users/me/avatar")
+    public ApiResult<Void> updateMyAvatar(@RequestBody @Valid AdminUpdateCurrentSysUserAvatarDTO dto) {
+        sysUserService.adminUpdateCurrentUserAvatar(dto);
+        return ApiResult.success();
+    }
+
+}

+ 4 - 24
src/main/java/cc/uncarbon/module/adminapi/web/sys/AdminSysUserController.java

@@ -1,7 +1,6 @@
 package cc.uncarbon.module.adminapi.web.sys;
 
 import cc.uncarbon.framework.core.constant.HelioConstant;
-import cc.uncarbon.framework.core.exception.BusinessException;
 import cc.uncarbon.framework.core.page.PageParam;
 import cc.uncarbon.framework.core.page.PageResult;
 import cc.uncarbon.framework.web.model.request.IdsDTO;
@@ -9,9 +8,11 @@ import cc.uncarbon.framework.web.model.response.ApiResult;
 import cc.uncarbon.module.adminapi.constant.AdminApiConstant;
 import cc.uncarbon.module.sys.annotation.SysLog;
 import cc.uncarbon.module.sys.enums.SysUserStatusEnum;
-import cc.uncarbon.module.sys.model.request.*;
+import cc.uncarbon.module.sys.model.request.AdminBindUserRoleRelationDTO;
+import cc.uncarbon.module.sys.model.request.AdminInsertOrUpdateSysUserDTO;
+import cc.uncarbon.module.sys.model.request.AdminListSysUserDTO;
+import cc.uncarbon.module.sys.model.request.AdminResetSysUserPasswordDTO;
 import cc.uncarbon.module.sys.model.response.SysUserBO;
-import cc.uncarbon.module.sys.model.response.VbenAdminUserInfoVO;
 import cc.uncarbon.module.sys.service.SysUserService;
 import cc.uncarbon.module.adminapi.util.AdminStpUtil;
 import cn.dev33.satoken.annotation.SaCheckLogin;
@@ -92,12 +93,6 @@ public class AdminSysUserController {
         return ApiResult.success();
     }
 
-    @Operation(summary = "取当前用户信息")
-    @GetMapping(value = "/sys/users/info")
-    public ApiResult<VbenAdminUserInfoVO> getCurrentUserInfo() {
-        return ApiResult.data(sysUserService.adminGetCurrentUserInfo());
-    }
-
     @SysLog(value = "重置某用户密码")
     @SaCheckPermission(type = AdminStpUtil.TYPE, value = PERMISSION_PREFIX + "resetPassword")
     @Operation(summary = "重置某用户密码")
@@ -112,21 +107,6 @@ public class AdminSysUserController {
         return ApiResult.success();
     }
 
-    @SysLog(value = "修改当前用户密码")
-    @Operation(summary = "修改当前用户密码")
-    @PostMapping(value = "/sys/users/me/password:update")
-    public ApiResult<Void> updatePassword(@RequestBody @Valid AdminUpdateCurrentSysUserPasswordDTO dto) {
-        if (!dto.getConfirmNewPassword().equals(dto.getNewPassword())) {
-            throw new BusinessException(400, "密码与确认密码不同,请检查");
-        }
-        sysUserService.adminUpdateCurrentUserPassword(dto);
-
-        // 用户更改密码后使其当前会话直接过期
-        AdminStpUtil.logout();
-
-        return ApiResult.success();
-    }
-
     @SaCheckPermission(type = AdminStpUtil.TYPE, value = PERMISSION_PREFIX + "bindRoles")
     @Operation(summary = "绑定用户与角色关联关系")
     @PutMapping(value = "/sys/users/{userId}/roles")

+ 22 - 0
src/main/java/cc/uncarbon/module/sys/entity/SysUserEntity.java

@@ -3,6 +3,8 @@ package cc.uncarbon.module.sys.entity;
 import cc.uncarbon.framework.core.enums.GenderEnum;
 import cc.uncarbon.framework.crud.entity.HelioBaseEntity;
 import cc.uncarbon.module.sys.enums.SysUserStatusEnum;
+import cc.uncarbon.module.sys.model.request.AdminUpdateCurrentSysUserAvatarDTO;
+import cc.uncarbon.module.sys.model.request.AdminUpdateCurrentSysUserInfoDTO;
 import cn.hutool.core.annotation.Alias;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -66,4 +68,24 @@ public class SysUserEntity extends HelioBaseEntity<Long> {
 	@TableField(value = "last_login_at")
 	private LocalDateTime lastLoginAt;
 
+	@Schema(description = "头像URL")
+	@TableField(value = "avatar_url")
+	private String avatarUrl;
+
+
+	public static SysUserEntity of(AdminUpdateCurrentSysUserInfoDTO dto) {
+		SysUserEntity ret = new SysUserEntity();
+		ret.setNickname(dto.getNickname())
+		   .setGender(dto.getGender())
+		   .setEmail(dto.getEmail())
+		   .setPhoneNo(dto.getPhoneNo());
+		return ret;
+	}
+
+	public static SysUserEntity of(AdminUpdateCurrentSysUserAvatarDTO dto) {
+		SysUserEntity ret = new SysUserEntity();
+		ret.setAvatarUrl(dto.getAvatarUrl());
+		return ret;
+	}
+
 }

+ 38 - 0
src/main/java/cc/uncarbon/module/sys/model/request/AdminUpdateCurrentSysUserAvatarDTO.java

@@ -0,0 +1,38 @@
+package cc.uncarbon.module.sys.model.request;
+
+import cc.uncarbon.framework.core.exception.BusinessException;
+import cn.hutool.core.text.CharSequenceUtil;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.Size;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+
+/**
+ * 后台管理-更新当前后台用户头像
+ */
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class AdminUpdateCurrentSysUserAvatarDTO implements Serializable {
+
+
+    @Schema(description = "头像URL", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Size(max = 255, message = "头像输入长度超限")
+    private String avatarUrl;
+
+    /**
+     * 实际使用时,请手动补充安全检查机制(如检查头像URL所属的CDN域名)
+     */
+    public void securityCheck() {
+        if (!CharSequenceUtil.startWithIgnoreCase(this.avatarUrl, "http")) {
+            throw new BusinessException(400, "头像输入格式不正确");
+        }
+    }
+
+}

+ 53 - 0
src/main/java/cc/uncarbon/module/sys/model/request/AdminUpdateCurrentSysUserInfoDTO.java

@@ -0,0 +1,53 @@
+package cc.uncarbon.module.sys.model.request;
+
+import cc.uncarbon.framework.core.constant.HelioConstant;
+import cc.uncarbon.framework.core.enums.GenderEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Pattern;
+import jakarta.validation.constraints.Size;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+
+/**
+ * 后台管理-更新当前后台用户信息资料
+ */
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class AdminUpdateCurrentSysUserInfoDTO implements Serializable {
+
+
+    @Schema(description = "昵称", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Size(max = 100, message = "【昵称】最长100位")
+    @NotBlank(message = "昵称不能为空")
+    private String nickname;
+
+    @Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "性别不能为空")
+    private GenderEnum gender;
+
+    @Schema(description = "邮箱", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Pattern(message = "邮箱格式有误", regexp = HelioConstant.Regex.EMAIL)
+    @Size(max = 255, message = "【邮箱】最长255位")
+    @NotBlank(message = "邮箱不能为空")
+    private String email;
+
+    @Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Pattern(message = "手机号格式有误", regexp = HelioConstant.Regex.CHINA_MAINLAND_PHONE_NO)
+    @Size(max = 20, message = "【手机号】最长20位")
+    @NotBlank(message = "手机号不能为空")
+    private String phoneNo;
+
+    @Schema(description = "头像URL", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Size(max = 255, message = "头像格式有误")
+    private String avatar;
+
+}

+ 3 - 0
src/main/java/cc/uncarbon/module/sys/model/response/SysUserBO.java

@@ -66,4 +66,7 @@ public class SysUserBO implements Serializable {
     @Schema(description = "所属部门名称")
     private String deptTitle;
 
+    @Schema(description = "头像URL")
+    private String avatarUrl;
+
 }

+ 13 - 0
src/main/java/cc/uncarbon/module/sys/model/response/VbenAdminUserInfoVO.java

@@ -1,5 +1,6 @@
 package cc.uncarbon.module.sys.model.response;
 
+import cc.uncarbon.framework.core.enums.GenderEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -30,4 +31,16 @@ public class VbenAdminUserInfoVO implements Serializable {
     @Schema(description = "最后登录时刻")
     private LocalDateTime lastLoginAt;
 
+    @Schema(description = "性别")
+    private GenderEnum gender;
+
+    @Schema(description = "邮箱")
+    private String email;
+
+    @Schema(description = "手机号")
+    private String phoneNo;
+
+    @Schema(description = "头像URL")
+    private String avatar;
+
 }

+ 26 - 0
src/main/java/cc/uncarbon/module/sys/service/SysUserService.java

@@ -274,6 +274,10 @@ public class SysUserService {
                 .username(sysUserBO.getUsername())
                 .nickname(sysUserBO.getNickname())
                 .lastLoginAt(sysUserBO.getLastLoginAt())
+                .gender(sysUserBO.getGender())
+                .email(sysUserBO.getEmail())
+                .phoneNo(sysUserBO.getPhoneNo())
+                .avatar(sysUserBO.getAvatarUrl())
                 .build();
     }
 
@@ -355,6 +359,28 @@ public class SysUserService {
         }
     }
 
+    /**
+     * 后台管理-更新当前用户信息资料
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void adminUpdateCurrentUserInfo(AdminUpdateCurrentSysUserInfoDTO dto) {
+        SysUserEntity update = SysUserEntity.of(dto);
+        update.setId(UserContextHolder.getUserId());
+        sysUserMapper.updateById(update);
+    }
+
+    /**
+     * 后台管理-更新当前用户头像
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void adminUpdateCurrentUserAvatar(AdminUpdateCurrentSysUserAvatarDTO dto) {
+        dto.securityCheck();
+
+        SysUserEntity update = SysUserEntity.of(dto);
+        update.setId(UserContextHolder.getUserId());
+        sysUserMapper.updateById(update);
+    }
+
     /*
     ----------------------------------------------------------------
                         私有方法 private methods