feat(merchant): 新增门店信息管理(建表/状态枚举/双Controller/i18n)

This commit is contained in:
DaxPay Dev
2026-06-25 10:47:15 +08:00
parent e0124221da
commit df2e2dceac
18 changed files with 710 additions and 4 deletions

View File

@@ -99,3 +99,57 @@ COMMENT ON COLUMN notify_message.version IS '版本号(乐观锁)';
COMMENT ON COLUMN notify_message.deleted IS '逻辑删除标志';
CREATE INDEX IF NOT EXISTS idx_notify_message_user ON notify_message (user_id, deleted, is_read);
-- ===================================
-- 商户门店(商户物理经营场所)
-- ===================================
CREATE TABLE IF NOT EXISTS mch_store_info (
id bigint NOT NULL,
mch_no varchar(32) NOT NULL,
store_no varchar(32) NOT NULL,
store_name varchar(128) NOT NULL,
contact_phone varchar(32),
logo_url varchar(512),
facade_url varchar(512),
interior_url varchar(512),
region_code varchar(12),
address varchar(256),
longitude numeric(10,7),
latitude numeric(10,7),
status varchar(16) NOT NULL DEFAULT 'enable',
remark varchar(512),
creator bigint,
create_time timestamptz(6),
last_modifier bigint,
last_modified_time timestamptz(6),
version int NOT NULL DEFAULT 0,
deleted boolean NOT NULL DEFAULT false,
CONSTRAINT mch_store_info_pkey PRIMARY KEY (id)
);
COMMENT ON TABLE mch_store_info IS '商户门店(商户物理经营场所)';
COMMENT ON COLUMN mch_store_info.id IS '主键';
COMMENT ON COLUMN mch_store_info.mch_no IS '商户号';
COMMENT ON COLUMN mch_store_info.store_no IS '门店号(系统生成, 唯一)';
COMMENT ON COLUMN mch_store_info.store_name IS '门店名称';
COMMENT ON COLUMN mch_store_info.contact_phone IS '联系人电话';
COMMENT ON COLUMN mch_store_info.logo_url IS '门店LOGO';
COMMENT ON COLUMN mch_store_info.facade_url IS '门头照';
COMMENT ON COLUMN mch_store_info.interior_url IS '门店内景照';
COMMENT ON COLUMN mch_store_info.region_code IS '行政区划代码(区县级)';
COMMENT ON COLUMN mch_store_info.address IS '详细地址';
COMMENT ON COLUMN mch_store_info.longitude IS '经度';
COMMENT ON COLUMN mch_store_info.latitude IS '纬度';
COMMENT ON COLUMN mch_store_info.status IS '状态(enable启用/disabled停用)';
COMMENT ON COLUMN mch_store_info.remark IS '备注';
COMMENT ON COLUMN mch_store_info.creator IS '创建人ID';
COMMENT ON COLUMN mch_store_info.create_time IS '创建时间';
COMMENT ON COLUMN mch_store_info.last_modifier IS '最后修改人ID';
COMMENT ON COLUMN mch_store_info.last_modified_time IS '最后修改时间';
COMMENT ON COLUMN mch_store_info.version IS '版本号(乐观锁)';
COMMENT ON COLUMN mch_store_info.deleted IS '逻辑删除标志';
-- 门店号唯一索引
CREATE UNIQUE INDEX IF NOT EXISTS uk_mch_store_info_store_no ON mch_store_info (store_no);
-- 商户号查询索引
CREATE INDEX IF NOT EXISTS idx_mch_store_info_mch_no ON mch_store_info (mch_no, deleted);

View File

@@ -0,0 +1,70 @@
package cn.daxpay.open.payment.admin.controller.merchant.store;
import cn.daxpay.open.payment.merchant.param.store.MchStoreInfoParam;
import cn.daxpay.open.payment.merchant.param.store.MchStoreInfoQuery;
import cn.daxpay.open.payment.merchant.result.store.MchStoreInfoResult;
import cn.daxpay.open.payment.merchant.service.store.MchStoreInfoService;
import cn.daxpay.open.platform.core.annotation.PermCode;
import cn.daxpay.open.platform.core.rest.Res;
import cn.daxpay.open.platform.core.rest.param.PageParam;
import cn.daxpay.open.platform.core.rest.result.PageResult;
import cn.daxpay.open.platform.core.rest.result.Result;
import cn.daxpay.open.platform.core.util.ValidationUtil;
import cn.daxpay.open.platform.core.validation.ValidationGroup;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/// 门店信息管理(管理端)
@PermCode(menuCode = "payment:merchant:store")
@Validated
@Tag(name = "门店信息管理(管理端)")
@RestController
@RequestMapping("/admin/mch/store")
@RequiredArgsConstructor
public class MchStoreInfoAdminController {
private final MchStoreInfoService mchStoreInfoService;
@PermCode(code = "add", nameCn = "门店新增", nameEn = "Store Add")
@Operation(summary = "新增门店")
@PostMapping("/add")
public Result<Void> add(@RequestBody @Validated(ValidationGroup.add.class) MchStoreInfoParam param) {
ValidationUtil.validateParam(param, ValidationGroup.add.class);
mchStoreInfoService.add(param);
return Res.ok();
}
@PermCode(code = "edit", nameCn = "门店编辑", nameEn = "Store Edit")
@Operation(summary = "修改门店")
@PostMapping("/update")
public Result<Void> update(@RequestBody @Validated(ValidationGroup.edit.class) MchStoreInfoParam param) {
ValidationUtil.validateParam(param, ValidationGroup.edit.class);
mchStoreInfoService.update(param);
return Res.ok();
}
@PermCode(code = "view", nameCn = "门店查看", nameEn = "Store View")
@Operation(summary = "门店分页")
@GetMapping("/page")
public Result<PageResult<MchStoreInfoResult>> page(PageParam pageParam, MchStoreInfoQuery query) {
return Res.ok(mchStoreInfoService.page(pageParam, query));
}
@PermCode(code = "view", nameCn = "门店查看", nameEn = "Store View")
@Operation(summary = "根据id查询门店")
@GetMapping("/get")
public Result<MchStoreInfoResult> findById(@NotNull(message = "{validation.field.id.notNull}") Long id) {
return Res.ok(mchStoreInfoService.findById(id));
}
@PermCode(code = "delete", nameCn = "门店删除", nameEn = "Store Delete")
@Operation(summary = "删除门店")
@PostMapping("/delete")
public Result<Void> delete(@NotNull(message = "{validation.field.id.notNull}") Long id) {
mchStoreInfoService.delete(id);
return Res.ok();
}
}

View File

@@ -0,0 +1,69 @@
package cn.daxpay.open.payment.merchant.controller.store;
import cn.daxpay.open.payment.merchant.param.store.MchStoreInfoParam;
import cn.daxpay.open.payment.merchant.param.store.MchStoreInfoQuery;
import cn.daxpay.open.payment.merchant.result.store.MchStoreInfoResult;
import cn.daxpay.open.payment.merchant.service.store.MchStoreInfoService;
import cn.daxpay.open.platform.core.rest.Res;
import cn.daxpay.open.platform.core.rest.param.PageParam;
import cn.daxpay.open.platform.core.rest.result.PageResult;
import cn.daxpay.open.platform.core.rest.result.Result;
import cn.daxpay.open.platform.core.validation.ValidationGroup;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/// # 门店信息管理
///
@Validated
@Tag(name = "门店信息管理")
@RestController
@RequestMapping("/mch/store")
@RequiredArgsConstructor
public class MchStoreInfoController {
private final MchStoreInfoService mchStoreInfoService;
@Operation(summary = "新增门店")
@PostMapping("/add")
public Result<Void> add(@RequestBody @Validated(ValidationGroup.add.class) MchStoreInfoParam param) {
mchStoreInfoService.add(param);
return Res.ok();
}
@Operation(summary = "修改门店")
@PostMapping("/update")
public Result<Void> update(@RequestBody @Validated(ValidationGroup.edit.class) MchStoreInfoParam param) {
mchStoreInfoService.update(param);
return Res.ok();
}
@Operation(summary = "门店分页")
@GetMapping("/page")
public Result<PageResult<MchStoreInfoResult>> page(PageParam pageParam, MchStoreInfoQuery query) {
return Res.ok(mchStoreInfoService.page(pageParam, query));
}
@Operation(summary = "门店列表")
@GetMapping("/list")
public Result<List<MchStoreInfoResult>> list() {
return Res.ok(mchStoreInfoService.list());
}
@Operation(summary = "根据id查询门店")
@GetMapping("/get")
public Result<MchStoreInfoResult> findById(@NotNull(message = "{validation.field.id.notNull}") Long id) {
return Res.ok(mchStoreInfoService.findById(id));
}
@Operation(summary = "删除门店")
@PostMapping("/delete")
public Result<Void> delete(@NotNull(message = "{validation.field.id.notNull}") Long id) {
mchStoreInfoService.delete(id);
return Res.ok();
}
}

View File

@@ -0,0 +1,24 @@
package cn.daxpay.open.payment.merchant.convert.store;
import cn.daxpay.open.payment.merchant.entity.store.MchStoreInfo;
import cn.daxpay.open.payment.merchant.param.store.MchStoreInfoParam;
import cn.daxpay.open.payment.merchant.result.store.MchStoreInfoResult;
import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.NullValuePropertyMappingStrategy;
import org.mapstruct.factory.Mappers;
/// # 门店信息转换
///
@Mapper
public interface MchStoreInfoConvert {
MchStoreInfoConvert CONVERT = Mappers.getMapper(MchStoreInfoConvert.class);
MchStoreInfoResult toResult(MchStoreInfo entity);
MchStoreInfo toEntity(MchStoreInfoParam param);
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void copy(MchStoreInfoParam param, @MappingTarget MchStoreInfo mchStore);
}

View File

@@ -0,0 +1,46 @@
package cn.daxpay.open.payment.merchant.dao.store;
import cn.daxpay.open.payment.merchant.entity.store.MchStoreInfo;
import cn.daxpay.open.payment.merchant.param.store.MchStoreInfoQuery;
import cn.daxpay.open.platform.common.mybatisplus.impl.BaseManager;
import cn.daxpay.open.platform.common.mybatisplus.query.generator.QueryGenerator;
import cn.daxpay.open.platform.common.mybatisplus.util.MpUtil;
import cn.daxpay.open.platform.core.rest.param.PageParam;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
/// # 门店信息管理
///
@Slf4j
@Repository
@RequiredArgsConstructor
public class MchStoreInfoManager extends BaseManager<MchStoreInfoMapper, MchStoreInfo> {
/// 根据门店号查询
public Optional<MchStoreInfo> findByStoreNo(String storeNo) {
return this.findByField(MchStoreInfo::getStoreNo, storeNo);
}
/// 判断门店号是否存在
public boolean existsByStoreNo(String storeNo) {
return existedByField(MchStoreInfo::getStoreNo, storeNo);
}
/// 分页
public Page<MchStoreInfo> page(PageParam pageParam, MchStoreInfoQuery query) {
Page<MchStoreInfo> mpPage = MpUtil.getMpPage(pageParam);
QueryWrapper<MchStoreInfo> wrapper = QueryGenerator.generator(query);
return this.page(mpPage, wrapper);
}
/// 根据商户号查询所有门店
public List<MchStoreInfo> findAllByMchNo(String mchNo) {
return this.findAllByField(MchStoreInfo::getMchNo, mchNo);
}
}

View File

@@ -0,0 +1,11 @@
package cn.daxpay.open.payment.merchant.dao.store;
import cn.daxpay.open.payment.merchant.entity.store.MchStoreInfo;
import com.github.yulichang.base.MPJBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/// # 门店信息
///
@Mapper
public interface MchStoreInfoMapper extends MPJBaseMapper<MchStoreInfo> {
}

View File

@@ -0,0 +1,69 @@
package cn.daxpay.open.payment.merchant.entity.store;
import cn.daxpay.open.payment.common.entity.merchant.MchBaseEntity;
import cn.daxpay.open.payment.merchant.convert.store.MchStoreInfoConvert;
import cn.daxpay.open.payment.merchant.result.store.MchStoreInfoResult;
import cn.daxpay.open.platform.common.mybatisplus.function.ToResult;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import lombok.experimental.FieldNameConstants;
import java.math.BigDecimal;
/// # 门店信息
///
@EqualsAndHashCode(callSuper = true)
@Data
@FieldNameConstants
@Accessors(chain = true)
@TableName("mch_store_info")
public class MchStoreInfo extends MchBaseEntity implements ToResult<MchStoreInfoResult> {
/// 门店号
@TableField(updateStrategy = FieldStrategy.NEVER, fill = FieldFill.INSERT)
private String storeNo;
/// 门店名称
private String storeName;
/// 联系人电话
private String contactPhone;
/// 门店LOGO
private String logoUrl;
/// 门头照
private String facadeUrl;
/// 门店内景照
private String interiorUrl;
/// 行政区划代码
private String regionCode;
/// 详细地址
private String address;
/// 经度
private BigDecimal longitude;
/// 纬度
private BigDecimal latitude;
/// 状态
/// @see cn.daxpay.open.platform.core.enums.merchant.StoreStatusEnum
private String status;
/// 备注
private String remark;
@Override
public MchStoreInfoResult toResult() {
return MchStoreInfoConvert.CONVERT.toResult(this);
}
}

View File

@@ -0,0 +1,74 @@
package cn.daxpay.open.payment.merchant.param.store;
import cn.daxpay.open.platform.core.validation.ValidationGroup;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/// # 门店信息
///
@Data
@Accessors(chain = true)
@Schema(title = "门店信息")
public class MchStoreInfoParam {
/// 主键
@Schema(description = "主键")
@NotNull(message = "{validation.field.id.notNull}", groups = ValidationGroup.edit.class)
private Long id;
/// 商户号
@Schema(description = "商户号")
private String mchNo;
/// 门店名称
@Schema(description = "门店名称")
@NotBlank(message = "{validation.field.storeName.notBlank}")
private String storeName;
/// 联系人电话
@Schema(description = "联系人电话")
private String contactPhone;
/// 门店LOGO
@Schema(description = "门店LOGO")
private String logoUrl;
/// 门头照
@Schema(description = "门头照")
private String facadeUrl;
/// 门店内景照
@Schema(description = "门店内景照")
private String interiorUrl;
/// 行政区划代码
@Schema(description = "行政区划代码")
private String regionCode;
/// 详细地址
@Schema(description = "详细地址")
private String address;
/// 经度
@Schema(description = "经度")
private BigDecimal longitude;
/// 纬度
@Schema(description = "纬度")
private BigDecimal latitude;
/// 状态
/// @see cn.daxpay.open.platform.core.enums.merchant.StoreStatusEnum
@Schema(description = "状态")
@NotBlank(message = "{validation.field.status.notBlank}")
private String status;
/// 备注
@Schema(description = "备注")
private String remark;
}

View File

@@ -0,0 +1,38 @@
package cn.daxpay.open.payment.merchant.param.store;
import cn.daxpay.open.platform.core.annotation.QueryParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
/// # 门店查询参数
///
@Data
@QueryParam(type = QueryParam.CompareTypeEnum.LIKE)
@Accessors(chain = true)
@Schema(title = "门店查询参数")
public class MchStoreInfoQuery {
/// 商户号
@Schema(description = "商户号")
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
private String mchNo;
/// 门店号
@Schema(description = "门店号")
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
private String storeNo;
/// 门店名称
@Schema(description = "门店名称")
private String storeName;
/// 联系人电话
@Schema(description = "联系人电话")
private String contactPhone;
/// 状态
@Schema(description = "状态")
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
private String status;
}

View File

@@ -0,0 +1,59 @@
package cn.daxpay.open.payment.merchant.result.store;
import cn.daxpay.open.platform.core.result.BaseResult;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import lombok.experimental.FieldNameConstants;
import java.math.BigDecimal;
/// # 门店信息
///
@EqualsAndHashCode(callSuper = true)
@Data
@FieldNameConstants
@Accessors(chain = true)
@Schema(title = "门店信息")
public class MchStoreInfoResult extends BaseResult {
@Schema(description = "商户号")
private String mchNo;
@Schema(description = "门店号")
private String storeNo;
@Schema(description = "门店名称")
private String storeName;
@Schema(description = "联系人电话")
private String contactPhone;
@Schema(description = "门店LOGO")
private String logoUrl;
@Schema(description = "门头照")
private String facadeUrl;
@Schema(description = "门店内景照")
private String interiorUrl;
@Schema(description = "行政区划代码")
private String regionCode;
@Schema(description = "详细地址")
private String address;
@Schema(description = "经度")
private BigDecimal longitude;
@Schema(description = "纬度")
private BigDecimal latitude;
@Schema(description = "状态")
private String status;
@Schema(description = "备注")
private String remark;
}

View File

@@ -0,0 +1,136 @@
package cn.daxpay.open.payment.merchant.service.store;
import cn.daxpay.open.payment.common.context.PaymentContext;
import cn.daxpay.open.payment.merchant.convert.store.MchStoreInfoConvert;
import cn.daxpay.open.payment.merchant.dao.info.MerchantInfoManager;
import cn.daxpay.open.payment.merchant.dao.store.MchStoreInfoManager;
import cn.daxpay.open.payment.merchant.entity.info.MerchantInfo;
import cn.daxpay.open.payment.merchant.entity.store.MchStoreInfo;
import cn.daxpay.open.payment.merchant.param.store.MchStoreInfoParam;
import cn.daxpay.open.payment.merchant.param.store.MchStoreInfoQuery;
import cn.daxpay.open.payment.merchant.result.store.MchStoreInfoResult;
import cn.daxpay.open.platform.common.mybatisplus.util.MpUtil;
import cn.daxpay.open.platform.core.code.CommonCode;
import cn.daxpay.open.platform.core.enums.client.ClientEnum;
import cn.daxpay.open.platform.core.exception.BizException;
import cn.daxpay.open.platform.core.exception.BizInfoException;
import cn.daxpay.open.platform.core.exception.DataNotExistException;
import cn.daxpay.open.platform.core.exception.config.ConfigErrorException;
import cn.daxpay.open.platform.core.rest.param.PageParam;
import cn.daxpay.open.platform.core.rest.result.PageResult;
import cn.daxpay.open.platform.iam.service.client.ClientCodeService;
import cn.hutool.core.util.RandomUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/// # 门店信息管理
///
@Slf4j
@Service
@RequiredArgsConstructor
public class MchStoreInfoService {
private final MchStoreInfoManager mchStoreInfoManager;
private final MerchantInfoManager merchantInfoManager;
private final ClientCodeService clientCodeService;
private final PaymentContext apiContext;
/// 新增门店
public void add(MchStoreInfoParam param) {
String mchNo = this.resolveMchNo(param.getMchNo());
MerchantInfo merchant = merchantInfoManager.findByMchNo(mchNo)
// 商户: 商户不存在
.orElseThrow(() -> new BizException(CommonCode.FAIL_CODE, "error.payment.merchant.mchNotExist"));
param.setMchNo(mchNo);
MchStoreInfo entity = MchStoreInfoConvert.CONVERT.toEntity(param);
// 生成门店号
entity.setStoreNo(this.generateStoreNo());
entity.setMchNo(mchNo);
mchStoreInfoManager.save(entity);
}
/// 修改门店
@Transactional(rollbackFor = Exception.class)
public void update(MchStoreInfoParam param) {
MchStoreInfo mchStore = mchStoreInfoManager.findById(param.getId())
// 商户: 门店不存在
.orElseThrow(() -> new DataNotExistException("error.payment.merchant.storeNotFound"));
this.checkStore(mchStore);
MchStoreInfoConvert.CONVERT.copy(param, mchStore);
mchStoreInfoManager.updateById(mchStore);
}
/// 分页
public PageResult<MchStoreInfoResult> page(PageParam pageParam, MchStoreInfoQuery query) {
return MpUtil.toPageResult(mchStoreInfoManager.page(pageParam, query));
}
/// 根据id查询
public MchStoreInfoResult findById(Long id) {
MchStoreInfo mchStore = mchStoreInfoManager.findById(id)
// 商户: 门店不存在
.orElseThrow(() -> new DataNotExistException("error.payment.merchant.storeNotFound"));
this.checkStore(mchStore);
return mchStore.toResult();
}
/// 门店列表(商户端按当前商户过滤)
public List<MchStoreInfoResult> list() {
String mchNo = this.resolveMchNo(null);
return mchStoreInfoManager.findAllByMchNo(mchNo).stream()
.map(MchStoreInfo::toResult)
.collect(Collectors.toList());
}
/// 删除
public void delete(Long id) {
MchStoreInfo mchStore = mchStoreInfoManager.findById(id)
// 商户: 门店不存在
.orElseThrow(() -> new DataNotExistException("error.payment.merchant.storeNotFound"));
this.checkStore(mchStore);
mchStoreInfoManager.deleteById(id);
}
/// 生成门店号
public String generateStoreNo() {
String storeNo = "S" + RandomUtil.randomNumbers(16);
for (int i = 0; i < 10; i++) {
if (!mchStoreInfoManager.existsByStoreNo(storeNo)) {
return storeNo;
}
storeNo = "S" + RandomUtil.randomNumbers(16);
}
// 商户: 门店号生成失败
throw new BizException(CommonCode.FAIL_CODE, "error.payment.merchant.storeNoGenFailed");
}
/// 解析商户号, 商户端从上下文获取, 管理端从参数获取
private String resolveMchNo(String paramMchNo) {
if (clientCodeService.getClientCode().equals(ClientEnum.MERCHANT.getCode())) {
return apiContext.getTradeInfo().getMchNo();
}
if (paramMchNo == null) {
// 商户: 数据错误,未发现商户号
throw new BizInfoException(CommonCode.FAIL_CODE, "error.payment.merchant.dataErrorNoMchNo");
}
return paramMchNo;
}
/// 如果和当前商户不匹配, 抛出错误(商户端校验)
public void checkStore(MchStoreInfo mchStore) {
if (clientCodeService.getClientCode().equals(ClientEnum.MERCHANT.getCode())) {
if (!mchStore.getMchNo().equals(apiContext.getTradeInfo().getMchNo())) {
// 商户: 门店不属于当前商户
throw new ConfigErrorException("error.payment.merchant.storeNoMatch");
}
}
}
}

View File

@@ -0,0 +1,4 @@
{
"disabled": "Disabled",
"enable": "Enabled"
}

View File

@@ -27,5 +27,6 @@
"payRefundStatusNotExist": "Pay refund status not found: {0}",
"payCallTypeNotSupported": "Unsupported checkout type: {0}",
"channelAuthTypeNotExist": "Auth type not found: {0}",
"mchAppStatusNotFound": "Merchant app status not found: {0}"
"mchAppStatusNotFound": "Merchant app status not found: {0}",
"storeStatusNotFound": "Store status not found: {0}"
}

View File

@@ -18,5 +18,8 @@
"specifiedAppConfigNotFound": "Specified application configuration not found",
"specifiedMchConfigNotFound": "Specified merchant configuration not found",
"adminRoleNotExist": "Merchant admin role not found, please check",
"apiConfigNotExist": "Merchant API configuration not found"
"apiConfigNotExist": "Merchant API configuration not found",
"storeNotFound": "Store not found",
"storeNoGenFailed": "Store number generation failed",
"storeNoMatch": "Store does not belong to the current merchant"
}

View File

@@ -0,0 +1,4 @@
{
"disabled": "停用",
"enable": "启用"
}

View File

@@ -27,5 +27,6 @@
"payRefundStatusNotExist": "该退款状态不存在: {0}",
"payCallTypeNotSupported": "不支持的收银台类型: {0}",
"channelAuthTypeNotExist": "认证类型不存在: {0}",
"mchAppStatusNotFound": "未找到对应的商户应用状态类型: {0}"
"mchAppStatusNotFound": "未找到对应的商户应用状态类型: {0}",
"storeStatusNotFound": "未找到对应的门店状态类型: {0}"
}

View File

@@ -18,5 +18,8 @@
"specifiedAppConfigNotFound": "未找到指定的应用配置",
"specifiedMchConfigNotFound": "未找到指定的商户配置",
"adminRoleNotExist": "商户管理员角色不存在, 请检查",
"apiConfigNotExist": "商户API配置不存在"
"apiConfigNotExist": "商户API配置不存在",
"storeNotFound": "门店信息不存在",
"storeNoGenFailed": "门店号生成失败",
"storeNoMatch": "门店不属于当前商户"
}

View File

@@ -0,0 +1,40 @@
package cn.daxpay.open.platform.core.enums.merchant;
import cn.daxpay.open.platform.core.exception.config.ConfigNotExistException;
import cn.daxpay.open.platform.core.i18n.I18nSupport;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/// # 门店状态
///
/// 字典: store_status
@Getter
@RequiredArgsConstructor
public enum StoreStatusEnum implements I18nSupport {
/// 禁用
DISABLED("disabled"),
/// 启用
ENABLE("enable");
/// 编码
private final String code;
/// 翻译 key 前缀
@Override
public String getI18nPrefix() {
return "enum.store_status";
}
/// 根据编码查找
public static StoreStatusEnum findByCode(String code) {
return Arrays.stream(values())
.filter(e -> e.getCode().equals(code))
.findFirst()
// 通用: 未找到对应的门店状态类型: {0}
.orElseThrow(() -> new ConfigNotExistException("error.common.storeStatusNotFound", code));
}
}