创建店铺密码强度校验

修改密码 可通过验证码
发送验证码类型限制
This commit is contained in:
2026-04-27 10:08:16 +08:00
parent c3ae15c7cc
commit 91fc6643a8
10 changed files with 93 additions and 38 deletions

View File

@@ -1,5 +1,6 @@
package com.czg.controller.admin;
import cn.hutool.core.util.StrUtil;
import com.czg.account.service.CommonService;
import com.czg.resp.CzgResult;
import com.czg.service.account.util.AliOssUtil;
@@ -8,6 +9,8 @@ import org.apache.commons.io.FilenameUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* 公共接口
* @author Administrator
@@ -20,13 +23,19 @@ public class CommonController {
@Resource
private AliOssUtil aliOssUtil;
private static final List<String> SMS_CODE_TYPE = List.of("editShopInfoOpePwd", "wxMiniPwd", "shopPwd");
/**
* 发送验证码
* @param type 验证码类型
* @param type 验证码类型 目前
* editShopInfoOpePwd 店铺操作密码
* wxMiniPwd 微信小程序用户登录密码
* shopPwd 店铺登录密码
* @return 是否成功
*/
@GetMapping("/sms")
public CzgResult<Boolean> sendSms(@RequestParam String type) {
if(StrUtil.isEmpty(type) || !SMS_CODE_TYPE.contains(type)) return CzgResult.failure("验证码类型错误");
return CzgResult.success(commonService.sendSms(type));
}

View File

@@ -40,7 +40,7 @@ public class ShopInfoController {
@SaAdminCheckRole("管理员")
@SaAdminCheckPermission(parentName = "店铺管理接口", value = "shopInfo:list", name = "店铺列表")
@GetMapping
public CzgResult<Page<ShopInfo>> get(PageDTO pageDTO, String profiles, String phone, String shopName, Integer status, Integer isHeadShop) {
public CzgResult<Page<ShopDetailDTO>> get(PageDTO pageDTO, String profiles, String phone, String shopName, Integer status, Integer isHeadShop) {
return CzgResult.success(shopInfoService.get(pageDTO, profiles, phone, shopName, status, isHeadShop));
}
@@ -49,7 +49,7 @@ public class ShopInfoController {
*
*/
@GetMapping("/otherShop")
public CzgResult<Page<ShopInfo>> getShopByMainId(PageDTO pageDTO, String shopName, Integer status) {
public CzgResult<Page<ShopDetailDTO>> getShopByMainId(PageDTO pageDTO, String shopName, Integer status) {
return CzgResult.success(shopInfoService.getShopByMainId(pageDTO, shopName, status));
}

View File

@@ -1,11 +1,13 @@
package com.czg.controller.admin;
import cn.hutool.core.util.StrUtil;
import com.czg.account.dto.user.SysUserAddDTO;
import com.czg.account.dto.user.SysUserEditDTO;
import com.czg.account.dto.user.SysUserEditPwdDTO;
import com.czg.account.service.SysUserService;
import com.czg.account.vo.SysUserDetailVO;
import com.czg.annotation.SaAdminCheckRole;
import com.czg.exception.CzgException;
import com.czg.resp.CzgResult;
import com.mybatisflex.core.paginate.Page;
import jakarta.annotation.Resource;
@@ -17,6 +19,7 @@ import java.io.IOException;
/**
* 系统用户管理
*
* @author Administrator
*/
@RestController
@@ -27,10 +30,11 @@ public class SysController {
/**
* 系统用户列表
* @param key 名称或邮箱搜索
*
* @param key 名称或邮箱搜索
* @param startTime 开始时间
* @param endTime 结束时间
* @param status 状态1启用、0禁用
* @param endTime 结束时间
* @param status 状态1启用、0禁用
* @return 分页数据
*/
// @SaAdminCheckPermission("sysUser:list")
@@ -42,6 +46,7 @@ public class SysController {
/**
* 员工相信信息
*
* @param id 用户id
* @return 员工信息
*/
@@ -53,6 +58,7 @@ public class SysController {
/**
* 系统账号修改
*
* @param sysUserEditDTO 修改信息
* @return 是否成功
*/
@@ -65,16 +71,22 @@ public class SysController {
/**
* 登录账号密码修改
* @param sysUserEditPwdDTO 修改西悉尼
*
* @param sysUserEditPwdDTO 修改密码
* 原密码与验证码 二选一
* @return 是否成功
*/
@PutMapping("/pwd")
public CzgResult<Boolean> editPwd(@RequestBody @Validated SysUserEditPwdDTO sysUserEditPwdDTO) {
if (StrUtil.isBlank(sysUserEditPwdDTO.getOriginalPassword()) || StrUtil.isBlank(sysUserEditPwdDTO.getCode())) {
throw new CzgException("原密码或验证码不能同时为空");
}
return CzgResult.success(sysUserService.editPwd(sysUserEditPwdDTO));
}
/**
* 系统用户删除
*
* @param id 用户id
* @return 是否成功
*/
@@ -87,6 +99,7 @@ public class SysController {
/**
* 系统用户添加
*
* @param sysUserAddDTO 添加信息
* @return 是否成功
*/
@@ -98,10 +111,11 @@ public class SysController {
/**
* 系统用户导出
* @param key 名称或邮箱搜索
*
* @param key 名称或邮箱搜索
* @param startTime 开始时间
* @param endTime 结束时间
* @param status 状态1启用、0禁用
* @param endTime 结束时间
* @param status 状态1启用、0禁用
* @throws IOException IO异常
*/
@SaAdminCheckRole("admin")

View File

@@ -1,12 +1,8 @@
package com.czg.account.dto.user;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author Administrator
*/
@@ -22,17 +18,21 @@ public class SysUserEditPwdDTO {
*/
// @NotBlank(message = "原密码不为空")
private String originalPassword;
/**
* 验证码
*/
private String code;
/**
* 确认密码
*/
@NotBlank(message = "确认密码不为空")
@NotBlank(message = "确认密码不为空")
private String checkPassword;
/**
* 密码
*/
@NotBlank(message = "确认密码不为空")
@NotBlank(message = "密码不为空")
private String password;

View File

@@ -30,9 +30,9 @@ public interface ShopInfoService extends IService<ShopInfo> {
*/
boolean checkSwitch(Long shopId, ShopSwitchTypeEnum switchType) throws ValidateException;
Page<ShopInfo> get(PageDTO pageDTO, String profiles, String phone, String shopName, Integer status, Integer isHeadShop);
Page<ShopDetailDTO> get(PageDTO pageDTO, String profiles, String phone, String shopName, Integer status, Integer isHeadShop);
Page<ShopInfo> getShopByMainId(PageDTO pageDTO, String shopName, Integer status);
Page<ShopDetailDTO> getShopByMainId(PageDTO pageDTO, String shopName, Integer status);
Boolean add(ShopInfoAddDTO shopInfoAddDTO);

View File

@@ -1,6 +1,8 @@
package com.czg.utils;
import cn.hutool.core.text.PasswdStrength;
import cn.hutool.core.util.StrUtil;
import com.czg.exception.CzgException;
import java.time.LocalDate;
@@ -21,6 +23,7 @@ public class CzgStrUtils {
/**
* 获取当天是周几
*
* @return 周几
*/
public static String getStrWeek() {
@@ -31,4 +34,17 @@ public class CzgStrUtils {
return "" + chineseWeeks[dayOfWeek];
}
public static void checkPwd(String pwd) {
if (StrUtil.isBlank(pwd)) {
throw new CzgException("密码不能为空");
}
if (pwd.length() < 6) {
throw new CzgException("密码长度不能小于6");
}
PasswdStrength.PASSWD_LEVEL level = PasswdStrength.getLevel(pwd);
if (level == PasswdStrength.PASSWD_LEVEL.EASY) {
throw new CzgException("密码强度弱,需包含字母、数字、特殊符号中至少两种");
}
}
}

View File

@@ -1,6 +1,5 @@
package com.czg.service.account.service.impl;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.czg.account.entity.SysUser;
import com.czg.account.service.CommonService;
@@ -10,6 +9,7 @@ import com.czg.exception.CzgException;
import com.czg.sa.StpKit;
import com.czg.service.RedisService;
import com.czg.system.service.SmsService;
import com.czg.utils.CzgRandomUtils;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
@@ -37,9 +37,9 @@ public class CommonServiceImpl implements CommonService {
if (val != null) {
throw new CzgException("请勿频繁获取");
}
int code = RandomUtil.randomInt(100000, 1000000);
String code = CzgRandomUtils.randomNumber(6,true);
redisService.set(key, code, 300);
smsService.sendCode(sysUser.getPhone(), String.valueOf(code));
smsService.sendCode(sysUser.getPhone(), code);
return true;
}

View File

@@ -26,6 +26,7 @@ import com.czg.service.account.mapper.ShopUserMapper;
import com.czg.system.dto.SysParamsDTO;
import com.czg.system.service.SysParamsService;
import com.czg.utils.AssertUtil;
import com.czg.utils.CzgStrUtils;
import com.czg.utils.GeoUtil;
import com.czg.utils.PageUtil;
import com.github.pagehelper.PageHelper;
@@ -113,7 +114,7 @@ public class ShopInfoServiceImpl extends ServiceImpl<ShopInfoMapper, ShopInfo> i
}
@Override
public Page<ShopInfo> get(PageDTO pageDTO, String profiles, String phone, String shopName, Integer status, Integer isHeadShop) {
public Page<ShopDetailDTO> get(PageDTO pageDTO, String profiles, String phone, String shopName, Integer status, Integer isHeadShop) {
QueryWrapper queryWrapper = new QueryWrapper();
if (StrUtil.isNotBlank(profiles)) {
queryWrapper.eq(ShopInfo::getProfiles, profiles);
@@ -135,11 +136,13 @@ public class ShopInfoServiceImpl extends ServiceImpl<ShopInfoMapper, ShopInfo> i
.eq(ShopInfo::getIsHeadShop, 1).ne(ShopInfo::getShopType, ShopTypeEnum.ONLY.getValue()));
Map<Long, String> shopKv = shopAllList.stream().collect(Collectors.toMap(ShopInfo::getId, ShopInfo::getShopName));
queryWrapper.orderBy(ShopInfo::getCreateTime, false);
Page<ShopInfo> page = page(new Page<>(pageDTO.page(), pageDTO.size()), queryWrapper);
Page<ShopDetailDTO> page = pageAs(new Page<>(pageDTO.page(), pageDTO.size()), queryWrapper, ShopDetailDTO.class);
page.getRecords().forEach(shopInfo -> {
ShopConfig shopConfig = shopConfigService.getById(shopInfo.getId());
BeanUtil.copyProperties(shopConfig, shopInfo);
shopInfo.setHeadShopName(shopKv.get(shopInfo.getMainId()));
SysUser sysUser = sysUserService.getById(shopInfo.getId());
shopInfo.setAccount(sysUser.getAccount());
});
return page;
}
@@ -190,7 +193,8 @@ public class ShopInfoServiceImpl extends ServiceImpl<ShopInfoMapper, ShopInfo> i
if (count > 0) {
throw new CzgException("账户已存在");
}
//校验密码长度和强度
CzgStrUtils.checkPwd(shopInfoAddDTO.getAccountPwd());
// 添加系统账号
shopInfoAddDTO.setRoleId(shopInfoAddDTO.getRoleId() == null ? 2L : shopInfoAddDTO.getRoleId());
SysUser sysUser = sysUserService.addUser(shopInfoAddDTO.getShopName(), shopInfoAddDTO.getAccountName(), shopInfoAddDTO.getAccountPwd(), shopInfoAddDTO.getPhone(), shopInfoAddDTO.getRoleId());
@@ -198,9 +202,10 @@ public class ShopInfoServiceImpl extends ServiceImpl<ShopInfoMapper, ShopInfo> i
// 保存店铺信息
ShopInfo shopInfo = BeanUtil.copyProperties(shopInfoAddDTO, ShopInfo.class);
shopInfo.setId(sysUser.getId());
//设置激活码
shopInfo.setStatus(1);
shopInfo.setProfiles("release");
if (StrUtil.isNotBlank(shopInfo.getProfiles())) {
shopInfo.setProfiles("release");
}
save(shopInfo);
if (StrUtil.isNotBlank(shopInfoAddDTO.getActivateCode())) {
activateShop(shopInfo, shopInfoAddDTO.getActivateCode());
@@ -391,7 +396,7 @@ public class ShopInfoServiceImpl extends ServiceImpl<ShopInfoMapper, ShopInfo> i
}
@Override
public Page<ShopInfo> getShopByMainId(PageDTO pageDTO, String shopName, Integer status) {
public Page<ShopDetailDTO> getShopByMainId(PageDTO pageDTO, String shopName, Integer status) {
Long loginId = (Long) StpKit.USER.getLoginId();
ShopInfo shopInfo = getById(loginId);
QueryWrapper queryWrapper = new QueryWrapper();
@@ -408,7 +413,12 @@ public class ShopInfoServiceImpl extends ServiceImpl<ShopInfoMapper, ShopInfo> i
} else {
queryWrapper.eq(ShopInfo::getId, loginId);
}
return page(new Page<>(pageDTO.page(), pageDTO.size()), queryWrapper);
Page<ShopDetailDTO> page = pageAs(new Page<>(pageDTO.page(), pageDTO.size()), queryWrapper, ShopDetailDTO.class);
page.getRecords().forEach(dto -> {
SysUser sysUser = sysUserService.getById(shopInfo.getId());
dto.setAccount(sysUser.getAccount());
});
return page;
}
@Override

View File

@@ -14,12 +14,14 @@ import com.czg.account.entity.SysUser;
import com.czg.account.entity.SysUsersRoles;
import com.czg.account.service.SysUserService;
import com.czg.account.vo.SysUserDetailVO;
import com.czg.config.RedisCst;
import com.czg.exception.CzgException;
import com.czg.sa.StpKit;
import com.czg.service.RedisService;
import com.czg.service.account.mapper.SysRoleMapper;
import com.czg.service.account.mapper.SysUserMapper;
import com.czg.service.account.mapper.SysUsersRolesMapper;
import com.czg.utils.CzgStrUtils;
import com.czg.utils.PageUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@@ -34,8 +36,6 @@ import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import static com.mybatisflex.core.query.QueryMethods.column;
/**
* 系统用户 服务层实现。
*
@@ -210,16 +210,22 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
throw new CzgException("修改失败");
}
}
if (StrUtil.isNotBlank(sysUserEditPwdDTO.getOriginalPassword()) &&
if (StrUtil.isNotBlank(sysUserEditPwdDTO.getCode())) {
Object value = redisService.get(RedisCst.SMS_CODE + sysUser.getPhone() + ":shopPwd");
if (!sysUserEditPwdDTO.getCode().equals(value)) {
throw new CzgException("验证码不正确");
}
} else if (StrUtil.isNotBlank(sysUserEditPwdDTO.getOriginalPassword()) &&
!sysUser.getPassword().equals(SecureUtil.md5(sysUser.getId() + sysUserEditPwdDTO.getOriginalPassword()))) {
throw new CzgException("原密码不正确");
} else {
throw new CzgException("修改失败");
}
if (!sysUserEditPwdDTO.getPassword().equals(sysUserEditPwdDTO.getCheckPassword())) {
throw new CzgException("两次密码不一致");
throw new CzgException("新密码与确认密码不一致");
}
CzgStrUtils.checkPwd(sysUserEditPwdDTO.getPassword());
sysUser.setPassword(SecureUtil.md5(sysUser.getId() + sysUserEditPwdDTO.getPassword()));
boolean isUp = updateById(sysUser);
if (isUp) {

View File

@@ -1,7 +1,6 @@
package com.czg.service.account.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.czg.account.dto.user.userinfo.UserInfoAssetsSummaryDTO;
@@ -19,6 +18,7 @@ import com.czg.service.account.mapper.ShopUserMapper;
import com.czg.service.account.mapper.UserInfoMapper;
import com.czg.service.account.util.AcAccountUtil;
import com.czg.system.service.SmsService;
import com.czg.utils.CzgRandomUtils;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
@@ -81,9 +81,9 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> i
if (StrUtil.isBlank(userInfo.getPhone())) {
throw new CzgException("账号未绑定手机号");
}
int code = RandomUtil.randomInt(100000, 1000000);
redisService.set("%s%s:%s".formatted(RedisCst.SMS_CODE, userInfo.getPhone(), type), String.valueOf(code), 300);
smsService.sendCode(userInfo.getPhone(), String.valueOf(code));
String code = CzgRandomUtils.randomNumber(6, false);
redisService.set("%s%s:%s".formatted(RedisCst.SMS_CODE, userInfo.getPhone(), type), code, 300);
smsService.sendCode(userInfo.getPhone(), code);
return true;
}