用户地址管理模块开发基本完成

This commit is contained in:
jieyuu 2024-07-07 17:23:08 +08:00
parent 86a1c4cf65
commit aa85ef8670
15 changed files with 478 additions and 40 deletions

View File

@ -0,0 +1,23 @@
package net.jieyuu.enums;
public enum AddressStatusEnum {
/**
* 是默认收货地址
*/
DEFAULT_STATUS(1),
/**
* 是默认收货地址
*/
COMMON_STATUS(0);
private int status;
private AddressStatusEnum(int status) {
this.status = status;
}
public int getStatus() {
return status;
}
}

View File

@ -29,6 +29,59 @@ public enum BizCodeEnum {
ACCOUNT_UNREGISTER(250002, "账号不存在"), ACCOUNT_UNREGISTER(250002, "账号不存在"),
ACCOUNT_PWD_ERROR(250003, "账号或者密码错误"), ACCOUNT_PWD_ERROR(250003, "账号或者密码错误"),
ACCOUNT_UNLOGIN(250004, "账号未登录"), ACCOUNT_UNLOGIN(250004, "账号未登录"),
/**
* 优惠券
*/
COUPON_CONDITION_ERROR(270001,"优惠券条件错误"),
COUPON_UNAVAILABLE(270002,"没有可用的优惠券"),
COUPON_NO_EXITS(270003,"优惠券不存在"),
COUPON_NO_STOCK(270005,"优惠券库存不足"),
COUPON_OUT_OF_LIMIT(270006,"优惠券领取超过限制次数"),
COUPON_OUT_OF_TIME(270407,"优惠券不在领取时间范围"),
COUPON_GET_FAIL(270407,"优惠券领取失败"),
COUPON_RECORD_LOCK_FAIL(270409,"优惠券锁定失败"),
/**
* 订单
*/
ORDER_CONFIRM_COUPON_FAIL(280001,"创建订单-优惠券使用失败,不满足价格条件"),
ORDER_CONFIRM_PRICE_FAIL(280002,"创建订单-验价失败"),
ORDER_CONFIRM_LOCK_PRODUCT_FAIL(280003,"创建订单-商品库存不足锁定失败"),
ORDER_CONFIRM_ADD_STOCK_TASK_FAIL(280004,"创建订单-新增商品库存锁定任务"),
ORDER_CONFIRM_TOKEN_NOT_EXIST(280008,"订单令牌缺少"),
ORDER_CONFIRM_TOKEN_EQUAL_FAIL(280009,"订单令牌不正确"),
ORDER_CONFIRM_NOT_EXIST(280010,"订单不存在"),
ORDER_CONFIRM_CART_ITEM_NOT_EXIST(280011,"购物车商品项不存在"),
/**
* 收货地址
*/
ADDRESS_ADD_FAIL(290001,"新增收货地址失败"),
ADDRESS_DEL_FAIL(290002,"删除收货地址失败"),
ADDRESS_NO_EXITS(290003,"地址不存在"),
/**
* 支付
*/
PAY_ORDER_FAIL(300001,"创建支付订单失败"),
PAY_ORDER_CALLBACK_SIGN_FAIL(300002,"支付订单回调验证签失败"),
PAY_ORDER_CALLBACK_NOT_SUCCESS(300003,"创建支付订单失败"),
PAY_ORDER_NOT_EXIST(300005,"订单不存在"),
PAY_ORDER_STATE_ERROR(300006,"订单状态不正常"),
PAY_ORDER_PAY_TIMEOUT(300007,"订单支付超时"),
/**
* 流控操作
*/
CONTROL_FLOW(500101,"限流控制"),
CONTROL_DEGRADE(500201,"降级控制"),
CONTROL_AUTH(500301,"认证控制"),
/**
* 文件相关
*/
FILE_UPLOAD_USER_IMG_FAIL(600101,"用户头像文件上传失败"); FILE_UPLOAD_USER_IMG_FAIL(600101,"用户头像文件上传失败");
@Getter @Getter

View File

@ -41,11 +41,14 @@ public class LoginInterceptor implements HandlerInterceptor {
String name = (String) claims.get("name"); String name = (String) claims.get("name");
String mail = (String) claims.get("mail"); String mail = (String) claims.get("mail");
LoginUser loginUser = new LoginUser(); // LoginUser loginUser = new LoginUser();
loginUser.setId(userId);
loginUser.setMail(mail); LoginUser loginUser = LoginUser.builder()
loginUser.setHeadImg(headImg); .headImg(headImg)
loginUser.setName(name); .id(userId)
.name(name)
.mail(mail)
.build();
//通过threadlocal传递用户信息 //通过threadlocal传递用户信息
threadLocal.set(loginUser); threadLocal.set(loginUser);
@ -58,11 +61,9 @@ public class LoginInterceptor implements HandlerInterceptor {
@Override @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
} }
@Override @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
} }
} }

View File

@ -2,9 +2,11 @@ package net.jieyuu.model;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data; import lombok.Data;
@Data @Data
@Builder
public class LoginUser { public class LoginUser {
/** /**
* 主键 * 主键

View File

@ -12,15 +12,10 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Slf4j @Slf4j
public class InterceptorConfig implements WebMvcConfigurer { public class InterceptorConfig implements WebMvcConfigurer {
@Bean
public LoginInterceptor loginInterceptor() {
return new LoginInterceptor();
}
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry registry
.addInterceptor(loginInterceptor()) .addInterceptor(new LoginInterceptor())
//拦截的路径 //拦截的路径
.addPathPatterns("/api/user/*/**", "/api/address/*/**") .addPathPatterns("/api/user/*/**", "/api/address/*/**")
//放行的路径 //放行的路径

View File

@ -4,10 +4,16 @@ package net.jieyuu.controller;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import net.jieyuu.enums.BizCodeEnum;
import net.jieyuu.request.AddressAddRequest;
import net.jieyuu.service.AddressService; import net.jieyuu.service.AddressService;
import net.jieyuu.utils.JsonData;
import net.jieyuu.vo.AddressVO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List;
/** /**
* <p> * <p>
* 电商-公司收发货地址表 前端控制器 * 电商-公司收发货地址表 前端控制器
@ -18,19 +24,48 @@ import org.springframework.web.bind.annotation.*;
*/ */
@Api(tags = "收货地址模块") @Api(tags = "收货地址模块")
@RestController @RestController
@RequestMapping("/api/adderss/v1/") @RequestMapping("/api/address/v1/")
public class AddressController { public class AddressController {
@Autowired @Autowired
AddressService addressService; AddressService addressService;
@ApiOperation("根据id查询地址详情") @ApiOperation("根据id查询地址详情")
@GetMapping("detail/{address_id}") @GetMapping("find/{address_id}")
public Object detail( public JsonData detail(
@ApiParam(value = "地址", required = true) @ApiParam(value = "地址", required = true)
@PathVariable("address_id") long id) { @PathVariable("address_id") long id) {
return addressService.detail(id); AddressVO addressVO = addressService.detail(id);
return addressVO == null ? JsonData.buildResult(BizCodeEnum.ADDRESS_NO_EXITS) : JsonData.buildSuccess(addressVO);
} }
@ApiOperation("新增收货地址")
@PostMapping("add")
public JsonData add(@ApiParam("地址对象")
@RequestBody AddressAddRequest addressAddRequest) {
addressService.add(addressAddRequest);
return JsonData.buildSuccess();
}
@ApiOperation("删除指定的收货地址")
@GetMapping("del/{address_id}")
public JsonData del(
@ApiParam(value = "地址", required = true)
@PathVariable("address_id") long id) {
int row = addressService.del(id);
return row == 1 ? JsonData.buildSuccess() : JsonData.buildResult(BizCodeEnum.ADDRESS_DEL_FAIL);
}
@ApiOperation("查询用户全部收货地址")
@GetMapping("/list")
public JsonData findUserAllAddress(){
List<AddressVO> list= addressService.listUserAllAddress();
return JsonData.buildSuccess(list);
}
} }

View File

@ -13,6 +13,7 @@ import net.jieyuu.service.NotifyService;
import net.jieyuu.service.UserService; import net.jieyuu.service.UserService;
import net.jieyuu.utils.CommonUtil; import net.jieyuu.utils.CommonUtil;
import net.jieyuu.utils.JsonData; import net.jieyuu.utils.JsonData;
import net.jieyuu.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest; import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -97,15 +98,28 @@ public class UserController {
} }
@ApiOperation("刷新accessToken") // @ApiOperation("刷新accessToken")
@PostMapping("refresh") // @PostMapping("refresh")
public JsonData getRefreshToken(Map<String, Object> param) { // public JsonData getRefreshToken(Map<String, Object> param) {
//先从redis寻找refresh_token // //先从redis寻找refresh_token
//refresh_token存在, 解密accessToken // //refresh_token存在, 解密accessToken
//重新调用JWTUtil 重新生成token // //重新调用JWTUtil 重新生成token
//
// return null;
// //不存在 重新登录
// }
/**
* 个人信息查询
* @return
*/
@ApiOperation("获取用户信息")
@GetMapping("detail")
public JsonData getUserInfo() {
UserVO userVO = userService.findUserDetail();
return JsonData.buildSuccess(userVO);
}
return null;
//不存在 重新登录
}
} }

View File

@ -0,0 +1,63 @@
package net.jieyuu.request;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "地址对象", description = "新增收货地址对象")
public class AddressAddRequest {
/**
* 用户id
*/
private Long userId;
/**
* 是否默认收货地址0->1->
*/
@ApiModelProperty(value = "是否默认收货地址0->否1->是", example = "0")
@JsonProperty("default_status")
private Integer defaultStatus;
/**
* 收发货人姓名
*/
@ApiModelProperty(value = "收货人姓名", example = "桀杰捷")
@JsonProperty("receive_name")
private String receiveName;
/**
* 收货人电话
*/
@ApiModelProperty(value = "收货人电话", example = "12343211234")
private String phone;
/**
* /直辖市
*/
@ApiModelProperty(value = "", example = "广东省")
private String province;
/**
*
*/
@ApiModelProperty(value = "城市", example = "湛江市")
private String city;
/**
*
*/
@ApiModelProperty(value = "", example = "麻章区")
private String region;
/**
* 详细地址
*/
@ApiModelProperty(value = "详细地址", example = "")
@JsonProperty("detail_address")
private String detailAddress;
}

View File

@ -1,9 +1,11 @@
package net.jieyuu.service; package net.jieyuu.service;
import net.jieyuu.mapper.AddressMapper;
import net.jieyuu.model.AddressDO; import net.jieyuu.model.AddressDO;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.beans.factory.annotation.Autowired; import net.jieyuu.request.AddressAddRequest;
import net.jieyuu.vo.AddressVO;
import java.util.List;
/** /**
* <p> * <p>
@ -14,7 +16,34 @@ import org.springframework.beans.factory.annotation.Autowired;
* @since 2024-02-12 * @since 2024-02-12
*/ */
public interface AddressService extends IService<AddressDO> { public interface AddressService extends IService<AddressDO> {
public AddressDO detail(Long id);
/**
* 查找详情
*
* @param id
* @return
*/
public AddressVO detail(Long id);
/**
* 新增收货地址
*
* @param addressAddRequest
*/
void add(AddressAddRequest addressAddRequest);
/**
* 根据id删除地址
* @param addressId
* @return
*/
int del(long addressId);
/**
* 查找用户全部收货地址
* @return
*/
List<AddressVO> listUserAllAddress();
} }

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import net.jieyuu.request.UserLoginRequest; import net.jieyuu.request.UserLoginRequest;
import net.jieyuu.request.UserRegisterRequest; import net.jieyuu.request.UserRegisterRequest;
import net.jieyuu.utils.JsonData; import net.jieyuu.utils.JsonData;
import net.jieyuu.vo.UserVO;
/** /**
* <p> * <p>
@ -16,9 +17,26 @@ import net.jieyuu.utils.JsonData;
*/ */
public interface UserService extends IService<UserDO> { public interface UserService extends IService<UserDO> {
//用户注册 /**
* 用户注册
*
* @param userRegisterRequest
* @return
*/
JsonData register(UserRegisterRequest userRegisterRequest); JsonData register(UserRegisterRequest userRegisterRequest);
//用户登录 /**
* 用户登录
*
* @param loginRequest
* @return
*/
JsonData login(UserLoginRequest loginRequest); JsonData login(UserLoginRequest loginRequest);
/**
* 查看用户详情
*
* @return
*/
UserVO findUserDetail();
} }

View File

@ -1,12 +1,25 @@
package net.jieyuu.service.impl; package net.jieyuu.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import net.jieyuu.enums.AddressStatusEnum;
import net.jieyuu.interceptor.LoginInterceptor;
import net.jieyuu.model.AddressDO; import net.jieyuu.model.AddressDO;
import net.jieyuu.mapper.AddressMapper; import net.jieyuu.mapper.AddressMapper;
import net.jieyuu.model.LoginUser;
import net.jieyuu.request.AddressAddRequest;
import net.jieyuu.service.AddressService; import net.jieyuu.service.AddressService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.jieyuu.vo.AddressVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* <p> * <p>
@ -17,14 +30,97 @@ import org.springframework.stereotype.Service;
* @since 2024-02-12 * @since 2024-02-12
*/ */
@Service @Service
@Slf4j
public class AddressServiceImpl extends ServiceImpl<AddressMapper, AddressDO> implements AddressService { public class AddressServiceImpl extends ServiceImpl<AddressMapper, AddressDO> implements AddressService {
@Autowired @Autowired
private AddressMapper addressMapper; private AddressMapper addressMapper;
@Override @Override
public AddressDO detail(Long id) { public AddressVO detail(Long id) {
QueryWrapper<AddressDO> queryWrapper = new QueryWrapper<>(); LoginUser loginUser = LoginInterceptor.threadLocal.get();
queryWrapper.eq("id", id);
return addressMapper.selectOne(queryWrapper); AddressDO addressDO = addressMapper.selectOne(new QueryWrapper<AddressDO>()
.eq("id", id)
.eq("user_id", loginUser.getId()));
if (addressDO == null) {
return null;
}
AddressVO addressVO = new AddressVO();
BeanUtils.copyProperties(addressDO, addressVO);
return addressVO;
}
/**
* 新增收货地址
*
* @param addressAddRequest
*/
@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public void add(AddressAddRequest addressAddRequest) {
LoginUser loginUser = LoginInterceptor.threadLocal.get();
AddressDO addressDO = new AddressDO();
addressDO.setCreateTime(new Date());
BeanUtils.copyProperties(addressAddRequest, addressDO);
addressDO.setUserId(loginUser.getId());
//查询是否有默认地址
if (addressDO.getDefaultStatus() == AddressStatusEnum.DEFAULT_STATUS.getStatus()) {
//查找数据库判断是否有默认地址
AddressDO defaultAddressDO = addressMapper.selectOne(new QueryWrapper<AddressDO>()
.eq("user_id", loginUser.getId())
.eq("default_status", AddressStatusEnum.DEFAULT_STATUS.getStatus()));
if (defaultAddressDO != null) {
//修改为非默认地址
addressDO.setDefaultStatus(AddressStatusEnum.COMMON_STATUS.getStatus());
addressMapper.update(defaultAddressDO, new QueryWrapper<AddressDO>().eq("id", defaultAddressDO.getId()));
}
}
int row = addressMapper.insert(addressDO);
//新增收货地址
log.info("新增收货地址:row={},data={}", row, addressDO);
}
@Override
public int del(long addressId) {
LoginUser loginUser = LoginInterceptor.threadLocal.get();
int rows = addressMapper.delete(
new QueryWrapper<AddressDO>()
.eq("id", addressId)
.eq("user_id", loginUser.getId())
);
return rows;
}
@Override
public List<AddressVO> listUserAllAddress() {
LoginUser loginUser = LoginInterceptor.threadLocal.get();
List<AddressDO> list = addressMapper.selectList(
new QueryWrapper<AddressDO>()
.eq("user_id", loginUser.getId())
);
//map映射
List<AddressVO> addressVOList = list.stream().map(obj -> {
AddressVO addressVO = new AddressVO();
BeanUtils.copyProperties(obj, addressVO);
return addressVO;
}).collect(Collectors.toList());
return addressVOList;
} }
} }

View File

@ -6,6 +6,7 @@ import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.jieyuu.enums.BizCodeEnum; import net.jieyuu.enums.BizCodeEnum;
import net.jieyuu.enums.SendCodeEnum; import net.jieyuu.enums.SendCodeEnum;
import net.jieyuu.interceptor.LoginInterceptor;
import net.jieyuu.model.LoginUser; import net.jieyuu.model.LoginUser;
import net.jieyuu.model.UserDO; import net.jieyuu.model.UserDO;
import net.jieyuu.mapper.UserMapper; import net.jieyuu.mapper.UserMapper;
@ -17,6 +18,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.jieyuu.utils.CommonUtil; import net.jieyuu.utils.CommonUtil;
import net.jieyuu.utils.JWTUtil; import net.jieyuu.utils.JWTUtil;
import net.jieyuu.utils.JsonData; import net.jieyuu.utils.JsonData;
import net.jieyuu.vo.UserVO;
import org.apache.commons.codec.digest.Md5Crypt; import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -148,7 +150,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, UserDO> implements
if (cryptPwd.equals(userDO.getPwd())) { if (cryptPwd.equals(userDO.getPwd())) {
//登陆成功 //登陆成功
//生成token令牌并且返回 //生成token令牌并且返回
LoginUser loginUser = new LoginUser(); LoginUser loginUser = LoginUser.builder().build();
BeanUtils.copyProperties(userDO, loginUser); BeanUtils.copyProperties(userDO, loginUser);
//accessToken //accessToken
String accessToken = JWTUtil.geneJsonWebToken(loginUser); String accessToken = JWTUtil.geneJsonWebToken(loginUser);
@ -170,5 +172,16 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, UserDO> implements
} }
} }
@Override
public UserVO findUserDetail() {
LoginUser loginUser = LoginInterceptor.threadLocal.get();
UserDO userDO = userMapper.selectOne(new QueryWrapper<UserDO>().eq("id", loginUser.getId()));
UserVO userVO = new UserVO();
BeanUtils.copyProperties(userDO, userVO);
return userVO;
}
} }

View File

@ -0,0 +1,53 @@
package net.jieyuu.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class AddressVO {
private Long id;
/**
* 用户id
*/
private Long userId;
/**
* 是否默认收货地址0->1->
*/
@JsonProperty("default_status")
private Integer defaultStatus;
/**
* 收发货人姓名
*/
@JsonProperty("receive_name")
private String receiveName;
/**
* 收货人电话
*/
private String phone;
/**
* /直辖市
*/
private String province;
/**
*
*/
private String city;
/**
*
*/
private String region;
/**
* 详细地址
*/
private String detailAddress;
}

View File

@ -0,0 +1,43 @@
package net.jieyuu.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class UserVO {
private Long id;
/**
* 昵称
*/
private String name;
/**
* 头像
*/
@JsonProperty("head_img")
private String headImg;
/**
* 用户签名
*/
private String slogan;
/**
* 0表示女1表示男
*/
private Integer sex;
/**
* 积分
*/
private Integer points;
/**
* 邮箱
*/
private String mail;
}

View File

@ -2,8 +2,8 @@ package net.jieyuu.biz;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.jieyuu.UserServiceApplication; import net.jieyuu.UserServiceApplication;
import net.jieyuu.model.AddressDO;
import net.jieyuu.service.AddressService; import net.jieyuu.service.AddressService;
import net.jieyuu.vo.AddressVO;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -22,8 +22,8 @@ public class AddressTest {
@Test @Test
public void testAddressDetail() { public void testAddressDetail() {
AddressDO addressDO = addressService.detail(1L); AddressVO addressVO = addressService.detail(1L);
log.info(addressDO.toString()); log.info(addressVO.toString());
} }