diff --git a/sql/pay-merchant-menu.sql b/sql/pay-merchant-menu.sql new file mode 100644 index 000000000..cc4a4e761 --- /dev/null +++ b/sql/pay-merchant-menu.sql @@ -0,0 +1,60 @@ +-- 支付模块-商户中心-菜单SQL +-- 菜单 SQL +INSERT INTO `sys_menu` ( + `name`, `permission`,`menu_type`,`sort`, `parent_id`, `path`, `icon`, `component`, + `status`, `creator`,`create_time`, `updater`, `update_time`, `deleted` +) VALUES ('支付管理', '', 1, 4,0, '/pay','pay', NULL, 0, '1', '2021-11-03 10:35:04', '1', '2021-11-03 10:35:04', b'0'); + +INSERT INTO `sys_menu`( + `name`, `permission`, `menu_type`, `sort`, `parent_id`, + `path`, `icon`, `component`, `status` +) +VALUES ( + '支付商户信息管理', '', 2, 0, ${table.parentMenuId}, + 'merchant', '', 'pay/merchant/index', 0 +); + +-- 按钮父菜单ID +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +INSERT INTO `sys_menu`( + `name`, `permission`, `menu_type`, `sort`, `parent_id`, + `path`, `icon`, `component`, `status` +) +VALUES ( + '支付商户信息查询', 'pay:merchant:query', 3, 1, @parentId, + '', '', '', 0 +); +INSERT INTO `sys_menu`( + `name`, `permission`, `menu_type`, `sort`, `parent_id`, + `path`, `icon`, `component`, `status` +) +VALUES ( + '支付商户信息创建', 'pay:merchant:create', 3, 2, @parentId, + '', '', '', 0 +); +INSERT INTO `sys_menu`( + `name`, `permission`, `menu_type`, `sort`, `parent_id`, + `path`, `icon`, `component`, `status` +) +VALUES ( + '支付商户信息更新', 'pay:merchant:update', 3, 3, @parentId, + '', '', '', 0 +); +INSERT INTO `sys_menu`( + `name`, `permission`, `menu_type`, `sort`, `parent_id`, + `path`, `icon`, `component`, `status` +) +VALUES ( + '支付商户信息删除', 'pay:merchant:delete', 3, 4, @parentId, + '', '', '', 0 +); +INSERT INTO `sys_menu`( + `name`, `permission`, `menu_type`, `sort`, `parent_id`, + `path`, `icon`, `component`, `status` +) +VALUES ( + '支付商户信息导出', 'pay:merchant:export', 3, 5, @parentId, + '', '', '', 0 +); diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java new file mode 100644 index 000000000..6ec9af43a --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java @@ -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); + } + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java new file mode 100644 index 000000000..4d83ff232 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java @@ -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; + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java new file mode 100644 index 000000000..2128de88b --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java @@ -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 { + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java new file mode 100644 index 000000000..80c206c2d --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java @@ -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; + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java new file mode 100644 index 000000000..c6c322282 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java @@ -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; + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java new file mode 100644 index 000000000..8a66ac953 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java @@ -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; + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java new file mode 100644 index 000000000..ba55458eb --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java @@ -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; + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java new file mode 100644 index 000000000..031d34fd5 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java @@ -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; + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java new file mode 100644 index 000000000..635876954 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java @@ -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; + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java new file mode 100644 index 000000000..9483ff120 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java @@ -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); + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java new file mode 100644 index 000000000..5abc3a231 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java @@ -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")); + } + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java new file mode 100644 index 000000000..df39d9efc --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.adminserver.modules.pay.enums; diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java new file mode 100644 index 000000000..db7926c12 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java @@ -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); + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java new file mode 100644 index 000000000..12981677f --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java @@ -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); + } + } + + +} diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/merchant/service/PayMerchantServiceTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/merchant/service/PayMerchantServiceTest.java new file mode 100644 index 000000000..a93808921 --- /dev/null +++ b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/merchant/service/PayMerchantServiceTest.java @@ -0,0 +1,192 @@ +package cn.iocoder.yudao.adminserver.modules.pay.merchant.service; + +import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.adminserver.BaseDbUnitTest; +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.dal.mysql.merchant.PayMerchantMapper; +import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.impl.PayMerchantServiceImpl; +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; +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.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.MERCHANT_NOT_EXISTS; +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.common.util.date.DateUtils.buildTime; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static org.junit.jupiter.api.Assertions.*; + +/** +* {@link PayMerchantServiceImpl} 的单元测试类 +* +* @author 芋艿 +*/ +@Import(PayMerchantServiceImpl.class) +public class PayMerchantServiceTest extends BaseDbUnitTest { + + @Resource + private PayMerchantServiceImpl merchantService; + + @Resource + private PayMerchantMapper merchantMapper; + + @Test + public void testCreateMerchant_success() { + // 准备参数 + PayMerchantCreateReqVO reqVO = randomPojo(PayMerchantCreateReqVO.class,o -> + o.setStatus(RandomUtil.randomEle(CommonStatusEnum.values()).getStatus())); + + // 调用 + Long merchantId = merchantService.createMerchant(reqVO); + // 断言 + assertNotNull(merchantId); + // 校验记录的属性是否正确 + PayMerchantDO merchant = merchantMapper.selectById(merchantId); + assertPojoEquals(reqVO, merchant,"no"); + } + + @Test + public void testUpdateMerchant_success() { + // mock 数据 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> + o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + merchantMapper.insert(dbMerchant);// @Sql: 先插入出一条存在的数据 + // 准备参数 + PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class, o -> { + o.setId(dbMerchant.getId()); // 设置更新的 ID + o.setStatus(CommonStatusEnum.DISABLE.getStatus()); + }); + + // 调用 + merchantService.updateMerchant(reqVO); + // 校验是否更新正确 + PayMerchantDO merchant = merchantMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, merchant); + } + + @Test + public void testUpdateMerchant_notExists() { + // 准备参数 + PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> merchantService.updateMerchant(reqVO), MERCHANT_NOT_EXISTS); + } + + @Test + public void testDeleteMerchant_success() { + // mock 数据 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, + o-> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + merchantMapper.insert(dbMerchant);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbMerchant.getId(); + + // 调用 + merchantService.deleteMerchant(id); + // 校验数据不存在了 + assertNull(merchantMapper.selectById(id)); + } + + @Test + public void testDeleteMerchant_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> merchantService.deleteMerchant(id), MERCHANT_NOT_EXISTS); + } + + @Test + public void testGetMerchantPage() { + // mock 数据 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到 + o.setNo("M1008611"); + o.setName("灿哥的杂货铺"); + o.setShortName("灿灿子"); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setRemark("灿哥的杂货铺"); + o.setCreateTime(buildTime(2021,11,3)); + }); + merchantMapper.insert(dbMerchant); + // 测试 no 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setNo("M200000"))); + // 测试 name 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setName("斌哥的杂货铺"))); + // 测试 shortName 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setShortName("斌斌子"))); + // 测试 status 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + // 测试 remark 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setRemark("斌哥的杂货铺"))); + // 测试 createTime 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setCreateTime(buildTime(2022,12,4)))); + // 准备参数 + PayMerchantPageReqVO reqVO = new PayMerchantPageReqVO(); + reqVO.setNo("M1008611"); + reqVO.setName("灿哥的杂货铺"); + reqVO.setShortName("灿灿子"); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setRemark("灿哥的杂货铺"); + reqVO.setBeginCreateTime(buildTime(2021,11,2)); + reqVO.setEndCreateTime(buildTime(2021,11,4)); + + // 调用 + PageResult<PayMerchantDO> pageResult = merchantService.getMerchantPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbMerchant, pageResult.getList().get(0)); + } + + @Test + public void testGetMerchantList() { + // mock 数据 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到 + o.setNo("M1008611"); + o.setName("灿哥的杂货铺"); + o.setShortName("灿灿子"); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setRemark("灿哥的杂货铺"); + o.setCreateTime(buildTime(2021,11,3)); + }); + merchantMapper.insert(dbMerchant); + // 测试 no 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setNo("M200000"))); + // 测试 name 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setName("斌哥的杂货铺"))); + // 测试 shortName 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setShortName("斌斌子"))); + // 测试 status 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + // 测试 remark 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setRemark("斌哥的杂货铺"))); + // 测试 createTime 不匹配 + merchantMapper.insert(ObjectUtils.clone(dbMerchant, o -> o.setCreateTime(buildTime(2022,12,4)))); + // 准备参数 + PayMerchantExportReqVO reqVO = new PayMerchantExportReqVO(); + reqVO.setNo("M1008611"); + reqVO.setName("灿哥的杂货铺"); + reqVO.setShortName("灿灿子"); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setRemark("灿哥的杂货铺"); + reqVO.setBeginCreateTime(buildTime(2021,11,2)); + reqVO.setEndCreateTime(buildTime(2021,11,4)); + + // 调用 + List<PayMerchantDO> list = merchantService.getMerchantList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbMerchant, list.get(0)); + } + +} diff --git a/yudao-admin-server/src/test/resources/sql/clean.sql b/yudao-admin-server/src/test/resources/sql/clean.sql index 75080b343..e4edd4deb 100644 --- a/yudao-admin-server/src/test/resources/sql/clean.sql +++ b/yudao-admin-server/src/test/resources/sql/clean.sql @@ -24,3 +24,6 @@ DELETE FROM "sys_sms_template"; DELETE FROM "sys_sms_log"; DELETE FROM "sys_error_code"; DELETE FROM "sys_social_user"; + +-- pay 开头的 DB +DELETE FROM pay_merchant; diff --git a/yudao-admin-server/src/test/resources/sql/create_tables.sql b/yudao-admin-server/src/test/resources/sql/create_tables.sql index db67cad23..6c6500386 100644 --- a/yudao-admin-server/src/test/resources/sql/create_tables.sql +++ b/yudao-admin-server/src/test/resources/sql/create_tables.sql @@ -449,3 +449,18 @@ CREATE TABLE IF NOT EXISTS "sys_social_user" ( "deleted" bit NOT NULL DEFAULT FALSE, PRIMARY KEY ("id") ) COMMENT '社交用户'; + +CREATE TABLE IF NOT EXISTS "pay_merchant" ( + "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "no" varchar(32) NOT NULL, + "name" varchar(64) NOT NULL, + "short_name" varchar(64) NOT NULL, + "status" tinyint NOT NULL, + "remark" varchar(255) DEFAULT NULL, + "creator" varchar(64) DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP , + "updater" varchar(64) DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit(1) NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '支付商户信息'; diff --git a/yudao-admin-ui/src/api/pay/merchant.js b/yudao-admin-ui/src/api/pay/merchant.js new file mode 100644 index 000000000..5dc6e96ee --- /dev/null +++ b/yudao-admin-ui/src/api/pay/merchant.js @@ -0,0 +1,67 @@ +import request from '@/utils/request' + +// 创建支付商户信息 +export function createMerchant(data) { + return request({ + url: '/pay/merchant/create', + method: 'post', + data: data + }) +} + +// 更新支付商户信息 +export function updateMerchant(data) { + return request({ + url: '/pay/merchant/update', + method: 'put', + data: data + }) +} + +// 支付商户状态修改 +export function changeMerchantStatus(id, status) { + const data = { + id, + status + } + return request({ + url: '/pay/merchant/update-status', + method: 'put', + data: data + }) +} + +// 删除支付商户信息 +export function deleteMerchant(id) { + return request({ + url: '/pay/merchant/delete?id=' + id, + method: 'delete' + }) +} + +// 获得支付商户信息 +export function getMerchant(id) { + return request({ + url: '/pay/merchant/get?id=' + id, + method: 'get' + }) +} + +// 获得支付商户信息分页 +export function getMerchantPage(query) { + return request({ + url: '/pay/merchant/page', + method: 'get', + params: query + }) +} + +// 导出支付商户信息 Excel +export function exportMerchantExcel(query) { + return request({ + url: '/pay/merchant/export-excel', + method: 'get', + params: query, + responseType: 'blob' + }) +} diff --git a/yudao-admin-ui/src/assets/icons/svg/merchant.svg b/yudao-admin-ui/src/assets/icons/svg/merchant.svg new file mode 100644 index 000000000..f1ecb8127 --- /dev/null +++ b/yudao-admin-ui/src/assets/icons/svg/merchant.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1635907181185" class="icon" viewBox="0 0 1184 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3259" xmlns:xlink="http://www.w3.org/1999/xlink" width="231.25" height="200"><defs><style type="text/css">@font-face { font-family: element-icons; src: url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.woff") format("woff"), url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.ttf ") format("truetype"); } +</style></defs><path d="M1005.633722 616.006249c-5.311502-0.479955-10.431022-1.27988-15.518545-2.143799-1.087898-0.127988-2.271787-0.287973-3.359685-0.479955-2.399775-0.415961-4.671562-1.055901-7.007343-1.631847-9.951067-2.143799-19.678155-4.831547-28.989282-8.351217l0 133.235509-731.355435 0 0-133.235509c-9.375121 3.551667-19.006218 6.303409-29.053276 8.511202-2.335781 0.415961-4.607568 1.055901-6.943349 1.535856-1.087898 0.191982-2.175796 0.31997-3.359685 0.511952-5.11952 0.767928-10.271037 1.535856-15.518545 2.079805-5.983439 0.479955-12.094866 0.863919-18.270287 0.863919-12.47883 0-24.701684-1.215886-36.540574-3.327688l0 357.310502c0 29.309252 24.573696 53.11502 54.874855 53.11502l841.073149 0c30.237165 0 54.810861-23.773771 54.810861-53.11502l0-357.342499c-11.83889 2.143799-24.061744 3.327688-36.540574 3.327688-6.07943 0-12.254851-0.351967-18.23829-0.863919z" p-id="3260"></path><path d="M182.83086 109.749711l804.500578 0c30.301159 0 54.874855-24.573696 54.874855-54.874855s-24.573696-54.874855-54.874855-54.874855l-804.500578 0c-30.301159 0-54.874855 24.573696-54.874855 54.874855 0.031997 30.301159 24.605693 54.874855 54.874855 54.874855z" p-id="3261"></path><path d="M1067.387932 164.592569l-964.549573 0-102.838359 256.007999c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288l-102.806362-256.007999z" p-id="3262"></path></svg> \ No newline at end of file diff --git a/yudao-admin-ui/src/assets/icons/svg/pay.svg b/yudao-admin-ui/src/assets/icons/svg/pay.svg new file mode 100644 index 000000000..ddab05def --- /dev/null +++ b/yudao-admin-ui/src/assets/icons/svg/pay.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1635906769564" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2420" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: element-icons; src: url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.woff") format("woff"), url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.ttf ") format("truetype"); } +</style></defs><path d="M512 0C230.4 0 0 230.4 0 512s230.4 512 512 512 512-230.4 512-512S793.6 0 512 0z m0 921.6c-225.28 0-409.6-184.32-409.6-409.6s184.32-409.6 409.6-409.6 409.6 184.32 409.6 409.6-184.32 409.6-409.6 409.6z" p-id="2421"></path><path d="M665.6 537.6h-102.4v-51.2h102.4c25.6 0 51.2-25.6 51.2-51.2s-25.6-51.2-51.2-51.2h-30.72l20.48-20.48c20.48-20.48 20.48-51.2 0-71.68s-51.2-20.48-71.68 0L512 363.52 440.32 296.96c-20.48-20.48-51.2-20.48-71.68 0s-20.48 51.2 0 71.68l20.48 20.48H358.4c-25.6 0-51.2 25.6-51.2 51.2s25.6 51.2 51.2 51.2h102.4v51.2H358.4c-25.6 0-51.2 25.6-51.2 51.2s25.6 51.2 51.2 51.2h102.4v56.32c0 25.6 20.48 46.08 46.08 46.08h10.24c25.6 0 46.08-20.48 46.08-46.08v-56.32h102.4c25.6 0 51.2-25.6 51.2-51.2s-25.6-56.32-51.2-56.32z" p-id="2422"></path></svg> \ No newline at end of file diff --git a/yudao-admin-ui/src/utils/dict.js b/yudao-admin-ui/src/utils/dict.js index ca1150a59..7c17cceb8 100644 --- a/yudao-admin-ui/src/utils/dict.js +++ b/yudao-admin-ui/src/utils/dict.js @@ -30,6 +30,9 @@ export const DICT_TYPE = { INF_API_ERROR_LOG_PROCESS_STATUS: 'inf_api_error_log_process_status', TOOL_CODEGEN_TEMPLATE_TYPE: 'tool_codegen_template_type', + + // 商户状态 + PAY_MERCHANT_STATUS: 'pay_merchant_status' } /** diff --git a/yudao-admin-ui/src/views/pay/merchant/index.vue b/yudao-admin-ui/src/views/pay/merchant/index.vue new file mode 100644 index 000000000..f57b59f96 --- /dev/null +++ b/yudao-admin-ui/src/views/pay/merchant/index.vue @@ -0,0 +1,295 @@ +<template> + <div class="app-container"> + + <!-- 搜索工作栏 --> + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> + <el-form-item label="商户号" prop="no"> + <el-input v-model="queryParams.no" placeholder="请输入商户号" clearable size="small" @keyup.enter.native="handleQuery"/> + </el-form-item> + <el-form-item label="商户全称" prop="name"> + <el-input v-model="queryParams.name" placeholder="请输入商户全称" clearable size="small" @keyup.enter.native="handleQuery"/> + </el-form-item> + <el-form-item label="商户简称" prop="shortName"> + <el-input v-model="queryParams.shortName" placeholder="请输入商户简称" clearable size="small" @keyup.enter.native="handleQuery"/> + </el-form-item> + <el-form-item label="开启状态" prop="status"> + <el-select v-model="queryParams.status" placeholder="请选择开启状态" clearable size="small"> + <el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/> + </el-select> + </el-form-item> + <el-form-item label="备注" prop="remark"> + <el-input v-model="queryParams.remark" placeholder="请输入备注" clearable size="small" @keyup.enter.native="handleQuery"/> + </el-form-item> + <el-form-item label="创建时间"> + <el-date-picker v-model="dateRangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd" + type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" /> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> + </el-form-item> + </el-form> + + <!-- 操作工具栏 --> + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" + v-hasPermi="['pay:merchant:create']">新增</el-button> + </el-col> + <el-col :span="1.5"> + <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" + v-hasPermi="['pay:merchant:export']">导出</el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <!-- 列表 --> + <el-table v-loading="loading" :data="list"> + <el-table-column label="商户编号" align="center" prop="id" /> + <el-table-column label="商户号" align="center" prop="no" /> + <el-table-column label="商户全称" align="center" prop="name" /> + <el-table-column label="商户简称" align="center" prop="shortName" /> + <el-table-column label="开启状态" align="center" prop="status" > + <template slot-scope="scope"> + <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1" @change="handleStatusChange(scope.row)" /> + </template> + </el-table-column> + <el-table-column label="备注" align="center" prop="remark" /> + <el-table-column label="创建时间" align="center" prop="createTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" + v-hasPermi="['pay:merchant:update']">修改</el-button> + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" + v-hasPermi="['pay:merchant:delete']">删除</el-button> + </template> + </el-table-column> + </el-table> + <!-- 分页组件 --> + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" + @pagination="getList"/> + + <!-- 对话框(添加 / 修改) --> + <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> +<!-- <el-form-item label="商户号" prop="no">--> +<!-- <el-input v-model="form.no" placeholder="请输入商户号" />--> +<!-- </el-form-item>--> + <el-form-item label="商户全称" prop="name"> + <el-input v-model="form.name" placeholder="请输入商户全称" /> + </el-form-item> + <el-form-item label="商户简称" prop="shortName"> + <el-input v-model="form.shortName" placeholder="请输入商户简称" /> + </el-form-item> + <el-form-item label="开启状态" prop="status"> + <el-radio-group v-model="form.status"> + <el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)"> + {{dict.label}}</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="备注" prop="remark"> + <el-input v-model="form.remark" placeholder="请输入备注" /> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">确 定</el-button> + <el-button @click="cancel">取 消</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { + createMerchant, + updateMerchant, + changeMerchantStatus, + deleteMerchant, + getMerchant, + getMerchantPage, + exportMerchantExcel +} from "@/api/pay/merchant"; +import {DICT_TYPE, getDictDatas} from "@/utils/dict"; +import {SysCommonStatusEnum} from "@/utils/constants"; + +export default { + name: "Merchant", + components: { + }, + data() { + return { + // 遮罩层 + loading: true, + // 显示搜索条件 + showSearch: true, + // 总条数 + total: 0, + // 支付商户信息列表 + list: [], + // 弹出层标题 + title: "", + // 是否显示弹出层 + open: false, + dateRangeCreateTime: [], + // 查询参数 + queryParams: { + pageNo: 1, + pageSize: 10, + no: null, + name: null, + shortName: null, + status: null, + remark: null, + }, + // 表单参数 + form: {}, + // 表单校验 + rules: { + no: [{ required: true, message: "商户号不能为空", trigger: "blur" }], + name: [{ required: true, message: "商户全称不能为空", trigger: "blur" }], + shortName: [{ required: true, message: "商户简称不能为空", trigger: "blur" }], + status: [{ required: true, message: "开启状态不能为空", trigger: "blur" }], + }, + // 数据字典 + statusDictDatas: getDictDatas(DICT_TYPE.PAY_MERCHANT_STATUS) + }; + }, + created() { + this.getList(); + }, + methods: { + /** 查询列表 */ + getList() { + this.loading = true; + // 处理查询参数 + let params = {...this.queryParams}; + this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime'); + // 执行查询 + getMerchantPage(params).then(response => { + this.list = response.data.list; + this.total = response.data.total; + this.loading = false; + }); + }, + /** 取消按钮 */ + cancel() { + this.open = false; + this.reset(); + }, + /** 表单重置 */ + reset() { + this.form = { + id: undefined, + no: undefined, + name: undefined, + shortName: undefined, + status: undefined, + remark: undefined, + }; + this.resetForm("form"); + }, + /** 搜索按钮操作 */ + handleQuery() { + this.queryParams.pageNo = 1; + this.getList(); + }, + /** 重置按钮操作 */ + resetQuery() { + this.dateRangeCreateTime = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + /** 新增按钮操作 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "添加支付商户信息"; + }, + /** 修改按钮操作 */ + handleUpdate(row) { + this.reset(); + const id = row.id; + getMerchant(id).then(response => { + this.form = response.data; + this.open = true; + this.title = "修改支付商户信息"; + }); + }, + // 用户状态修改 + handleStatusChange(row) { + let text = row.status === SysCommonStatusEnum.ENABLE ? "启用" : "停用"; + this.$confirm('确认要"' + text + '""' + row.name + '"商户吗?', "警告", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(function() { + return changeMerchantStatus(row.id, row.status); + }).then(() => { + this.msgSuccess(text + "成功"); + }).catch(function() { + row.status = row.status === SysCommonStatusEnum.ENABLE ? SysCommonStatusEnum.DISABLE + : SysCommonStatusEnum.ENABLE; + }); + }, + /** 提交按钮 */ + submitForm() { + this.$refs["form"].validate(valid => { + if (!valid) { + return; + } + // 修改的提交 + if (this.form.id != null) { + updateMerchant(this.form).then(response => { + this.msgSuccess("修改成功"); + this.open = false; + this.getList(); + }); + return; + } + // 添加的提交 + createMerchant(this.form).then(response => { + this.msgSuccess("新增成功"); + this.open = false; + this.getList(); + }); + }); + }, + /** 删除按钮操作 */ + handleDelete(row) { + const id = row.id; + this.$confirm('是否确认删除支付商户信息编号为"' + id + '"的数据项?', "警告", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(function() { + return deleteMerchant(id); + }).then(() => { + this.getList(); + this.msgSuccess("删除成功"); + }) + }, + /** 导出按钮操作 */ + handleExport() { + // 处理查询参数 + let params = {...this.queryParams}; + params.pageNo = undefined; + params.pageSize = undefined; + this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime'); + // 执行导出 + this.$confirm('是否确认导出所有支付商户信息数据项?', "警告", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(function() { + return exportMerchantExcel(params); + }).then(response => { + this.downloadExcel(response, '支付商户信息.xls'); + }) + } + } +}; +</script> diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java index d2b20111a..b8edba7e8 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; @@ -29,7 +31,9 @@ public class PayMerchantDO extends BaseDO { /** * 商户号 * 例如说,M233666999 + * 只有新增时插入,不允许修改 */ + @TableField(fill = FieldFill.INSERT) private String no; /** * 商户全称 diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java index d2b940223..a4c88d8c0 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java @@ -28,4 +28,8 @@ public interface PayErrorCodeCoreConstants { ErrorCode PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING = new ErrorCode(1007003001, "支付交易拓展单不处于待支付"); ErrorCode PAY_ORDER_EXTENSION_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007003002, "支付订单不处于已支付"); + /** + * ========== 支付商户信息 1-007-004-000 ========== + */ + ErrorCode MERCHANT_NOT_EXISTS = new ErrorCode(1007004000, "支付商户信息不存在"); }