瀏覽代碼

用户收件地址代码生成

shuaidawang 3 年之前
父節點
當前提交
1deb04d256
共有 19 個文件被更改,包括 778 次插入2 次删除
  1. 3 0
      yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
  2. 84 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java
  3. 0 1
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/package-info.java
  4. 39 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java
  5. 14 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressCreateReqVO.java
  6. 41 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressExportReqVO.java
  7. 43 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressPageReqVO.java
  8. 19 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressRespVO.java
  9. 18 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressUpdateReqVO.java
  10. 32 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java
  11. 55 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java
  12. 0 1
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/package-info.java
  13. 44 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java
  14. 21 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/AddressTypeEnum.java
  15. 70 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressService.java
  16. 82 0
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java
  17. 196 0
      yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java
  18. 1 0
      yudao-module-member/yudao-module-member-impl/src/test/resources/sql/clean.sql
  19. 16 0
      yudao-module-member/yudao-module-member-impl/src/test/resources/sql/create_tables.sql

+ 3 - 0
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java

@@ -21,4 +21,7 @@ public interface ErrorCodeConstants {
     ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1004003004, "Token 已经过期");
     ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1004003005, "未绑定账号,需要进行绑定");
 
+    // ========== 用户收件地址 1004004000 ==========
+    ErrorCode ADDRESS_NOT_EXISTS = new ErrorCode(1004004000, "用户收件地址不存在");
+
 }

+ 84 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java

@@ -0,0 +1,84 @@
+package cn.iocoder.yudao.module.member.controller.app.address;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressPageReqVO;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO;
+import cn.iocoder.yudao.module.member.convert.address.AddressConvert;
+import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO;
+import cn.iocoder.yudao.module.member.service.address.AddressService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.Collection;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Api(tags = "用户 APP - 用户收件地址")
+@RestController
+@RequestMapping("/member/address")
+@Validated
+public class AppAddressController {
+
+    @Resource
+    private AddressService addressService;
+
+    @PostMapping("/create")
+    @ApiOperation("创建用户收件地址")
+
+    public CommonResult<Long> createAddress(@Valid @RequestBody AppAddressCreateReqVO createReqVO) {
+        return success(addressService.createAddress(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @ApiOperation("更新用户收件地址")
+
+    public CommonResult<Boolean> updateAddress(@Valid @RequestBody AppAddressUpdateReqVO updateReqVO) {
+        addressService.updateAddress(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation("删除用户收件地址")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
+
+    public CommonResult<Boolean> deleteAddress(@RequestParam("id") Long id) {
+        addressService.deleteAddress(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @ApiOperation("获得用户收件地址")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+
+    public CommonResult<AppAddressRespVO> getAddress(@RequestParam("id") Long id) {
+        AddressDO address = addressService.getAddress(id);
+        return success(AddressConvert.INSTANCE.convert(address));
+    }
+
+    @GetMapping("/list")
+    @ApiOperation("获得用户收件地址列表")
+    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
+
+    public CommonResult<List<AppAddressRespVO>> getAddressList(@RequestParam("ids") Collection<Long> ids) {
+        List<AddressDO> list = addressService.getAddressList(ids);
+        return success(AddressConvert.INSTANCE.convertList(list));
+    }
+
+    @GetMapping("/page")
+    @ApiOperation("获得用户收件地址分页")
+
+    public CommonResult<PageResult<AppAddressRespVO>> getAddressPage(@Valid AppAddressPageReqVO pageVO) {
+        PageResult<AddressDO> pageResult = addressService.getAddressPage(pageVO);
+        return success(AddressConvert.INSTANCE.convertPage(pageResult));
+    }
+
+}

+ 0 - 1
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/package-info.java

@@ -1 +0,0 @@
-package cn.iocoder.yudao.module.member.controller.app.address;

+ 39 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java

@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.member.controller.app.address.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+/**
+* 用户收件地址 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class AppAddressBaseVO {
+
+    @ApiModelProperty(value = "用户编号", required = true)
+    @NotNull(message = "用户编号不能为空")
+    private Integer userId;
+
+    @ApiModelProperty(value = "收件人名称", required = true)
+    @NotNull(message = "收件人名称不能为空")
+    private String name;
+
+    @ApiModelProperty(value = "手机号", required = true)
+    @NotNull(message = "手机号不能为空")
+    private String mobile;
+
+    @ApiModelProperty(value = "地区编码", required = true)
+    @NotNull(message = "地区编码不能为空")
+    private Integer areaCode;
+
+    @ApiModelProperty(value = "收件详细地址", required = true)
+    @NotNull(message = "收件详细地址不能为空")
+    private String detailAddress;
+
+    @ApiModelProperty(value = "地址类型", required = true)
+    @NotNull(message = "地址类型不能为空")
+    private Integer type;
+
+}

+ 14 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressCreateReqVO.java

@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.module.member.controller.app.address.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("用户 APP - 用户收件地址创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class AppAddressCreateReqVO extends AppAddressBaseVO {
+
+}

+ 41 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressExportReqVO.java

@@ -0,0 +1,41 @@
+package cn.iocoder.yudao.module.member.controller.app.address.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel(value = "用户 APP - 用户收件地址 Excel 导出 Request VO", description = "参数和 AddressPageReqVO 是一致的")
+@Data
+public class AppAddressExportReqVO {
+
+    @ApiModelProperty(value = "用户编号")
+    private Integer userId;
+
+    @ApiModelProperty(value = "收件人名称")
+    private String name;
+
+    @ApiModelProperty(value = "手机号")
+    private String mobile;
+
+    @ApiModelProperty(value = "地区编码")
+    private Integer areaCode;
+
+    @ApiModelProperty(value = "收件详细地址")
+    private String detailAddress;
+
+    @ApiModelProperty(value = "地址类型")
+    private Integer type;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始创建时间")
+    private Date beginCreateTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束创建时间")
+    private Date endCreateTime;
+
+}

+ 43 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressPageReqVO.java

@@ -0,0 +1,43 @@
+package cn.iocoder.yudao.module.member.controller.app.address.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel("用户 APP - 用户收件地址分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class AppAddressPageReqVO extends PageParam {
+
+    @ApiModelProperty(value = "用户编号")
+    private Integer userId;
+
+    @ApiModelProperty(value = "收件人名称")
+    private String name;
+
+    @ApiModelProperty(value = "手机号")
+    private String mobile;
+
+    @ApiModelProperty(value = "地区编码")
+    private Integer areaCode;
+
+    @ApiModelProperty(value = "收件详细地址")
+    private String detailAddress;
+
+    @ApiModelProperty(value = "地址类型")
+    private Integer type;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始创建时间")
+    private Date beginCreateTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束创建时间")
+    private Date endCreateTime;
+
+}

+ 19 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressRespVO.java

@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.module.member.controller.app.address.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+@ApiModel("用户 APP - 用户收件地址 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class AppAddressRespVO extends AppAddressBaseVO {
+
+    @ApiModelProperty(value = "编号", required = true)
+    private Long id;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private Date createTime;
+
+}

+ 18 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressUpdateReqVO.java

@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.module.member.controller.app.address.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("用户 APP - 用户收件地址更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class AppAddressUpdateReqVO extends AppAddressBaseVO {
+
+    @ApiModelProperty(value = "编号", required = true)
+    @NotNull(message = "编号不能为空")
+    private Long id;
+
+}

+ 32 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java

@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.module.member.convert.address;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.*;
+import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO;
+
+/**
+ * 用户收件地址 Convert
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface AddressConvert {
+
+    AddressConvert INSTANCE = Mappers.getMapper(AddressConvert.class);
+
+    AddressDO convert(AppAddressCreateReqVO bean);
+
+    AddressDO convert(AppAddressUpdateReqVO bean);
+
+    AppAddressRespVO convert(AddressDO bean);
+
+    List<AppAddressRespVO> convertList(List<AddressDO> list);
+
+    PageResult<AppAddressRespVO> convertPage(PageResult<AddressDO> page);
+
+}

+ 55 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java

@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.module.member.dal.dataobject.address;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.member.enums.AddressTypeEnum;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+/**
+ * 用户收件地址 DO
+ *
+ * @author 芋道源码
+ */
+@TableName("member_address")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class AddressDO extends BaseDO {
+
+    /**
+     * 编号
+     */
+    @TableId
+    private Long id;
+    /**
+     * 用户编号
+     */
+    private Integer userId;
+    /**
+     * 收件人名称
+     */
+    private String name;
+    /**
+     * 手机号
+     */
+    private String mobile;
+    /**
+     * 地区编码
+     */
+    private Integer areaCode;
+    /**
+     * 收件详细地址
+     */
+    private String detailAddress;
+    /**
+     * 地址类型,主要分为默认地址,和普通地址
+     *
+     * 外键 {@link AddressTypeEnum}
+     */
+    private Integer type;
+
+}

+ 0 - 1
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/package-info.java

@@ -1 +0,0 @@
-package cn.iocoder.yudao.module.member.dal.dataobject.address;

+ 44 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java

@@ -0,0 +1,44 @@
+package cn.iocoder.yudao.module.member.dal.mysql.address;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO;
+import org.apache.ibatis.annotations.Mapper;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.*;
+
+/**
+ * 用户收件地址 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface AddressMapper extends BaseMapperX<AddressDO> {
+
+    default PageResult<AddressDO> selectPage(AppAddressPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<AddressDO>()
+                .eqIfPresent(AddressDO::getUserId, reqVO.getUserId())
+                .likeIfPresent(AddressDO::getName, reqVO.getName())
+                .eqIfPresent(AddressDO::getMobile, reqVO.getMobile())
+                .eqIfPresent(AddressDO::getAreaCode, reqVO.getAreaCode())
+                .eqIfPresent(AddressDO::getDetailAddress, reqVO.getDetailAddress())
+                .eqIfPresent(AddressDO::getType, reqVO.getType())
+                .betweenIfPresent(AddressDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc(AddressDO::getId));
+    }
+
+    default List<AddressDO> selectList(AppAddressExportReqVO reqVO) {
+        return selectList(new LambdaQueryWrapperX<AddressDO>()
+                .eqIfPresent(AddressDO::getUserId, reqVO.getUserId())
+                .likeIfPresent(AddressDO::getName, reqVO.getName())
+                .eqIfPresent(AddressDO::getMobile, reqVO.getMobile())
+                .eqIfPresent(AddressDO::getAreaCode, reqVO.getAreaCode())
+                .eqIfPresent(AddressDO::getDetailAddress, reqVO.getDetailAddress())
+                .eqIfPresent(AddressDO::getType, reqVO.getType())
+                .betweenIfPresent(AddressDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc(AddressDO::getId));
+    }
+
+}

+ 21 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/AddressTypeEnum.java

@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.member.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 用户收件地址的类型枚举
+ */
+@Getter
+@AllArgsConstructor
+public enum AddressTypeEnum {
+
+    DEFAULT(1, "默认收件地址"),
+    NORMAL(2, "普通收件地址"), // 即非默认收件笛之爱
+
+    ;
+
+    private final Integer type;
+    private final String desc;
+
+}

+ 70 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressService.java

@@ -0,0 +1,70 @@
+package cn.iocoder.yudao.module.member.service.address;
+
+import java.util.*;
+import javax.validation.*;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.*;
+import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+/**
+ * 用户收件地址 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface AddressService {
+
+    /**
+     * 创建用户收件地址
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createAddress(@Valid AppAddressCreateReqVO createReqVO);
+
+    /**
+     * 更新用户收件地址
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateAddress(@Valid AppAddressUpdateReqVO updateReqVO);
+
+    /**
+     * 删除用户收件地址
+     *
+     * @param id 编号
+     */
+    void deleteAddress(Long id);
+
+    /**
+     * 获得用户收件地址
+     *
+     * @param id 编号
+     * @return 用户收件地址
+     */
+    AddressDO getAddress(Long id);
+
+    /**
+     * 获得用户收件地址列表
+     *
+     * @param ids 编号
+     * @return 用户收件地址列表
+     */
+    List<AddressDO> getAddressList(Collection<Long> ids);
+
+    /**
+     * 获得用户收件地址分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 用户收件地址分页
+     */
+    PageResult<AddressDO> getAddressPage(AppAddressPageReqVO pageReqVO);
+
+    /**
+     * 获得用户收件地址列表, 用于 Excel 导出
+     *
+     * @param exportReqVO 查询条件
+     * @return 用户收件地址列表
+     */
+    List<AddressDO> getAddressList(AppAddressExportReqVO exportReqVO);
+
+}

+ 82 - 0
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java

@@ -0,0 +1,82 @@
+package cn.iocoder.yudao.module.member.service.address;
+
+import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.*;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.*;
+import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import cn.iocoder.yudao.module.member.convert.address.AddressConvert;
+import cn.iocoder.yudao.module.member.dal.mysql.address.AddressMapper;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
+
+/**
+ * 用户收件地址 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class AddressServiceImpl implements AddressService {
+
+    @Resource
+    private AddressMapper addressMapper;
+
+    @Override
+    public Long createAddress(AppAddressCreateReqVO createReqVO) {
+        // 插入
+        AddressDO address = AddressConvert.INSTANCE.convert(createReqVO);
+        addressMapper.insert(address);
+        // 返回
+        return address.getId();
+    }
+
+    @Override
+    public void updateAddress(AppAddressUpdateReqVO updateReqVO) {
+        // 校验存在
+        this.validateAddressExists(updateReqVO.getId());
+        // 更新
+        AddressDO updateObj = AddressConvert.INSTANCE.convert(updateReqVO);
+        addressMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteAddress(Long id) {
+        // 校验存在
+        this.validateAddressExists(id);
+        // 删除
+        addressMapper.deleteById(id);
+    }
+
+    private void validateAddressExists(Long id) {
+        if (addressMapper.selectById(id) == null) {
+            throw exception(ADDRESS_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public AddressDO getAddress(Long id) {
+        return addressMapper.selectById(id);
+    }
+
+    @Override
+    public List<AddressDO> getAddressList(Collection<Long> ids) {
+        return addressMapper.selectBatchIds(ids);
+    }
+
+    @Override
+    public PageResult<AddressDO> getAddressPage(AppAddressPageReqVO pageReqVO) {
+        return addressMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public List<AddressDO> getAddressList(AppAddressExportReqVO exportReqVO) {
+        return addressMapper.selectList(exportReqVO);
+    }
+
+}

+ 196 - 0
yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java

@@ -0,0 +1,196 @@
+package cn.iocoder.yudao.module.member.service.address;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressExportReqVO;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressPageReqVO;
+import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO;
+import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO;
+import cn.iocoder.yudao.module.member.dal.mysql.address.AddressMapper;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.Import;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
+import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.ADDRESS_NOT_EXISTS;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+* {@link AddressServiceImpl} 的单元测试类
+*
+* @author 芋道源码
+*/
+@Import(AddressServiceImpl.class)
+public class AddressServiceImplTest extends BaseDbUnitTest {
+
+    @Resource
+    private AddressServiceImpl addressService;
+
+    @Resource
+    private AddressMapper addressMapper;
+
+    @Test
+    public void testCreateAddress_success() {
+        // 准备参数
+        AppAddressCreateReqVO reqVO = randomPojo(AppAddressCreateReqVO.class);
+
+        // 调用
+        Long addressId = addressService.createAddress(reqVO);
+        // 断言
+        assertNotNull(addressId);
+        // 校验记录的属性是否正确
+        AddressDO address = addressMapper.selectById(addressId);
+        assertPojoEquals(reqVO, address);
+    }
+
+    @Test
+    public void testUpdateAddress_success() {
+        // mock 数据
+        AddressDO dbAddress = randomPojo(AddressDO.class);
+        addressMapper.insert(dbAddress);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        AppAddressUpdateReqVO reqVO = randomPojo(AppAddressUpdateReqVO.class, o -> {
+            o.setId(dbAddress.getId()); // 设置更新的 ID
+        });
+
+        // 调用
+        addressService.updateAddress(reqVO);
+        // 校验是否更新正确
+        AddressDO address = addressMapper.selectById(reqVO.getId()); // 获取最新的
+        assertPojoEquals(reqVO, address);
+    }
+
+    @Test
+    public void testUpdateAddress_notExists() {
+        // 准备参数
+        AppAddressUpdateReqVO reqVO = randomPojo(AppAddressUpdateReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> addressService.updateAddress(reqVO), ADDRESS_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeleteAddress_success() {
+        // mock 数据
+        AddressDO dbAddress = randomPojo(AddressDO.class);
+        addressMapper.insert(dbAddress);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbAddress.getId();
+
+        // 调用
+        addressService.deleteAddress(id);
+       // 校验数据不存在了
+       assertNull(addressMapper.selectById(id));
+    }
+
+    @Test
+    public void testDeleteAddress_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> addressService.deleteAddress(id), ADDRESS_NOT_EXISTS);
+    }
+
+    @Test
+    @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+    public void ins() {
+       // mock 数据
+       AddressDO dbAddress = randomPojo(AddressDO.class, o -> { // 等会查询到
+           o.setUserId(null);
+           o.setName(null);
+           o.setMobile(null);
+           o.setAreaCode(null);
+           o.setDetailAddress(null);
+           o.setType(null);
+           o.setCreateTime(null);
+       });
+       addressMapper.insert(dbAddress);
+       // 测试 userId 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setUserId(null)));
+       // 测试 name 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setName(null)));
+       // 测试 mobile 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setMobile(null)));
+       // 测试 areaCode 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setAreaCode(null)));
+       // 测试 detailAddress 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setDetailAddress(null)));
+       // 测试 type 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setType(null)));
+       // 测试 createTime 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setCreateTime(null)));
+       // 准备参数
+       AppAddressPageReqVO reqVO = new AppAddressPageReqVO();
+       reqVO.setUserId(null);
+       reqVO.setName(null);
+       reqVO.setMobile(null);
+       reqVO.setAreaCode(null);
+       reqVO.setDetailAddress(null);
+       reqVO.setType(null);
+       reqVO.setBeginCreateTime(null);
+       reqVO.setEndCreateTime(null);
+
+       // 调用
+       PageResult<AddressDO> pageResult = addressService.getAddressPage(reqVO);
+       // 断言
+       assertEquals(1, pageResult.getTotal());
+       assertEquals(1, pageResult.getList().size());
+       assertPojoEquals(dbAddress, pageResult.getList().get(0));
+    }
+
+    @Test
+    @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+    public void testGetAddressList() {
+       // mock 数据
+       AddressDO dbAddress = randomPojo(AddressDO.class, o -> { // 等会查询到
+           o.setUserId(null);
+           o.setName(null);
+           o.setMobile(null);
+           o.setAreaCode(null);
+           o.setDetailAddress(null);
+           o.setType(null);
+           o.setCreateTime(null);
+       });
+       addressMapper.insert(dbAddress);
+       // 测试 userId 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setUserId(null)));
+       // 测试 name 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setName(null)));
+       // 测试 mobile 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setMobile(null)));
+       // 测试 areaCode 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setAreaCode(null)));
+       // 测试 detailAddress 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setDetailAddress(null)));
+       // 测试 type 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setType(null)));
+       // 测试 createTime 不匹配
+       addressMapper.insert(cloneIgnoreId(dbAddress, o -> o.setCreateTime(null)));
+       // 准备参数
+       AppAddressExportReqVO reqVO = new AppAddressExportReqVO();
+       reqVO.setUserId(null);
+       reqVO.setName(null);
+       reqVO.setMobile(null);
+       reqVO.setAreaCode(null);
+       reqVO.setDetailAddress(null);
+       reqVO.setType(null);
+       reqVO.setBeginCreateTime(null);
+       reqVO.setEndCreateTime(null);
+
+       // 调用
+       List<AddressDO> list = addressService.getAddressList(reqVO);
+       // 断言
+       assertEquals(1, list.size());
+       assertPojoEquals(dbAddress, list.get(0));
+    }
+
+}

+ 1 - 0
yudao-module-member/yudao-module-member-impl/src/test/resources/sql/clean.sql

@@ -1 +1,2 @@
 DELETE FROM "member_user";
+DELETE FROM "member_address";

+ 16 - 0
yudao-module-member/yudao-module-member-impl/src/test/resources/sql/create_tables.sql

@@ -30,3 +30,19 @@ CREATE TABLE IF NOT EXISTS "inf_file" (
     PRIMARY KEY ("id")
 ) COMMENT '文件表';
 
+CREATE TABLE IF NOT EXISTS "member_address" (
+    "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "user_id" int(11) NOT NULL,
+    "name" varchar(10) NOT NULL,
+    "mobile" varchar(20) NOT NULL,
+    "area_code" int(11) NOT NULL,
+    "detail_address" varchar(250) NOT NULL,
+    "type" tinyint(4) NOT NULL,
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "creator" varchar(64) DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "updater" varchar(64) DEFAULT '',
+    PRIMARY KEY ("id")
+    ) COMMENT '用户收件地址';
+