完成支付模块的商户管理开发以及单元测试

This commit is contained in:
aquan
2021-11-03 17:49:08 +08:00
parent aa77eb029f
commit 1a721ceb5f
25 changed files with 1258 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant;
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
import cn.iocoder.yudao.adminserver.modules.pay.convert.merchant.PayMerchantConvert;
import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserUpdateStatusReqVO;
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "支付商户信息")
@RestController
@RequestMapping("/pay/merchant")
@Validated
public class PayMerchantController {
@Resource
private PayMerchantService merchantService;
@PostMapping("/create")
@ApiOperation("创建支付商户信息")
@PreAuthorize("@ss.hasPermission('pay:merchant:create')")
public CommonResult<Long> createMerchant(@Valid @RequestBody PayMerchantCreateReqVO createReqVO) {
return success(merchantService.createMerchant(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新支付商户信息")
@PreAuthorize("@ss.hasPermission('pay:merchant:update')")
public CommonResult<Boolean> updateMerchant(@Valid @RequestBody PayMerchantUpdateReqVO updateReqVO) {
merchantService.updateMerchant(updateReqVO);
return success(true);
}
@PutMapping("/update-status")
@ApiOperation("修改支付商户状态")
@PreAuthorize("@ss.hasPermission('pay:merchant:update')")
public CommonResult<Boolean> updateMerchantStatus(@Valid @RequestBody PayMerchantUpdateStatusReqVO reqVO) {
merchantService.updateMerchantStatus(reqVO.getId(), reqVO.getStatus());
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除支付商户信息")
@ApiImplicitParam(name = "id", value = "编号", required = true)
@PreAuthorize("@ss.hasPermission('pay:merchant:delete')")
public CommonResult<Boolean> deleteMerchant(@RequestParam("id") Long id) {
merchantService.deleteMerchant(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得支付商户信息")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('pay:merchant:query')")
public CommonResult<PayMerchantRespVO> getMerchant(@RequestParam("id") Long id) {
PayMerchantDO merchant = merchantService.getMerchant(id);
return success(PayMerchantConvert.INSTANCE.convert(merchant));
}
@GetMapping("/list")
@ApiOperation("获得支付商户信息列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('pay:merchant:query')")
public CommonResult<List<PayMerchantRespVO>> getMerchantList(@RequestParam("ids") Collection<Long> ids) {
List<PayMerchantDO> list = merchantService.getMerchantList(ids);
return success(PayMerchantConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("获得支付商户信息分页")
@PreAuthorize("@ss.hasPermission('pay:merchant:query')")
public CommonResult<PageResult<PayMerchantRespVO>> getMerchantPage(@Valid PayMerchantPageReqVO pageVO) {
PageResult<PayMerchantDO> pageResult = merchantService.getMerchantPage(pageVO);
return success(PayMerchantConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@ApiOperation("导出支付商户信息 Excel")
@PreAuthorize("@ss.hasPermission('pay:merchant:export')")
@OperateLog(type = EXPORT)
public void exportMerchantExcel(@Valid PayMerchantExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<PayMerchantDO> list = merchantService.getMerchantList(exportReqVO);
// 导出 Excel
List<PayMerchantExcelVO> datas = PayMerchantConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "支付商户信息.xls", "数据", PayMerchantExcelVO.class, datas);
}
}

View File

@@ -0,0 +1,33 @@
package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 支付商户信息 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class PayMerchantBaseVO {
@ApiModelProperty(value = "商户号")
private String no;
@ApiModelProperty(value = "商户全称", required = true)
@NotNull(message = "商户全称不能为空")
private String name;
@ApiModelProperty(value = "商户简称", required = true)
@NotNull(message = "商户简称不能为空")
private String shortName;
@ApiModelProperty(value = "开启状态", required = true)
@NotNull(message = "开启状态不能为空")
private Integer status;
@ApiModelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,14 @@
package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("支付商户信息创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PayMerchantCreateReqVO extends PayMerchantBaseVO {
}

View File

@@ -0,0 +1,41 @@
package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 支付商户信息 Excel VO
*
* @author 芋艿
*/
@Data
public class PayMerchantExcelVO {
@ExcelProperty("商户编号")
private Long id;
@ExcelProperty("商户号")
private String no;
@ExcelProperty("商户全称")
private String name;
@ExcelProperty("商户简称")
private String shortName;
@ExcelProperty(value = "开启状态",converter = DictConvert.class)
@DictFormat("pay_merchant_status")
private Integer status;
@ExcelProperty("备注")
private String remark;
@ExcelProperty("创建时间")
private Date createTime;
}

View File

@@ -0,0 +1,38 @@
package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.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 = "支付商户信息 Excel 导出 Request VO", description = "参数和 PayMerchantPageReqVO 是一致的")
@Data
public class PayMerchantExportReqVO {
@ApiModelProperty(value = "商户号")
private String no;
@ApiModelProperty(value = "商户全称")
private String name;
@ApiModelProperty(value = "商户简称")
private String shortName;
@ApiModelProperty(value = "开启状态")
private Integer status;
@ApiModelProperty(value = "备注")
private String remark;
@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;
}

View File

@@ -0,0 +1,40 @@
package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.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("支付商户信息分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PayMerchantPageReqVO extends PageParam {
@ApiModelProperty(value = "商户号")
private String no;
@ApiModelProperty(value = "商户全称")
private String name;
@ApiModelProperty(value = "商户简称")
private String shortName;
@ApiModelProperty(value = "开启状态")
private Integer status;
@ApiModelProperty(value = "备注")
private String remark;
@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;
}

View File

@@ -0,0 +1,19 @@
package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
@ApiModel("支付商户信息 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PayMerchantRespVO extends PayMerchantBaseVO {
@ApiModelProperty(value = "商户编号", required = true)
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@@ -0,0 +1,18 @@
package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("支付商户信息更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PayMerchantUpdateReqVO extends PayMerchantBaseVO {
@ApiModelProperty(value = "商户编号", required = true)
@NotNull(message = "商户编号不能为空")
private Long id;
}

View File

@@ -0,0 +1,21 @@
package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@ApiModel("商户更新状态 Request VO")
@Data
public class PayMerchantUpdateStatusReqVO {
@ApiModelProperty(value = "商户编号", required = true, example = "1024")
@NotNull(message = "商户编号不能为空")
private Long id;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举")
@NotNull(message = "状态不能为空")
private Integer status;
}

View File

@@ -0,0 +1,34 @@
package cn.iocoder.yudao.adminserver.modules.pay.convert.merchant;
import java.util.*;
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
/**
* 支付商户信息 Convert
*
* @author 芋艿
*/
@Mapper
public interface PayMerchantConvert {
PayMerchantConvert INSTANCE = Mappers.getMapper(PayMerchantConvert.class);
PayMerchantDO convert(PayMerchantCreateReqVO bean);
PayMerchantDO convert(PayMerchantUpdateReqVO bean);
PayMerchantRespVO convert(PayMerchantDO bean);
List<PayMerchantRespVO> convertList(List<PayMerchantDO> list);
PageResult<PayMerchantRespVO> convertPage(PageResult<PayMerchantDO> page);
List<PayMerchantExcelVO> convertList02(List<PayMerchantDO> list);
}

View File

@@ -0,0 +1,42 @@
package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant;
import java.util.*;
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
/**
* 支付商户信息 Mapper
*
* @author 芋艿
*/
@Mapper
public interface PayMerchantMapper extends BaseMapperX<PayMerchantDO> {
default PageResult<PayMerchantDO> selectPage(PayMerchantPageReqVO reqVO) {
return selectPage(reqVO, new QueryWrapperX<PayMerchantDO>()
.likeIfPresent("no", reqVO.getNo())
.likeIfPresent("name", reqVO.getName())
.likeIfPresent("short_name", reqVO.getShortName())
.eqIfPresent("status", reqVO.getStatus())
.eqIfPresent("remark", reqVO.getRemark())
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc("id"));
}
default List<PayMerchantDO> selectList(PayMerchantExportReqVO reqVO) {
return selectList(new QueryWrapperX<PayMerchantDO>()
.likeIfPresent("no", reqVO.getNo())
.likeIfPresent("name", reqVO.getName())
.likeIfPresent("short_name", reqVO.getShortName())
.eqIfPresent("status", reqVO.getStatus())
.eqIfPresent("remark", reqVO.getRemark())
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc("id"));
}
}

View File

@@ -0,0 +1 @@
package cn.iocoder.yudao.adminserver.modules.pay.enums;

View File

@@ -0,0 +1,77 @@
package cn.iocoder.yudao.adminserver.modules.pay.service.merchant;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 支付商户信息 Service 接口
*
* @author 芋艿
*/
public interface PayMerchantService {
/**
* 创建支付商户信息
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createMerchant(@Valid PayMerchantCreateReqVO createReqVO);
/**
* 更新支付商户信息
*
* @param updateReqVO 更新信息
*/
void updateMerchant(@Valid PayMerchantUpdateReqVO updateReqVO);
/**
* 删除支付商户信息
*
* @param id 编号
*/
void deleteMerchant(Long id);
/**
* 获得支付商户信息
*
* @param id 编号
* @return 支付商户信息
*/
PayMerchantDO getMerchant(Long id);
/**
* 获得支付商户信息列表
*
* @param ids 编号
* @return 支付商户信息列表
*/
List<PayMerchantDO> getMerchantList(Collection<Long> ids);
/**
* 获得支付商户信息分页
*
* @param pageReqVO 分页查询
* @return 支付商户信息分页
*/
PageResult<PayMerchantDO> getMerchantPage(PayMerchantPageReqVO pageReqVO);
/**
* 获得支付商户信息列表, 用于 Excel 导出
*
* @param exportReqVO 查询条件
* @return 支付商户信息列表
*/
List<PayMerchantDO> getMerchantList(PayMerchantExportReqVO exportReqVO);
/**
* 修改商户状态
* @param id 商户编号
* @param status 状态
*/
void updateMerchantStatus(Long id, Integer status);
}

View File

@@ -0,0 +1,125 @@
package cn.iocoder.yudao.adminserver.modules.pay.service.merchant.impl;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantCreateReqVO;
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO;
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantPageReqVO;
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantUpdateReqVO;
import cn.iocoder.yudao.adminserver.modules.pay.convert.merchant.PayMerchantConvert;
import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMapper;
import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.google.common.annotations.VisibleForTesting;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* 支付商户信息 Service 实现类
*
* @author 芋艿
*/
@Service
@Validated
public class PayMerchantServiceImpl implements PayMerchantService {
@Resource
private PayMerchantMapper merchantMapper;
@Override
public Long createMerchant(PayMerchantCreateReqVO createReqVO) {
// 插入
PayMerchantDO merchant = PayMerchantConvert.INSTANCE.convert(createReqVO);
// 根据 年月日时分秒毫秒 生成时间戳
String merchantNo = "M" + DateUtil.format(LocalDateTime.now(),"yyyyMMddHHmmssSSS");
merchant.setNo(merchantNo);
merchantMapper.insert(merchant);
// 返回
return merchant.getId();
}
@Override
public void updateMerchant(PayMerchantUpdateReqVO updateReqVO) {
// 校验存在
this.validateMerchantExists(updateReqVO.getId());
// 更新
PayMerchantDO updateObj = PayMerchantConvert.INSTANCE.convert(updateReqVO);
merchantMapper.updateById(updateObj);
}
@Override
public void deleteMerchant(Long id) {
// 校验存在
this.validateMerchantExists(id);
// 删除
merchantMapper.deleteById(id);
}
private void validateMerchantExists(Long id) {
if (merchantMapper.selectById(id) == null) {
throw exception(MERCHANT_NOT_EXISTS);
}
}
@Override
public PayMerchantDO getMerchant(Long id) {
return merchantMapper.selectById(id);
}
@Override
public List<PayMerchantDO> getMerchantList(Collection<Long> ids) {
return merchantMapper.selectBatchIds(ids);
}
@Override
public PageResult<PayMerchantDO> getMerchantPage(PayMerchantPageReqVO pageReqVO) {
return merchantMapper.selectPage(pageReqVO);
}
@Override
public List<PayMerchantDO> getMerchantList(PayMerchantExportReqVO exportReqVO) {
return merchantMapper.selectList(exportReqVO);
}
/**
* 修改商户状态
*
* @param id 商户编号
* @param status 状态
*/
@Override
public void updateMerchantStatus(Long id, Integer status) {
// 校验商户存在
this.checkMerchantExists(id);
// 更新状态
PayMerchantDO merchant = new PayMerchantDO();
merchant.setId(id);
merchant.setStatus(status);
merchantMapper.updateById(merchant);
}
/**
* 检查商户是否存在
* @param id 商户编号
*/
@VisibleForTesting
public void checkMerchantExists(Long id) {
if (id == null) {
return;
}
PayMerchantDO merchant = merchantMapper.selectById(id);
if (merchant == null) {
throw exception(MERCHANT_NOT_EXISTS);
}
}
}