Merge remote-tracking branch 'origin/master'

This commit is contained in:
sin 2019-03-11 13:44:24 +08:00
commit 0dd5129f83
48 changed files with 945 additions and 138 deletions

2
.gitignore vendored
View File

@ -18,8 +18,8 @@
*.iws
*.iml
*.ipr
target/*
*.class
target/*
### NetBeans ###
/nbproject/private/

View File

@ -86,6 +86,7 @@
COUNT(1)
FROM resource
WHERE pid = #{pid}
AND deleted = 0
</select>
<insert id="insert" parameterType="ResourceDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">

View File

@ -0,0 +1,16 @@
package cn.iocoder.common.framework.util;
/**
* 校验工具类
*/
public class ValidationUtil {
public static boolean isMobile(String mobile) {
if (mobile == null || mobile.length() != 11) {
return false;
}
// TODO 芋艿后面完善手机校验
return true;
}
}

View File

@ -3,7 +3,9 @@ package cn.iocoder.common.framework.vo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.util.Assert;
public class CommonResult<T> {
import java.io.Serializable;
public class CommonResult<T> implements Serializable {
public static Integer CODE_SUCCESS = 0;

View File

@ -30,6 +30,12 @@
<artifactId>dubbo</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -16,14 +16,14 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController("productCategoryController_users")
@RequestMapping("users/product/category")
@RequestMapping("users/category")
@Api("商品分类")
public class UsersProductCategoryController {
@Reference(validation = "true")
private ProductCategoryService productCategoryService;
@GetMapping
@GetMapping("/list")
@ApiOperation("获得指定编号下的子分类的数组")
@ApiImplicitParam(name = "pid", value = "指定分类编号", required = true, example = "0")
public List<UsersProductCategoryVO> list(@RequestParam("pid") Integer pid) {

View File

@ -92,6 +92,12 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>admin-sdk</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
@ -119,6 +125,16 @@
</annotationProcessorPaths>
</configuration>
</plugin>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>

View File

@ -1,6 +1,7 @@
package cn.iocoder.mall.user.application.config;
import cn.iocoder.common.framework.config.GlobalExceptionHandler;
import cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor;
import cn.iocoder.mall.user.sdk.interceptor.UserSecurityInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@ -13,15 +14,18 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc
@Configuration
@Import(value = {GlobalExceptionHandler.class, // 统一全局返回
UserSecurityInterceptor.class}) // 安全拦截器实现认证和授权功能
UserSecurityInterceptor.class, AdminSecurityInterceptor.class}) // 安全拦截器实现认证和授权功能
public class MVCConfiguration implements WebMvcConfigurer {
@Autowired
private UserSecurityInterceptor securityInterceptor;
@Autowired
private AdminSecurityInterceptor adminSecurityInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(securityInterceptor).addPathPatterns("/user/**", "/admin/**"); // 只拦截我们定义的接口
registry.addInterceptor(securityInterceptor).addPathPatterns("/users/**"); // 只拦截我们定义的接口
registry.addInterceptor(adminSecurityInterceptor).addPathPatterns("/admins/**"); // 只拦截我们定义的接口
}
@Override

View File

@ -1,25 +0,0 @@
package cn.iocoder.mall.user.application.controller;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
import cn.iocoder.mall.user.application.vo.UserInfoVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
@Api("用户模块")
public class UserController {
@GetMapping("/info")
@ApiOperation(value = "用户信息")
public CommonResult<UserInfoVO> info() {
// TODO 芋艿正在实现中
UserInfoVO user = new UserInfoVO().setId(UserSecurityContextHolder.getContext().getUid());
return CommonResult.success(user);
}
}

View File

@ -0,0 +1,69 @@
package cn.iocoder.mall.user.application.controller.admins;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.application.convert.UserConvert;
import cn.iocoder.mall.user.application.vo.admins.AdminsUserPageVO;
import cn.iocoder.mall.user.service.api.UserService;
import cn.iocoder.mall.user.service.api.bo.UserPageBO;
import cn.iocoder.mall.user.service.api.dto.UserPageDTO;
import cn.iocoder.mall.user.service.api.dto.UserUpdateDTO;
import com.alibaba.dubbo.config.annotation.Reference;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/admins/user")
@Api("用户模块")
public class AdminsUserController {
@Reference(validation = "true")
private UserService userService;
// 分页
@GetMapping("/page")
@ApiOperation(value = "用户分页")
@ApiImplicitParams({
@ApiImplicitParam(name = "nickname", value = "昵称,模糊匹配", example = "小王"),
@ApiImplicitParam(name = "pageNo", value = "页码,从 0 开始", example = "0"),
@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, example = "10"),
})
public CommonResult<AdminsUserPageVO> page(@RequestParam(value = "nickname", required = false) String nickname,
@RequestParam(value = "pageNo", defaultValue = "0") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
UserPageDTO userPageDTO = new UserPageDTO().setNickname(nickname).setPageNo(pageNo).setPageSize(pageSize);
// 查询分页
CommonResult<UserPageBO> result = userService.getUserPage(userPageDTO);
// 转换结果
return UserConvert.INSTANCE.convert(result);
}
@PostMapping("/update")
@ApiOperation(value = "更新用户基本信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户编号", required = true, example = "1"),
@ApiImplicitParam(name = "nickname", value = "昵称", required = true, example = "小王"),
@ApiImplicitParam(name = "avatar", value = "头像", required = true, example = "http://www.iocoder.cn/xxx.jpg"),
})
public CommonResult<Boolean> update(@RequestParam("id") Integer id,
@RequestParam("nickname") String nickname,
@RequestParam("avatar") String avatar) {
UserUpdateDTO userUpdateDTO = new UserUpdateDTO().setId(id).setNickname(nickname).setNickname(nickname).setAvatar(avatar);
// 更新
return userService.updateUser(userUpdateDTO);
}
@PostMapping("/update_status")
@ApiOperation(value = "更新用户状态")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户编号", required = true, example = "1"),
@ApiImplicitParam(name = "status", value = "状态。1 - 开启2 - 禁用", required = true, example = "1"),
})
public CommonResult<Boolean> updateStatus(@RequestParam("id") Integer id,
@RequestParam("status") Integer status) {
return userService.updateUserStatus(id, status);
}
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.user.application.controller;
package cn.iocoder.mall.user.application.controller.users;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.application.convert.PassportConvert;
@ -7,7 +7,7 @@ import cn.iocoder.mall.user.service.api.MobileCodeService;
import cn.iocoder.mall.user.service.api.OAuth2Service;
import cn.iocoder.mall.user.service.api.UserService;
import cn.iocoder.mall.user.service.api.bo.OAuth2AccessTokenBO;
import cn.iocoder.mall.user.application.vo.MobileRegisterVO;
import cn.iocoder.mall.user.application.vo.users.MobileRegisterVO;
import com.alibaba.dubbo.config.annotation.Reference;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@ -19,7 +19,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user/passport")
@RequestMapping("users/passport")
@Api("Passport 模块")
public class PassportController {
@ -51,13 +51,15 @@ public class PassportController {
}
@PermitAll
@PostMapping("mobile/send")
@PostMapping("mobile/send_register_code")
@ApiOperation(value = "发送手机验证码")
@ApiImplicitParam(name = "mobile", value = "手机号", required = true, example = "15601691300")
public CommonResult<Void> mobileSend(@RequestParam("mobile") String mobile) {
return mobileCodeService.send(mobile);
}
// TODO 芋艿改绑手机号
// TODO 功能qq 登陆
@PermitAll
@PostMapping("/qq/login")

View File

@ -0,0 +1,50 @@
package cn.iocoder.mall.user.application.controller.users;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.application.convert.UserConvert;
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
import cn.iocoder.mall.user.application.vo.users.UsersUserVO;
import cn.iocoder.mall.user.service.api.UserService;
import cn.iocoder.mall.user.service.api.bo.UserBO;
import cn.iocoder.mall.user.service.api.dto.UserUpdateDTO;
import com.alibaba.dubbo.config.annotation.Reference;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users/user")
@Api("用户模块")
public class UserController {
@Reference(validation = "true")
private UserService userService;
@GetMapping("/info")
@ApiOperation(value = "用户信息")
public CommonResult<UsersUserVO> info() {
CommonResult<UserBO> userResult = userService.getUser(UserSecurityContextHolder.getContext().getUserId());
return UserConvert.INSTANCE.convert2(userResult);
}
@PostMapping("/update_avatar")
@ApiOperation(value = "更新头像")
public CommonResult<Boolean> updateAvatar(@RequestParam("avatar") String avatar) {
// 创建
UserUpdateDTO userUpdateDTO = new UserUpdateDTO().setId(UserSecurityContextHolder.getContext().getUserId())
.setAvatar(avatar);
// 更新头像
return userService.updateUser(userUpdateDTO);
}
@PostMapping("/update_nickname")
@ApiOperation(value = "更新昵称")
public CommonResult<Boolean> updateNickname(@RequestParam("nickname") String nickname) {
// 创建
UserUpdateDTO userUpdateDTO = new UserUpdateDTO().setId(UserSecurityContextHolder.getContext().getUserId())
.setNickname(nickname);
// 更新头像
return userService.updateUser(userUpdateDTO);
}
}

View File

@ -2,7 +2,7 @@ package cn.iocoder.mall.user.application.convert;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.service.api.bo.OAuth2AccessTokenBO;
import cn.iocoder.mall.user.application.vo.MobileRegisterVO;
import cn.iocoder.mall.user.application.vo.users.MobileRegisterVO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

View File

@ -0,0 +1,23 @@
package cn.iocoder.mall.user.application.convert;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.application.vo.admins.AdminsUserPageVO;
import cn.iocoder.mall.user.application.vo.users.UsersUserVO;
import cn.iocoder.mall.user.service.api.bo.UserBO;
import cn.iocoder.mall.user.service.api.bo.UserPageBO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface UserConvert {
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
@Mappings({})
CommonResult<AdminsUserPageVO> convert(CommonResult<UserPageBO> result);
@Mappings({})
CommonResult<UsersUserVO> convert2(CommonResult<UserBO> result);
}

View File

@ -1,21 +0,0 @@
package cn.iocoder.mall.user.application.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("用户信息 VO")
public class UserInfoVO {
@ApiModelProperty(value = "用户编号", required = true, example = "123")
private Long id;
public Long getId() {
return id;
}
public UserInfoVO setId(Long id) {
this.id = id;
return this;
}
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.mall.user.application.vo.admins;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.List;
@ApiModel("用户分页 VO")
public class AdminsUserPageVO {
@ApiModelProperty(value = "用户数组")
private List<AdminsUserVO> users;
@ApiModelProperty(value = "用户总数")
private Integer count;
public List<AdminsUserVO> getUsers() {
return users;
}
public AdminsUserPageVO setUsers(List<AdminsUserVO> users) {
this.users = users;
return this;
}
public Integer getCount() {
return count;
}
public AdminsUserPageVO setCount(Integer count) {
this.count = count;
return this;
}
}

View File

@ -0,0 +1,78 @@
package cn.iocoder.mall.user.application.vo.admins;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
@ApiModel("用户 VO")
public class AdminsUserVO {
@ApiModelProperty(value = "用户编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "手机号", required = true, example = "15601691300")
private String mobile;
@ApiModelProperty(value = "昵称", required = true, example = "小王")
private String nickname;
@ApiModelProperty(value = "头像", required = true, example = "http://www.iocoder.cn/xxx.jpg")
private String avatar;
@ApiModelProperty(value = "账号状态", required = true, example = "1")
private Integer status;
@ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式")
private Date createTime;
public Integer getId() {
return id;
}
public AdminsUserVO setId(Integer id) {
this.id = id;
return this;
}
public String getMobile() {
return mobile;
}
public AdminsUserVO setMobile(String mobile) {
this.mobile = mobile;
return this;
}
public String getNickname() {
return nickname;
}
public AdminsUserVO setNickname(String nickname) {
this.nickname = nickname;
return this;
}
public String getAvatar() {
return avatar;
}
public AdminsUserVO setAvatar(String avatar) {
this.avatar = avatar;
return this;
}
public Integer getStatus() {
return status;
}
public AdminsUserVO setStatus(Integer status) {
this.status = status;
return this;
}
public Date getCreateTime() {
return createTime;
}
public AdminsUserVO setCreateTime(Date createTime) {
this.createTime = createTime;
return this;
}
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.user.application.vo;
package cn.iocoder.mall.user.application.vo.users;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

View File

@ -0,0 +1,54 @@
package cn.iocoder.mall.user.application.vo.users;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("用户信息 VO")
public class UsersUserVO {
@ApiModelProperty(value = "用户编号", required = true, example = "123")
private Integer id;
@ApiModelProperty(value = "手机号", required = true, example = "15601691300")
private String mobile;
@ApiModelProperty(value = "昵称", required = true, example = "小王")
private String nickname;
@ApiModelProperty(value = "头像", required = true, example = "http://www.iocoder.cn/xxx.jpg")
private String avatar;
public Integer getId() {
return id;
}
public UsersUserVO setId(Integer id) {
this.id = id;
return this;
}
public String getMobile() {
return mobile;
}
public UsersUserVO setMobile(String mobile) {
this.mobile = mobile;
return this;
}
public String getNickname() {
return nickname;
}
public UsersUserVO setNickname(String nickname) {
this.nickname = nickname;
return this;
}
public String getAvatar() {
return avatar;
}
public UsersUserVO setAvatar(String avatar) {
this.avatar = avatar;
return this;
}
}

View File

@ -4,4 +4,6 @@ spring:
# server
server:
port: 8082
port: 18082
servlet:
context-path: /user-api/

View File

@ -5,14 +5,14 @@ package cn.iocoder.mall.user.sdk.context;
*/
public class UserSecurityContext {
private final Long uid;
private final Integer userId;
public UserSecurityContext(Long uid) {
this.uid = uid;
public UserSecurityContext(Integer userId) {
this.userId = userId;
}
public Long getUid() {
return uid;
public Integer getUserId() {
return userId;
}
}

View File

@ -38,7 +38,7 @@ public class UserSecurityInterceptor extends HandlerInterceptorAdapter {
}
authentication = result.getData();
// 添加到 SecurityContext
UserSecurityContext context = new UserSecurityContext(authentication.getUid());
UserSecurityContext context = new UserSecurityContext(authentication.getUserId());
UserSecurityContextHolder.setContext(context);
}
// 校验是否需要已授权

View File

@ -1,5 +1,41 @@
package cn.iocoder.mall.user.service.api;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.service.api.bo.UserBO;
import cn.iocoder.mall.user.service.api.bo.UserPageBO;
import cn.iocoder.mall.user.service.api.dto.UserPageDTO;
import cn.iocoder.mall.user.service.api.dto.UserUpdateDTO;
public interface UserService {
CommonResult<UserPageBO> getUserPage(UserPageDTO userPageDTO);
CommonResult<UserBO> getUser(Integer userId);
/**
* 更新用户基本信息
*
* @param userUpdateDTO 更新 DTO
* @return 更新结果
*/
CommonResult<Boolean> updateUser(UserUpdateDTO userUpdateDTO);
/**
* 更新用户状态
*
* @param userId 用户编号
* @param status 状态
* @return 更新结果
*/
CommonResult<Boolean> updateUserStatus(Integer userId, Integer status);
/**
* 更新用户手机号
*
* @param userId 用户编号
* @param mobile 手机号
* @return 更新结果
*/
CommonResult<Boolean> updateUserMobile(Integer userId, String mobile);
}

View File

@ -7,14 +7,14 @@ public class OAuth2AuthenticationBO implements Serializable {
/**
* 用户编号
*/
private Long uid;
private Integer userId;
public Long getUid() {
return uid;
public Integer getUserId() {
return userId;
}
public OAuth2AuthenticationBO setUid(Long uid) {
this.uid = uid;
public OAuth2AuthenticationBO setUserId(Integer userId) {
this.userId = userId;
return this;
}

View File

@ -1,22 +1,43 @@
package cn.iocoder.mall.user.service.api.bo;
import java.util.Date;
public class UserBO {
/**
* 用户编号
*/
private Long uid;
private Integer id;
/**
* 手机号
*/
private String mobile;
/**
* 昵称
*/
private String nickname;
/**
* 头像
*/
private String avatar;
/**
* 账号状态
*
* 1 - 开启
* 2 - 禁用
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
public Long getUid() {
return uid;
public Integer getId() {
return id;
}
public UserBO setUid(Long uid) {
this.uid = uid;
public UserBO setId(Integer id) {
this.id = id;
return this;
}
@ -29,4 +50,39 @@ public class UserBO {
return this;
}
public String getNickname() {
return nickname;
}
public UserBO setNickname(String nickname) {
this.nickname = nickname;
return this;
}
public String getAvatar() {
return avatar;
}
public UserBO setAvatar(String avatar) {
this.avatar = avatar;
return this;
}
public Integer getStatus() {
return status;
}
public UserBO setStatus(Integer status) {
this.status = status;
return this;
}
public Date getCreateTime() {
return createTime;
}
public UserBO setCreateTime(Date createTime) {
this.createTime = createTime;
return this;
}
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.mall.user.service.api.bo;
import java.util.List;
public class UserPageBO {
/**
* 用户数组
*/
private List<UserBO> users;
/**
* 总量
*/
private Integer count;
public List<UserBO> getUsers() {
return users;
}
public UserPageBO setUsers(List<UserBO> users) {
this.users = users;
return this;
}
public Integer getCount() {
return count;
}
public UserPageBO setCount(Integer count) {
this.count = count;
return this;
}
}

View File

@ -0,0 +1,14 @@
package cn.iocoder.mall.user.service.api.constant;
public class UserConstants {
/**
* 状态 - 开启
*/
public static final Integer STATUS_ENABLE = 1;
/**
* 状态 - 关闭
*/
public static final Integer STATUS_DISABLE = 2;
}

View File

@ -20,6 +20,9 @@ public enum UserErrorCodeEnum {
// ========== 用户模块 ==========
USER_MOBILE_NOT_REGISTERED(1001002000, "手机号未注册用户"),
USER_MOBILE_ALREADY_REGISTERED(1001002001, "手机号已经注册用户"),
USER_NOT_EXISTS(1001002002, "用户不存在"),
USER_STATUS_EQUALS(1001002003, "账号已经是该状态"),
USER_MOBILE_EQUALS(1001002004, "账号已经是该手机号"),
// ========== 手机验证码模块 ==========
MOBILE_CODE_NOT_FOUND(1001003000, "验证码不存在"),

View File

@ -0,0 +1,46 @@
package cn.iocoder.mall.user.service.api.dto;
import javax.validation.constraints.NotNull;
public class UserPageDTO {
/**
* 查询的昵称
*
* 模糊查询
*/
private String nickname;
@NotNull(message = "页码不能为空")
private Integer pageNo;
@NotNull(message = "每页条数不能为空")
private Integer pageSize;
public Integer getPageNo() {
return pageNo;
}
public String getNickname() {
return nickname;
}
public UserPageDTO setNickname(String nickname) {
this.nickname = nickname;
return this;
}
public UserPageDTO setPageNo(Integer pageNo) {
this.pageNo = pageNo;
return this;
}
public Integer getPageSize() {
return pageSize;
}
public UserPageDTO setPageSize(Integer pageSize) {
this.pageSize = pageSize;
return this;
}
}

View File

@ -0,0 +1,48 @@
package cn.iocoder.mall.user.service.api.dto;
/**
* 用户更新 DTO
*/
public class UserUpdateDTO {
/**
* 用户编号
*/
private Integer id;
/**
* 昵称
*/
private String nickname;
/**
* 头像
*/
private String avatar;
public Integer getId() {
return id;
}
public UserUpdateDTO setId(Integer id) {
this.id = id;
return this;
}
public String getNickname() {
return nickname;
}
public UserUpdateDTO setNickname(String nickname) {
this.nickname = nickname;
return this;
}
public String getAvatar() {
return avatar;
}
public UserUpdateDTO setAvatar(String avatar) {
this.avatar = avatar;
return this;
}
}

View File

@ -2,10 +2,13 @@ package cn.iocoder.mall.user.convert;
import cn.iocoder.mall.user.dataobject.UserDO;
import cn.iocoder.mall.user.service.api.bo.UserBO;
import cn.iocoder.mall.user.service.api.dto.UserUpdateDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface UserConvert {
@ -14,4 +17,10 @@ public interface UserConvert {
@Mappings({})
UserBO convert(UserDO userDO);
@Mappings({})
UserDO convert(UserUpdateDTO userUpdateDTO);
@Mappings({})
List<UserBO> convert(List<UserDO> userDOs);
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.mall.user.dao;
import cn.iocoder.mall.user.dataobject.OAuth2AccessTokenDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
@ -10,4 +11,6 @@ public interface OAuth2AccessTokenMapper {
OAuth2AccessTokenDO selectByTokenId(String tokenId);
void updateToInvalidByUserId(@Param("userId") Integer userId);
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.mall.user.dao;
import cn.iocoder.mall.user.dataobject.OAuth2RefreshTokenDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
@ -8,4 +9,6 @@ public interface OAuth2RefreshTokenMapper {
void insert(OAuth2RefreshTokenDO entity);
void updateToInvalidByUserId(@Param("userId") Integer userId);
}

View File

@ -1,13 +1,26 @@
package cn.iocoder.mall.user.dao;
import cn.iocoder.mall.user.dataobject.UserDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserMapper {
void insert(UserDO entity);
UserDO selectByMobile(String mobile);
int update(UserDO entity);
UserDO selectByMobile(@Param("mobile") String mobile);
UserDO selectById(@Param("id") Integer id);
List<UserDO> selectListByNicknameLike(@Param("nickname") String nickname,
@Param("offset") Integer offset,
@Param("limit") Integer limit);
Integer selectCountByNicknameLike(@Param("nickname") String nickname);
}

View File

@ -8,7 +8,7 @@ public class MobileCodeDO {
/**
* 编号
*/
private Long id;
private Integer id;
/**
* 手机号
*/
@ -28,7 +28,7 @@ public class MobileCodeDO {
/**
* 注册的用户编号
*/
private Long usedUid;
private Integer usedUserId;
/**
* 创建时间
*/
@ -38,11 +38,11 @@ public class MobileCodeDO {
*/
private Date usedTime;
public Long getId() {
public Integer getId() {
return id;
}
public MobileCodeDO setId(Long id) {
public MobileCodeDO setId(Integer id) {
this.id = id;
return this;
}
@ -83,12 +83,12 @@ public class MobileCodeDO {
return this;
}
public Long getUsedUid() {
return usedUid;
public Integer getUsedUserId() {
return usedUserId;
}
public MobileCodeDO setUsedUid(Long usedUid) {
this.usedUid = usedUid;
public MobileCodeDO setUsedUserId(Integer usedUserId) {
this.usedUserId = usedUserId;
return this;
}

View File

@ -15,7 +15,7 @@ public class OAuth2AccessTokenDO {
/**
* 用户编号
*/
private Long uid;
private Integer userId;
/**
* 过期时间
*/
@ -47,12 +47,12 @@ public class OAuth2AccessTokenDO {
return this;
}
public Long getUid() {
return uid;
public Integer getUserId() {
return userId;
}
public OAuth2AccessTokenDO setUid(Long uid) {
this.uid = uid;
public OAuth2AccessTokenDO setUserId(Integer userId) {
this.userId = userId;
return this;
}

View File

@ -16,7 +16,7 @@ public class OAuth2RefreshTokenDO {
/**
* 用户编号
*/
private Long uid;
private Integer userId;
/**
* 是否有效
*/
@ -39,12 +39,12 @@ public class OAuth2RefreshTokenDO {
return this;
}
public Long getUid() {
return uid;
public Integer getUserId() {
return userId;
}
public OAuth2RefreshTokenDO setUid(Long uid) {
this.uid = uid;
public OAuth2RefreshTokenDO setUserId(Integer userId) {
this.userId = userId;
return this;
}

View File

@ -12,7 +12,7 @@ public class UserDO extends BaseDO {
/**
* 用户编号
*/
private Long id;
private Integer id;
/**
* 手机号
*/
@ -25,12 +25,19 @@ public class UserDO extends BaseDO {
* 头像
*/
private String avatar;
/**
* 账号状态
*
* 1 - 开启
* 2 - 禁用
*/
private Integer status;
public Long getId() {
public Integer getId() {
return id;
}
public UserDO setId(Long id) {
public UserDO setId(Integer id) {
this.id = id;
return this;
}
@ -62,4 +69,13 @@ public class UserDO extends BaseDO {
return this;
}
public Integer getStatus() {
return status;
}
public UserDO setStatus(Integer status) {
this.status = status;
return this;
}
}

View File

@ -10,7 +10,7 @@ public class UserRegisterDO {
/**
* 用户编号
*/
private Long id;
private Integer id;
/**
* 创建时间
*/
@ -21,11 +21,11 @@ public class UserRegisterDO {
// TODO 芋艿 方式手机注册qq 等等
public Long getId() {
public Integer getId() {
return id;
}
public UserRegisterDO setId(Long id) {
public UserRegisterDO setId(Integer id) {
this.id = id;
return this;
}

View File

@ -1,6 +1,8 @@
package cn.iocoder.mall.user.service;
import cn.iocoder.common.framework.constant.SysErrorCodeEnum;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.util.ValidationUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.dao.MobileCodeMapper;
import cn.iocoder.mall.user.dataobject.MobileCodeDO;
@ -68,19 +70,17 @@ public class MobileCodeServiceImpl implements MobileCodeService {
* 更新手机验证码已使用
*
* @param id 验证码编号
* @param uid 用户编号
* @param userId 用户编号
*/
public void useMobileCode(Long id, Long uid) {
MobileCodeDO update = new MobileCodeDO().setId(id).setUsed(true).setUsedUid(uid).setUsedTime(new Date());
public void useMobileCode(Integer id, Integer userId) {
MobileCodeDO update = new MobileCodeDO().setId(id).setUsed(true).setUsedUserId(userId).setUsedTime(new Date());
mobileCodeMapper.update(update);
}
// TODO 芋艿后面要返回有效时间
public CommonResult<Void> send(String mobile) {
// TODO 芋艿校验手机格式
// 校验手机号码是否已经注册
if (userService.getUser(mobile) != null) {
return ServiceExceptionUtil.error(UserErrorCodeEnum.USER_MOBILE_ALREADY_REGISTERED.getCode());
if (!ValidationUtil.isMobile(mobile)) {
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "手机格式不正确"); // TODO 有点搓
}
// 校验是否可以发送验证码
MobileCodeDO lastMobileCodePO = mobileCodeMapper.selectLast1ByMobile(mobile);

View File

@ -94,19 +94,32 @@ public class OAuth2ServiceImpl implements OAuth2Service {
return CommonResult.success(OAuth2Convert.INSTANCE.convertToAuthentication(accessTokenDO));
}
private OAuth2AccessTokenDO createOAuth2AccessToken(Long uid, String refreshToken) {
/**
* 移除用户对应的 Token
*
* @param userId 管理员编号
*/
@Transactional
public void removeToken(Integer userId) {
// 设置 access token 失效
oauth2AccessTokenMapper.updateToInvalidByUserId(userId);
// 设置 refresh token 失效
oauth2RefreshTokenMapper.updateToInvalidByUserId(userId);
}
private OAuth2AccessTokenDO createOAuth2AccessToken(Integer uid, String refreshToken) {
OAuth2AccessTokenDO accessToken = new OAuth2AccessTokenDO().setId(generateAccessToken())
.setRefreshToken(refreshToken)
.setUid(uid)
.setUserId(uid)
.setExpiresTime(new Date(System.currentTimeMillis() + accessTokenExpireTimeMillis))
.setValid(true);
oauth2AccessTokenMapper.insert(accessToken);
return accessToken;
}
private OAuth2RefreshTokenDO createOAuth2RefreshToken(Long uid) {
private OAuth2RefreshTokenDO createOAuth2RefreshToken(Integer uid) {
OAuth2RefreshTokenDO refreshToken = new OAuth2RefreshTokenDO().setId(generateRefreshToken())
.setUid(uid)
.setUserId(uid)
.setExpiresTime(new Date(System.currentTimeMillis() + refreshTokenExpireTimeMillis))
.setValid(true);
oauth2RefreshTokenMapper.insert(refreshToken);

View File

@ -1,13 +1,22 @@
package cn.iocoder.mall.user.service;
import cn.iocoder.common.framework.constant.SysErrorCodeEnum;
import cn.iocoder.common.framework.dataobject.BaseDO;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.util.ValidationUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.convert.UserConvert;
import cn.iocoder.mall.user.dao.UserMapper;
import cn.iocoder.mall.user.dao.UserRegisterMapper;
import cn.iocoder.mall.user.dataobject.UserDO;
import cn.iocoder.mall.user.dataobject.UserRegisterDO;
import cn.iocoder.mall.user.service.api.UserService;
import cn.iocoder.mall.user.service.api.bo.UserBO;
import cn.iocoder.mall.user.service.api.bo.UserPageBO;
import cn.iocoder.mall.user.service.api.constant.UserConstants;
import cn.iocoder.mall.user.service.api.constant.UserErrorCodeEnum;
import cn.iocoder.mall.user.service.api.dto.UserPageDTO;
import cn.iocoder.mall.user.service.api.dto.UserUpdateDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
@ -25,7 +34,7 @@ public class UserServiceImpl implements UserService {
@Autowired
private UserRegisterMapper userRegisterMapper;
@Autowired
private MobileCodeServiceImpl mobileCodeService;
private OAuth2ServiceImpl oAuth2Service;
public UserDO getUser(String mobile) {
return userMapper.selectByMobile(mobile);
@ -33,14 +42,16 @@ public class UserServiceImpl implements UserService {
@Transactional
public CommonResult<UserDO> createUser(String mobile) {
// TODO 芋艿校验手机格式
if (!ValidationUtil.isMobile(mobile)) {
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "手机格式不正确"); // TODO 有点搓
}
// 校验用户是否已经存在
if (getUser(mobile) != null) {
return ServiceExceptionUtil.error(UserErrorCodeEnum.USER_MOBILE_ALREADY_REGISTERED.getCode());
}
// 创建用户
UserDO userDO = new UserDO().setMobile(mobile);
userDO.setCreateTime(new Date());
UserDO userDO = new UserDO().setMobile(mobile).setStatus(UserConstants.STATUS_ENABLE);
userDO.setCreateTime(new Date()).setDeleted(BaseDO.DELETED_NO);
userMapper.insert(userDO);
// 插入注册信息
createUserRegister(userDO);
@ -54,4 +65,86 @@ public class UserServiceImpl implements UserService {
userRegisterMapper.insert(userRegisterDO);
}
@Override
public CommonResult<UserPageBO> getUserPage(UserPageDTO userPageDTO) {
UserPageBO userPageBO = new UserPageBO();
// 查询分页数据
int offset = userPageDTO.getPageNo() * userPageDTO.getPageSize();
userPageBO.setUsers(UserConvert.INSTANCE.convert(userMapper.selectListByNicknameLike(userPageDTO.getNickname(),
offset, userPageDTO.getPageSize())));
// 查询分页总数
userPageBO.setCount(userMapper.selectCountByNicknameLike(userPageDTO.getNickname()));
return CommonResult.success(userPageBO);
}
@Override
public CommonResult<UserBO> getUser(Integer userId) {
return CommonResult.success(UserConvert.INSTANCE.convert(userMapper.selectById(userId)));
}
@Override
public CommonResult<Boolean> updateUser(UserUpdateDTO userUpdateDTO) {
// 校验用户存在
if (userMapper.selectById(userUpdateDTO.getId()) == null) {
return ServiceExceptionUtil.error(UserErrorCodeEnum.USER_NOT_EXISTS.getCode());
}
// 更新用户
UserDO updateUser = UserConvert.INSTANCE.convert(userUpdateDTO);
userMapper.update(updateUser);
// 返回成功
return CommonResult.success(true);
}
@Override
public CommonResult<Boolean> updateUserStatus(Integer userId, Integer status) {
// 校验参数
if (!isValidStatus(status)) {
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "变更状态必须是开启1或关闭2"); // TODO 有点搓
}
// 校验用户存在
UserDO user = userMapper.selectById(userId);
if (user == null) {
return ServiceExceptionUtil.error(UserErrorCodeEnum.USER_NOT_EXISTS.getCode());
}
// 如果状态相同则返回错误
if (status.equals(user.getStatus())) {
return ServiceExceptionUtil.error(UserErrorCodeEnum.USER_STATUS_EQUALS.getCode());
}
// 更新管理员状态
UserDO updateUser = new UserDO().setId(userId).setStatus(status);
userMapper.update(updateUser);
// 如果是关闭管理员则标记 token 失效否则管理员还可以继续蹦跶
if (UserConstants.STATUS_DISABLE.equals(status)) {
oAuth2Service.removeToken(userId);
}
// 返回成功
return CommonResult.success(true);
}
@Override
public CommonResult<Boolean> updateUserMobile(Integer userId, String mobile) {
if (!ValidationUtil.isMobile(mobile)) {
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "手机格式不正确"); // TODO 有点搓
}
// 校验用户存在
UserDO user = userMapper.selectById(userId);
if (user == null) {
return ServiceExceptionUtil.error(UserErrorCodeEnum.USER_NOT_EXISTS.getCode());
}
// 如果状态相同则返回错误
if (mobile.equals(user.getMobile())) {
return ServiceExceptionUtil.error(UserErrorCodeEnum.USER_MOBILE_EQUALS.getCode());
}
// 更新管理员状态
UserDO updateUser = new UserDO().setId(userId).setMobile(mobile);
userMapper.update(updateUser);
// 返回成功
return CommonResult.success(true);
}
private boolean isValidStatus(Integer status) {
return UserConstants.STATUS_ENABLE.equals(status)
|| UserConstants.STATUS_DISABLE.equals(status);
}
}

View File

@ -1,14 +1,10 @@
spring:
# datasource
datasource:
url: jdbc:mysql://127.0.0.1:33061/mall_user?useSSL=false
url: jdbc:mysql://180.167.213.26:13306/mall_user?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
# server
server:
port: 8082
password: ${MALL_MYSQL_PASSWORD}
# mybatis
mybatis:

View File

@ -5,10 +5,10 @@
<insert id="insert" parameterType="MobileCodeDO">
INSERT INTO mobile_code (
id, mobile, code, today_index, used,
used_uid, used_time, create_time
userd_user_id, used_time, create_time
) VALUES (
#{id}, #{mobile}, #{code}, #{todayIndex}, #{used},
#{usedUid}, #{usedTime}, #{createTime}
#{usedUserId}, #{usedTime}, #{createTime}
)
</insert>
@ -16,7 +16,7 @@
UPDATE mobile_code
<set>
<if test="used != null"> used = #{used}, </if>
<if test="usedUid != null"> used_uid = #{usedUid}, </if>
<if test="usedUserId != null"> userd_user_id = #{usedUserId}, </if>
<if test="usedTime != null"> used_time = #{usedTime}, </if>
</set>
WHERE id = #{id}
@ -25,7 +25,7 @@
<select id="selectLast1ByMobile" parameterType="String" resultType="MobileCodeDO">
SELECT
id, mobile, code, today_index, used,
used_uid, used_time, create_time
userd_user_id, used_time, create_time
FROM mobile_code
WHERE mobile = #{mobile}
ORDER BY id DESC

View File

@ -4,19 +4,26 @@
<insert id="insert" parameterType="OAuth2AccessTokenDO">
INSERT INTO oauth2_access_token (
id, refresh_token, adminId, valid, expires_time,
id, refresh_token, user_id, valid, expires_time,
create_time
) VALUES (
#{id}, #{refreshToken}, #{adminId}, #{valid}, #{expiresTime},
#{id}, #{refreshToken}, #{userId}, #{valid}, #{expiresTime},
#{createTime}
)
</insert>
<select id="selectByTokenId" parameterType="String" resultType="OAuth2AccessTokenDO">
SELECT
id, adminId, valid, expires_time
id, user_id, valid, expires_time
FROM oauth2_access_token
WHERE id = #{id}
</select>
<update id="updateToInvalidByUserId" parameterType="Integer">
UPDATE oauth2_access_token
SET valid = 0
WHERE user_id = #{userId}
AND valid = 1
</update>
</mapper>

View File

@ -4,10 +4,17 @@
<insert id="insert" parameterType="OAuth2RefreshTokenDO">
INSERT INTO oauth2_refresh_token (
id, adminId, valid, expires_time, create_time
id, user_id, valid, expires_time, create_time
) VALUES (
#{id}, #{adminId}, #{valid}, #{expiresTime}, #{createTime}
#{id}, #{userId}, #{valid}, #{expiresTime}, #{createTime}
)
</insert>
<update id="updateToInvalidByUserId" parameterType="Integer">
UPDATE oauth2_refresh_token
SET valid = 0
WHERE user_id = #{userId}
AND valid = 1
</update>
</mapper>

View File

@ -2,19 +2,81 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.mall.user.dao.UserMapper">
<sql id="FIELDS">
id, mobile, nickname, avatar, status,
create_time, deleted
</sql>
<insert id="insert" parameterType="UserDO" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users (
id, mobile, create_time
id, mobile, status, create_time, deleted
) VALUES (
#{id}, #{mobile}, #{createTime}
#{id}, #{mobile}, #{status} #{createTime}, #{deleted}
)
</insert>
<select id="selectByMobile" parameterType="String" resultType="UserDO">
SELECT
id, mobile
FROM users
WHERE mobile = #{mobile}
<update id="update" parameterType="UserDO">
UPDATE users
<set>
<if test="mobile != null">
, mobile = #{mobile}
</if>
<if test="nickname != null">
, nickname = #{nickname}
</if>
<if test="avatar != null">
, avatar = #{avatar}
</if>
<if test="status != null">
, status = #{status}
</if>
<if test="deleted != null">
, deleted = #{deleted}
</if>
</set>
WHERE id = #{id}
</update>
<select id="selectById" parameterType="Integer" resultType="UserDO">
SELECT
<include refid="FIELDS" />
FROM users
WHERE id = #{id}
AND deleted = 0
</select>
<select id="selectByMobile" parameterType="String" resultType="UserDO">
SELECT
<include refid="FIELDS" />
FROM users
WHERE mobile = #{mobile}
AND deleted = 0
</select>
<select id="selectListByNicknameLike" resultType="UserDO">
SELECT
<include refid="FIELDS" />
FROM users
<where>
<if test="nickname != null">
nickname LIKE "%"#{nickname}"%"
</if>
AND deleted = 0
</where>
LIMIT #{offset}, #{limit}
</select>
<select id="selectCountByNicknameLike" resultType="Integer">
SELECT
COUNT(1)
FROM users
<where>
<if test="nickname != null">
nickname LIKE "%"#{nickname}"%"
</if>
AND deleted = 0
</where>
</select>
</mapper>

View File

@ -2,11 +2,14 @@ package cn.iocoder.mall.user.convert;
import cn.iocoder.mall.user.dataobject.UserDO;
import cn.iocoder.mall.user.service.api.bo.UserBO;
import cn.iocoder.mall.user.service.api.dto.UserUpdateDTO;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2019-03-08T17:14:01+0800",
date = "2019-03-10T20:36:11+0800",
comments = "version: 1.3.0.Final, compiler: javac, environment: Java 11.0.1 (Oracle Corporation)"
)
public class UserConvertImpl implements UserConvert {
@ -19,8 +22,42 @@ public class UserConvertImpl implements UserConvert {
UserBO userBO = new UserBO();
userBO.setId( userDO.getId() );
userBO.setMobile( userDO.getMobile() );
userBO.setNickname( userDO.getNickname() );
userBO.setAvatar( userDO.getAvatar() );
userBO.setStatus( userDO.getStatus() );
userBO.setCreateTime( userDO.getCreateTime() );
return userBO;
}
@Override
public UserDO convert(UserUpdateDTO userUpdateDTO) {
if ( userUpdateDTO == null ) {
return null;
}
UserDO userDO = new UserDO();
userDO.setId( userUpdateDTO.getId() );
userDO.setNickname( userUpdateDTO.getNickname() );
userDO.setAvatar( userUpdateDTO.getAvatar() );
return userDO;
}
@Override
public List<UserBO> convert(List<UserDO> userDOs) {
if ( userDOs == null ) {
return null;
}
List<UserBO> list = new ArrayList<UserBO>( userDOs.size() );
for ( UserDO userDO : userDOs ) {
list.add( convert( userDO ) );
}
return list;
}
}