将 onemall 老代码,统一到归档目录,后续不断迁移移除
This commit is contained in:
108
归档/user-service-project/user-service-app/pom.xml
Normal file
108
归档/user-service-project/user-service-app/pom.xml
Normal file
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>user-service-project</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>user-service-app</artifactId>
|
||||
<dependencies>
|
||||
<!-- RPC 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-dubbo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- 系统服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>system-service-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- 用户服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>user-service-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId> <!-- 需要开启 Web 容器,因为 Actuator 需要使用到 -->
|
||||
</dependency>
|
||||
|
||||
<!-- Registry 和 Config 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 监控相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-jdk8</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<!-- 使用 spring-boot-maven-plugin 插件打包 -->
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.iocoder.mall.userservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableFeignClients(basePackages = {"cn.iocoder.mall.systemservice.rpc"})
|
||||
@EnableDiscoveryClient
|
||||
public class UserServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(UserServiceApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package cn.iocoder.mall.userservice.controller;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.userservice.manager.address.UserAddressManager;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressCreateReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressRespDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressUpdateReqDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/user/address")
|
||||
public class UserAddressController {
|
||||
|
||||
@Autowired
|
||||
private UserAddressManager userAddressManager;
|
||||
|
||||
@PostMapping("createUserAddress")
|
||||
public CommonResult<Integer> createUserAddress(@RequestBody UserAddressCreateReqDTO createDTO) {
|
||||
return success(userAddressManager.createUserAddress(createDTO));
|
||||
}
|
||||
|
||||
@PostMapping("updateUserAddress")
|
||||
public CommonResult<Boolean> updateUserAddress(@RequestBody UserAddressUpdateReqDTO updateDTO) {
|
||||
userAddressManager.updateUserAddress(updateDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("deleteUserAddress")
|
||||
public CommonResult<Boolean> deleteUserAddress(@RequestParam("userAddressId") Integer userAddressId) {
|
||||
userAddressManager.deleteUserAddress(userAddressId);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("getUserAddress")
|
||||
public CommonResult<UserAddressRespDTO> getUserAddress(@RequestParam("userAddressId")Integer userAddressId) {
|
||||
return success(userAddressManager.getUserAddress(userAddressId));
|
||||
}
|
||||
|
||||
@GetMapping("listUserAddressesByIds")
|
||||
public CommonResult<List<UserAddressRespDTO>> listUserAddresses(@RequestParam("userAddressIds")List<Integer> userAddressIds) {
|
||||
return success(userAddressManager.listUserAddresses(userAddressIds));
|
||||
}
|
||||
|
||||
@GetMapping("listUserAddresses")
|
||||
public CommonResult<List<UserAddressRespDTO>> listUserAddresses(@RequestParam("userId")Integer userId, @RequestParam("type")Integer type) {
|
||||
return success(userAddressManager.listUserAddresses(userId, type));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.iocoder.mall.userservice.controller;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.userservice.manager.user.UserManager;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserCreateReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserPageReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserRespDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserUpdateReqDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/user/manage")
|
||||
public class UserManageController {
|
||||
|
||||
@Autowired
|
||||
private UserManager userManager;
|
||||
|
||||
@GetMapping("getUser")
|
||||
public CommonResult<UserRespDTO> getUser(@RequestParam("id") Integer id) {
|
||||
return success(userManager.getUser(id));
|
||||
}
|
||||
|
||||
@GetMapping("listUsers")
|
||||
public CommonResult<List<UserRespDTO>> listUsers(@RequestParam("userIds") List<Integer> userIds) {
|
||||
return success(userManager.listUsers(userIds));
|
||||
}
|
||||
|
||||
@PostMapping("createUserIfAbsent")
|
||||
public CommonResult<UserRespDTO> createUserIfAbsent(@RequestBody UserCreateReqDTO createDTO) {
|
||||
return success(userManager.createUserIfAbsent(createDTO));
|
||||
}
|
||||
|
||||
@PostMapping("updateUser")
|
||||
public CommonResult<Boolean> updateUser(@RequestBody UserUpdateReqDTO updateDTO) {
|
||||
userManager.updateUser(updateDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("pageUser")
|
||||
public CommonResult<PageResult<UserRespDTO>> pageUser(@RequestBody UserPageReqDTO pageDTO) {
|
||||
return success(userManager.pageUser(pageDTO));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package cn.iocoder.mall.userservice.dal.mysql.dataobject.address;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
|
||||
import cn.iocoder.mall.userservice.enums.address.UserAddressType;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 用户收件地址
|
||||
*
|
||||
* idx_userId 索引:基于 {@link #userId} 字段
|
||||
*
|
||||
* @author Sin
|
||||
* @time 2019-04-06 13:22
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("user_address")
|
||||
public class UserAddressDO extends DeletableDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer userId;
|
||||
/**
|
||||
* 收件人名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 收件手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 地区编码
|
||||
*/
|
||||
private Integer areaCode;
|
||||
/**
|
||||
* 收件详细地址
|
||||
*/
|
||||
private String detailAddress;
|
||||
/**
|
||||
* 地址类型,主要分为默认地址,和普通地址
|
||||
*
|
||||
* 外键 {@link UserAddressType}
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package cn.iocoder.mall.userservice.dal.mysql.dataobject.sms;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.mall.userservice.enums.sms.UserSmsSceneEnum;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 手机验证码 DO
|
||||
*
|
||||
* idx_mobile 索引:基于 {@link #mobile} 字段
|
||||
*/
|
||||
@TableName("user_sms_code")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class UserSmsCodeDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 发送场景
|
||||
*
|
||||
* 外键 {@link UserSmsSceneEnum}
|
||||
*/
|
||||
private Integer scene;
|
||||
/**
|
||||
* 创建 IP
|
||||
*/
|
||||
private String createIp;
|
||||
/**
|
||||
* 今日发送的第几条
|
||||
*/
|
||||
private Integer todayIndex;
|
||||
/**
|
||||
* 是否使用
|
||||
*/
|
||||
private Boolean used;
|
||||
/**
|
||||
* 使用时间
|
||||
*/
|
||||
private Date usedTime;
|
||||
/**
|
||||
* 使用 IP
|
||||
*/
|
||||
private String usedIp;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package cn.iocoder.mall.userservice.dal.mysql.dataobject.user;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.mall.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 用户实体
|
||||
*
|
||||
* uk_mobile 索引:基于 {@link #mobile} 字段
|
||||
*/
|
||||
@TableName(value = "users")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class UserDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 用户状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 手机
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 经过加密的密码串
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* {@link #password} 的盐
|
||||
*/
|
||||
private String passwordSalt;
|
||||
/**
|
||||
* 注册 IP
|
||||
*/
|
||||
private String createIp;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package cn.iocoder.mall.userservice.dal.mysql.dataobject.user;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户三方开放平台授权,例如:QQ / 微博 / 微信等等。
|
||||
*
|
||||
* TODO 优化点:需要在改改
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserThirdAuthDO {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*
|
||||
* 外键 {@link UserDO#uid}
|
||||
*/
|
||||
private Long uid;
|
||||
|
||||
// ========== 授权相关字段
|
||||
|
||||
/**
|
||||
* 用户的唯一标识
|
||||
*/
|
||||
private String openid;
|
||||
/**
|
||||
* 开放平台
|
||||
*
|
||||
* @see cn.iocoder.mall.user.api.constant.ThirdPlatformConstant
|
||||
*/
|
||||
private Integer platform;
|
||||
/**
|
||||
* 访问令牌
|
||||
*/
|
||||
private Date accessToken;
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private Date expireTime;
|
||||
/**
|
||||
* 刷新令牌
|
||||
*/
|
||||
private Date refreshToken;
|
||||
/**
|
||||
* 授权范围。一般情况下,使用逗号分隔
|
||||
*/
|
||||
private String scopes;
|
||||
|
||||
// ========== 基础信息
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* TODO 芋艿,找地方统一枚举。0-未知,1-男,2-女
|
||||
*/
|
||||
private Integer gender;
|
||||
// TODO https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
|
||||
// TODO 芋艿,其他字段,国家/省份/城市/地区等
|
||||
// TODO 芋艿,头像
|
||||
// TODO 芋艿,微信独有 unionid
|
||||
/**
|
||||
* 统一存储基础信息,使用 JSON 格式化,避免未有效解析的情况。
|
||||
*/
|
||||
private String extras;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.iocoder.mall.userservice.dal.mysql.mapper.address;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.dataobject.address.UserAddressDO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface UserAddressMapper extends BaseMapper<UserAddressDO> {
|
||||
|
||||
default List<UserAddressDO> selectListByUserIdAndType(Integer userId, @Nullable Integer type) {
|
||||
return selectList(new QueryWrapperX<UserAddressDO>().eq("user_id", userId)
|
||||
.eqIfPresent("type", type));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.mall.userservice.dal.mysql.mapper.sms;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.dataobject.sms.UserSmsCodeDO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserSmsCodeMapper extends BaseMapper<UserSmsCodeDO> {
|
||||
|
||||
/**
|
||||
* 获得手机号的最后一个手机验证码
|
||||
*
|
||||
* @param mobile 手机号
|
||||
* @param scene 发送场景,选填
|
||||
* @return 手机验证码
|
||||
*/
|
||||
default UserSmsCodeDO selectLastByMobile(String mobile, Integer scene) {
|
||||
QueryWrapperX<UserSmsCodeDO> query = new QueryWrapperX<UserSmsCodeDO>()
|
||||
.eq("mobile", mobile)
|
||||
.eqIfPresent("scene", scene)
|
||||
.orderByDesc("id")
|
||||
.last("limit 1");
|
||||
return selectOne(query);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.mall.userservice.dal.mysql.mapper.user;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.dataobject.user.UserDO;
|
||||
import cn.iocoder.mall.userservice.service.user.bo.UserPageBO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserMapper extends BaseMapper<UserDO> {
|
||||
|
||||
default UserDO selectByMobile(String mobile) {
|
||||
return selectOne(new QueryWrapper<UserDO>()
|
||||
.eq("mobile", mobile)
|
||||
);
|
||||
}
|
||||
|
||||
default IPage<UserDO> selectPage(UserPageBO pageBO) {
|
||||
return selectPage(new Page<>(pageBO.getPageNo(), pageBO.getPageSize()),
|
||||
new QueryWrapperX<UserDO>().likeIfPresent("nickname", pageBO.getNickname())
|
||||
.eqIfPresent("status", pageBO.getStatus()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package cn.iocoder.mall.userservice.manager.address;
|
||||
|
||||
import cn.iocoder.mall.userservice.convert.address.UserAddressConvert;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressCreateReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressRespDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressUpdateReqDTO;
|
||||
import cn.iocoder.mall.userservice.service.address.UserAddressService;
|
||||
import cn.iocoder.mall.userservice.service.address.bo.UserAddressBO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户收件地址 Manager
|
||||
*/
|
||||
@Service
|
||||
public class UserAddressManager {
|
||||
|
||||
@Autowired
|
||||
private UserAddressService userAddressService;
|
||||
|
||||
/**
|
||||
* 创建用户收件地址
|
||||
*
|
||||
* @param createDTO 创建用户收件地址 DTO
|
||||
* @return 用户收件地址
|
||||
*/
|
||||
public Integer createUserAddress(UserAddressCreateReqDTO createDTO) {
|
||||
UserAddressBO userAddressBO = userAddressService.createUserAddress(UserAddressConvert.INSTANCE.convert(createDTO));
|
||||
return userAddressBO.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户收件地址
|
||||
*
|
||||
* @param updateDTO 更新用户收件地址 DTO
|
||||
*/
|
||||
public void updateUserAddress(UserAddressUpdateReqDTO updateDTO) {
|
||||
userAddressService.updateUserAddress(UserAddressConvert.INSTANCE.convert(updateDTO));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户收件地址
|
||||
*
|
||||
* @param userAddressId 用户收件地址编号
|
||||
*/
|
||||
public void deleteUserAddress(Integer userAddressId) {
|
||||
userAddressService.deleteUserAddress(userAddressId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户收件地址
|
||||
*
|
||||
* @param userAddressId 用户收件地址编号
|
||||
* @return 用户收件地址
|
||||
*/
|
||||
public UserAddressRespDTO getUserAddress(Integer userAddressId) {
|
||||
UserAddressBO userAddressBO = userAddressService.getUserAddress(userAddressId);
|
||||
return UserAddressConvert.INSTANCE.convert(userAddressBO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户收件地址列表
|
||||
*
|
||||
* @param userAddressIds 用户收件地址编号列表
|
||||
* @return 用户收件地址列表
|
||||
*/
|
||||
public List<UserAddressRespDTO> listUserAddresses(List<Integer> userAddressIds) {
|
||||
List<UserAddressBO> userAddressBOs = userAddressService.listUserAddresses(userAddressIds);
|
||||
return UserAddressConvert.INSTANCE.convertList02(userAddressBOs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定用户的收件地址列表
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param type 地址类型
|
||||
* @return 收件地址列表
|
||||
*/
|
||||
public List<UserAddressRespDTO> listUserAddresses(Integer userId, Integer type) {
|
||||
List<UserAddressBO> userAddressBOs = userAddressService.listUserAddresses(userId, type);
|
||||
return UserAddressConvert.INSTANCE.convertList02(userAddressBOs);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.mall.userservice.manager.sms;
|
||||
|
||||
import cn.iocoder.mall.userservice.rpc.sms.dto.UserSendSmsCodeReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.sms.dto.UserVerifySmsCodeReqDTO;
|
||||
import cn.iocoder.mall.userservice.service.sms.UserSmsCodeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UserSmsCodeManager {
|
||||
|
||||
@Autowired
|
||||
private UserSmsCodeService userSmsCodeService;
|
||||
|
||||
public void sendSmsCode(UserSendSmsCodeReqDTO sendSmsCodeDTO) {
|
||||
// 生成短信验证码
|
||||
String smsCode = userSmsCodeService.createSmsCode(sendSmsCodeDTO.getMobile(),
|
||||
sendSmsCodeDTO.getScene(), sendSmsCodeDTO.getIp());
|
||||
// TODO 调用发送验证码
|
||||
}
|
||||
|
||||
public void verifySmsCode(UserVerifySmsCodeReqDTO verifySmsCodeDTO) {
|
||||
userSmsCodeService.verifySmsCode(verifySmsCodeDTO.getMobile(), verifySmsCodeDTO.getCode(),
|
||||
verifySmsCodeDTO.getScene(), verifySmsCodeDTO.getIp());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package cn.iocoder.mall.userservice.manager.user;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.enums.UserTypeEnum;
|
||||
import cn.iocoder.common.framework.util.StringUtils;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.systemservice.rpc.oauth.OAuthFeign;
|
||||
import cn.iocoder.mall.systemservice.rpc.oauth.dto.OAuth2RemoveTokenByUserReqDTO;
|
||||
import cn.iocoder.mall.userservice.convert.user.UserConvert;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserCreateReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserPageReqDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserRespDTO;
|
||||
import cn.iocoder.mall.userservice.rpc.user.dto.UserUpdateReqDTO;
|
||||
import cn.iocoder.mall.userservice.service.user.UserService;
|
||||
import cn.iocoder.mall.userservice.service.user.bo.UserBO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class UserManager {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private OAuthFeign oAuthFeign;
|
||||
|
||||
public UserRespDTO createUserIfAbsent(UserCreateReqDTO createDTO) {
|
||||
// 用户已经存在
|
||||
UserBO userBO = userService.getUser(createDTO.getMobile());
|
||||
if (userBO != null) {
|
||||
return UserConvert.INSTANCE.convert(userBO);
|
||||
}
|
||||
// 用户不存在,则进行创建
|
||||
userBO = userService.createUser(UserConvert.INSTANCE.convert(createDTO));
|
||||
return UserConvert.INSTANCE.convert(userBO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户
|
||||
*
|
||||
* @param updateDTO 更新用户 DTO
|
||||
*/
|
||||
public void updateUser(UserUpdateReqDTO updateDTO) {
|
||||
// 更新管理员信息
|
||||
userService.updateUser(UserConvert.INSTANCE.convert(updateDTO));
|
||||
// 如果修改密码,或者禁用管理员
|
||||
if (StringUtils.hasText(updateDTO.getPassword())
|
||||
|| CommonStatusEnum.DISABLE.getValue().equals(updateDTO.getStatus())) {
|
||||
oAuthFeign.removeToken(new OAuth2RemoveTokenByUserReqDTO().setUserId(updateDTO.getId())
|
||||
.setUserType(UserTypeEnum.ADMIN.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @return 用户
|
||||
*/
|
||||
public UserRespDTO getUser(Integer userId) {
|
||||
UserBO userBO = userService.getUser(userId);
|
||||
return UserConvert.INSTANCE.convert(userBO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户列表
|
||||
*
|
||||
* @param userIds 用户编号列表
|
||||
* @return 用户列表
|
||||
*/
|
||||
public List<UserRespDTO> listUsers(List<Integer> userIds) {
|
||||
List<UserBO> userBOs = userService.listUsers(userIds);
|
||||
return UserConvert.INSTANCE.convertList02(userBOs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户分页
|
||||
*
|
||||
* @param pageDTO 用户分页查询
|
||||
* @return 用户分页结果
|
||||
*/
|
||||
public PageResult<UserRespDTO> pageUser(UserPageReqDTO pageDTO) {
|
||||
PageResult<UserBO> pageResultBO = userService.pageUser(UserConvert.INSTANCE.convert(pageDTO));
|
||||
return UserConvert.INSTANCE.convertPage(pageResultBO);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package cn.iocoder.mall.userservice.service.address;
|
||||
|
||||
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.util.CollectionUtils;
|
||||
import cn.iocoder.mall.userservice.convert.address.UserAddressConvert;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.dataobject.address.UserAddressDO;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.mapper.address.UserAddressMapper;
|
||||
import cn.iocoder.mall.userservice.enums.address.UserAddressType;
|
||||
import cn.iocoder.mall.userservice.service.address.bo.UserAddressBO;
|
||||
import cn.iocoder.mall.userservice.service.address.bo.UserAddressCreateBO;
|
||||
import cn.iocoder.mall.userservice.service.address.bo.UserAddressUpdateBO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.mall.userservice.enums.UserErrorCodeConstants.USER_ADDRESS_NOT_FOUND;
|
||||
|
||||
/**
|
||||
* 用户收件地址 Service
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class UserAddressService {
|
||||
|
||||
@Autowired
|
||||
private UserAddressMapper userAddressMapper;
|
||||
|
||||
/**
|
||||
* 创建用户收件地址
|
||||
*
|
||||
* @param createBO 创建用户收件地址 BO
|
||||
* @return 用户收件地址
|
||||
*/
|
||||
@Transactional
|
||||
public UserAddressBO createUserAddress(@Valid UserAddressCreateBO createBO) {
|
||||
// 如果添加的是默认收件地址,则将原默认地址修改为非默认
|
||||
if (UserAddressType.DEFAULT.getType().equals(createBO.getType())) {
|
||||
List<UserAddressDO> addressDOs = userAddressMapper.selectListByUserIdAndType(
|
||||
createBO.getUserId(), UserAddressType.DEFAULT.getType());
|
||||
if (!CollectionUtils.isEmpty(addressDOs)) {
|
||||
addressDOs.forEach(userAddressDO -> userAddressMapper.updateById(new UserAddressDO()
|
||||
.setId(userAddressDO.getId()).setType(UserAddressType.DEFAULT.getType())));
|
||||
}
|
||||
}
|
||||
// 插入到数据库
|
||||
UserAddressDO userAddressDO = UserAddressConvert.INSTANCE.convert(createBO);
|
||||
userAddressMapper.insert(userAddressDO);
|
||||
// 返回
|
||||
return UserAddressConvert.INSTANCE.convert(userAddressDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户收件地址
|
||||
*
|
||||
* @param updateBO 更新用户收件地址 BO
|
||||
*/
|
||||
@Transactional
|
||||
public void updateUserAddress(@Valid UserAddressUpdateBO updateBO) {
|
||||
// 校验更新的用户收件地址是否存在
|
||||
if (userAddressMapper.selectById(updateBO.getId()) == null) {
|
||||
throw ServiceExceptionUtil.exception(USER_ADDRESS_NOT_FOUND);
|
||||
}
|
||||
// 如果修改的是默认收件地址,则将原默认地址修改为非默认
|
||||
if (UserAddressType.DEFAULT.getType().equals(updateBO.getType())) {
|
||||
List<UserAddressDO> addressDOs = userAddressMapper.selectListByUserIdAndType(
|
||||
updateBO.getUserId(), UserAddressType.DEFAULT.getType());
|
||||
if (!CollectionUtils.isEmpty(addressDOs)) {
|
||||
addressDOs.stream().filter(userAddressDO -> userAddressDO.getId().equals(updateBO.getId())) // 过滤掉更新的收件地址
|
||||
.forEach(userAddressDO -> userAddressMapper.updateById(new UserAddressDO()
|
||||
.setId(userAddressDO.getId()).setType(UserAddressType.DEFAULT.getType())));
|
||||
}
|
||||
}
|
||||
// 更新到数据库
|
||||
UserAddressDO updateObject = UserAddressConvert.INSTANCE.convert(updateBO);
|
||||
userAddressMapper.updateById(updateObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户收件地址
|
||||
*
|
||||
* @param userAddressId 用户收件地址编号
|
||||
*/
|
||||
public void deleteUserAddress(Integer userAddressId) {
|
||||
// 校验删除的用户收件地址是否存在
|
||||
if (userAddressMapper.selectById(userAddressId) == null) {
|
||||
throw ServiceExceptionUtil.exception(USER_ADDRESS_NOT_FOUND);
|
||||
}
|
||||
// 标记删除
|
||||
userAddressMapper.deleteById(userAddressId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户收件地址
|
||||
*
|
||||
* @param userAddressId 用户收件地址编号
|
||||
* @return 用户收件地址
|
||||
*/
|
||||
public UserAddressBO getUserAddress(Integer userAddressId) {
|
||||
UserAddressDO userAddressDO = userAddressMapper.selectById(userAddressId);
|
||||
return UserAddressConvert.INSTANCE.convert(userAddressDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户收件地址列表
|
||||
*
|
||||
* @param userAddressIds 用户收件地址编号列表
|
||||
* @return 用户收件地址列表
|
||||
*/
|
||||
public List<UserAddressBO> listUserAddresses(List<Integer> userAddressIds) {
|
||||
List<UserAddressDO> userAddressDOs = userAddressMapper.selectBatchIds(userAddressIds);
|
||||
return UserAddressConvert.INSTANCE.convertList(userAddressDOs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定用户的收件地址列表
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param type 地址类型
|
||||
* @return 收件地址列表
|
||||
*/
|
||||
public List<UserAddressBO> listUserAddresses(Integer userId, Integer type) {
|
||||
List<UserAddressDO> userAddressDOs = userAddressMapper.selectListByUserIdAndType(userId, type);
|
||||
return UserAddressConvert.INSTANCE.convertList(userAddressDOs);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package cn.iocoder.mall.userservice.service.address.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户收件地址 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserAddressBO {
|
||||
|
||||
/**
|
||||
* 收件地址编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer userId;
|
||||
/**
|
||||
* 收件人名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 地区编码
|
||||
*/
|
||||
private Integer areaCode;
|
||||
/**
|
||||
* 收件详细地址
|
||||
*/
|
||||
private String detailAddress;
|
||||
/**
|
||||
* 地址类型
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package cn.iocoder.mall.userservice.service.address.bo;
|
||||
|
||||
import cn.iocoder.common.framework.validator.Mobile;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 用户收件地址创建 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserAddressCreateBO {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
/**
|
||||
* 收件人名称
|
||||
*/
|
||||
@NotEmpty(message = "收件人名称不能为空")
|
||||
private String name;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@NotEmpty(message = "手机号不能为空")
|
||||
@Mobile
|
||||
private String mobile;
|
||||
/**
|
||||
* 地区编码
|
||||
*/
|
||||
@NotNull(message = "地区编码不能为空")
|
||||
private Integer areaCode;
|
||||
/**
|
||||
* 收件详细地址
|
||||
*/
|
||||
@NotEmpty(message = "收件详细地址不能为空")
|
||||
private String detailAddress;
|
||||
/**
|
||||
* 地址类型
|
||||
*/
|
||||
@NotNull(message = "地址类型不能为空")
|
||||
private Integer type;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package cn.iocoder.mall.userservice.service.address.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 用户收件地址更新 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserAddressUpdateBO {
|
||||
|
||||
/**
|
||||
* 收件地址编号
|
||||
*/
|
||||
@NotNull(message = "收件地址编号不能为空")
|
||||
private Integer id;
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
/**
|
||||
* 收件人名称
|
||||
*/
|
||||
@NotEmpty(message = "收件人名称不能为空")
|
||||
private String name;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@NotEmpty(message = "手机号不能为空")
|
||||
private String mobile;
|
||||
/**
|
||||
* 地区编码
|
||||
*/
|
||||
@NotNull(message = "地区编码不能为空")
|
||||
private Integer areaCode;
|
||||
/**
|
||||
* 收件详细地址
|
||||
*/
|
||||
@NotEmpty(message = "收件详细地址不能为空")
|
||||
private String detailAddress;
|
||||
/**
|
||||
* 地址类型
|
||||
*/
|
||||
@NotNull(message = "地址类型不能为空")
|
||||
private Integer type;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package cn.iocoder.mall.userservice.service.sms;
|
||||
|
||||
import cn.iocoder.common.framework.exception.ServiceException;
|
||||
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.validator.Mobile;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.dataobject.sms.UserSmsCodeDO;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.mapper.sms.UserSmsCodeMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static cn.iocoder.mall.userservice.enums.UserErrorCodeConstants.*;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
public class UserSmsCodeService {
|
||||
|
||||
/**
|
||||
* 每条验证码的过期时间,单位:毫秒
|
||||
*/
|
||||
@Value("${modules.user-sms-code-service.code-expire-time-millis}")
|
||||
private int codeExpireTimes;
|
||||
/**
|
||||
* 每日发送最大数量
|
||||
*/
|
||||
@Value("${modules.user-sms-code-service.send-maximum-quantity-per-day}")
|
||||
private int sendMaximumQuantityPerDay;
|
||||
/**
|
||||
* 短信发送频率,单位:毫秒
|
||||
*/
|
||||
@Value("${modules.user-sms-code-service.send-frequency}")
|
||||
private int sendFrequency;
|
||||
|
||||
@Autowired
|
||||
private UserSmsCodeMapper userSmsCodeMapper;
|
||||
|
||||
/**
|
||||
* 创建短信验证码,并返回它
|
||||
*
|
||||
* 注意,不包括发送逻辑
|
||||
*
|
||||
* @param mobile 手机号
|
||||
* @param scene 发送场景
|
||||
* @param ip IP
|
||||
* @return 短信验证码
|
||||
*/
|
||||
public String createSmsCode(@Mobile String mobile, Integer scene, String ip) {
|
||||
// 校验是否可以发送验证码,不用筛选场景
|
||||
UserSmsCodeDO lastUserSmsCodeDO = userSmsCodeMapper.selectLastByMobile(mobile, null);
|
||||
if (lastUserSmsCodeDO != null) {
|
||||
if (lastUserSmsCodeDO.getTodayIndex() >= sendMaximumQuantityPerDay) { // 超过当天发送的上限。
|
||||
throw ServiceExceptionUtil.exception(USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY);
|
||||
}
|
||||
if (System.currentTimeMillis() - lastUserSmsCodeDO.getCreateTime().getTime() < sendFrequency) { // 发送过于频繁
|
||||
throw ServiceExceptionUtil.exception(USER_SMS_CODE_SEND_TOO_FAST);
|
||||
}
|
||||
// TODO 提升,每个 IP 每天可发送数量
|
||||
// TODO 提升,每个 IP 每小时可发送数量
|
||||
}
|
||||
// 创建验证码记录
|
||||
UserSmsCodeDO newMobileCodePO = new UserSmsCodeDO().setMobile(mobile)
|
||||
.setCode("9999") // TODO 芋艿,随机 4 位验证码 or 6 位验证码
|
||||
.setScene(scene)
|
||||
.setTodayIndex(lastUserSmsCodeDO != null ? lastUserSmsCodeDO.getTodayIndex() : 1)
|
||||
.setCreateIp(ip).setUsed(false);
|
||||
newMobileCodePO.setCreateTime(new Date());
|
||||
userSmsCodeMapper.insert(newMobileCodePO);
|
||||
return newMobileCodePO.getCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证短信验证码是否正确。
|
||||
* 如果正确,则将验证码标记成已使用
|
||||
* 如果错误,则抛出 {@link ServiceException} 异常
|
||||
*
|
||||
* @param mobile 手机号
|
||||
* @param code 验证码
|
||||
* @param scene 发送场景
|
||||
* @param ip IP
|
||||
*/
|
||||
public void verifySmsCode(String mobile, String code, Integer scene, String ip) {
|
||||
// 校验验证码
|
||||
UserSmsCodeDO mobileCodeDO = userSmsCodeMapper.selectLastByMobile(mobile, scene);
|
||||
if (mobileCodeDO == null) { // 若验证码不存在,抛出异常
|
||||
throw ServiceExceptionUtil.exception(USER_SMS_CODE_NOT_FOUND);
|
||||
}
|
||||
if (System.currentTimeMillis() - mobileCodeDO.getCreateTime().getTime() >= codeExpireTimes) { // 验证码已过期
|
||||
throw ServiceExceptionUtil.exception(USER_SMS_CODE_EXPIRED);
|
||||
}
|
||||
if (mobileCodeDO.getUsed()) { // 验证码已使用
|
||||
throw ServiceExceptionUtil.exception(USER_SMS_CODE_USED);
|
||||
}
|
||||
if (!mobileCodeDO.getCode().equals(code)) {
|
||||
throw ServiceExceptionUtil.exception(USER_SMS_CODE_NOT_CORRECT);
|
||||
}
|
||||
// 使用验证码
|
||||
UserSmsCodeDO updateObj = new UserSmsCodeDO().setId(mobileCodeDO.getId())
|
||||
.setUsed(true).setUsedTime(new Date()).setUsedIp(ip);
|
||||
userSmsCodeMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package cn.iocoder.mall.userservice.service.user;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.util.DigestUtils;
|
||||
import cn.iocoder.common.framework.util.StringUtils;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.userservice.convert.user.UserConvert;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.dataobject.user.UserDO;
|
||||
import cn.iocoder.mall.userservice.dal.mysql.mapper.user.UserMapper;
|
||||
import cn.iocoder.mall.userservice.service.user.bo.UserBO;
|
||||
import cn.iocoder.mall.userservice.service.user.bo.UserCreateBO;
|
||||
import cn.iocoder.mall.userservice.service.user.bo.UserPageBO;
|
||||
import cn.iocoder.mall.userservice.service.user.bo.UserUpdateBO;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.mall.userservice.enums.UserErrorCodeConstants.*;
|
||||
|
||||
@Service
|
||||
public class UserService {
|
||||
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
|
||||
public UserBO getUser(Integer id) {
|
||||
UserDO userDO = userMapper.selectById(id);
|
||||
return UserConvert.INSTANCE.convert(userDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户列表
|
||||
*
|
||||
* @param userIds 用户编号列表
|
||||
* @return 用户列表
|
||||
*/
|
||||
public List<UserBO> listUsers(List<Integer> userIds) {
|
||||
List<UserDO> userDOs = userMapper.selectBatchIds(userIds);
|
||||
return UserConvert.INSTANCE.convertList(userDOs);
|
||||
}
|
||||
|
||||
public UserBO getUser(String mobile) {
|
||||
UserDO userDO = userMapper.selectByMobile(mobile);
|
||||
return UserConvert.INSTANCE.convert(userDO);
|
||||
}
|
||||
|
||||
public UserBO createUser(UserCreateBO createBO) {
|
||||
UserDO userDO = UserConvert.INSTANCE.convert(createBO)
|
||||
.setStatus(CommonStatusEnum.ENABLE.getValue());
|
||||
// 加密密码
|
||||
String passwordSalt = genPasswordSalt();
|
||||
String password = createBO.getPassword();
|
||||
if (!StringUtils.hasText(password)) {
|
||||
password = genPassword();
|
||||
}
|
||||
password = encodePassword(password, passwordSalt);
|
||||
userDO.setPassword(password).setPasswordSalt(passwordSalt);
|
||||
// 保存用户
|
||||
userMapper.insert(userDO);
|
||||
return UserConvert.INSTANCE.convert(userDO);
|
||||
}
|
||||
|
||||
public void updateUser(UserUpdateBO updateBO) {
|
||||
// 校验用户存在
|
||||
UserDO userDO = userMapper.selectById(updateBO.getId());
|
||||
if (userDO == null) {
|
||||
throw ServiceExceptionUtil.exception(USER_NOT_EXISTS);
|
||||
}
|
||||
// 校验手机唯一
|
||||
if (StringUtils.hasText(updateBO.getMobile())) {
|
||||
UserDO mobileAdmin = userMapper.selectByMobile(updateBO.getMobile());
|
||||
if (mobileAdmin != null && !mobileAdmin.getId().equals(updateBO.getId())) {
|
||||
throw ServiceExceptionUtil.exception(USER_MOBILE_EXISTS);
|
||||
}
|
||||
}
|
||||
// 如果有更新状态,则校验是否已经是该状态
|
||||
if (updateBO.getStatus() != null && updateBO.getStatus().equals(userDO.getStatus())) {
|
||||
throw ServiceExceptionUtil.exception(USER_STATUS_EQUALS);
|
||||
}
|
||||
// 更新到数据库
|
||||
UserDO updateUser = UserConvert.INSTANCE.convert(updateBO);
|
||||
// 如果更新密码,需要特殊加密
|
||||
if (StringUtils.hasText(updateBO.getPassword())) {
|
||||
String passwordSalt = genPasswordSalt();
|
||||
String password = encodePassword(updateBO.getPassword(), passwordSalt);
|
||||
updateUser.setPassword(password).setPasswordSalt(passwordSalt);
|
||||
}
|
||||
userMapper.updateById(updateUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得用户分页
|
||||
*
|
||||
* @param pageBO 用户分页查询
|
||||
* @return 用户分页结果
|
||||
*/
|
||||
public PageResult<UserBO> pageUser(UserPageBO pageBO) {
|
||||
IPage<UserDO> userDOPage = userMapper.selectPage(pageBO);
|
||||
return UserConvert.INSTANCE.convertPage(userDOPage);
|
||||
}
|
||||
|
||||
private String genPasswordSalt() {
|
||||
return DigestUtils.genBcryptSalt();
|
||||
}
|
||||
|
||||
private String genPassword() {
|
||||
return StringUtils.uuid(true);
|
||||
}
|
||||
|
||||
private String encodePassword(String password, String salt) {
|
||||
return DigestUtils.bcrypt(password, salt);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package cn.iocoder.mall.userservice.service.user.bo;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserBO {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 用户状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 手机
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 经过加密的密码串
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* {@link #password} 的盐
|
||||
*/
|
||||
private String passwordSalt;
|
||||
/**
|
||||
* 注册时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package cn.iocoder.mall.userservice.service.user.bo;
|
||||
|
||||
import cn.iocoder.common.framework.validator.Mobile;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 用户创建 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserCreateBO {
|
||||
|
||||
/**
|
||||
* 昵称,允许空
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 头像,允许空
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 手机
|
||||
*/
|
||||
@NotNull(message = "手机号不能为空")
|
||||
@Mobile
|
||||
private String mobile;
|
||||
/**
|
||||
* 原始密码,允许空
|
||||
*
|
||||
* 当为空时,会自动进行生成
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* IP 地址
|
||||
*/
|
||||
private String createIp;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.mall.userservice.service.user.bo;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import cn.iocoder.common.framework.vo.PageParam;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 用户分页 BO
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class UserPageBO extends PageParam {
|
||||
|
||||
/**
|
||||
* 昵称
|
||||
*
|
||||
* 模糊
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package cn.iocoder.mall.userservice.service.user.bo;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import cn.iocoder.common.framework.validator.Mobile;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 用户更新 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserUpdateBO {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer id;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@Mobile
|
||||
private String mobile;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
spring:
|
||||
# 数据源配置项
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/mall_user?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: zhuyang
|
||||
# Spring Cloud 配置项
|
||||
cloud:
|
||||
nacos:
|
||||
# Spring Cloud Nacos Discovery 配置项
|
||||
discovery:
|
||||
server-addr: localhost:8848 # Nacos 服务器地址
|
||||
namespace: dev # Nacos 命名空间
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Dubbo 注册中心
|
||||
registry:
|
||||
# address: spring-cloud://localhost:8848 # 指定 Dubbo 服务注册中心的地址
|
||||
address: nacos://localhost:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
|
||||
@@ -0,0 +1,24 @@
|
||||
spring:
|
||||
# 数据源配置项
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/mall_user?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: zhuyang
|
||||
# Spring Cloud 配置项
|
||||
cloud:
|
||||
nacos:
|
||||
# Spring Cloud Nacos Discovery 配置项
|
||||
discovery:
|
||||
server-addr: localhost:8848 # Nacos 服务器地址
|
||||
namespace: dev # Nacos 命名空间
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Dubbo 注册中心
|
||||
registry:
|
||||
# address: spring-cloud://localhost:8848 # 指定 Dubbo 服务注册中心的地址
|
||||
address: nacos://localhost:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
|
||||
# Dubbo 服务提供者的配置
|
||||
provider:
|
||||
tag: ${DUBBO_TAG} # Dubbo 路由分组
|
||||
@@ -0,0 +1,5 @@
|
||||
##################### 业务模块 #####################
|
||||
## UserSmsCodeService
|
||||
modules.user-sms-code-service.code-expire-time-millis = 600000
|
||||
modules.user-sms-code-service.send-maximum-quantity-per-day = 10
|
||||
modules.user-sms-code-service.send-frequency = 60000
|
||||
@@ -0,0 +1,52 @@
|
||||
spring:
|
||||
# Application 的配置项
|
||||
application:
|
||||
name: user-service
|
||||
# Profile 的配置项
|
||||
profiles:
|
||||
active: local
|
||||
|
||||
# MyBatis Plus 配置项
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: auto
|
||||
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
|
||||
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
|
||||
mapper-locations: classpath*:mapper/*.xml
|
||||
type-aliases-package: cn.iocoder.mall.userservice.dal.mysql.dataobject
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Spring Cloud Alibaba Dubbo 专属配置
|
||||
cloud:
|
||||
subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用
|
||||
# Dubbo 提供者的协议
|
||||
protocol:
|
||||
name: dubbo
|
||||
port: -1
|
||||
# Dubbo 提供服务的扫描基础包
|
||||
scan:
|
||||
base-packages: cn.iocoder.mall.userservice.rpc
|
||||
# Dubbo 服务提供者的配置
|
||||
provider:
|
||||
filter: -exception
|
||||
validation: true # 开启 Provider 参数校验
|
||||
UserRpc:
|
||||
version: 1.0.0
|
||||
UserSmsCodeRpc:
|
||||
version: 1.0.0
|
||||
UserAddressRpc:
|
||||
version: 1.0.0
|
||||
# Dubbo 服务消费者的配置
|
||||
consumer:
|
||||
OAuth2Rpc:
|
||||
version: 1.0.0
|
||||
|
||||
# Actuator 监控配置项
|
||||
management:
|
||||
server.port: 38081 # 独立端口,避免被暴露出去
|
||||
endpoints.web.exposure.include: '*' # 暴露所有监控端点
|
||||
server.port: ${management.server.port} # 设置使用 Actuator 的服务器端口,因为 RPC 服务不需要 Web 端口
|
||||
@@ -0,0 +1,15 @@
|
||||
-- ----------------------------
|
||||
-- Table structure for users
|
||||
-- ----------------------------
|
||||
INSERT INTO `mall_user`.`users`(`id`, `nickname`, `avatar`, `status`, `mobile`, `password`, `password_salt`, `create_ip`, `create_time`, `update_time`) VALUES (243, '芋艿X', 'http://www.iocoder.cn/images/common/zsxq/02.png', 2, '15601691340', '$2a$10$oBHjsjw57u3/g.g47kUAV.Q3i/TrMm62fobwFjGEjNGKUcqfgs2em', '$2a$10$oBHjsjw57u3/g.g47kUAV.', '127.0.0.1', '2020-07-03 20:41:57', '2020-07-26 00:51:38');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_sms_code
|
||||
-- ----------------------------
|
||||
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_sms_code
|
||||
-- ----------------------------
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for users
|
||||
-- ----------------------------
|
||||
CREATE TABLE `users` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
|
||||
`nickname` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '昵称',
|
||||
`avatar` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '头像',
|
||||
`status` tinyint(4) NOT NULL COMMENT '状态',
|
||||
`mobile` varchar(11) COLLATE utf8mb4_bin NOT NULL COMMENT '手机号',
|
||||
`password` varchar(255) COLLATE utf8mb4_bin NOT NULL COMMENT '加密后的密码',
|
||||
`password_salt` varchar(64) COLLATE utf8mb4_bin NOT NULL COMMENT '密码的盐',
|
||||
`create_ip` varchar(32) COLLATE utf8mb4_bin NOT NULL COMMENT '注册 IP',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_mobile` (`mobile`) USING BTREE COMMENT '手机号'
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=245 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='用户';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_sms_code
|
||||
-- ----------------------------
|
||||
CREATE TABLE `user_sms_code` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`mobile` varchar(11) NOT NULL COMMENT '手机号',
|
||||
`code` varchar(6) NOT NULL COMMENT '验证码',
|
||||
`create_ip` varchar(15) NOT NULL COMMENT '创建 IP',
|
||||
`scene` tinyint(4) NOT NULL COMMENT '发送场景',
|
||||
`today_index` tinyint(4) NOT NULL COMMENT '今日发送的第几条',
|
||||
`used` tinyint(4) NOT NULL COMMENT '是否使用',
|
||||
`used_time` datetime DEFAULT NULL COMMENT '使用时间',
|
||||
`used_ip` varchar(255) DEFAULT NULL COMMENT '使用 IP',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `idx_mobile` (`mobile`) USING BTREE COMMENT '手机号'
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=445 DEFAULT CHARSET=utf8mb4 COMMENT='手机验证码';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_sms_code
|
||||
-- ----------------------------
|
||||
CREATE TABLE `user_address` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '收件地址编号',
|
||||
`user_id` int(11) NOT NULL COMMENT '用户编号',
|
||||
`name` varchar(10) COLLATE utf8mb4_bin NOT NULL COMMENT '收件人名称',
|
||||
`mobile` varchar(20) COLLATE utf8mb4_bin NOT NULL COMMENT '手机号',
|
||||
`area_code` int(11) NOT NULL COMMENT '地区编码',
|
||||
`detail_address` varchar(250) COLLATE utf8mb4_bin NOT NULL COMMENT '收件详细地址',
|
||||
`type` tinyint(4) NOT NULL COMMENT '地址类型',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '删除状态',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `idx_userId` (`user_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='用户收件地址';
|
||||
Reference in New Issue
Block a user