diff --git a/fys-common/src/main/java/com/fuyuanshen/constants/RedisConstants.java b/fys-common/src/main/java/com/fuyuanshen/constants/RedisConstants.java new file mode 100644 index 0000000..af4820a --- /dev/null +++ b/fys-common/src/main/java/com/fuyuanshen/constants/RedisConstants.java @@ -0,0 +1,8 @@ +package com.fuyuanshen.constants; + +public class RedisConstants { + + public static final String APP_FORGOT_PASSWORD_SMS_TOKEN = "app_sms_forgotPassword:"; + + public static final String APP_REGISTER_SMS_TOKEN = "app_sms_register:"; +} diff --git a/fys-system/src/main/java/com/fuyuanshen/modules/security/rest/AuthController.java b/fys-system/src/main/java/com/fuyuanshen/modules/security/rest/AuthController.java index 974bbe8..621e12d 100644 --- a/fys-system/src/main/java/com/fuyuanshen/modules/security/rest/AuthController.java +++ b/fys-system/src/main/java/com/fuyuanshen/modules/security/rest/AuthController.java @@ -146,7 +146,7 @@ public class AuthController { @Log("app用户登录") @ApiOperation("app用户登录") @AnonymousPostMapping(value = "/app/login") - public ResponseEntity APPLogin(@Validated @RequestBody AppAuthUserDto authUser, HttpServletRequest request) throws Exception { + public ResponseVO APPLogin(@Validated @RequestBody AppAuthUserDto authUser, HttpServletRequest request) throws Exception { // 1. 构建查询参数 APPUserQuery appUserQuery = new APPUserQuery(); @@ -196,7 +196,7 @@ public class AuthController { onlineUserService.saveAppOnlineUser(jwtUser, token, request); // 11. 返回结果 - return ResponseEntity.ok(authInfo); + return ResponseVO.success(authInfo); } diff --git a/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/app/APPUser.java b/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/app/APPUser.java index 653c72c..83bd2e4 100644 --- a/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/app/APPUser.java +++ b/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/app/APPUser.java @@ -133,4 +133,8 @@ public class APPUser extends BaseEntity implements Serializable { @ApiModelProperty(hidden = true) private Integer userType; + /** + * 地区 + */ + private String region; } \ No newline at end of file diff --git a/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/dto/app/APPForgotPasswordDTO.java b/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/dto/app/APPForgotPasswordDTO.java new file mode 100644 index 0000000..0c7c6d8 --- /dev/null +++ b/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/dto/app/APPForgotPasswordDTO.java @@ -0,0 +1,27 @@ +package com.fuyuanshen.modules.system.domain.dto.app; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * @author: 默苍璃 + * @date: 2025-06-1818:36 + */ +@Data +public class APPForgotPasswordDTO { + + @NotBlank(message = "手机号不能为空") + @ApiModelProperty(value = "手机号(APP登录)") + private String phoneNumber; + + + @NotBlank(message = "密码不能为空") + @ApiModelProperty(value = "密码") + private String password; + + @ApiModelProperty(value = "验证码") + @NotBlank(message = "验证码不能为空") + private String verificationCode; +} diff --git a/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/dto/app/APPUpdateUserDTO.java b/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/dto/app/APPUpdateUserDTO.java new file mode 100644 index 0000000..39c1e3c --- /dev/null +++ b/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/dto/app/APPUpdateUserDTO.java @@ -0,0 +1,32 @@ +package com.fuyuanshen.modules.system.domain.dto.app; + +import com.fuyuanshen.modules.system.domain.app.APPUser; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.constraints.NotBlank; + +/** + * @author: 默苍璃 + * @date: 2025-06-1818:36 + */ +@Data +public class APPUpdateUserDTO { + + + @ApiModelProperty(value = "ID", hidden = true) + private Long id; + + @ApiModelProperty(value = "用户昵称") + private String nickName; + + @ApiModelProperty(value = "地区") + private String region; + + @ApiModelProperty(value = "用户性别") + private String gender; + + @ApiModelProperty(value = "头像图片") + private MultipartFile file; +} diff --git a/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/vo/APPUserVo.java b/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/vo/APPUserVo.java new file mode 100644 index 0000000..32dba88 --- /dev/null +++ b/fys-system/src/main/java/com/fuyuanshen/modules/system/domain/vo/APPUserVo.java @@ -0,0 +1,25 @@ +package com.fuyuanshen.modules.system.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author: 默苍璃 + * @date: 2025-06-1211:34 + */ +@Data +public class APPUserVo { + + @ApiModelProperty(value = "ID") + private Long id; + + @ApiModelProperty(value = "用户昵称") + private String nickName; + + @ApiModelProperty(value = "用户性别") + private String gender; + + @ApiModelProperty(value = "电话号码") + private Long phone; + +} diff --git a/fys-system/src/main/java/com/fuyuanshen/modules/system/rest/app/APPUserController.java b/fys-system/src/main/java/com/fuyuanshen/modules/system/rest/app/APPUserController.java index 529729a..a7ff195 100644 --- a/fys-system/src/main/java/com/fuyuanshen/modules/system/rest/app/APPUserController.java +++ b/fys-system/src/main/java/com/fuyuanshen/modules/system/rest/app/APPUserController.java @@ -15,54 +15,30 @@ */ package com.fuyuanshen.modules.system.rest.app; -import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fuyuanshen.annotation.Log; import com.fuyuanshen.annotation.rest.AnonymousPostMapping; import com.fuyuanshen.exception.BadRequestException; -import com.fuyuanshen.modules.security.service.UserCacheManager; -import com.fuyuanshen.modules.security.service.dto.JwtUserDto; -import com.fuyuanshen.modules.system.constant.UserConstants; -import com.fuyuanshen.modules.system.domain.Dept; -import com.fuyuanshen.modules.system.domain.Role; -import com.fuyuanshen.modules.system.domain.User; import com.fuyuanshen.modules.system.domain.app.APPUser; -import com.fuyuanshen.modules.system.domain.dto.UserPassVo; +import com.fuyuanshen.modules.system.domain.dto.DeviceForm; import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria; +import com.fuyuanshen.modules.system.domain.dto.app.APPForgotPasswordDTO; +import com.fuyuanshen.modules.system.domain.dto.app.APPUpdateUserDTO; import com.fuyuanshen.modules.system.domain.dto.app.APPUserDTO; -import com.fuyuanshen.modules.system.domain.query.APPUserQuery; -import com.fuyuanshen.modules.system.domain.vo.ConsumerVo; +import com.fuyuanshen.modules.system.domain.vo.APPUserVo; import com.fuyuanshen.modules.system.enums.UserType; -import com.fuyuanshen.modules.system.mapper.UserMapper; -import com.fuyuanshen.modules.system.service.*; import com.fuyuanshen.modules.system.service.app.APPUserService; import com.fuyuanshen.modules.utils.ResponseVO; import com.fuyuanshen.utils.PageResult; import com.fuyuanshen.utils.SecurityUtils; -import com.fuyuanshen.utils.StringUtils; -import com.fuyuanshen.utils.enums.CodeEnum; -import io.netty.util.internal.StringUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.poi.ss.formula.functions.T; +import org.apache.ibatis.annotations.Param; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; /** * @author Zheng Jie @@ -91,10 +67,17 @@ public class APPUserController { @ApiOperation("用户中心") @GetMapping(value = "/get") @PreAuthorize("@el.check('appUser:get')") - public ResponseVO getAPPUser(UserQueryCriteria criteria) { + public ResponseVO getAPPUser() { String userName = SecurityUtils.getCurrentUsername(); - return null; -// return ResponseVO.success(appUserService.getAPPUser(criteria)); + APPUser appUser = appUserService.getLoginData(userName); + + APPUserVo appUserVo = new APPUserVo(); + appUserVo.setId(appUser.getId()); + appUserVo.setNickName(appUser.getNickName()); + appUserVo.setGender(appUser.getGender()); + appUserVo.setPhone(appUser.getPhone()); + + return ResponseVO.success(appUserVo); } @Log("app用户注册") @@ -103,21 +86,52 @@ public class APPUserController { public ResponseVO APPRegister(@Validated @RequestBody APPUserDTO user) throws Exception { //暫定0000 - if (user.getVerificationCode() == null || !"0000".equals(user.getVerificationCode())) { + if (!"0000".equals(user.getVerificationCode())) { throw new BadRequestException("验证码错误"); } appUserService.addUser(user); return ResponseVO.success("success!!!"); } + @Log("发送用户注册验证码") + @ApiOperation("发送用户注册验证码") + @AnonymousPostMapping(value = "/sendRegisterSms") + public ResponseVO sendRegisterSms(@Param("phoneNumber") String phoneNumber) throws Exception { +// appUserService.sendSms(phoneNumber); + return ResponseVO.success("success!!!"); + } + @Log("修改APP用户") @ApiOperation("修改APP用户") @PutMapping @PreAuthorize("@el.check('appUser:edit')") - public ResponseVO updateUser(@Validated(APPUser.Update.class) @RequestBody APPUser appUser) throws Exception { - appUserService.updateById(appUser); + public ResponseVO updateUser(@Validated @ModelAttribute APPUpdateUserDTO appUser) throws Exception { + Long userId = SecurityUtils.getCurrentUserId(); + if(!userId.equals(appUser.getId())){ + throw new BadRequestException("不能修改他人资料"); + } + + appUserService.updateUser(appUser); return ResponseVO.success("success!!!"); } + @Log("忘记密码") + @ApiOperation("忘记密码") + @AnonymousPostMapping(value = "/forgotPassword") + public ResponseVO forgotPassword(@RequestBody APPForgotPasswordDTO appForgotPasswordDTO) throws Exception { + if (!"0000".equals(appForgotPasswordDTO.getVerificationCode())) { + throw new BadRequestException("验证码错误"); + } + appUserService.forgotPassword(appForgotPasswordDTO); + return ResponseVO.success("success!!!"); + } + + @Log("发送忘记密码验证码") + @ApiOperation("发送忘记密码验证码") + @AnonymousPostMapping(value = "/sendForgotPasswordSms") + public ResponseVO sendForgotPasswordSms(@Param("phoneNumber") String phoneNumber) throws Exception { +// appUserService.sendSms(phoneNumber); + return ResponseVO.success("success!!!"); + } } diff --git a/fys-system/src/main/java/com/fuyuanshen/modules/system/service/app/APPUserService.java b/fys-system/src/main/java/com/fuyuanshen/modules/system/service/app/APPUserService.java index c8fdacf..2d1cbf8 100644 --- a/fys-system/src/main/java/com/fuyuanshen/modules/system/service/app/APPUserService.java +++ b/fys-system/src/main/java/com/fuyuanshen/modules/system/service/app/APPUserService.java @@ -21,6 +21,8 @@ import com.fuyuanshen.modules.security.service.dto.app.AppRoleDto; import com.fuyuanshen.modules.system.domain.Role; import com.fuyuanshen.modules.system.domain.app.APPUser; import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria; +import com.fuyuanshen.modules.system.domain.dto.app.APPForgotPasswordDTO; +import com.fuyuanshen.modules.system.domain.dto.app.APPUpdateUserDTO; import com.fuyuanshen.modules.system.domain.dto.app.APPUserDTO; import com.fuyuanshen.modules.utils.ResponseVO; import com.fuyuanshen.utils.PageResult; @@ -54,4 +56,10 @@ public interface APPUserService extends IService { ResponseVO addUser(APPUserDTO user); Integer selectRoleByUserLevel(Set roles); + + void forgotPassword(APPForgotPasswordDTO appForgotPasswordDTO); + + void sendSms(String phoneNumber); + + void updateUser(APPUpdateUserDTO appUser); } diff --git a/fys-system/src/main/java/com/fuyuanshen/modules/system/service/impl/app/APPUserServiceImpl.java b/fys-system/src/main/java/com/fuyuanshen/modules/system/service/impl/app/APPUserServiceImpl.java index 83da1ad..f89014d 100644 --- a/fys-system/src/main/java/com/fuyuanshen/modules/system/service/impl/app/APPUserServiceImpl.java +++ b/fys-system/src/main/java/com/fuyuanshen/modules/system/service/impl/app/APPUserServiceImpl.java @@ -15,24 +15,35 @@ */ package com.fuyuanshen.modules.system.service.impl.app; +import cn.hutool.core.util.RandomUtil; import cn.hutool.crypto.digest.MD5; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuyuanshen.constants.DeviceConstants; import com.fuyuanshen.exception.BadRequestException; import com.fuyuanshen.modules.system.domain.Role; import com.fuyuanshen.modules.system.domain.app.APPUser; import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria; +import com.fuyuanshen.modules.system.domain.dto.app.APPForgotPasswordDTO; +import com.fuyuanshen.modules.system.domain.dto.app.APPUpdateUserDTO; import com.fuyuanshen.modules.system.domain.dto.app.APPUserDTO; import com.fuyuanshen.modules.system.mapper.app.APPUserMapper; import com.fuyuanshen.modules.system.service.app.APPUserService; import com.fuyuanshen.modules.utils.ResponseVO; import com.fuyuanshen.utils.*; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.io.IOException; import java.util.Set; +import static com.fuyuanshen.constants.RedisConstants.*; + /** * @author Zheng Jie * @date 2018-11-23 @@ -45,6 +56,19 @@ public class APPUserServiceImpl extends ServiceImpl impl private final PasswordEncoder passwordEncoder; + @Autowired + private final RedisUtils redisUtils; + + @Value("${file.app_avatar.pic}") + private String filePath; + @Value("${file.app_avatar.ip}") + private String ip; + + /** + * 文件访问路径前缀 + */ + public static final String FILE_ACCESS_PREFIX = "images"; + public static final String FILE_AVATAR_PREFIX = "avatar"; /** * 查询APP/小程序用户 * @@ -73,6 +97,14 @@ public class APPUserServiceImpl extends ServiceImpl impl if (appUserMapper.getByUsername(username) != null) { throw new BadRequestException("该手机号已被注册"); } + +/* Object verificationCode = redisUtils.get(APP_REGISTER_SMS_TOKEN + username); + if (verificationCode == null) { + throw new BadRequestException("验证码已过期"); + } + if(!user.getVerificationCode().equals(verificationCode.toString())){ + throw new BadRequestException("验证码错误"); + }*/ APPUser appUser = new APPUser(); appUser.setUsername(user.getPhoneNumber()); @@ -96,4 +128,67 @@ public class APPUserServiceImpl extends ServiceImpl impl return 0; } + @Override + public void forgotPassword(APPForgotPasswordDTO appForgotPasswordDTO) { + String phoneNumber = appForgotPasswordDTO.getPhoneNumber(); + APPUser appUser = appUserMapper.appFindByUsername(phoneNumber); + if (appUser == null) { + throw new BadRequestException("手机号不存在"); + } + /*Object verificationCode = redisUtils.get(APP_FORGOT_PASSWORD_SMS_TOKEN + phoneNumber); + if (verificationCode == null) { + throw new BadRequestException("验证码已过期"); + } + if(!appForgotPasswordDTO.getVerificationCode().equals(verificationCode.toString())){ + throw new BadRequestException("验证码错误"); + }*/ + appUser.setPassword(appForgotPasswordDTO.getPassword()); + appUserMapper.updateById(appUser); + } + + @Override + public void sendSms(String phoneNumber) { + if (appUserMapper.appFindByUsername(phoneNumber) == null) { + throw new BadRequestException("手机号不存在"); + } + // todo 发送验证码 + + redisUtils.set(APP_FORGOT_PASSWORD_SMS_TOKEN + phoneNumber, RandomUtil.randomNumbers(4), 5 * 60); + + } + + @Override + public void updateUser(APPUpdateUserDTO appUser) { + APPUser updUser= new APPUser(); + updUser.setId(appUser.getId()); + updUser.setNickName(appUser.getNickName()); + try { + updUser.setAvatarPath(saveUserAvatarImage(appUser.getFile())); + }catch (IOException e){ + throw new BadRequestException("上传头像失败"); + } + updUser.setRegion(appUser.getRegion()); + updUser.setGender(appUser.getGender()); + appUserMapper.updateById(updUser); + } + + private String saveUserAvatarImage(MultipartFile file) throws IOException { + if (file == null || file.isEmpty()) { + return null; + } + + String originalFileName = file.getOriginalFilename(); + String fileExtension = originalFileName.substring(originalFileName.lastIndexOf(".") + 1); + String newFileName = "PS_" + RandomUtil.randomNumbers(8) + "." + fileExtension; + + File newFile = new File(filePath + FILE_AVATAR_PREFIX + File.separator + newFileName); + + if (!newFile.getParentFile().exists()) { + newFile.getParentFile().mkdirs(); + } + + file.transferTo(newFile); + + return ip + DeviceConstants.FILE_ACCESS_PREFIX + "/" + FILE_AVATAR_PREFIX + "/" + newFileName; + } } diff --git a/fys-system/src/main/resources/config/application-dev.yml b/fys-system/src/main/resources/config/application-dev.yml index 5892d92..177945c 100644 --- a/fys-system/src/main/resources/config/application-dev.yml +++ b/fys-system/src/main/resources/config/application-dev.yml @@ -141,6 +141,10 @@ file: device: pic: C:\eladmin\file\ #设备图片存储路径 ip: http://fuyuanshen.com:81/ #服务器地址 + app_avatar: + pic: C:\eladmin\file\ #设备图片存储路径 + #ip: http://fuyuanshen.com:81/ #服务器地址 + ip: https://fuyuanshen.com/ #服务器地址 logging: level: diff --git a/fys-system/src/main/resources/config/application-prod.yml b/fys-system/src/main/resources/config/application-prod.yml index 63a86da..9208981 100644 --- a/fys-system/src/main/resources/config/application-prod.yml +++ b/fys-system/src/main/resources/config/application-prod.yml @@ -151,3 +151,7 @@ file: pic: /home/eladmin/file/ #设备图片存储路径 #ip: http://fuyuanshen.com:81/ #服务器地址 ip: https://fuyuanshen.com/ #服务器地址 + app_avatar: + pic: /home/eladmin/app_avatar/ #设备图片存储路径 + #ip: http://fuyuanshen.com:81/ #服务器地址 + ip: https://fuyuanshen.com/ #服务器地址 diff --git a/fys-system/src/main/resources/config/application.yml b/fys-system/src/main/resources/config/application.yml index 0669a77..76c354c 100644 --- a/fys-system/src/main/resources/config/application.yml +++ b/fys-system/src/main/resources/config/application.yml @@ -43,6 +43,8 @@ spring: multipart: max-file-size: 5MB # 设置单个上传文件的最大大小为10MB max-request-size: 5MB + jackson: + default-property-inclusion: non_null # pid: # file: /自行指定位置/eladmin.pid