付费会员配置 #71

Merged
root merged 2 commits from khy1 into master 2024-10-24 16:43:32 +08:00
17 changed files with 552 additions and 20 deletions

View File

@ -0,0 +1,21 @@
import request from '@/config/axios'
// 付费会员配置 VO
export interface PaidMemberConfigVO {
id: number // 编号
openPaidMember: boolean // 开启付费会员
paidMemberPrice: boolean // 商品付费会员价
}
// 付费会员配置 API
export const PaidMemberConfigApi = {
// 查询付费会员配置详情
getPaidMemberConfig: async () => {
return await request.get({ url: `/member/paid-member-config/get` })
},
// 保存付费会员配置
savePaidMemberConfig: async (data: PaidMemberConfigVO) => {
return await request.put({ url: `/member/paid-member-config/save`, data })
}
}

View File

@ -0,0 +1,114 @@
<template>
<doc-alert title="会员手册(功能开启)" url="https://doc.iocoder.cn/member/build/" />
<ContentWrap>
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="120px"
v-loading="formLoading"
>
<!-- <el-form-item label="hideId" v-show="false">-->
<!-- <el-input v-model="formData.id" />-->
<!-- </el-form-item>-->
<el-tabs>
<el-tab-pane label="付费会员配置">
<el-form-item label="开启付费会员" prop="openPaidMember">
<el-radio v-model="formData.openPaidMember" :label="true">开启</el-radio>
<el-radio v-model="formData.openPaidMember" :label="false">关闭</el-radio>
<el-text class="w-full" size="small" type="info">
付费会员开关
</el-text>
</el-form-item>
<el-form-item v-if="formData.openPaidMember === true" label="商品付费会员价" prop="paidMemberPrice">
<el-radio v-model="formData.paidMemberPrice" :label="true">开启</el-radio>
<el-radio v-model="formData.paidMemberPrice" :label="false">关闭</el-radio>
<el-text class="w-full" size="small" type="info">
商品付费会员价是否展示
</el-text>
</el-form-item>
</el-tab-pane>
</el-tabs>
<el-form-item>
<el-button type="primary" @click="onSubmit">提交</el-button>
</el-form-item>
</el-form>
</ContentWrap>
</template>
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import * as PadiMemberTypeVoApi from '@/api/member/memberconfig'
import PaidMemberConfigForm from './PaidMemberConfigForm.vue'
import * as ConfigApi from "@/api/member/config";
/** 付费会员配置 列表 */
defineOptions({ name: 'PaidMemberConfig' })
const message = useMessage() //
const { t } = useI18n() //
const loading = ref(true) //
const formLoading = ref(false) // 12
const formData = ref({
id: undefined,
openPaidMember: true,
paidMemberPrice: true
})
const formRules = reactive({})
const formRef = ref() // Ref
const onSubmit = async () => {
//
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
const data = formData.value as unknown as PadiMemberTypeVoApi.PaidMemberConfigVO
await PadiMemberTypeVoApi.PaidMemberConfigApi.savePaidMemberConfig(data)
message.success(t('common.updateSuccess'))
dialogVisible.value = false
} finally {
formLoading.value = false
}
}
/** 查询付费会员配置 */
const getPaidMemberConfig = async () =>{
try {
const data = await PadiMemberTypeVoApi.PaidMemberConfigApi.getPaidMemberConfig()
if(data == null){
return
}
formData.value = data
}finally {
}
}
// 使 watch openPaidMember
watch(
() => formData.value.openPaidMember,
(newVal) => {
if (!newVal) {
formData.value.paidMemberPrice = false; // openPaidMember false paidMemberPriceStatus
}
// newVal true v-if
},
{ immediate: true } //
);
/** 初始化 **/
onMounted(() => {
getPaidMemberConfig()
})
</script>

View File

@ -9,19 +9,19 @@
label-width="68px"
>
<el-form-item label="会员类型" prop="payMemberType">
<el-input
v-model="queryParams.payMemberType"
placeholder="请输入用户会员类型"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
<!-- <el-select v-model ="queryParams.payMemberType" placeholder="请选择会员类型">-->
<!-- <el-option v-for ="item in cardlist"-->
<!-- :key="item.id"-->
<!-- :label="item.name"-->
<!-- :value="item.name"></el-option>-->
<!-- </el-select>-->
<!-- <el-input-->
<!-- v-model="queryParams.payMemberType"-->
<!-- placeholder="请输入用户会员类型"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- class="!w-240px"-->
<!-- />-->
<el-select v-model ="queryParams.payMemberType" placeholder="请选择会员类型" @keyup.enter="handleQuery" class="!w-240px">
<el-option v-for ="item in cardlist"
:key="item.id"
:label="item.name"
:value="item.name"/>
</el-select>
</el-form-item>
<el-form-item label="支付方式" prop="payType">
<!-- <el-input-->
@ -108,7 +108,7 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import { PaidMemberUserApi, PaidMemberUserVO } from '@/api/member/memberuser'
import * as CardApi from '@/api/member/type'
import * as CardVoApid from '@/api/member/type'
import PaidMemberUserForm from './PaidMemberUserForm.vue'
/** 付费会员 列表 */
@ -217,10 +217,10 @@ const handleExport = async () => {
}
}
const cardlist = ref<CardApi.cardVO[]>([])//
const cardlist = ref<CardVoApid.cardVO[]>([])//
/** 初始化 **/
onMounted(async () => {
await getList()
cardlist.value = (await CardApi.getcardlist()) as CardApi.cardVO[]
cardlist.value = (await CardVoApid.cardApi.getcardlist()) as CardVoApid.cardVO[]
})
</script>

View File

@ -69,8 +69,9 @@ public interface ErrorCodeConstants {
ErrorCode MEMBER_USER_NOT_EXISTS = new ErrorCode(1_004_021_000, "会员不存在");
ErrorCode PAID_MEMBER_ORDER_NOT_EXISTS = new ErrorCode(1_004_022_000, "付费会员订单不存在");
ErrorCode PAID_MEMBER_USER_ORDER_NO_NOT_EXISTS = new ErrorCode(1_004_023_000, "生成会员订单号失败,请重新提交");
ErrorCode PAID_MEMBER_USER_NOT_OPEN = new ErrorCode(1_004_021_000, "会员未开通");
ErrorCode PAID_MEMBER_USER_PASSED = new ErrorCode(1_004_021_000, "会员已过期");
ErrorCode PAID_MEMBER_USER_NOT_OPEN = new ErrorCode(1_004_024_000, "会员未开通");
ErrorCode PAID_MEMBER_USER_PASSED = new ErrorCode(1_004_025_000, "会员已过期");
ErrorCode PAID_MEMBER_CONFIG_NOT_EXISTS = new ErrorCode(1_004_026_000, "付费会员配置不存在");
}

View File

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.member.controller.admin.memberconfig;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.member.controller.admin.memberconfig.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.memberconfig.PaidMemberConfigDO;
import cn.iocoder.yudao.module.member.service.memberconfig.PaidMemberConfigService;
@Tag(name = "管理后台 - 付费会员配置")
@RestController
@RequestMapping("/member/paid-member-config")
@Validated
public class PaidMemberConfigController {
@Resource
private PaidMemberConfigService paidMemberConfigService;
@PutMapping("/save")
@Operation(summary = "保存付费会员配置")
@PreAuthorize("@ss.hasPermission('member:paid-member-config:save')")
public CommonResult<Boolean> updatePaidMemberConfig(@Valid @RequestBody PaidMemberConfigSaveReqVO saveReqVO) {
paidMemberConfigService.saveConfig(saveReqVO);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得付费会员配置")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('member:paid-member-config:query')")
public CommonResult<PaidMemberConfigRespVO> getPaidMemberConfig() {
PaidMemberConfigDO paidMemberConfig = paidMemberConfigService.getConfig();
return success(BeanUtils.toBean(paidMemberConfig, PaidMemberConfigRespVO.class));
}
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.member.controller.admin.memberconfig.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 付费会员配置分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PaidMemberConfigPageReqVO extends PageParam {
@Schema(description = "开启付费会员")
private Boolean openPaidMember;
@Schema(description = "商品付费会员价", example = "20313")
private Boolean paidMemberPrice;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.member.controller.admin.memberconfig.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 付费会员配置 Response VO")
@Data
@ExcelIgnoreUnannotated
public class PaidMemberConfigRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "9256")
@ExcelProperty("编号")
private Long id;
@Schema(description = "开启付费会员", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("开启付费会员")
private Boolean openPaidMember;
@Schema(description = "商品付费会员价", requiredMode = Schema.RequiredMode.REQUIRED, example = "20313")
@ExcelProperty("商品付费会员价")
private Boolean paidMemberPrice;
@Schema(description = "创建时间")
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.member.controller.admin.memberconfig.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 付费会员配置新增/修改 Request VO")
@Data
public class PaidMemberConfigSaveReqVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "9256")
private Long id;
@Schema(description = "开启付费会员", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "开启付费会员不能为空")
private Boolean openPaidMember;
@Schema(description = "商品付费会员价", requiredMode = Schema.RequiredMode.REQUIRED, example = "20313")
private Boolean paidMemberPrice;
}

View File

@ -4,6 +4,9 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "用户 APP - 用户个人信息 Response VO")
@Data
@ -45,6 +48,7 @@ public class AppMemberUserInfoRespVO {
private String cardName;
@Schema(description = "会员名称", requiredMode = Schema.RequiredMode.REQUIRED)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private String cardExpirationTime;
@Schema(description = "用户 App - 会员等级")

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.member.convert.memberconfig;
import cn.iocoder.yudao.module.member.controller.admin.memberconfig.vo.PaidMemberConfigSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.memberconfig.PaidMemberConfigDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* 付费会员配置 Convert
*
*/
@Mapper
public interface PaidMemberConfigConvert {
PaidMemberConfigConvert INSTANCE = Mappers.getMapper(PaidMemberConfigConvert.class);
PaidMemberConfigDO convert(PaidMemberConfigSaveReqVO bean);
}

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.member.dal.dataobject.memberconfig;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 付费会员配置 DO
*
* @author 管理员
*/
@TableName("paid_member_config")
@KeySequence("paid_member_config_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PaidMemberConfigDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 开启付费会员
*/
private Boolean openPaidMember;
/**
* 商品付费会员价
*/
private Boolean paidMemberPrice;
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.member.dal.mysql.memberconfig;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.member.dal.dataobject.memberconfig.PaidMemberConfigDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.member.controller.admin.memberconfig.vo.*;
/**
* 付费会员配置 Mapper
*
* @author 管理员
*/
@Mapper
public interface PaidMemberConfigMapper extends BaseMapperX<PaidMemberConfigDO> {
default PageResult<PaidMemberConfigDO> selectPage(PaidMemberConfigPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<PaidMemberConfigDO>()
.eqIfPresent(PaidMemberConfigDO::getOpenPaidMember, reqVO.getOpenPaidMember())
.eqIfPresent(PaidMemberConfigDO::getPaidMemberPrice, reqVO.getPaidMemberPrice())
.betweenIfPresent(PaidMemberConfigDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(PaidMemberConfigDO::getId));
}
}

View File

@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.member.service.memberconfig;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.member.controller.admin.memberconfig.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.memberconfig.PaidMemberConfigDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
/**
* 付费会员配置 Service 接口
*
* @author 管理员
*/
public interface PaidMemberConfigService {
/**
* 创建付费会员配置
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createPaidMemberConfig(@Valid PaidMemberConfigSaveReqVO createReqVO);
/**
* 更新付费会员配置
*
* @param updateReqVO 更新信息
*/
void updatePaidMemberConfig(@Valid PaidMemberConfigSaveReqVO updateReqVO);
/**
* 删除付费会员配置
*
* @param id 编号
*/
void deletePaidMemberConfig(Long id);
/**
* 获得付费会员配置
*
* @param id 编号
* @return 付费会员配置
*/
PaidMemberConfigDO getPaidMemberConfig(Long id);
/**
* 获得付费会员配置分页
*
* @param pageReqVO 分页查询
* @return 付费会员配置分页
*/
PageResult<PaidMemberConfigDO> getPaidMemberConfigPage(PaidMemberConfigPageReqVO pageReqVO);
/**
* 获得付费会员配置
*
* @return 会员配置
*/
PaidMemberConfigDO getConfig();
void saveConfig(PaidMemberConfigSaveReqVO saveReqVO);
}

View File

@ -0,0 +1,94 @@
package cn.iocoder.yudao.module.member.service.memberconfig;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.member.convert.memberconfig.PaidMemberConfigConvert;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.member.controller.admin.memberconfig.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.memberconfig.PaidMemberConfigDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.dal.mysql.memberconfig.PaidMemberConfigMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
/**
* 付费会员配置 Service 实现类
*
* @author 管理员
*/
@Service
@Validated
public class PaidMemberConfigServiceImpl implements PaidMemberConfigService {
@Resource
private PaidMemberConfigMapper paidMemberConfigMapper;
@Override
public Long createPaidMemberConfig(PaidMemberConfigSaveReqVO createReqVO) {
// 插入
PaidMemberConfigDO paidMemberConfig = BeanUtils.toBean(createReqVO, PaidMemberConfigDO.class);
paidMemberConfigMapper.insert(paidMemberConfig);
// 返回
return paidMemberConfig.getId();
}
@Override
public void updatePaidMemberConfig(PaidMemberConfigSaveReqVO updateReqVO) {
// 校验存在
validatePaidMemberConfigExists(updateReqVO.getId());
// 更新
PaidMemberConfigDO updateObj = BeanUtils.toBean(updateReqVO, PaidMemberConfigDO.class);
paidMemberConfigMapper.updateById(updateObj);
}
@Override
public void deletePaidMemberConfig(Long id) {
// 校验存在
validatePaidMemberConfigExists(id);
// 删除
paidMemberConfigMapper.deleteById(id);
}
private void validatePaidMemberConfigExists(Long id) {
if (paidMemberConfigMapper.selectById(id) == null) {
throw exception(PAID_MEMBER_CONFIG_NOT_EXISTS);
}
}
@Override
public PaidMemberConfigDO getPaidMemberConfig(Long id) {
return paidMemberConfigMapper.selectById(id);
}
@Override
public PageResult<PaidMemberConfigDO> getPaidMemberConfigPage(PaidMemberConfigPageReqVO pageReqVO) {
return paidMemberConfigMapper.selectPage(pageReqVO);
}
@Override
public PaidMemberConfigDO getConfig() {
List<PaidMemberConfigDO> list = paidMemberConfigMapper.selectList();
return CollectionUtils.getFirst(list);
}
@Override
public void saveConfig(PaidMemberConfigSaveReqVO saveReqVO) {
//存在则更新
PaidMemberConfigDO paidMemberConfigDO = getConfig();
if(paidMemberConfigDO != null){
paidMemberConfigMapper.updateById(PaidMemberConfigConvert.INSTANCE.convert(saveReqVO).setId(paidMemberConfigDO.getId()));
return;
}
//不存在则进行插入
paidMemberConfigMapper.insert(PaidMemberConfigConvert.INSTANCE.convert(saveReqVO));
}
}

View File

@ -322,7 +322,7 @@ public class MemberUserServiceImpl implements MemberUserService {
validateMobileUnique(memberUserDO.getId(), memberUserDO.getMobile());
// 更新
if(memberUserDO.getLevelId() == 5){
if(memberUserDO.getLevelId() != null && memberUserDO.getLevelId() == 5){
memberUserDO.setLevelId(Long.parseLong("1"));
}
memberUserMapper.updateById(memberUserDO);

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.dal.mysql.order;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
@ -59,4 +60,9 @@ public interface PayOrderMapper extends BaseMapperX<PayOrderDO> {
.lt(PayOrderDO::getExpireTime, expireTime));
}
default PayOrderDO selectByAppIdAndMerchantOrderIdAndSubject(Long appId, String merchantOrderId, String subject){
return selectOne(PayOrderDO::getAppId, appId,
PayOrderDO::getMerchantOrderId, merchantOrderId,
PayOrderDO::getSubject,subject);
}
}

View File

@ -120,10 +120,14 @@ public class PayOrderServiceImpl implements PayOrderService {
public Long createOrder(PayOrderCreateReqDTO reqDTO) {
// 校验 App
PayAppDO app = appService.validPayApp(reqDTO.getAppId());
// 查询对应的支付交易单是否已经存在如果是则直接返回
PayOrderDO order = orderMapper.selectByAppIdAndMerchantOrderId(
reqDTO.getAppId(), reqDTO.getMerchantOrderId());
if(reqDTO.getSubject() != null && reqDTO.getSubject().equals("会员支付购卡")){
/// 查询对应的会员购卡是否已经存在如果是则直接返回(付费会员订单)
order = orderMapper.selectByAppIdAndMerchantOrderIdAndSubject(reqDTO.getAppId(),reqDTO.getMerchantOrderId()
,reqDTO.getSubject());
}
if (order != null) {
log.warn("[createOrder][appId({}) merchantOrderId({}) 已经存在对应的支付单({})]", order.getAppId(),
order.getMerchantOrderId(), toJsonString(order)); // 理论来说不会出现这个情况